02 — User Personas (Bulk Module)
- 1. Persona map
- 2. Admissions Admin — "Mira"
- 3. Registrar — "Daniel"
- 4. Org Admin — "Priya"
- 5. IT/Platform Support — "Alex"
- 6. Excluded personas
- 7. Permission reality check (for design)
Who drives bulk import/export, and what each persona needs from it. Overlaid on the platform roles in 00-shared/01 §3. Derived from the bulk module source; no invented users. Analytics
(proposed).
1. Persona map
| Persona | Role / permission | Bulk behaviour | Screens (05) |
|---|---|---|---|
| Admissions Admin (admin team) | user.import, user.create, student.create, student.read (permissions.constants.ts:7,10,25-26) | Runs the majority of imports at admission time; fixes and re-uploads rejected rows | SS1-SS4 |
| Registrar / Front-office staff | student.read + limited create (permissions.constants.ts:25-26) | Exports current rosters; occasionally imports small batches | SS1, SS4 |
| Org Admin | all org perms (rbac.member.*, organization.*) | Owns entity coverage decisions, audits import outcomes, unlocks future entities (planned) | SS1-SS4 |
| IT/Platform Support | platform-level | Diagnoses malformed files, encoding issues, and timeouts | SS4 (debug copy) |
| Class Teacher / Parent / Student | student.read-adjacent or none | No bulk access — read-only consumers of imported data elsewhere | — |
2. Admissions Admin — "Mira"
- Context: end of admission season; 400+ new enrollments arrive as an Excel sheet from the admissions office; she must have them in the system by Friday.
- Goal: one upload → everyone created → a report that names exactly which rows failed and why.
- Needs: template to fill (
GET /bulk/export/students); upload; clear per-row errors; fix-and-reupload without retyping good rows; confidence that re-uploading a file that already succeeded won't duplicate students. - Pain today: the API is synchronous — a large file blocks the request;
there is no queue/progress (
bulk-import.service.ts:22-65), so she needs progress UI and a size cap. Duplicates are rejected per row (students-import.adapter.ts:49-56) — good news for idempotent re-upload. - Success metric: 100% of rows either imported or explained in the error list; no duplicated users; ≤ 2 upload attempts per batch.
3. Registrar — "Daniel"
- Context: weekly export of the current student roster for the state department.
- Goal: a single click produces
students.csvwithadmissionNumber, rollNumber, status, admissionDate(students-import.adapter.ts:92-97), sorted by admission number (:90-91). - Needs: export preserves sort; file downloads as an attachment named
<entity>.csv(bulk.controller.ts:55-58); content-typetext/csv(:52). - Pain today: none — export is stateless and fast. He occasionally wants the same file as the import template — note the export shape is not the import shape (export omits names/grade/section/email; see 04 §6).
4. Org Admin — "Priya"
- Context: decides which entities are maintained by bulk operations; owns tenant configuration.
- Goal: students today; teachers, fees, library catalog, exam marks
(planned)— adapter registry deferred (bulk-import.service.ts:15-16). - Needs: a visible inventory of supported entities on the Import screen so
the UI never offers what the API 404s on (
bulk-import.service.ts:17-20). - Pain today: entity list is hard-coded in the backend; the client must
hard-code
studentstoo until(planned)discovery lands.
5. IT/Platform Support — "Alex"
- Context: tickets like "import failed" or "file hangs".
- Needs: the exact error strings and row numbers from the report; the
request-relative root causes: malformed CSV (400,
bulk-import.service.ts:31-33), empty CSV (:34-35), unknown entity (404,:17-20), missing file (400,bulk.controller.ts:43-46). - Diagnosis notes: any UTF-8/BOM/encoding quirk, CRLF line endings, quoted
commas, and whitespace around headers (trim is per-cell
:29, header names are not normalized —students-import.adapter.ts:17-26).
6. Excluded personas
- Students/Parents: never touch bulk surfaces; imported users receive
in-app notifications via
UserCreated/StudentCreatedevents (event-queue-map.ts:10,28) — they are recipients, not actors. - Teachers: no bulk entity today
(planned)teacher adapter. - Mobile-first users: bulk is a desktop/web-admin workflow
(
(forward-looking)client; 00-shared/01 §9).
7. Permission reality check (for design)
- Route guard today is JwtAuthGuard only (
bulk.controller.ts:28-31); RBAC enforcement onuser.import/student.createis(planned). The UI should show the bulk entry point only to users the client can identify as admin-capable (client-side gate), and handle 403 gracefully once the server guard lands. - No
student.importpermission exists (permissions.constants.ts:25-28hasstudent.read/create/update/deleteonly) — the intended import permission isuser.import(:10)(planned)binding.