Data Retention & Deletion Policy

Last updated: 2026-06-18. This is the engineering source-of-truth for retention behavior. Counsel must confirm the windows below against COPPA (16 CFR Part 312) and applicable state student-/teen-privacy laws before this is published to users.

Principles

  1. No indefinite retention. A child's record is kept while the account is active and deleted on request, subject only to the narrow legal-hold exceptions below.
  2. Parent-owned and parent-deletable. A connected, approved parent (or the account owner) controls the data and can delete it at any time.
  3. Verifiable-consent and safety evidence survives deletion in redacted, tombstoned form — the law requires us to be able to show consent was obtained and to retain abuse/safety evidence.

Retention windows

CategoryActive retentionOn account/child deletion
Student profile + longitudinal record (profile, /private, academics, saved schools, timeline)While activeHard-deleted immediately; backstop purge ≤ 30 days
Account doc, directory card, athlete profileWhile activeHard-deleted
Documents, media (Firestore + Storage objects)While activeHard-deleted (record + users/{uid}/** Storage)
Consent state (/consents)While activeHard-deleted
Consent audit (/parentalConsents)Duration of account + legal holdRetained, tombstoned/redacted
Moderation records (/reports, /blocks)Safety/legal holdRetained, tombstoned/redacted
Conversations with held/quarantined messagesSafety/legal holdRetained, tombstoned/redacted
Aggregate, zero-PII metrics (/metricsAggregates)Indefinite (no PII)Unaffected (k-anonymized counts only)

Deletion SLA

  • Acknowledged immediately when a parent/owner submits a request (requestAccountDeletion).
  • Executed immediately on in-app confirmation (executeAccountDeletion).
  • Guaranteed within 30 days for any pending request via the daily runDeletionSla sweeper.

Where this is implemented

  • firebase/functions/accountDeletion.jsrequestAccountDeletion, executeAccountDeletion, deleteStudent (cascade), runDeletionSla (sweeper).
  • JuniorProspect/Features/Parent/Views/DeleteChildDataView.swift — the parent UI (Family → "Delete this child's data").
  • Every phase writes an audit_logs row (record.deletion.requested|executed).

Open items for counsel

  • Confirm the 30-day SLA and the legal-hold retention period for tombstoned consent/safety records.
  • Confirm whether a full parent-account closure (beyond per-child deletion) needs its own flow and notice.
  • Confirm notice/disclosure language to surface this policy in-app and at sign-up.