update
This commit is contained in:
@@ -2,27 +2,127 @@
|
||||
|
||||
**ID:** ORG-002
|
||||
**Priority:** Critical
|
||||
**Status:** Planned
|
||||
**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
|
||||
- [ ] 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
|
||||
- [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
|
||||
- Need new Invitation model with token and expiry
|
||||
- Use `ReceptionMailer` for invitation emails
|
||||
- RoleManager can be leveraged for role assignment
|
||||
- Consider invitation expiry (7 days default)
|
||||
- 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
|
||||
- New feature - core organizational functionality
|
||||
- [ ] 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
|
||||
|
||||
Reference in New Issue
Block a user