KidsCode Gift (Mokawill LLC) · Effective Date: August 16, 2026
Purpose. This document provides a technical accounting of every safeguard implemented by KidsCode Gift to comply with the Children's Online Privacy Protection Act (COPPA) and the FTC's implementing Rule. Each section references the specific database tables, API routes, and source files where the safeguard is enforced. This document is intended for internal compliance review, regulatory inquiry, and parental transparency.
Contents
Before collecting any personal information from a child under 13, KidsCode Gift provides direct notice to the child's parent or guardian. The notice includes a description of the types of information collected, the opportunity to consent, and a link to this platform's Privacy Policy (src/app/privacy/page.tsx), which contains a dedicated COPPA section (Section 4) describing parental rights and data practices.
Consent is recorded at the point of collection. The students table stores two fields that constitute the audit trail for direct notice:
| Field | Type | Purpose |
|---|---|---|
| consent_source | TEXT | Identifies who provided consent (e.g., "parent", "school") and through which flow |
| consent_at | TIMESTAMPTZ | Timestamp of when parental consent was granted |
These fields are populated during child profile creation and during workshop enrollment checkout. The parental data review UI at /dashboard/parent/data (src/app/dashboard/parent/data/page.tsx) surfaces both fields to the parent, confirming that notice was given and consent recorded.
KidsCode Gift obtains verifiable parental consent before collecting personal information from children under 13, consistent with 16 C.F.R. § 312.5(b). Two consent flows are implemented:
A parent or guardian creates a child profile through the parent dashboard. The parent must be authenticated (Supabase Auth) and must have a role of parent on their profiles row. The child record is inserted into the students table with parent_id set to the authenticated parent's user ID, consent_source set to "parent", and consent_at set to the current timestamp. This ensures that every child record has an attributable, verifiable consent event.
For school-mediated enrollments, a school administrator who has been verified by KidsCode Gift may enroll students. The school admin's account is linked to a schools record. Enrollments created through the school flow set consent_source to "school", attributing consent to the institution acting in loco parentis. School admins are subject to the same authentication and role-based access controls as other platform users.
If KidsCode Gift discovers that personal information has been collected from a child under 13 without verifiable parental consent, the data is deleted immediately via the child deletion API (src/app/api/account/child-delete/route.ts).
KidsCode Gift collects only the minimum personal information necessary to provide the coding education service. The following fields are stored in the students table for each child:
| Field | Type | Description |
|---|---|---|
| display_name | TEXT | A non-real-name identifier chosen by the parent; need not be the child’s legal name |
| grade | TEXT | Educational grade level (e.g., "5th grade"); used for age-appropriate content routing |
| age | INT | Child’s age; used to enforce age-gated features |
| consent | BOOLEAN | Whether parental consent is on file |
| consent_source | TEXT | Source of consent (parent or school) |
| consent_at | TIMESTAMPTZ | When consent was recorded |
| recording_consent | BOOLEAN | Whether the parent consented to session recording (see Section 7) |
| learning_goals | TEXT[] | Optional learning objectives set by the parent |
| avatar_emoji | TEXT | A chosen emoji avatar; no photo or image of the child is collected |
| emergency_contact_name | TEXT | Emergency contact (optional, parent-provided) |
| emergency_contact_phone | TEXT | Emergency contact phone (optional, parent-provided) |
| parent_id | UUID | FK to the parent’s authenticated user account |
What we do NOT collect from children: precise geolocation, biometric data, voice recordings, photographs, government ID numbers, or social media profile data. AI tutor chat interactions are processed for response generation only and are not used to train AI models (see Privacy Policy Section 7).
Learning progress data (projects, learning events, certificates) is linked to the child's record via student_id foreign keys on the projects, learning_events, and completion_certificates tables. This data is used solely to track educational progress and issue completion certificates.
Parents can review all data associated with their children through the Parental Data Review page at /dashboard/parent/data (src/app/dashboard/parent/data/page.tsx). This interface is restricted to users with a parent or admin role (enforced at lines 54–63 of the page component). For each child, the parent can view:
The parental data review UI includes a one-click export function that downloads a JSON file containing all of the child's data, tagged with coppa_request: true for audit traceability (see handleDownload at lines 114–160 of the page component).
Parents can permanently delete all data associated with a child through the deletion API at POST /api/account/child-delete (src/app/api/account/child-delete/route.ts). The deletion endpoint:
student.parent_id === user.id, line 72).workshop_enrollments where student_id matches (line 84)completion_certificates where student_id matches (line 87)students record itself (line 96)Deletion is irreversible. Once completed, no personal information about the child remains in the students table or its related tables.
KidsCode Gift does not sell, rent, or disclose children's personal information to data brokers or for behavioral advertising. Personal information is shared only with the following service providers (processors) strictly necessary for platform operations, and only the minimum data required:
| Provider | Data Shared | Purpose | Legal Basis |
|---|---|---|---|
| Stripe, Inc. | Parent/guardian email, billing name, payment card token | Payment processing for subscriptions and workshop enrollments | Service provider / processor agreement; COPPA § 312.9 (parental consent covers payment) |
| Daily.co | Participant display name, session join token | Live video session delivery for online workshops | Service provider / processor agreement; data used solely for session connectivity |
| Checkr, Inc. | Instructor name, email, and background check candidate ID | Criminal background checks for instructors who interact with children | Service provider / processor agreement; safety verification under COPPA § 312.11 |
Each provider is bound by a data processing agreement prohibiting use of children's data for any purpose beyond the specified service. No provider receives more data than is strictly necessary for the stated purpose. Checkr background check results are stored only as a status enum (e.g., clear, consider) — the full report contents are never stored on KidsCode Gift servers (see src/app/api/webhooks/checkr/route.ts).
All tables containing personal information have Row-Level Security (RLS) enabled at the PostgreSQL level. RLS policies ensure that a parent can only read or modify data for their own children (students.parent_id = auth.uid()), and that children cannot access data belonging to other users. The webhook_events table has RLS enabled with all access revoked from authenticated and anon roles, restricting access to the service role only.
Administrative access to children's data is governed by the staff authorization system defined in src/lib/admin/guards.ts. Every admin request resolves a StaffContext by looking up the user's active staff_members row (lines 60–66), verifying that the staff member's access has not been revoked (revoked_at IS NULL). Permission checks (requirePermission) enforce role-based access control, and a two-person rule (requireTwoPerson) requires a second approver for high-value actions such as refunds and payouts.
Every time a staff member views a minor's record, a PII access event is logged to the pii_access_log table via the logPiiAccess function (src/lib/admin/audit.ts, lines 73–94). Each log entry records the staff member's ID, the subject type (child, student, parent, or teacher), the subject ID, and the purpose of access. This creates a complete audit trail of who accessed whose data and why.
Additionally, all administrative mutations are logged to the audit_log table via the logAudit function (lines 36–68), capturing before/after state, the actor, the action, the reason, and the IP and user agent. The audit system fails closed: if an audit write fails, the entire action is aborted (line 66).
Staff accounts are required to use multi-factor authentication through Supabase Auth. MFA enrollment is enforced at the authentication layer before a staff session can be established, adding an additional layer of protection against credential compromise for any account with access to children's data.
All data in transit is encrypted via TLS 1.2+. Data at rest is encrypted by the managed PostgreSQL provider (Supabase). Service role keys used for administrative operations are stored as server-side environment variables and never exposed to the client.
Some workshops may be recorded for educational review purposes. Recording is only enabled when the workshop creator sets recording_enabled = true on the workshops table. KidsCode Gift enforces explicit, affirmative parental consent before a child can enroll in a recorded workshop.
During checkout (src/app/api/workshops/checkout/route.ts, lines 273–311):
recording_enabled === true, the checkout request must include recordingConsent === true. If consent is not given, the enrollment is rejected with HTTP 400 (lines 278–281).workshop_enrollments stores recording_consent (boolean) and consent_at (timestamp) to create a permanent audit trail of the consent decision (lines 309–310).The recording_consent field is also surfaced to parents in the data review UI, allowing them to verify which workshops have recording consent on file for their child.
Consistent with 16 C.F.R. § 312.6, parents have the following rights with respect to personal information collected from their child. All rights are exercisable through the parental dashboard or by contacting contact@kidscodegift.com.
| Right | How to Exercise | Implementation Reference |
|---|---|---|
| Right to Review | View all data collected from your child at /dashboard/parent/data | src/app/dashboard/parent/data/page.tsx (load function, lines 50–110) |
| Right to Export | Download a complete JSON export of your child’s data with one click | src/app/dashboard/parent/data/page.tsx (handleDownload, lines 114–160) |
| Right to Delete | Permanently delete your child’s account and all associated data | POST /api/account/child-delete (src/app/api/account/child-delete/route.ts) |
| Right to Refuse Further Collection | Delete the child profile to stop all further data collection; or contact support to restrict specific data uses | Deletion removes all enrollment and certificate data, preventing further collection |
| Right to Revoke Consent | Delete the child profile; consent is voided upon deletion | consent_at and consent_source are removed with the students record |
KidsCode Gift responds to parental requests within 5 business days, as stated in the Privacy Policy (Section 4.3).
All instructors who teach live workshops involving children must pass a criminal background check administered by Checkr, Inc. before they are permitted to interact with students. The background check workflow is integrated via:
src/lib/checkr.ts — Checkr API integration and status mapping utilities.src/app/api/webhooks/checkr/route.ts — Webhook receiver that processes Checkr report status updates. Only the status enum is stored on the instructor's profiles row (checkr_status); the full report is never stored.verification_status is set to pending only after Checkr returns clear or consider, and an admin must manually approve the instructor before they can publish workshops.Internal staff with access to children's data are managed through the staff_members table. Each staff member has a role (e.g., owner, admin, support) that determines their permissions via the permission matrix in src/lib/admin/permissions.ts. Staff access can be revoked at any time by setting revoked_at, which immediately removes all administrative access.
All staff actions involving personal data are logged to the audit_log table (via logAudit in src/lib/admin/audit.ts), and all views of minor's records are logged to pii_access_log (via logPiiAccess). These logs provide a complete, tamper-evident record of every staff interaction with children's data, supporting periodic compliance reviews and regulatory inquiries.
All staff members with access to children's personal information receive training on COPPA requirements, data minimization principles, and the platform's security protocols before being granted access. Training covers the proper use of the audit and PII logging systems, the two-person approval rule for sensitive actions, and the procedures for responding to parental data requests within the required 5-business-day window.
For questions about this COPPA compliance documentation, to submit a parental request, or to report a concern regarding children's privacy, contact:
This document is maintained as a living record of the platform's COPPA safeguards and is updated whenever implementation changes are made. Last reviewed: August 16, 2026.