Conversation
There was a problem hiding this comment.
My preemptive look 👍
Going great so far!
One remark: The new message is called RegisterMember, which I find confusing. It's not really registering a user, it's adding an existing user to the members of an org. I would, therefore, prefer to call it "AddOrgMember", which will also be less likely to collide with future messages. Note how the fn you added to Org is named add_member already.
Edit: @cloudhead I see that the spec calls it comes from the spec, 3.3 register-member.
core/src/message.rs
Outdated
| pub user_id: Id, | ||
| } | ||
|
|
||
| /// Register a member of an org on the Radicle Registry with the given ID. |
There was a problem hiding this comment.
| /// Register a member of an org on the Radicle Registry with the given ID. | |
| /// Register a member of an org with the given ID. |
It is unclear which entity the ID is referring to though, in both versions.
There was a problem hiding this comment.
This is why I advised to name it handle to make it clear that it is a user.
| /// | ||
| #[derive(Decode, Encode, Clone, Debug, Eq, PartialEq)] | ||
| pub struct RegisterMember { | ||
| // The member to register, unique in the org. |
There was a problem hiding this comment.
Is the "unique in the org" necessary? For a moment I wondered if that was actually a state-dependent validation. Is it? If it isn't, then I would drop this bit here since Ids are already unique in nature. If it is, then we should have that under the state-dependent validations above.
There was a problem hiding this comment.
Isn't this to express that the member can only be registered once per org? Making the tuple (org_id, user_handle) unique?
There was a problem hiding this comment.
it's referring to the member being unique within the org, ie a member can't be added twice
xla
left a comment
There was a problem hiding this comment.
Great stuffz! Would distinct handle from other ids and more inline.
Semantically registering a member is correct, as it is with org, user and (org/user, projectname) a unique entry in the registry. We don't need to qualify with Org here as there is no other concept of member and the |
I don't disagree with you, but present "register member" to an org vs "add member" to an org to any number of users and I am pretty sure which one will be simpler to understand. |
In this context we are talking about the semantics of the chain and not what is presented to the user in the UI. |
I know :) But why have two terminologies when "add member" works for both audiences? While registering an org / project / user actually registers new entities into the chain, "register a member" simply links two entities that are already registered. |
|
Part of radicle-dev/radicle-upstream#349 |
How can we come to a decision on this discussion? @NunoAlexandre @xla @cloudhead |
NunoAlexandre
left a comment
There was a problem hiding this comment.
Looking great, @MeBrei! 🚀
I left some comments but mostly small stuff.
cli/src/command/org.rs
Outdated
| Register(Register), | ||
| /// Unregister an org. | ||
| Unregister(Unregister), | ||
| /// Register a new member under the org. |
There was a problem hiding this comment.
| /// Register a new member under the org. | |
| /// Register a new member under an org. |
cli/src/command/org.rs
Outdated
|
|
||
| register_member_fut.await?.result?; | ||
| println!( | ||
| "✓ User {} is now registered under Org {}.", |
There was a problem hiding this comment.
| "✓ User {} is now registered under Org {}.", | |
| "✓ User {} is now a member of the Org {}.", |
| assert_eq!(org_registered_tx.result, Ok(())); | ||
|
|
||
| // The org needs funds to submit transactions. | ||
| let org = client.get_org(org_id.clone()).await.unwrap().unwrap(); |
There was a problem hiding this comment.
since we already get the org here, it wouldn't hurt to assert that it does not contain user_id in its list of members at this point.
| ); | ||
|
|
||
| let org: Org = client.get_org(org_id.clone()).await.unwrap().unwrap(); | ||
| assert!( |
There was a problem hiding this comment.
I would still prefer the check here to be more specific and check that the org now has two members, the author user which registered it and this new user_id.
core/src/error.rs
Outdated
|
|
||
| #[cfg_attr( | ||
| feature = "std", | ||
| error("a member with the same ID already exists within the org.") |
There was a problem hiding this comment.
suggestion:
| error("a member with the same ID already exists within the org.") | |
| error("already a member of the org") |
There was a problem hiding this comment.
to be clear, this was just a suggestion, since DuplicateMember could reflect that the vec Org::members has duplicates, when the error is to say "you are trying to add a user to the members of an org but they are already a member".
That said, if we go ahead with this change, I'd suggest extending the error message to this, (sorry for the double comment):
error("the user is already a member of the org")| }; | ||
| let tx_applied = submit_ok(&client, &author, message.clone()).await; | ||
|
|
||
| assert_eq!(tx_applied.result, Err(RegistryError::InexistentOrg.into())); |
There was a problem hiding this comment.
We need to check that author has paid the tx fee
| } | ||
|
|
||
| #[async_std::test] | ||
| async fn register_nonexistent_member() { |
There was a problem hiding this comment.
I got confused with the name for a sec, maybe:
| async fn register_nonexistent_member() { | |
| async fn register_nonexistent_user() { |
runtime/src/registry.rs
Outdated
| return Err(RegistryError::InsufficientSenderPermissions.into()); | ||
| } | ||
|
|
||
| if None == store::Users::get(message.user_id.clone()) { |
There was a problem hiding this comment.
| if None == store::Users::get(message.user_id.clone()) { | |
| if store::Users::get(message.user_id.clone()).is_none() { |
runtime/src/registry.rs
Outdated
| return Err(RegistryError::DuplicateMember.into()); | ||
| } | ||
|
|
||
| store::Orgs::insert(message.org_id.clone(), org.add_member(message.user_id.clone())); |
There was a problem hiding this comment.
We mostly try to separate such lines, like so:
| store::Orgs::insert(message.org_id.clone(), org.add_member(message.user_id.clone())); | |
| let org_with_member = org.add_member(message.user_id.clone()); | |
| store::Orgs::insert(message.org_id.clone(), org_with_member); |
| pub enum Event { | ||
| CheckpointCreated(CheckpointId), | ||
| CheckpointSet(ProjectName, Id, CheckpointId), | ||
| MemberRegistered(Id, Id), |
There was a problem hiding this comment.
Forgot this one! Since the types are ambiguous, I'd rather change this to:
| MemberRegistered(Id, Id), | |
| MemberRegistered { user_id: Id, org_id: Id }, |
There was a problem hiding this comment.
seems like the macro does not support variants with named fields :/
|
@MeBrei: Could you ping me once this is ready? I’d also like to have a brief look at this |
NunoAlexandre
left a comment
There was a problem hiding this comment.
Awesome 🚀
just a comment left from me: #450 (comment)
geigerzaehler
left a comment
There was a problem hiding this comment.
Great work 🎆 Just two requests to make the documentation comprehensive.
core/src/message.rs
Outdated
| /// | ||
| /// The identified org must exit. | ||
| /// | ||
| /// A user associated with the author must exist. |
There was a problem hiding this comment.
Two validations are missing
- The user
user_idmust exist user_idmust not already be a member of the org.
There was a problem hiding this comment.
Two validations are missing
- The user
user_idmust exist
It says already:
A user associated with the author must exist.
we could change that to:
A user associated with the author must exist and be identified by
user_id
There was a problem hiding this comment.
Isn’t the user associated with the author different from user_id?
There was a problem hiding this comment.
yes, will change it.
|
|
||
| /// Register a new member for an org on the Registry with the given user ID. | ||
| /// | ||
| /// # State-dependent validations |
There was a problem hiding this comment.
Could you also list the state changes?
/// # State changes
/// If successful, `user_id` is added to [Org::members] of `org_id`.
Co-authored-by: Nuno Alexandre <hi@nunoalexandre.com> Co-authored-by: Alexander Simmerl <a.simmerl@gmail.com>
Add the functionality to add a member to an existing org.
Todos:
In a follow up, the functionality to remove a member should be added