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 (Settings Module)

Roles, goals, permissions, and expected behavior for every consumer of the Settings module. Permission values are exact from src/modules/rbac/permissions.constants.ts. Critical caveat: the settings controller carries no @Permissions metadata (settings.controller.ts:19 — JWT guard only), so settings.read/update/delete (permissions.constants.ts:75-77) are declared but not enforced today (OQ-2). The UI still gates on them for forward-compatibility; the server is the authority only for authentication, not permission.


1. Org Admin (org_admin role) — flagship user

AttributeValue
FrequencyDaily; config changes weekly (term boundaries, grading, theme)
PermissionsAll (role seeds ALL_PERMISSIONS, rbac/schemas/role.schema.ts:23 — includes settings.read/update/delete)
GoalSee the whole org config in one place; change values with the right input; batch-save term changes
Pain pointsFree-form keys with no description; not knowing a value's type until it breaks; deleted keys that can't be recreated (OQ-5)
Core jobBrowse GET /settings (optionally ?group=), edit PUT /settings, batch PUT /settings/bulk, remove DELETE /settings/:key
Expected behaviorGroup tabs; typed editors per value; immediate save feedback; dirty tracking across edits
Mental model"Settings is my school's control panel."

2. Setting Editor (delegated staff — e.g., office manager, ICT coordinator)

AttributeValue
FrequencySeveral times/week
PermissionsCustom role with settings.read/update (not settings.delete) — once server enforcement lands (OQ-2)
GoalUpdate attendance thresholds, notification toggles, academic labels without touching org-level or theme
Pain pointsAccidental bulk-save of half-edited values; JSON fields they can't parse
ExpectedGroup-scoped view (attendance only), per-field save, JSON editor with syntax feedback, "saved" snackbar per key
Mental model"I only touch my group's knobs."

3. Platform Admin (platform_admin, cross-tenant)

AttributeValue
PermissionsisPlatformAdmin bypasses the tenant scope entirely (base.repository.ts:21-23; set in jwt-auth.guard.ts:54)
FrequencyOn-demand support/diagnostics
GoalCompare tenant configs; fix a broken setting during support
RestrictionsPlatform admin must hold a real tenant JWT; its GET /settings returns all tenants' settings merged (no tenant filter) — the UI must show a "cross-tenant view" warning if surfaced
Mental model"Global view; treat carefully."

4. Config Consumer (machine / other modules) (planned)

AttributeValue
AccessGET /settings?group= or GET /settings/:key with a service account (API keys, auth module)
GoalRead org config at runtime (grading scale, working days, theme colors)
StatusNo consumer exists in src/ today (OQ-1); settings consumption by other modules is future wiring
NoteValues are untyped — consumers must handle unknown (setting.schema.ts:21-22)

5. Read-Only Staff / Teacher (everyone else)

AttributeValue
PermissionsNo settings.* perms in seeded roles (rbac/schemas/role.schema.ts:31-42)
BehaviorNever sees the Settings surface in the UI (hidden by permission gating); settings screens are admin-only
CaveatBecause the server does not enforce settings.* today, any authenticated user could call the API — UI hiding is the only defense until OQ-2 is resolved

6. Role → settings-appearance matrix

Surfaceorg_adminsetting editorplatform_adminteacher/staff/parent/student
/settings section (module)✓ (granted groups)hidden
Settings list + group filter✓ (cross-tenant warning)
Edit (PUT)✓ (update perm)
Batch save (PUT /bulk)
Delete (DELETE)perms settings.delete
Org embedded settings (S4 tabs in Organizations module)
Feature flags (sibling surface)

Server-side truth: authentication only (JWT). Permission gating is client-side (route guard reads user.permissions) until @Permissions('settings.*') lands on settings.controller.ts — mirror the pattern of files.controller.ts:30 / webhooks.controller.ts:22 when that happens.