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

02 — User Personas (RBAC Module)

Five personas cover the RBAC surface. Derived from the seeded roles (role.schema.ts:8-65), the endpoints (rbac.controller.ts), and the guard pipeline (rbac.guard.ts). The "Role manager" and "Member viewer" personas are forward-looking: the server currently gates /rbac/* behind @Roles('org_admin') (rbac.controller.ts:21), so their ability to act depends on OQ-R1.


1. Priya — Organization Admin (primary persona)

"I need to control who can touch what, and I don't have time for IT tickets."

  • Slug/roles: org_admin — all 95 permissions (role.schema.ts:17-24).
  • Context: Principal/admin of a 400-student school. Created the org at registration; the system auto-added her as org_admin member (auth.service.ts:84-99).
  • Goals
    • Seed the org quickly: teachers, accountant, librarian, transport manager each get a fitting role without exposing admin powers.
    • Create a custom role ("Fee Counter Clerk") with exactly fees.collect, student.read, receipts.read — no more, no less.
    • Add members, fix a wrong role, and remove a leaver in under a minute.
    • Never accidentally lock herself out; never let a staff member see salary/finance data.
  • Frustrations
    • A custom role she creates becomes un-editable (system-lock bug, role.schema.ts:78-79 default; see OQ-R2) — the UI must force isSystem:false and warn.
    • Members list shows raw member docs without names (rbac.service.ts:109-111) — the UI must merge user.read data (OQ-R7).
    • She can't tell a leaver's permissions at a glance; wants an audit trail.
  • Needs: permission matrix grouped by module with search; system-role lock badges; member tiles with role chips; 403-prevention copy ("You are about to remove your own org_admin — you will lose access to this screen").

2. Arjun — Role Manager (forward-looking, OQ-R1)

"I audit access quarterly. I want to see who holds what, and why."

  • Roles (proposed): a custom role holding rbac.role.read, rbac.role.update, rbac.member.read, rbac.member.update, user.read, audit.readnot org_admin.
  • Context: Operations head trusted with access governance but deliberately not with org billing/settings.
  • Goals: browse roles, inspect a role's permission set, adjust a role's perms, reassign a member's roles, review the permission-audit view (GET /audit-logs, audit.controller.ts:17).
  • Frustrations: today the server rejects him with 403 — @Roles('org_admin') (rbac.controller.ts:21) ignores his rbac.* permissions. Screen copy must explain "managed by Organization Admin" until OQ-R1 ships.
  • Needs: read-only-friendly layouts (view mode for the matrix), permission diff preview before saving, audit filter by actor/action.

3. Samira — Member Viewer

"I just need to know who's on the transport desk this week."

  • Roles: custom role with rbac.member.read, user.read (or a staff member).
  • Context: receptionist cross-checking who can issue books.
  • Goals: open the members list, see names + role chips, search a member.
  • Frustrations: zero write affordances must ever render for her; a stray "Add member" button that 403s on tap is a trust-breaker.
  • Needs: view-only matrix/member list; no FAB; 403 states never reached via UI.

4. Vikram — Platform Admin (sysadmin)

"One product, thousands of tenants. I watch from above, not inside."

  • Slug: platform_admin[] permissions (role.schema.ts:8-16), cross-tenant repository bypass (base.repository.ts:21).
  • Context: platform operator. Tenant-scoped RBAC is none of his daily business; his concern is that tenant A's admin can never touch tenant B.
  • Goals: verify tenant isolation (QA 14), support escalation reads, never appear in tenant RBAC screens as a normal actor.
  • Frustrations: platform_admin is not org_admin — the /rbac/* controller would 403 him (rbac.controller.ts:21); repository scoping lets him read across tenants (base.repository.ts:22). The client must treat platform_admin as a distinct shell persona with its own tenant picker — the tenant RBAC screens stay reachable only with an org_admin token in that tenant.

5. David — Guarded End-User (teacher)

"I hit a locked door once; I never want to hit it again."

  • Slug: teacherstudent.read, attendance.mark, attendance.edit (role.schema.ts:25-32).
  • Context: marks attendance daily, sees student rosters. RBAC is invisible to him — until it isn't.
  • Goals: never see admin screens; when a route changes mid-session (role edited at lunch), get kicked gracefully with a reason, not a white 403 screen.
  • Frustrations: a 403 with no explanation; a hidden-then-broken menu item; being logged out without explanation after an admin changed his role (JWT roles frozen at login, auth.service.ts:145-154; OQ-R4).
  • Needs: 403 screen with cause + contact copy; route tree rebuilt on permission change (05_Global_Information_Architecture.md §9); offline-tolerant lists.

Persona → screen matrix

ScreenPriya (org_admin)Arjun (role mgr, planned)Samira (viewer)Vikram (platform)David (teacher)
Roles listfullread/edit (planned)
Role detailfullread
Role editor + matrixfulledit (planned)
Members listfullread/edit (planned)read (if granted)tenant-picker (planned)
Add memberfulledit (planned)
Permission auditfull (audit.read)read
403 screenneveruntil OQ-R1never via UInever via UIwhen role revoked mid-session