# Business Logic Model — Unit 5: User Management ## Process Overview Unit 5 covers three main user flows: 1. **Invite User** — two-step dialog: fill in email + role → copy generated invite link 2. **Copy Pending Invite Link** — one-click copy from the user table row for pending invitations 3. **Change Role** — dropdown action in the user table row; optimistic or confirmed update --- ## Flow 1 — Invite User ```mermaid sequenceDiagram box rgba(246,224,94,0.4) Browser participant U as Gebruiker participant FE as UsersPage participant DLG as InviteUserDialog end box rgba(99,179,237,0.4) Backend participant API as Users API end U->>FE: Click Invite User button FE->>DLG: Open dialog at Step 1 DLG-->>U: Show form with email and role fields U->>DLG: Enter email and select role U->>DLG: Submit form DLG->>DLG: Validate with zod schema alt Validation fails DLG-->>U: Show inline field errors else Validation passes DLG->>API: POST /api/v1/Users/invite with email and role alt API error API-->>DLG: 400 or 409 error response DLG-->>U: Show FormErrorBanner with error message else API success API-->>DLG: 200 with inviteLink DLG->>DLG: Advance to Step 2 DLG-->>U: Show invite link with Copy button U->>DLG: Click Copy to clipboard DLG->>FE: Invalidate useUsers query FE->>API: GET /api/v1/Users API-->>FE: Updated user list with new pending user FE-->>U: Table refreshed U->>DLG: Close dialog end end ``` Text alternative: User opens dialog, fills email and role, submits; on success the backend returns an invite link shown in Step 2 with a copy button; closing the dialog triggers a user list refresh. --- ## Flow 2 — Copy Pending Invite Link from Table Row ```mermaid sequenceDiagram box rgba(246,224,94,0.4) Browser participant U as Gebruiker participant Row as UserTableRow end U->>Row: Click copy-link icon on pending user row Row->>Row: Read inviteLink from UserListItem Row->>Row: navigator.clipboard.writeText with inviteLink Row-->>U: Show toast "Invite link copied to clipboard" ``` Text alternative: Copy invite link is a client-side operation — the link is already in the fetched user list (inviteLink field); no API call required. --- ## Flow 3 — Change User Role ```mermaid sequenceDiagram box rgba(246,224,94,0.4) Browser participant U as Gebruiker participant Row as UserTableRow participant FE as UsersPage end box rgba(99,179,237,0.4) Backend participant API as Users API end U->>Row: Open role dropdown for a user Row-->>U: Show available roles based on requester role U->>Row: Select new role Row->>API: PUT /api/v1/Users/{userId}/role with newRole alt API error API-->>Row: 403 or 409 error Row-->>U: Show toast with error message else API success API-->>Row: 200 OK Row->>FE: Invalidate useUsers query FE->>API: GET /api/v1/Users API-->>FE: Updated user list with new role FE-->>U: Table row updated with new role badge end ``` Text alternative: User selects a new role from a dropdown in the table row; on backend success the user list is re-fetched to reflect the updated role. --- ## useInvitation.ts Migration (supporting InviteCompletePage) `useInvitation.ts` was created in Unit 2 with raw `useState`/`useEffect`. In Unit 5 it is migrated to TanStack Query for consistency. This does not change the behavior of `InviteCompletePage` — only the internal implementation of the hooks changes. | Hook | Before (Unit 2) | After (Unit 5) | |---|---|---| | `useValidateInvitation(token)` | useState + useEffect | useQuery (auto-fetches on mount) | | `useCompleteInvitation()` | useState + useCallback | useMutation | | Types | Local interfaces in useInvitation.ts | Shared types from types.ts | Local types (`InvitationValidationResponse`, `InvitationCompleteRequest`, `InvitationCompleteResponse`) are removed and replaced with `InvitationValidation` and `InviteCompleteRequest` from `types.ts`.