EduWay
Technical architecture v1.6

How a school platform holds together under load

Modular monolith on Django. Video traffic never hits the application server. Billing, classrooms and homework stay isolated through explicit service boundaries.

Three structural decisions

One app server

Nginx, Daphne, PostgreSQL, Redis and Celery share the application host for year-one simplicity — with Celery resource limits so heavy jobs do not starve live lessons.

Video bypasses the app

Browsers join Jitsi over WebRTC with short-lived JWT passes. Lesson peak load scales on the videobridge, not on Django.

Slow work goes async

Reports, file conversion, LLM assistance and ephemeral recorders run in Celery. External failures do not take the school offline.

Module map

Twelve apps, clear ownership

Billing knows nothing about lesson content. Classroom knows nothing about money. Cross-module rules — “inactive subscription → no lesson entry” — go through owner services only.

accounts
Users & roles

Student, Parent, Teacher, Curator, Club instructor

school
Academic structure

Years, semesters, grades 0–11, groups, shifts

scheduling
Timetable

Lessons, consultations, later iCal export

courses
Course builder

Topics, lessons, materials, cloning

classroom
Live room

LessonSession, Jitsi JWT, chat, board

homework
Assignments

Tests, uploads, submissions, review

grades
Journal

Scores 1–12, attendance, student diary

billing
Money

Tariffs, invoices, webhooks, debt cycle

clubs
Clubs

Directions, groups, separate billing

notifications
Messages

Email + in-app notifications

integrations
External APIs

Payments, R2, Anthropic

manage_panel
/manage/

Operational UI for admin / deputy / curator

Critical flows

Where complexity actually lives

FLOW 1

Joining a lesson

Schedule creates a LessonSession → student clicks Join → Django checks group + active subscription → issues short-lived JWT → browser connects to Jitsi directly. A bare room link is useless without a valid pass.

FLOW 2

Payment

Monthly invoice = tariff − discount + clubs → redirect to LiqPay/Fondy/Portmone → signed webhook → mark paid, renew subscription, notify. Overdue invoices open curator retention work.

FLOW 3

Homework with files

Student uploads straight to Cloudflare R2 via a signed URL. The app stores a Submission reference and notifies the teacher — the application server never carries the file bytes.

FLOW 4

Debt restriction

Auto reminders on day 5 and 10. On day 12 the curator reviews a shortlist, unticks negotiated cases, restricts the rest. Lessons close; chat and pay stay open. Payment webhook unlocks instantly. Race-safe: the server re-checks invoice status inside a locked transaction before restricting anyone.

Infrastructure

Year-one footprint

LayerChoiceWhy
ApplicationHetzner CAX31 (ARM)Nginx + Daphne + Postgres + Redis + Celery
VideoHetzner CAX41 Jitsi~12 rooms; second JVB for 20+ peak
RecordingEphemeral Jibri fleetSpun up before a shift, destroyed after; MVP records distance webinars only
FilesCloudflare R2Materials, homework, selected recordings
BackupsContinuous WAL → R2Point-in-time recovery is mandatory — parent money is on the line
LLMAnthropic APITeacher content assistant, offline from the critical path
Delivery plan

Monetisation is in MVP on purpose

PHASE 1 · MVP

Sell and teach

Auth, roles, /manage/, academic structure, tariffs, payments, timetable, Jitsi rooms, journals, preschool start.

PHASE 2

Full school life

Parent cabinet, homework, debt cycle, clubs, flexible enrolment, distance mode, calendar, notifications.

PHASE 3

Advantage layer

Interactive board, selective recording, LLM assistant, progress analytics, CSV export for state reporting, iCal.

ARCHITECTURE · v1.6