Five views of the same system: its architecture, a request, an AI call, its security and its quality gates. Every diagram uses the real names from the code.
What the system is made of, from the screens people use to the database underneath.
How the data is organized.
Users, profiles and schools at the root; every school-scoped table carries its school. Personal fields are encrypted and key records are immutable.
How the data is organized
A user can hold several profiles, each with one of seven roles, in a school (the tenant root). A family link joins
a parent profile to a student profile and carries the consent record. School-scoped tables hold lessons, tasks
with three teacher-written help levels, submissions, wellbeing check-ins, journal entries, insight reports, the
audit log and attachments. Every row carries its school. Personal fields are encrypted, and the audit log,
journal and insight reports are immutable.
School-scoped tablesParent and studentevery row carries its schoolOne login,many profilesUserEmail (encrypted)Password hashSession tokenSchool (tenant root)Country and settingsAI and storage overridesContent safety levelProfileRole: one of sevenSchool and sectionName and ID (encrypted)Active flagFamily linkParent ↔ studentConsent status and expiryIP, user agent, terms hashLessonTeacher, section, subjectObjective, activity typeTaskThree help levelslow · medium · highWritten by the teacherSubmissionStudent answerAI help historyEncrypted prompt copyWellbeing check-inStudent and sectionSentiment, optional wordEncrypted, can anonymizeJournal entryTeacher observationEncrypted noteImmutableInsight reportAI-assisted draftTeacher’s final textEncrypted, immutableAudit logWho, what, when, whereImmutableKey events kept foreverAttachmentTask and lesson filesS3-compatible storageSigned, expiring URLs
Four checkpoints run before any page loads.
They run on every request, so a page cannot forget them. Checkpoints 3 and 4 protect minors.
Checkpoint 1 · Session
Who are you?
One active session per person. Signing in elsewhere closes the first.
set_tenant_context
Checkpoint 2 · School
Which school?
Rows are stamped with their school and cannot be moved to another.
TenantMixin
Checkpoint 3 · Minors
Did a parent consent?
No valid consent, no access. The attempt is audited.
enforce_parent_consent
Checkpoint 4 · Launch
Is the school live?
Students wait until their school has gathered its parents’ consents.
enforce_institution_launch_status
After the checkpoints: a role check (403 if not allowed), the service, encrypted columns, then the page.
Many callers, one door to the provider.
Chat and help calls pass through one client: safety rules go in, moderation and audit come out. Prompt text is never shown here, only the structure.
How an AI call is governed
Two kinds of callers reach one client, AIClient.generate(): PromptService (a registry, a loader and a builder,
used by parent chat and grading) and direct callers (student help and chat, lesson authoring, curriculum
parsing). Inside the client: safety rules are prepended, the provider answers, the reply is moderated, and the
call is audited. Unsafe replies become a safe message.
PromptServiceRegistry: role + questionLoader: typed contextBuilder: composes promptParent chat · gradingDirect callersStudent help and chatLesson authoringCurriculum parsingAIClient.generate()1SafetyRules for minorsare prepended tothe call, aheadof everything.2ProviderAnthropic, OpenAIor an offlinefallback, set perschool.3ModerateThe reply ischecked: providerAPI, or Spanishkeyword rules.4AuditEvery call islogged. Unsafereplies become asafe message.Unsafe reply →safe messageAudit logrequest · replyAI providerAnthropic · OpenAIoffline fallback
How a prompt is built.
Four layers in a fixed order: two in the system message, two in the user message. Structure only, never the prompt text.
How a prompt is built
Every AI call is a stack of four layers. Two go in the system message: the safety rules, always first, and a role
frame. Two go in the user message: a task prompt that depends on the scenario, and a typed context holding only the
data that call needs. The stack is wrapped in a provider envelope (Anthropic or OpenAI), sent to the provider, and
the reply is moderated and audited; grading replies are parsed into a grade and an explanation. The four scenarios
are student help, student chat, parent chat and grading. The diagram shows structure only, never prompt text.
Prompt stackSafety rulesSystemAbsolute rules for minors. Always first.SAFETY_INSTRUCTIONRole frameSystemWho the model acts as in this call.system messageTask promptUserOne per scenario: tutor, parent questions, grading.services/prompts/buildersTyped contextUserOnly the data this call needs, as structured fields.services/prompts/contextsProvider envelopeAnthropic: one systemfield and one usermessage. OpenAI: systemand user messages.Same prompt, either way.AI providerAnthropic · OpenAIReply handlingChecked by moderationand written to the audit logUnsafe: replaced by asafe messageGrading: parsed to JSON{ grade, explanation }Four scenarios, one stackStudent helpThe teacher’s help text, plus grade,style, help level and detail modeStudent chatLesson and task material; falls backwhen there is no official materialParent chatOne of nine questions, with progress,attendance and journal summariesGradingAcademic principles, task, answerand scale → a proposed grade
AI call simulator · scripted, no network, synthetic data
Student · help level MEDIUM: trace
The student asks for help on a task
Context for this school is loaded
Safety rules are prepended
The provider answers
The reply is moderated
The call is audited
Prompt structure (redacted)
Safety rules
The teacher’s help text, level MEDIUM
Learning style
Task context
Parent · “How is my child doing?”: trace
The registry routes (parent, question)
The loader builds a typed context
The builder composes the prompt
Safety rules are prepended
The reply is moderated
The call is audited
Prompt structure (redacted)
Safety rules
Role instructions
Typed context (synthetic here)
Teacher · propose a grade: trace
The registry routes the grading request
The loader reads the submission
The builder adds the academic principles
Safety rules are prepended
The reply is moderated
A proposal returns for the teacher to confirm
Prompt structure (redacted)
Safety rules
Academic principles: delegate, describe, discern, be diligent
Submission (synthetic here)
Student · unsafe message: trace
The student writes something harmful
The safety rules tell the model to answer with care and point to a trusted adult
The reply is moderated and flagged if unsafe
A safe message replaces an unsafe reply
A permanent audit event is written; critical cases are flagged for review
Prompt structure (redacted)
Safety rules
The student’s message
The safety rules steer the model toward a careful answer, and the reply is checked and flagged if unsafe.
Who could try what, and what stops them.
How security is layered, then a threat model in one table.
Security architecture
The security architecture in layers, from the browser through the web layer (HTTPS, HSTS, CSRF, secure cookies,
rate limits), four checkpoints (session, school, parental consent, school launch), a role check, the service and
the database, where personal fields are encrypted. Blocked attempts and key events go to a permanent audit log.
AI calls leave the service for the AI provider; student and parent calls get safety rules in, reply moderation
and audit.
NetworkIdentity and consentDataBrowserstudent · parentteacherWeb layerHTTPS + HSTSCSRF · Secure cookiesRate limitsCheckpoints1 session · 2 school3 consent · 4 launchRole checkNot allowed → 403ServiceBusiness rulesQueries scoped tothe schoolDatabaseEncrypted personalfields · write-onceaudit and recordsAudit logBlocked attempts · logins · AI callsKey events are kept permanentlyAI providerAnthropic · OpenAIoffline fallbackStudent andparent calls: safetyrules in, replymoderated, audited
Consent is a flow, not a checkbox.
A single-use link, a recorded acceptance with the terms’ hash, an activated profile and a permanent audit event. It can be revoked at any time.
How parental consent works
The school admin sends an invitation. The platform sends the parent a single-use link valid for seven days. The
parent opens it without logging in and accepts the terms. The platform checks the token and expiry, stores the
time, IP address and a hash of the accepted terms, and clears the token. The student profile is activated and a
permanent audit event is written. Consent can be revoked at any time: the student profile is deactivated, the
token is cleared and the event is audited.
School adminsends invitationsParentno login neededPlatformchecks and recordsAudit logpermanent eventsStudentprofileSends the invitationSingle-use link, valid 7 daysOpens the link, no login neededAccepts the termsChecks token and expiryStores time, IP and terms hashClears the token (single use)Student profile activatedEvent kept permanentlyRevoke any time: the student profile is deactivated, the token is cleared and the event is audited.
Every attack has a stopper.
Who
Tries to
Stopped by
Student
Get unsafe content from the AI
Safety rules in the call, reply moderation, audit; critical cases flagged for review
Student
Enter without parental consent
Consent and school-launch checkpoints on every request; the attempt is audited
Anyone
Guess national IDs in parent onboarding
Sliding-window limits on failed lookups, per user and per IP; names masked
Staff of another school
Read another school’s data
Rows stamped with their school and immutable; role checks; access-control tests; review for cross-school access
Stolen login
Reuse a session elsewhere
One active session per person; Secure and HttpOnly cookies; HSTS in production
Database leak
Read personal data from a copy
Field-level encryption with a key per field; encrypted backups
Threat explorer · pick an attack
Stopped at: Safety rules in the call, then reply moderation
The rules lead every call. An unsafe reply is replaced with a safe message and the event is audited.
Stopped at: Checkpoint 3 · Parental consent
Blocked and audited on every request.
Stopped at: Sliding-window limits per user and per IP
Names are also masked in the invite flow.
Stopped at: Checkpoint 2, role checks and access-control tests
Every row carries its school and cannot be moved to another.
Stopped at: Field-level encryption and encrypted backups
Each kind of field has its own key, and backups are encrypted.
A piece of data has a lifecycle.
Each stage has a rule, from the first write to the purge.
1 · Collect
Consent first
Parents consent before a student gets access.
2 · Store
Encrypted
Personal fields are encrypted on write, with a key per field.
3 · Use
Scoped and audited
Role and school are checked; sensitive reads leave a trace.
4 · Retain
By type
Security and consent events are kept; other logs 365 days; attachments 90.
5 · Purge
AI prompts: 30 days
A cleanup job removes the content of AI prompts.
No green checks, no commit.
Each gate must pass before a change moves on. If one fails, the change stops there and gets fixed.
Gate 1 · On edit
Still starts?
The app must still import after each change.
import check
Gate 2 · Commit
Still consistent?
Schema and services must match the models, or the commit is blocked.
pre-commit hook
Gate 3 · Review
Safe and green?
Security review of the diff first, then the full test suite. A human confirms the commit.
/pre-commit routine
Gate 4 · CI
Green anywhere?
Tests repeat on a clean machine with PostgreSQL 15, on every push and pull request.
GitHub Actions
Release
Data first
Database migrations run before the new version starts.
flask db upgrade
Also: data scripts carry a production guard, and a daily encrypted database backup runs on GitHub Actions.