Files
rootnode-academy/docs/STUDENT_GUARDIAN_DATA_MODEL.md
T
ced4568andClaude Sonnet 5 788fb197e0 docs(phase8): document enrollment operations
New: PHASE8_ENROLLMENT_OPERATIONS.md (phase summary), WINTER_BREAK_CAMP_OPERATIONS.md
(the real operational walkthrough), REGISTRATION_AND_GUARDIAN_COMMUNICATIONS.md,
OFFERING_ADMIN_GUIDE.md.

Updated: ROOTNODE_ACADEMY_BUSINESS_AND_PRODUCT_ARCHITECTURE.md (BUILT NOW/PHASE 8 BUILT
table), OFFERING_AND_REGISTRATION_MODEL.md (both ordering bugs, launch readiness,
registration enforcement), STUDENT_GUARDIAN_DATA_MODEL.md (guardian communications now
wired), WEBSITE_ENROLLMENT_INTEGRATION.md (the real, live registration contract with
worked examples, replacing the old speculative future-flow section), platform/README.md
(test list).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-26 23:59:42 -05:00

5.0 KiB

Student & Guardian Data Model

Phase 7 Step 28 — why student and guardian identities are kept separate, what data-minimization principles govern the new guardians/student_guardians tables, and what still needs professional/legal review before any of this touches a real minor's data in production.

Why separate identities

A student's own identity (students table — email/login_identifier, unchanged) is their academic account. A guardian (guardians, new this phase) is a real, separate identity: a parent with three enrolled children is one guardian row linked to three students via student_guardians, not a guardian email copy-pasted into three student records. This mirrors exactly the reasoning docs/WEBSITE_ENROLLMENT_INTEGRATION.md already gave for keeping contact_email off students.email — a contact address is not an academic identity, and now a guardian is a real relationship, not a workaround field.

What this phase deliberately did NOT build

  • No Parent Portal. A guardian record has no login, no password, no session — it cannot authenticate into anything yet. Building that is a real, separate future decision.
  • No child-activity surveillance. Nothing in this schema or its routes lets a guardian (once they could log in, in some future phase) see a student's Lab activity, scenario attempts, or detailed learning analytics by default. A guardian relationship is a contact/authorization record, not a monitoring grant.
  • No automatic broad access. student_guardians.can_receive_communications and is_primary_contact govern notification targeting only — wired into notifications.js's resolveRecipient() as of Phase 8 (a communications-enabled primary guardian is the LAST fallback, tried only after the student's own email and any enrollment-level contact_email — see docs/REGISTRATION_AND_GUARDIAN_COMMUNICATIONS.md), never authorization to student data.

Data minimization

Only fields with a genuine, near-term operational purpose were added: display_name, email, phone, and a free-text notes field for a guardian; relationship (parent/guardian/authorized_contact/emergency_contact), is_primary_contact, and can_receive_communications for the relationship itself. Registration-time fields (readiness_notes, accessibility_notes, emergency_contact_name/emergency_contact_phone) were chosen because a real camp/cohort genuinely needs them operationally — no medical-record functionality was built, and accessibility_notes is a free-text operational note (e.g. "uses a screen reader," "needs extra Lab time"), never a structured health/diagnosis field.

RBAC

Guardian records and registration detail (readiness/accessibility/emergency-contact notes) are admin/owner-only routes — a plain instructor's existing cohort-scoped access to a student's academic progress is unchanged, but they do not automatically see guardian contact information or registration notes through the new routes. See admin-offerings-routes.js's own RBAC comment and platform/test/e2e-phase7.js's guardian-RBAC test.

Adult vs. minor enrollment

An adult learner registers and is their own registrant_email/eventual student identity — no guardian row is created or required. A minor's registration requires a guardian_id (enforced by a database CHECK constraint on offering_registrations, not just application logic). Neither path writes a guardian's email into students.email — a minor with no email of their own still gets login_identifier-based identity (the same mechanism docs/WEBSITE_ENROLLMENT_INTEGRATION.md already established), preserving the identity semantics Phase 5A/5C set up.

Retention — flagged, not decided

This phase does not implement a data-retention or deletion policy for guardian/registration records. Requires future legal/business review: how long registration data (especially accessibility/emergency-contact notes for a minor) should be retained after an offering completes or a registration is cancelled, and what a guardian's/family's data-deletion request process should look like.

Items explicitly requiring professional/legal review before production use with real minors

  • Whether the current field set (name/email/phone/relationship) is sufficient or whether jurisdiction-specific requirements (e.g. COPPA-adjacent consent language, state-specific camp/ minor-supervision regulations) require additional structured fields.
  • The actual legal text of any participation agreement, media consent, or liability waiver — agreement_definitions.body_summary is a plain-language placeholder for admin-UI display only, never a substitute for attorney-reviewed legal language.
  • Data retention/deletion policy for guardian and registration records.
  • Whether emergency_contact_name/emergency_contact_phone need to be encrypted at rest beyond Postgres's existing storage (no additional encryption was added this phase).

None of the above is resolved by this phase's work — they are named here specifically so they are not silently assumed away.