02 — User Personas (Attendance Module)
- 1. Teacher — "the marker"
- 2. Organization Admin — "the overseer"
- 3. Parent — "the watcher"
- 4. Student — "the self-checker"
- 5. Biometric Operator — "the integrator"
- Persona matrix → screens (map to 05_Screen_Inventory.md)
Five personas that drive the attendance surface. Every claim derives from
src/modules/**— roles/permissions fromrole.schema.ts:8-65andpermissions.constants.ts:29-30,39-43; marking model fromattendance.schema.tsandattendance.service.ts; alerting/reporting fromattendance.worker.tsandreports.service.ts.
1. Teacher — "the marker"
"I need the whole class done before the bell stops ringing."
| Attribute | Value |
|---|---|
| Role | teacher — ['student.read','attendance.mark','attendance.edit'] (role.schema.ts:31) |
| Frequency | 2–8 times/day, per class period, peak at class start |
| Context | Standing, tablet/phone in hand, 40 students, < 60 s per class |
| Pain | Double-entry, slow grids, losing work to a bad connection |
| Success | Bulk mark in one tap; late students caught without re-marking everyone |
| Sources | mark-attendance.dto.ts:11-49; attendance.service.ts:48-54 (bulk = one request) |
Needs: default-present grid (fast path), tap-cycle to change a row, batch ops, undo for mistaps, offline queue that flushes when signal returns, PATCH for corrections later.
2. Organization Admin — "the overseer"
"Is attendance actually being taken, and what does the month look like?"
| Attribute | Value |
|---|---|
| Role | org_admin — ALL_PERMISSIONS incl. attendance.mark/edit, report.generate/read, biometric.* (role.schema.ts:23; permissions.constants.ts:29-30,39-43) |
| Frequency | Daily glance; weekly/monthly deep-dives; end-of-term |
| Pain | No visibility into unmarked classes; slow aggregations |
| Success | Summary counts per status (attendance.service.ts:103-113), monthly report job (reports.service.ts:110-137), device health |
| Sources | GET /attendance/summary; POST /reports/generate; dashboard.service.ts:54-65 |
Needs: today's completion % (marked vs roster), month heatmap by class, per-student drill down, device ingest status (what's coming in from biometric).
3. Parent — "the watcher"
"Tell me the moment my child is marked absent — and show me the month."
| Attribute | Value |
|---|---|
| Role | parent — ['student.read'] (role.schema.ts:55) — no attendance permission today (OQ-7) |
| Frequency | Daily at dismissal; on alert; weekly review |
| Pain | Finding out about absences days later; no context for a lone "absent" |
| Success | Absent alert the same day; month strip showing pattern (absences/lates cluster?) |
| Sources | Alert path: attendance.worker.ts:69-80 (log-only today, OQ-1); history read: attendance.service.ts:63-73 |
| Semantics | "3 absences → alert recommended" counts all absences, not consecutive days (attendance.worker.ts:70-74) |
Needs: child selector, month calendar heatmap, alert inbox item that deep-links to the day, "3 absences this month" honesty (never promise "consecutive" semantics — OQ-1).
4. Student — "the self-checker"
"What's my attendance %? I need to know before the report card."
| Attribute | Value |
|---|---|
| Role | student — [] permissions (role.schema.ts:63) — read-only via student.read surface today (OQ-7) |
| Frequency | Weekly; before exams (attendance % often gates exams) |
| Pain | No per-status breakdown; "present" vs "late" impact on % unclear |
| Success | Own history: GET /attendance/student/:studentId (END_TO_END_USER_FLOWS.md:324-325,348) + summary derived client-side |
| Sources | attendance.service.ts:63-73; report-job report card includes attendance indirectly (reports.service.ts:85-108) |
Needs: % present, month heatmap, status legend, absence reasons they can raise with the teacher.
5. Biometric Operator — "the integrator"
"Are punches landing, and are they turning into attendance?"
| Attribute | Value |
|---|---|
| Role | Admin-adjacent staff with biometric.log.create/read, biometric.device.manage (permissions.constants.ts:41-43) |
| Frequency | Setup; daily health check; incident response |
| Pain | Devices silently failing; punches stored but never becoming attendance |
| Success | Device status (active/inactive/offline, biometric-device.schema.ts:7-11), ingest count today, clear "logs only" vs "derived" pipeline status |
| Sources | POST /biometric/ingest (biometric.controller.ts:14-18); biometric_logs schema (biometric-log.schema.ts:7-27); biometric-sync cron */15 (scheduler.service.ts:71-76) |
| Gap | No worker consumes biometric-sync today — derivation (planned) (OQ-3); UI must show "captured but not yet applied" |
Needs: device list w/ last-punch time, ingest trend, explicit badge "not yet applied to attendance" while OQ-3 is unresolved.
Persona matrix → screens (map to 05_Screen_Inventory.md)
| Persona | Primary screens | Permissions needed |
|---|---|---|
| Teacher | S1 Today's roster, S2 Marking grid, S3 Batch edit, S4 History/calendar | attendance.mark, attendance.edit, student.read |
| Org Admin | S4 History, S5 Monthly report, S6 Report detail, S8 Device status | attendance.*, report.*, biometric.* |
| Parent | S7 Student profile (child), alert deep-link | student.read (OQ-7) |
| Student | S7 Student profile (self) | student.read (OQ-7) |
| Operator | S8 Device status | biometric.device.manage, biometric.log.read |