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

Roles, goals, permissions, and expected behavior for every consumer of the Auth module. Permission values are exact from rbac/schemas/role.schema.ts:8 (DEFAULT_ROLES) and rbac/permissions.constants.ts (ALL_PERMISSIONS). Auth self-service endpoints (/auth/sessions, /auth/api-keys, /auth/2fa/*, /auth/logout-all) require only a valid JWT — no permission metadata (OQ-5). What differs is which permissions a role carries in the rest of the product.


1. Anonymous Visitor (prospect / pre-registration)

AttributeValue
FrequencyOne-time; 10–15 min journey
GoalRegister their school + admin account, get tokens, verify email, enable 2FA
Pain pointsTypo'd emails, lost verification emails, rate-limit 429 on retry storms
Core jobPOST /auth/register (firstName,lastName,email,password≥8,tenantId) → tokens in data.accessToken/refreshToken
RestrictionsRate auth 5/min (auth.controller.ts:31); unknown tenantId accepted (created with that id)
Expected behaviourImmediate login after submit; "verify your email" prompt (target contract), 2FA onboarding nudge
Mental model"Fill form → I'm in → I'll confirm email from inbox"

2. School Admin (org_admin) — flagship user

AttributeDetail
FrequencySeveral times/day, many devices
PermissionsALL_PERMISSIONS (role.schema.ts:23) — org owner
GoalFast secure login, full device visibility, harden account with 2FA, API keys for integrations
Pain pointAccount lockouts, 2FA device loss, "unknown device" logins they didn't make
ExpectedLogin → home; sessions screen lists all devices w/ browser/os/ip/location; per-device logout (DELETE /auth/sessions/:id), logout-all (POST /auth/logout-all), 2FA enable/verify/disable, API-key create→show-once
RestrictionsRevocation is by session id with no ownership check (OQ-5); keys revoked individually
Mental model"Who's currently me? What to cancel?"

3. Teacher / Staff / Accountant / Parent / Student (low-permission roles)

AttributeDetail
Permissions (from roles)teacher ['student.read','attendance.mark','attendance.edit']; staff ['student.read']; accountant ['fees.collect','student.read']; parent ['student.read']; student [] (role.schema.ts:31-42)
Frequency1–3 logins/day phone/tablet
Goal"Just let me in", password reset without losing the day
Pain pointsForgot password over weekends; refresh expiry mid-work → single silent refresh; push→deep link login
ExpectedRemembered device → auto-login (secure storage + refresh); reset flow intuitive step 1→2→3
RestrictionsRegistration flow is opaque (their account is created by admin via users); no tenant selection necessary — token carries tenant
Mental model"One account, don't ask me again if possible"
Auth-specific noteThese roles never touch sessions/2FA/API keys normally (UI hides the Security section except self-service password).

4. Platform Admin (platform_admin, cross-tenant)

AttributeDetail
Permissionspermissions: [] but JwtAuthGuard sets isPlatformAdmin=true when role present (jwt-auth.guard.ts:54) — bypass seed
FrequencyOn-demand support; diagnostics
GoalResolve tenant issues; impersonation (planned); never logged into spec-touched accounts
RestrictionsMust hold a real tenant token; cross-tenant token on a tenant → tenantId mismatch → guard re-scopes ctx.tenantId from token (jwt-auth.guard.ts:44-55)
ExpectedSession revocation on a user's behalf is not provided by AuthController today (future impersonate/unlock endpoints (planned) IMPLEMENTATION_PLAN.md)

5. M2M Integrator (API key consumer)

AttributeDetail
AuthAuthorization: Bearer <apiKey> (raw key); keys never logged
GoalScoped machine access: library sync, fee batch, report pull, transport
PermissionsKey scopes[] free-form strings from CreateApiKeyDto (create-api-key.dto.ts:12); not yet checked by any guard — scoping is metadata today (OQ)
RestrictionsPOST /auth/api-keys (name, scopes?) returns {id,prefix,key}key visible once only (auth.service.ts:414); revoke via DELETE /auth/api-keys/:id
LifecyclelistApiKeys{id,name,prefix,scopes,createdAt,lastUsedAt} (never full key); lastUsedAt updated elsewhere (api-key.repository.ts:35)

6. Visitor who abandons registration

AttributeDetail
FrequencyRegistration abandons
BehaviorMay return via /verify-email token; may retry register → 409 duplicate; may reset password on the pre-verify account

7. Role→auth-appearance matrix

Valueorg_adminteacher/staff/accountant/parent/studentplatform_adminAPI-key consumer
Login screen— (uses key)
Email verify interstitial (target)✓ (on register)via invite flow
2FA onboardingrecommendedoptionaln/a
Sessions screen✓ (self)
API keys screenadmin mayviews on behalf? no
Security settings (change password, etc.)✓ (self)
Use PATCH /users/:id/preferences for theme/language

Roles/goal frequency: shared baseline 00-shared/01. Every persona's auth-facing needs collapse to: log me in, keep me in (silent refresh), let me back in (reset), and don't scare me. The module's killer features (session map, 2FA, key vault) are the admin-facing differentiators.