Systems & interfaces
Shaala OS
Paper in, decisions out — school operations that read their own forms and repair their own timetable.
SUBSTITUTE REPAIR
45 → 6s
SOLVER
CP-SAT
EXTRACTION
per-field
The problem
Indian schools run on paper. Admission forms, attendance registers, leave applications, marks sheets. The timetable is built by hand over a week in July and it holds until the first Tuesday somebody calls in sick.
Here is the number that made me build this: one teacher absence costs a clerk about 45 minutes. Not of thinking — of walking. Pull the register, find which periods that teacher covers, cross-reference who else is free in each of those slots, check nobody ends up double-booked, then physically find those people and tell them. Meanwhile three classes sit unsupervised.
And the principal learns about problems in the order people complain about them. A class went uncovered, a student slid past the attendance cliff, a section is short a teacher next month — all of it arrives late, through whoever shouts.
What I built
One system where the paper becomes records, the records drive a real solver, and the solver's output arrives as a decision the principal can take with one tap.
Three demo logins — admin, teacher, parent — no password, so anyone can open it and see the whole thing work.

Mark a teacher absent and every uncovered period surfaces with ranked candidates. One tap each, then the Outbox drafts the notifications.
How it works
Documents
Upload a form, and it goes through preprocessing, then Gemini extraction that emits a confidence score per field rather than one score for the page. Anything below threshold lands in a human review queue with the original scan beside it. Only after a human commits does it become a record.
That review step is the whole design. An extraction pipeline that writes straight to the database is a pipeline that silently corrupts a student's date of birth, and nobody finds out for two years.
Timetables
The timetable is a constraint satisfaction problem, so it's solved as one — OR-Tools CP-SAT, with teacher availability, room capacity, subject-hour requirements and consecutive-period rules encoded as hard and soft constraints.
Two things make it usable rather than merely correct. Explain-any-cell: click any slot and the system tells you which constraints put that teacher in that room at that hour. And drag-and-drop with live validation: move a period by hand and the solver re-checks in place, so a head of department can override the machine without being able to break the schedule.
Substitute repair is the same solver run over a much smaller problem: hold everything fixed, mark one teacher unavailable, rank candidates for each newly-empty slot by subject match, load, and how recently they last covered. Forty-five minutes of corridor-walking becomes six seconds and five taps.
One system, not five
A single Postgres schema and a single WebSocket event bus. When a teacher is marked absent, the timetable view, the Action Center, the parent app and the Outbox all react to the same event — no polling, no page an admin has to remember to refresh, no two screens disagreeing about who is teaching 8B at eleven.
The Action Center
Not a wall of charts. A prioritised inbox of things that need a decision, each with enough context to decide and a control to act. Behind it: signal detectors watching attendance trajectories, uncovered periods, and a 7-day staffing forecast built from an EWMA plus a seasonal baseline — with a backtest, so the forecast can be checked rather than believed.
Decisions
Human-in-the-loop review with per-field confidence
Trusting the extraction and writing straight to records
A wrong admission record is discovered years later by the student, not minutes later by the clerk. Per-field confidence lets high-certainty fields pass and routes only genuinely ambiguous ones to a person, so review stays cheap without making the system trustworthy-by-assumption.
OR-Tools CP-SAT
A greedy or genetic scheduler
A greedy scheduler produces a timetable that is plausible and unexplainable. CP-SAT produces one that is provably feasible and — because the constraints are explicit — can answer 'why is this teacher here?' for any cell. In a school, the explanation is what makes the output acceptable to the people it schedules.
One WebSocket event bus
Per-feature polling
Five screens polling five endpoints will disagree with each other, and the disagreements surface as a parent being told their child's class is covered when it isn't. One event, one source of truth, every view reacting.
Transparent EWMA plus a seasonal baseline for staffing
An ML forecasting model
A principal will not act on a number they cannot interrogate. EWMA with a published backtest is a forecast you can argue with; a black box is one you either obey or ignore, and in practice they ignore it.
What I'd do differently
The Flutter admin app and the FastAPI service grew their own overlapping ideas of what a "period" is. Two models of the same domain object, drifting — which is why some edge cases in drag-and-drop only reproduce on the client. Given the time again I'd generate the client models from the API schema instead of writing them twice.
And the whole thing assumes a single school. Multi-tenancy would be a schema migration and an auth rewrite, not a feature flag — worth knowing before anyone tries to use it for a group of schools.