02 — User Personas (Results Module)
- 2.1 Teacher (subject examiner) — primary marks-entry user
- 2.2 Exam coordinator / academic head — publication owner
- 2.3 Student (and parent) — consumer of published results
- 2.4 Institution admin — configuration & oversight
- 2.5 (forward-looking) Platform operator
- Persona × capability matrix (today vs intended)
Personas are grounded in the code's actor model: every request carries a JWT (
JwtAuthGuard,result.controller.ts:10), tenant comes from token (base.repository.ts:20-30), andactorIdis recorded on domain events (examination.service.ts:167,result.service.ts:117). Roles beyond the guard are not yet enforced (noresult.*permissions inpermissions.constants.ts:1-97).
2.1 Teacher (subject examiner) — primary marks-entry user
- Goal: record marks for each student per exam-subject, correctly and fast; fix mistakes.
- Uses:
POST /api/v1/results/exam-subject/:examSubjectId/marks(result.controller.ts:26-31). - Needs: subject list per exam (
GET /api/v1/examinations/:id/subjects,examination.controller.ts:51-53), student list, max-marks context (maximumMarks,examination-subject.schema.ts:27-28), per-student re-entry without duplicates. - Pain: over-max marks are rejected with 404 (
examination.service.ts:145-146) — confusing error text must be surfaced by the client. - Permission today: any valid JWT. Intended:
result.compute/exam.mark(planned).
2.2 Exam coordinator / academic head — publication owner
- Goal: verify completeness of marks, then release results atomically per exam.
- Uses:
POST /api/v1/examinations/:id/publish(examination.controller.ts:54-56). - Needs: completion overview per exam (how many students have entries), preview report cards, publish confirmation; cannot un-publish (no such endpoint).
- Permission today: any valid JWT. Intended:
result.publish(planned).
2.3 Student (and parent) — consumer of published results
- Goal: see report card per exam: subject-wise marks, totals, percentage, overall grade.
- Uses:
GET /api/v1/results/report-card/:studentId/:examId(result.controller.ts:32-37) andGET /api/v1/results/student/:studentId(:16-20). - Reality gap: no server-side check that the JWT subject owns
studentId; nopublishedAtfilter (examination-result.repository.ts:20-40). The client must gate this experience behind publish state and later server RBAC(planned). - Pain:
subjectNamein report cards is the raw subject ID (result.service.ts:75) — client must map IDs → display names.
2.4 Institution admin — configuration & oversight
- Goal: define exams (
POST /api/v1/examinations,examination.controller.ts:27-29), add subjects withmaximumMarks/passingMarks(examination-subject.schema.ts:27-31), monitor publish history. - Uses: full examinations CRUD (
examination.controller.ts:27-43). - Permission today: any valid JWT. Intended:
exam.create/update/delete,result.read(planned).
2.5 (forward-looking) Platform operator
- Cross-tenant support: platform admin bypasses tenant scope (
base.repository.ts:21-23) — out of Phase 1 client scope.
Persona × capability matrix (today vs intended)
| Capability | Teacher | Coordinator | Student/Parent | Admin |
|---|---|---|---|---|
| Enter marks (upsert) | ✅ today | ✅ today | — | ✅ today |
| Read results | ✅ today (all) | ✅ today | ⚠️ not scoped | ✅ today |
| Report card | ✅ today | ✅ today | ⚠️ not scoped | ✅ today |
| Publish exam | ✅ today | ✅ today | — | ✅ today |
| RBAC-restricted | (planned) | (planned) | (planned) | (planned) |
⚠️ Today every endpoint is available to any authenticated user; the matrix above reflects the intended design (
permissions.constants.tshas noresult.*entries yet).