Use Case 017: Team Member Invitation and Collaboration
Overview
| Property | Value |
|---|---|
| Use Case ID | UC-017 |
| Use Case Name | Team Member Invitation and Collaboration |
| Module | Identity Management - Team Collaboration |
| Priority | Medium |
| Status | Implemented |
| Version | 1.0 |
| Last Updated | February 23, 2026 |
Description
This use case describes how ApplicationUsers can invite team members to collaborate within their tenant or organization, assign role-based permissions, and manage team access across multiple applications. Team members can be invited with customizable access levels, receive onboarding emails, and gain independent permission management while maintaining tenant isolation and security boundaries.
Actors
| Actor | Description | Role |
|---|---|---|
| Team Owner | ApplicationUser with team management capabilities | Primary |
| Team Member | Invited user joining an existing team/tenant | Primary |
| System | Application Manager platform | Supporting |
| Email Service | SMTP or AWS SES for invitation emails | Supporting |
| Administrator | System admin monitoring team activity (optional) | Secondary |
Preconditions
- Application Manager is running and accessible
- Team Owner is authenticated ApplicationUser with
team:invitecapability - Team Owner's tenant is active
- Email service is configured and operational
- At least one role is defined for team member assignment
- Target email address is available (not already in tenant)
Postconditions
Success Postconditions
- Team member invitation record created in database
- Invitation email sent with secure token link
- Upon acceptance, new ApplicationUser created and linked to team/tenant
- Team member assigned specified roles and application access
- Team member inherits tenant context from Team Owner
- Activity logged in audit trail
- Team dashboard updated with new member
Failure Postconditions
- No invitation created if validation fails
- Error message logged and returned to Team Owner
- Duplicate invitation prevented (email already in tenant)
- Expired tokens rejected with clear error messages
Triggers
- Team Owner clicks "Invite Team Member" in team management interface
- Team Owner submits invitation form with email and role
- API client calls
/api/v1/teams/invitationsPOST endpoint - Invited user clicks invitation link in email
- Team Owner resends expired invitation
Basic Flow (Happy Path)
Alternative Flows
Alt-1: Duplicate Invitation
Trigger: Team Owner invites email already in tenant
Flow:
- API validates invitation email
- DB query finds existing ApplicationUser with same email in tenant
- API returns 409 Conflict error
- Web displays: "User with this email is already a team member"
- Team Owner can view existing member in team list
Alt-2: Invitation Expired
Trigger: Team Member clicks link after expiration (default: 7 days)
Flow:
- Team Member clicks invitation link
- API validates token
- DB query shows invitation expired
- Web displays: "This invitation has expired"
- Web shows "Request New Invitation" button
- Team Member can contact Team Owner for new invitation
- Team Owner can resend invitation via UI
Alt-3: Resend Invitation
Trigger: Team Owner resends invitationto user who hasn't accepted
Flow:
- Owner clicks "Resend" on pending invitation
- API generates new token with fresh expiration
- DB updates invitation record with new token
- Email service sends new invitation email
- Previous token is invalidated
- Web confirms: "Invitation resent successfully"
Alt-4: Invitation Rejected/Cancelled
Trigger: Team Member declines or Team Owner cancels invitation
Flow:
- User clicks "Decline Invitation" or Owner clicks "Cancel"
- API marks invitation as rejected/cancelled
- DB updates invitation status
- Token invalidated
- Audit log records action
- Team Owner notified if Member declined
Alt-5: External Identity Provider User
Trigger: Team Member email matches existing SSO user
Flow:
- Team Member accepts invitation
- API detects email matches SSO provider user
- Web prompts: "Sign in with [Provider]"
- User authenticates via SSO
- API links SSO identity to team/tenant
- User granted team access without password
Business Rules
Invitation Rules
- BR-017-01: Invitation tokens expire after 7 days by default (configurable)
- BR-017-02: One active invitation per email per tenant at a time
- BR-017-03: Invitation email must not already exist as active user in tenant
- BR-017-04: Team Owner must have
team:invitecapability - BR-017-05: Invited user inherits Team Owner's tenant context
- BR-017-06: Maximum pending invitations per tenant: 50 (configurable)
Role Assignment Rules
- BR-017-07: Team Owner can only assign roles they possess or below their level
- BR-017-08: At least one role must be assigned to team member
- BR-017-09: Application access limited to apps Team Owner has access to
- BR-017-10: Admin roles cannot be assigned via team invitation
Token Security Rules
- BR-017-11: Invitation tokens are cryptographically random (256-bit)
- BR-017-12: Tokens are single-use only
- BR-017-13: Expired or used tokens return 403 Forbidden
- BR-017-14: Token validation must check expiration and status
Data Requirements
TeamInvitation Entity
| Field | Type | Constraints | Description |
|---|---|---|---|
Id |
Guid | Primary Key | Unique invitation identifier |
TenantId |
Guid | Required, FK | Target tenant |
InvitedBy |
Guid | Required, FK | Team Owner's user ID |
Email |
string(255) | Required | Invitee email address |
Token |
string(512) | Required, Unique | Secure invitation token |
Status |
enum | Required | Pending, Accepted, Rejected, Expired, Cancelled |
Roles |
JSON | Required | Array of role IDs to assign |
ApplicationIds |
JSON | Required | Array of app IDs for access |
PersonalMessage |
string(1000) | Optional | Custom message from inviter |
ExpiresAt |
DateTimeOffset | Required | Token expiration time |
CreatedAt |
DateTimeOffset | Required | Invitation creation time |
AcceptedAt |
DateTimeOffset | Nullable | Acceptance timestamp |
AcceptedByUserId |
Guid | Nullable, FK | Created user ID after acceptance |
TeamMember View
| Field | Type | Description |
|---|---|---|
UserId |
Guid | Team member user ID |
Email |
string | User email |
FullName |
string | User display name |
Roles |
Array | Assigned role names |
JoinedAt |
DateTimeOffset | Team join date |
LastActiveAt |
DateTimeOffset | Last activity timestamp |
Status |
enum | Active, Suspended, Removed |
User Interface
Team Management Dashboard
Components:
- Team member list with roles and status
- "Invite Team Member" button (if user has capability)
- Pending invitations section
- Search and filter team members
- Bulk role assignment controls
Invitation Form
Fields:
- Email address (required, validated)
- Roles (multi-select dropdown, required)
- Application access (multi-select dropdown, pre-filled with Owner's apps)
- Personal message (optional, 1000 char max)
- "Send Invitation" button
Example:
┌─────────────────────────────────────────┐
│ Invite Team Member │
├─────────────────────────────────────────┤
│ Email Address * │
│ [_________________________________] │
│ │
│ Roles * │
│ [✓] Developer │
│ [ ] Viewer │
│ [ ] Content Manager │
│ │
│ Application Access * │
│ [✓] Workflow Designer │
│ [✓] Configuration Manager │
│ [ ] Fee Manager │
│ │
│ Personal Message (Optional) │
│ [_________________________________] │
│ [_________________________________] │
│ │
│ [Cancel] [Send Invitation] │
└─────────────────────────────────────────┘
Invitation Acceptance Page
Components:
- Team/organization name and logo
- Inviter name and message
- Sign up form (name, password)
- "Accept Invitation" button
- "Decline" link
API Endpoints
Create Team Invitation
Endpoint: POST /api/v1/teams/invitations
Headers:
Authorization: Bearer {user_token}
Content-Type: application/json
Request Body:
{
"email": "newmember@example.com",
"roles": ["role-id-1", "role-id-2"],
"applicationIds": ["app-id-1", "app-id-2"],
"personalMessage": "Welcome to our team! Looking forward to working with you."
}
Response: 201 Created
{
"invitationId": "550e8400-e29b-41d4-a716-446655440000",
"email": "newmember@example.com",
"invitedBy": {
"userId": "123e4567-e89b-12d3-a456-426614174000",
"fullName": "Jane Smith"
},
"status": "Pending",
"expiresAt": "2026-03-02T10:30:00Z",
"createdAt": "2026-02-23T10:30:00Z",
"invitationLink": "https://app-manager.example.com/invitations/accept?token=abc123..."
}
Verify Invitation Token
Endpoint: GET /api/v1/invitations/verify?token={token}
Response: 200 OK
{
"valid": true,
"invitationId": "550e8400-e29b-41d4-a716-446655440000",
"email": "newmember@example.com",
"teamName": "Acme Corp Development Team",
"invitedBy": "Jane Smith",
"roles": [
{"id": "role-1", "name": "Developer"},
{"id": "role-2", "name": "Viewer"}
],
"applications": [
{"id": "app-1", "name": "Workflow Designer"},
{"id": "app-2", "name": "Configuration Manager"}
],
"expiresAt": "2026-03-02T10:30:00Z"
}
Accept Invitation
Endpoint: POST /api/v1/invitations/accept
Request Body:
{
"token": "abc123xyz789...",
"fullName": "John Doe",
"password": "SecureP@ssw0rd123",
"acceptTerms": true
}
Response: 201 Created
{
"userId": "789e4567-e89b-12d3-a456-426614174999",
"email": "newmember@example.com",
"fullName": "John Doe",
"tenantId": "tenant-123",
"roles": ["Developer", "Viewer"],
"applications": ["Workflow Designer", "Configuration Manager"],
"loginToken": "ey...",
"sessionToken": "ey..."
}
List Team Members
Endpoint: GET /api/v1/teams/members
Query Parameters:
status: Filter by status (Active, Suspended, Removed)search: Search by name or emailpage: Page numberpageSize: Results per page
Response: 200 OK
{
"members": [
{
"userId": "123e4567-e89b-12d3-a456-426614174000",
"email": "jane@example.com",
"fullName": "Jane Smith",
"roles": ["Admin", "Developer"],
"joinedAt": "2025-01-15T10:00:00Z",
"lastActiveAt": "2026-02-23T09:15:00Z",
"status": "Active"
},
{
"userId": "789e4567-e89b-12d3-a456-426614174999",
"email": "john@example.com",
"fullName": "John Doe",
"roles": ["Developer", "Viewer"],
"joinedAt": "2026-02-23T10:45:00Z",
"lastActiveAt": "2026-02-23T10:45:00Z",
"status": "Active"
}
],
"pagination": {
"page": 1,
"pageSize": 20,
"totalCount": 2,
"totalPages": 1
}
}
Resend Invitation
Endpoint: POST /api/v1/invitations/{invitationId}/resend
Response: 200 OK
{
"invitationId": "550e8400-e29b-41d4-a716-446655440000",
"newToken": "xyz789...",
"newExpiresAt": "2026-03-09T11:00:00Z",
"emailSent": true
}
Performance Requirements
- PR-017-01: Invitation creation completed within 2 seconds
- PR-017-02: Token validation completed within 100ms
- PR-017-03: Invitation acceptance (user creation) completed within 3 seconds
- PR-017-04: Team member list loads within 1 second for teams up to 1000 members
- PR-017-05: Email delivery initiated within 5 seconds of invitation creation
Security Considerations
Authentication & Authorization
- Team Owner must be authenticated ApplicationUser
team:invitecapability required to create invitations- Invitation tokens transmitted only via secure email
- HTTPS required for all invitation acceptance flows
Token Security
- Invitation tokens cryptographically random (256-bit)
- Tokens hashed before storage in database
- Single-use tokens invalidated after acceptance
- Expired tokens rejected with 403 Forbidden
Data Protection
- Invitation emails sanitized to prevent injection attacks
- Personal messages limited to 1000 characters
- Rate limiting: Max 10 invitations per user per hour
- Audit trail for all invitation activities
Tenant Isolation
- Team members strictly isolated to inviter's tenant
- Cross-tenant invitation attempts blocked
- Tenant boundary enforced in all queries
Testing Scenarios
Test Case TC-017-01: Successful Team Member Invitation
Preconditions:
- Team Owner authenticated with
team:invitecapability - Email service configured
Steps:
- Team Owner submits invitation for "newuser@example.com"
- System creates invitation record
- System sends email
- New user receives email and clicks link
- New user completes signup form
- System creates ApplicationUser and links to tenant
- New user redirected to dashboard
Expected Results:
- Invitation record created with status "Accepted"
- ApplicationUser created with correct tenant
- Roles and apps assigned as specified
- Audit log contains invitation and acceptance events
Test Case TC-017-02: Duplicate Email Prevention
Steps:
- Team Owner invites "existing@example.com"
- System checks email against tenant users
Expected Results:
- 409 Conflict error returned
- Error message: "User with this email is already a team member"
- No invitation created
Test Case TC-017-03: Expired Token Rejection
Steps:
- Create invitation with expiration in past
- User attempts to accept invitation
Expected Results:
- 403 Forbidden error returned
- Error message: "This invitation has expired"
- No user created
Test Case TC-017-04: Invitation Resend
Steps:
- Team Owner creates invitation
- Team Owner clicks "Resend" after 3 days
- New email sent with new token
Expected Results:
- Old token invalidated
- New token generated with fresh expiration
- Email sent with new link
- Invitation record updated
Monitoring and Analytics
Metrics
- invitation.created: Count of invitations created (by tenant, by role)
- invitation.accepted: Count of accepted invitations (time to accept)
- invitation.expired: Count of expired invitations
- invitation.rejected: Count of declined invitations
- team.member.count: Active team members per tenant
- team.growth.rate: Team member additions per week/month
Alerts
- High invitation rejection rate: > 30% within 30 days
- Invitation service failure: Email delivery failures > 5% in 1 hour
- Suspicious invitation activity: > 20 invitations from one user in 1 hour
Dashboards
- Team growth trends
- Invitation acceptance rates
- Average time to invitation acceptance
- Most common roles assigned to new members
Related Use Cases
- UC-005: Administrator User Management - Initial admin creation
- UC-006: Role-Based Access Control - Role assignment to team members
- UC-015: Application User Provisioning - Manual user creation by admins
- UC-003: Application Access Validation - Team member accessing applications
- UC-010: Activity Logging and Audit Trail - Invitation activity logging
Notes and Assumptions
Assumptions
- Email service is reliable and configured
- Users have valid email addresses
- HTTPS is required for invitation links
- Invitation emails may be delayed but eventually delivered
Implementation Notes
- Consider implementing invitation templates for customization
- Future: Support for bulk team member imports via CSV
- Future: Integration with Slack/Teams for invitation notifications
- Future: Role recommendations based on inviter's role and team structure
Edge Cases
- Concurrent invitation acceptance: Last acceptance wins for same email
- Orphaned invitations: Cleanup job deletes invitations > 30 days old
- Team Owner removal: Pending invitations remain valid if Team Owner leaves
- Tenant deactivation: All pending invitations cancelled
Revision History
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0 | 2026-02-23 | System | Initial use case documentation |