Files
slp-modular-cms/aidlc-docs/features/cms-frontend/construction/unit-5/functional-design/business-logic-model.md
T
2026-06-22 21:14:22 +02:00

4.2 KiB

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

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.


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

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.