System architecture
Four layers, each with a single responsibility
Experience layer
- Next.js App Router (React server components)
- Role-aware shell: sidebar, topbar, switchers
- Route-level loading states for every navigation
- Responsive layouts, fixed LTR direction in all languages
Domain layer
- Curriculum service: year → subject → topic → lesson
- Assessment service: questions, marking, attempts
- Progress service: mastery, streaks, readiness
- Recommendation rule engine and Ask TTT assistant
Data layer
- Prisma schema as the single source of truth
- Typed collections mirrored in the client store
- Deterministic seed data for every environment
- Audit log for every content and account change
Platform layer
- Role-based access control per route prefix
- Subscription and seat entitlements
- Mapbox for centre locations
- Safeguarding filters on generated content
Browser
Parent · Pupil · Teacher · Admin
App Router
Server components + route loaders
Domain services
Curriculum · Assessment · Progress
Prisma data model
Typed collections + audit log
Data flow: one answered question
From tap to updated reporting
- 1
Pupil answers
Practice runner
- 2
Answer normalised
Case, spacing, units
- 3
Marked instantly
Correct / incorrect
- 4
Attempt stored
Child, question, seconds
- 5
Aggregates rebuilt
Topic mastery, subject score
- 6
Surfaces update
Dashboard, Insights, Marking
Read paths
Selectors derive every number on screen from attempts, lesson progress and paper scores. Nothing is stored twice.
Write paths
Writes are small and append-only: an attempt, a progress row, an assignment toggle, an audit event.
Boundaries
A pupil write can only ever touch their own profile; teacher and admin writes touch content, never billing.
Business flows
The four journeys the platform is built around
Family onboarding
Parent signs in
Add child profile (year group, school)
Plan and seats checked
Curriculum filtered to the year group
Dashboard seeded with recommendations
Practice and marking
Pupil opens a practice set
Answer normalised and compared
Attempt written with time taken
Explanation shown immediately
Mastery and subject score recalculated
Content pipeline
Teacher drafts lesson or question
Second teacher reviews
Admin publishes
Content appears in Learn, Practice, Studio
Audit event recorded
SATs readiness
Paper downloaded
Score recorded against the child
Paper average recalculated
Weak topics surfaced in Insights
Revision practice suggested by Ask TTT
Recommendation rule engine
Deterministic rules, evaluated in weight order, that decide what a child sees next
| Rule | Name | When | Then | Weight |
|---|---|---|---|---|
| R1 | Continue learning | A lesson has progress above 0% and below 100% | Pin it to the dashboard as the next action, ordered by most recent activity | Highest |
| R2 | Weak topic focus | Topic accuracy is below 60% with at least 4 answers | Recommend the topic’s practice set and its explainer video | High |
| R3 | Assignment due | An assignment is incomplete and due within 3 days | Raise it in Upcoming and mark it on the pupil dashboard | High |
| R4 | Streak protection | No answers recorded today and the streak is 3 days or more | Offer a 5-question set from the strongest topic to keep the streak alive | Medium |
| R5 | SATs window | Child is in Year 6 and within one term of the SATs | Bias recommendations towards arithmetic, reasoning and past papers | Medium |
| R6 | Stretch | Topic mastery is 90% or above | Offer greater-depth questions and mark the topic as secure in Insights | Low |
Child signals
Attempts · progress · papers
Rule evaluation
R1 → R6, first match wins per slot
Ranked actions
Lesson · practice · video · paper
Surfaces
Dashboard · Insights · Ask TTT
Content pipeline
Draft to published, with review built in
Draft
Author-only. Invisible to families and pupils.
In review
A second teacher checks wording, marks and explanation.
Published
Live in Learn, Practice, Studio and Papers.
Archived
Hidden from pupils; historic attempts stay in analytics.
Status changes are recorded in the audit log with the actor and timestamp, so any piece of content can be traced from first draft to the moment pupils saw it.
Data model
Core entities and how they relate
YearGroup
has many Topics, Children, Papers
Subject
has many Topics
Topic
has many Lessons, Questions, Videos, PracticeSets
Lesson
has many LessonProgress rows
Question
has many Attempts, belongs to PracticeSets
Child
has Attempts, LessonProgress, Assignments, PaperAttempts
User
guardian of Children, author of Lessons and Questions
Subscription
has many Invoices, grants seats to a User
Role isolation
Access is granted per route prefix, so no workspace leaks into another
| Area | Parent | Pupil | Teacher | Admin |
|---|---|---|---|---|
| Dashboard, Learn, Practice, Studio, Papers, Ask | Allowed | Allowed | — | — |
| Insights and family reporting | Allowed | — | Allowed | — |
| Billing, plans and seats | Allowed | — | — | Allowed |
| Achievements | — | Allowed | — | — |
| Authoring and marking | — | — | Allowed | Allowed |
| Curriculum and content management | — | — | — | Allowed |
| People, subscriptions and audit log | — | — | — | Allowed |
Ask TTT pipeline
How a question becomes an explanation and extra practice
Prompt
Parent or pupil question
Intent + keywords
Topic, child, task
Context assembled
Progress + published content
Answer drafted
Explanation in teacher voice
Practice generated
Saveable as a set