Appearance
IE.3: Invitation Status Management
Summary
Counselors can review and revoke client invitations. Invitation status changes happen through accept, reject, revoke, and expiration checks. Expiration is not a separate persisted status in the current service; it is enforced when public details or acceptance are requested.
Role
- Primary: Counselor, Client
- Secondary: Guest, System
Entry Point
- Counselor UI: Clients -> Invitations list
- API:
GET /api/v1/clients/invitations - API:
POST /api/v1/clients/invitations/:invitation_id/revoke - Invitee URL:
/invitations/:token
Preconditions
- Counselor is authenticated and owns the invitation to list or revoke it.
- Invitee is authenticated as the invited email to accept or reject.
- Invitation exists and is pending for any state-changing action.
Steps
- Counselor opens the invitations list.
- Frontend loads paginated invitations with optional search and status filter.
- Backend returns invitations owned by the counselor.
- Counselor can revoke a pending invitation from the row action menu.
- Backend verifies ownership and pending status, then marks the invitation revoked.
- Invitee can accept a pending invitation from
/invitations/:token. - Backend verifies email match, role, pending status, expiration, and no existing relationship.
- Backend marks invitation accepted while creating the relationship.
- Invitee can reject a pending invitation.
- Backend verifies email match and pending status, then marks invitation rejected.
- Public invitation loading rejects expired invitations even if their stored status is still pending.
Diagram
Edge Cases
- Revoke after processing: Only pending invitations can be revoked.
- Reject after processing: Only pending invitations can be rejected.
- Accept after rejection/revocation: Backend returns a bad request because the invitation is no longer pending.
- Expired invitation: Public details and acceptance return errors based on
expires_at. - Wrong counselor: Revoke returns forbidden if the invitation belongs to another counselor.
- Wrong invitee account: Accept/reject returns forbidden if the signed-in email does not match the invited email.
- Status list display: The frontend list displays pending, accepted, rejected, and revoked; expired is enforced as a validation condition.
Current Implementation Notes
- Frontend:
frontend/src/features/clients/components/invitation-list.tsx - Backend:
backend/internal/services/client_service.go,backend/repositories/client_invitation_repository.go
Screenshot Status
- Not captured.