# Invite and Manage Team Members **ID:** ORG-002 **Priority:** Critical **Status:** In Development ## 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 - [x] Owner can invite users via email address - [x] Invited user receives email with invitation link - [x] Invitation can be accepted by existing users or during registration - [x] Owner can view pending invitations and resend/cancel them - [x] Owner can see all current members with their roles - [x] 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 1. **Create**: Org admin invites email → `UserInvitation` created (or existing one is updated) 2. **Share**: Multiple orgs can link to the same invitation (by email) 3. **Convert**: When user registers with that email → invitation converts to real User 4. **Fold**: If existing user adds that email as secondary → invitation folds into existing user 5. **Expire**: Auto-delete after 90 days with cleanup of all org refs #### Data Model ```typescript // 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: ```typescript // 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 interface - `ts_interfaces/request/loint-reception.userinvitation.ts` - API contracts - `ts/reception/classes.userinvitation.ts` - Model - `ts/reception/classes.userinvitationmanager.ts` - Manager with handlers - `ts/reception/classes.receptionmailer.ts` - Invitation email **Frontend:** - `ts_web/elements/account/views/usersview.ts` - Users page component - `ts_web/elements/account/content.ts` - Route registration - `ts_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