05 — Screen Inventory (RBAC Module)
- S1 — Roles list
- S2 — Role detail
- S3 — Role editor (permission matrix — hero)
- S4 — Members list
- S5 — Add member
- S6 — Permission audit view
Six screens. Every element traces to an endpoint (
rbac.controller.ts) or schema field (role.schema.ts,organization-member.schema.ts). Detailed specs in 06; forms in 08; wire contracts in 12.
| # | Screen | Route | Server endpoint(s) | Personas |
|---|---|---|---|---|
| S1 | Roles list | /settings/roles | GET /rbac/roles | Priya, Arjun |
| S2 | Role detail | /settings/roles/:id | GET /rbac/roles (client-side lookup) | Priya, Arjun |
| S3 | Role editor (permission matrix) | /settings/roles/new, /settings/roles/:id/edit | GET /rbac/permissions, POST /rbac/roles, PATCH /rbac/roles/:id | Priya, Arjun |
| S4 | Members list | /settings/members | GET /rbac/members + user.read merge | Priya, Arjun, Samira |
| S5 | Add member | /settings/members/add (bottom sheet) | POST /rbac/members | Priya, Arjun |
| S6 | Permission audit view | /settings/access-audit | GET /audit-logs?action=&entityType=&actorId= (audit.controller.ts:17-34) | Priya, Arjun |
S1 — Roles list
- Purpose: browse the tenant's roles; distinguish locked system roles from custom.
- Elements:
headlineMedium"Roles & Permissions"; search field (client-filter on name/slug); list ofRoleRowsorted priority desc (rbac.service.ts:76);RoleRow= name + slug (mono) + description + system badge + permission-count badge; trailingAppMenu(Edit / Delete) on custom roles only; FAB "Create role". - States: loading
AppSkeleton(list); errorAppErrorState; empty "No custom roles yet — create your first role". - Server note: returns raw array, not paginated (
rbac.service.ts:75-77); nometain envelope (response-envelope.interceptor.ts:55-59).
S2 — Role detail
- Purpose: read a role; jump to edit; see what it grants.
- Elements: header (name, slug, description, priority, system badge); "N of 95
permissions" summary with permission group tiles (each group: label + chips of
granted perms — reuse
PermissionGroupSectionread-mode); CTA "Edit permissions" (disabled for system roles); member holders section(proposed)— server offers no members-by-role endpoint, so holders would require client-side join ofGET /rbac/ members+ roles ((proposed), OQ-R7). - States: loading; error 404 (role soft-deleted or wrong tenant → treat as not
found,
RESOURCE_NOT_FOUND); system-role banner "System roles cannot be edited".
S3 — Role editor (permission matrix — hero)
- Purpose: create/edit a role's permission set. The matrix is the module's hero component (07 §1, 06 §3, 15 §2).
- Elements: form header (name, slug, description, priority — 08 §1); live badge
"X of 95 selected";
AppSearchBarfiltering groups/perms; group sections (23 groups, §06) each with select-all toggle +PermissionChips; bottom bar: "Cancel" / "Save role" (loading state); duplicate-slug inline error on 409. - Rules (derived): system roles never reach the editor (server refuses with 400
"Cannot modify system roles."
rbac.service.ts:94-95); create always sendsisSystem:false(OQ-R2); save is one PATCH with the full array (rbac.service.ts:96$set— no per-cell endpoint). - States: loading (permissions + role fetch); error; dirty-state unsaved-changes dialog on back.
S4 — Members list
- Purpose: who belongs to the tenant and with which roles.
- Elements:
headlineMedium"Members"; search (name/email via merged profile);MemberTile=AppAvatar(user initials/photo) + displayName + email (user.readmerge, OQ-R7) + role chips + status badge (activeonly today,organization-member.schema.ts:7-11;invited/suspendedrender-only) + joined date; trailingAppMenu(Edit roles / Remove) — hidden for the viewer persona; FAB "Add member". - Server note: sorted
joinedAt desc(rbac.service.ts:110); array, not paginated; no profile join (see OQ-R7). - States: loading/error/empty ("No members yet — add your first member").
S5 — Add member
- Purpose: create a membership: pick an existing user + one or more role slugs.
- Elements: full-height
AppBottomSheet:AppSearchBaruser picker (fromGET /api/v1/users,users.controller.ts); selected user tile; role picker (FilterChips fromGET /rbac/roles, system + custom, ordered by priority); "Add member" CTA; inline error for duplicate member (client pre-check — server 500s on E11000, OQ-R5). - Fields/validation: 08 §2 —
userId@IsMongoId(add-member.dto.ts:6),roles@IsArray @IsString({each})(add-member.dto.ts:10-12). - Server note:
PATCH /rbac/members/:idreuses this DTO but ignoresuserId(rbac.controller.ts:71-72) — the edit-roles sheet can reuse the same role picker.
S6 — Permission audit view
- Purpose: answer "who changed what, when" for RBAC events (and all other actions).
- Elements: filter bar (action dropdown, entityType dropdown, actorId picker —
all query params of
audit.controller.ts:20-25); paginated log list (page/limit, default limit 50 server-sideaudit.controller.ts:20; envelope hasmeta— paginated shape per 07 §2); row = timestamp, action, entityType, actorId (mono), requestId. - States: loading/error/empty "No activity recorded"; pull-to-refresh; infinite scroll (paginated).
- Gate note: server guard is
JwtAuthGuardonly (audit.controller.ts:9) — theaudit.readpermission is not enforced yet (Phase-5(planned),docs/IMPLEMENTATION_PLAN.md:241); client gates the route onaudit.readregardless.