833cf3b4b8
- Marked the status of "Invite and Manage Team Members" story as Complete in README. - Updated the status of ORG-002 to Complete in the corresponding markdown file. - Modified OrganizationManager to assign roles as 'owner' during organization creation. - Implemented bulk invitation feature in UserInvitationManager, allowing multiple users to be invited via CSV upload. - Added IReq_BulkCreateInvitations interface for bulk invitation requests. - Enhanced CreateOrgForm to update state with new roles upon organization creation. - Introduced BulkInviteModal for bulk inviting users, including email validation and role assignment. - Updated UsersView to support ownership transfer and bulk invitation functionality. - Improved account state management to handle new roles and organizations.
4.3 KiB
4.3 KiB
Invite and Manage Team Members
ID: ORG-002 Priority: Critical Status: Complete
User Story
As an organization owner, I want to invite team members to my organization and manage their access so that my team can collaborate securely.
Acceptance Criteria
- Owner can invite users via email address
- Invited user receives email with invitation link
- Invitation can be accepted by existing users or during registration
- Owner can view pending invitations and resend/cancel them
- Owner can see all current members with their roles
- Owner can remove members from organization
- Owner can transfer ownership to another member
- Bulk invite via CSV upload
Technical Implementation
UserInvitation System
The invitation system uses a shared UserInvitation model that supports multiple organizations inviting the same email address.
Invitation Lifecycle
- Create: Org admin invites email →
UserInvitationcreated (or existing one is updated) - Share: Multiple orgs can link to the same invitation (by email)
- Convert: When user registers with that email → invitation converts to real User
- Fold: If existing user adds that email as secondary → invitation folds into existing user
- Expire: Auto-delete after 90 days with cleanup of all org refs
Data Model
// IUserInvitation
{
id: string;
data: {
email: string; // Unique key for sharing
token: string; // Secure invitation link token
status: 'pending' | 'accepted' | 'expired' | 'cancelled';
createdAt: number;
expiresAt: number; // 90 days from creation
organizationRefs: Array<{ // Multiple orgs can share
organizationId: string;
invitedByUserId: string;
invitedAt: number;
roles: string[]; // Roles to assign on acceptance
}>;
acceptedAt?: number;
convertedToUserId?: string;
};
}
Role System Enhancement
Users can have multiple roles within an organization:
// IRole
{
id: string;
data: {
userId: string;
organizationId: string;
roles: string[]; // e.g., ['owner', 'billing-admin', 'developer']
};
}
Standard roles: owner, admin, editor, viewer, guest
Custom roles are also supported.
API Endpoints
| Method | Purpose |
|---|---|
createInvitation |
Invite email to org with roles |
getOrgInvitations |
List pending invitations |
getOrgMembers |
List members with roles |
cancelInvitation |
Cancel pending invitation |
resendInvitation |
Resend invitation email |
removeMember |
Remove user from org |
updateMemberRoles |
Change member's roles |
transferOwnership |
Transfer org ownership |
acceptInvitation |
Accept invitation |
getInvitationByToken |
Get invitation details for landing page |
Frontend Implementation
The Users page (/account/org/:orgName/users) provides:
- Members tab: List all members with roles, remove/edit actions
- Pending tab: List pending invitations with resend/cancel
- Invite tab: Form to invite by email with role selection
Files
Backend:
ts_interfaces/data/loint-reception.userinvitation.ts- Data interfacets_interfaces/request/loint-reception.userinvitation.ts- API contractsts/reception/classes.userinvitation.ts- Modelts/reception/classes.userinvitationmanager.ts- Manager with handlersts/reception/classes.receptionmailer.ts- Invitation email
Frontend:
ts_web/elements/account/views/usersview.ts- Users page componentts_web/elements/account/content.ts- Route registrationts_web/elements/account/navigation.ts- Nav link
Technical Notes
- Organization and User models exist with association
- UserInvitation model stores invitation data with 90-day expiry
ReceptionMailer.sendInvitationEmail()handles email delivery- RoleManager updated to support
roles: string[]array - Backward compatible with existing single-role data
Related Stories
- ORG-003: Assign Roles to Members (enhanced with multi-role support)
Related TODOs
- Integrate invitation acceptance into registration flow
- Add email verification flow for secondary emails (folding)
- Implement scheduled cleanup job for expired invitations
- Add CSV bulk invite feature