Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

04 — Information Architecture (RBAC Module)

Where RBAC lives in the app shell (00-shared/05). RBAC is an admin-governance surface: it sits under the Settings umbrella, gated by the rbac.* permission family, and is invisible to non-admin personas.


1. Placement in the app shell

AppShell (role-aware, 05_Global_Information_Architecture.md §1)
 └─ NavigationDrawer / Rail
     ├─ Home, Students, Attendance, Academics, Fees, … (module destinations)
     └─ Settings  (roles: admin — 05 §2 "Settings | /settings | admin")
         ├─ Organization profile
         ├─ Roles & Permissions   ← RBAC package entry
         │    ├─ Roles (list)
         │    ├─ Create role
         │    ├─ Role detail
         │    └─ Role editor (permission matrix)
         ├─ Members (organization people + roles)
         │    ├─ Add member
         └─ Access audit  (permission audit view; audit.read)
  • Entry point: Settings → "Roles & Permissions" (routes /settings/roles, /settings/members, /settings/access-audit).
  • Why Settings, not a top-level tab: the global nav (05 §2) reserves top-level destinations for daily-use modules; RBAC is occasional governance. Matches 05 §2 "Users & Roles | /users, /roles | admin".

2. Information hierarchy

Roles & Permissions
 ├─ Roles (the "what can be done" catalog)         [GET /rbac/roles, GET /rbac/permissions]
 │    ├─ System roles (7, locked badges)
 │    └─ Custom roles (tenant)
 │         └─ Role detail: identity + priority + permission summary
 │              └─ Editor: full permission matrix (hero)
 └─ Members (the "who has which roles")           [GET /rbac/members]
      ├─ Member tile: user identity (merged via user.read, OQ-R7) + role chips
      └─ Add member: user picker + role picker     [POST /rbac/members]
 └─ Access audit (the "who did what")             [GET /audit-logs, audit.controller.ts:17]
      └─ Filter: action / entityType / actorId

Parent-child rule: Role detail is reachable from Roles list only; member rows link forward to nothing (no per-member detail screen — the API exposes none; PATCH /rbac/ members/:id is the only member write, rbac.controller.ts:69-73).

3. Screen-to-route table

RouteScreenGuard (client)Server gate
/settings/rolesRoles listrbac.role.read@Roles('org_admin') (rbac.controller.ts:21)
/settings/roles/newRole editor (create)rbac.role.createsame
/settings/roles/:idRole detailrbac.role.readsame
/settings/roles/:id/editRole editor (edit)rbac.role.updatesame
/settings/membersMembers listrbac.member.readsame
/settings/members/addAdd member (sheet)rbac.member.createsame
/settings/access-auditPermission auditaudit.read@UseGuards(JwtAuthGuard) only (audit.controller.ts:9; perm gate (planned))

Client guard vs server gate mismatch (flagged): the client gates on rbac.* permissions, the server on the org_admin role (OQ-R1). Until OQ-R1 lands, client routes must additionally require the org_admin role claim, else users with rbac.* perms would see screens that 403. Implemented as roleOrPermissionGuard(['org_admin'], ['rbac.role.read']) (see 13 §4, 15 §5).

4. Navigation rules

  • Destinations hidden for anyone without the gate (05 §3 "Unauthorized destinations are hidden and unroutable").
  • Roles and Members are sibling tabs under one "Access" section header; Access audit is a third tab (not nested deeper).
  • Breadcrumb (desktop ≥ 2 levels): Settings / Roles / {role name}.
  • Keyboard: Ctrl+K global search may surface roles/members by name; N on Roles and Members lists starts the create flow (desktop).

5. Content model (what each screen shows)

ScreenPrimary entitiesSecondaryEmpty state
Roles listRole (name, slug, description, isSystem, priority, permissions[]role.schema.ts:69-85)perm count badge, member count (proposed)"No custom roles yet"
Role detailRole identity + full perm setmember holders (proposed)
Role editor95-perm matrixsearch, group select-all, count
Members listMember (userId, roles[], status, joinedAtorganization-member.schema.ts:15-31) + merged user profilerole chips, status badge"No members yet"
Add memberUser picker + role picker
Access auditAuditLog rows (action, entityType, actorId, ts)filters"No activity recorded"
  • Users — identity for member tiles; user.read…user.import (studylyon-blueprint/04-Modules/Users.md:71-79).
  • Auth — JWT carries roles claim (jwt-payload.interface.ts:3); re-login required for claim refresh.
  • Organizations — tenant context; seedDefaults(org.slug) quirk (organizations.service.ts:58).
  • AuditGET /audit-logs backs the permission audit view (audit.controller.ts:17-34).
  • 05 Shared GIA §9 — client mirrors permissions.constants.ts; route rebuild on role change.