Roles, goals, permissions, and expected behavior for every consumer of the Parents
module. Permission values are exact from rbac/schemas/role.schema.ts (DEFAULT_ROLES)
and rbac/permissions.constants.ts (ALL_PERMISSIONS). Server fact: parent endpoints
are JWT-only today — parent.controller.ts:23 declares only JwtAuthGuard; no
@Permissions() metadata; no parent.* permission exists in ALL_PERMISSIONS
(permissions.constants.ts:1-97). Permission columns below state the intended model
(from blueprint 04-Modules/Parents.md:64-70, flagged (planned)) and the actual
server posture.
ALL_PERMISSIONS (role.schema.ts:23) — but none of them are parent-scoped; all parent ops work for them anyway (JWT-only)
Frequency
Daily during admissions/custody changes; occasional otherwise
Goal
Complete guardian picture: create profiles, link parents to students, manage primary guardians, resolve billing/pickup disputes
Core job
POST /parents (with existing userId from POST /users), POST /parents/link/:studentId, PATCH /parents/:id, DELETE /parents/link/:linkId
Pain points
Duplicate profiles per parent (only prevented by 409 on same userId); no search on the parent list (parent.service.ts:58-61 ignores q); no audit UI yet
Mental model
"Every child needs at least one guardian who answers the phone."
role-scoped (e.g., student.read + crm.read/crm.lead.manage — permissions.constants.ts:33-34,47); parent endpoints are JWT-only so they can operate today
Frequency
Peak season: dozens of admissions/week
Goal
Enrollment flow: student record exists → attach mother/father/guardian → mark primary → set pickup
Core job
POST /students (student.controller.ts:38), then POST /parents/link/:studentId with relationship, isPrimaryGuardian, pickupAllowed
Pain points
Link is a separate step after student creation (no auto-link on enrollment despite blueprint "Consumes: StudentCreated (auto-link…)" 04-Modules/Parents.md:41 — not implemented); parents of siblings must be re-linked per child
Mental model
"Enroll → then 'who do we call?'"
Note
The blueprint link routes (POST /students/:id/parents, 04-Modules/Parents.md:29-30) are not what the controller implements — use /parents/link/:studentId (parent.controller.ts:47-52).
role parent = ['student.read'] only (role.schema.ts:50-56) — no parent. permission*; profile created by admin
Frequency
2–10×/month during term (attendance alerts, results, fees)
Goal
See only own linked children (privacy boundary, USER_PERSONAS.md:48-53), check own relationship/primary flag, update emergency/pickup flags, receive absentee/result alerts (04-Modules/Parents.md:49)
Core job
Log in → my children → per-child details (attendance/results via other modules, student.read) → my profile edit
Pain points
Cannot resolve "my profile" today: no /parents/me, no userId filter on the list (OQ-1 in 01_Product_Overview.md)
Restrictions
Sees data only for linked children; cross-tenant access structurally impossible (base.repository.ts:20-30)
Mental model
"This school app knows which kids are mine."
Platform note
Parent student.read is honored by other modules' authorization patterns (planned); the parents module itself has no owner check (OQ-8)
each guardian = separate User → separate parents doc → separate links (parent.schema.ts:36 unique per userId)
Goal
Each guardian sees the shared children; exactly one primary per child for communications; pickup rights split
Core job
Admin links all three via POST /parents/link/:studentId per child; primary set per link
Pain points
Server allows multiple primaries per student (no exclusivity, OQ-5); switching primary = PATCH of two links (old false / new true) — no dedicated endpoint; unlink of primary does not auto-promote (OQ-4)
Expected behaviour
UI: per-child guardian list with radio "Primary guardian"; switching writes both links; unlink blocks if it would leave zero guardians or warns when removing the primary
Mental model
"Grandma can pick up, but Dad gets the bills." (billing flag = financialResponsibility, student-parent-link.schema.ts:30-32)
Intended permission model (planned): parent.read, parent.create, parent.update,
parent.delete, parent.link (04-Modules/Parents.md:64-70) — none present in
ALL_PERMISSIONS today (permissions.constants.ts). UI must gate on these once seeded
and treat server as JWT-only until then.