Skip to content
Arunish Rajput@arunishrajput

Systems & interfaces

Shaala OS

Paper in, decisions out — school operations that read their own forms and repair their own timetable.

Live2026Solo buildPaperBuddy EduHack — Future-Ready Ops track
FastAPIFlutterPostgreSQLWebSocketsGemini VisionOR-Tools CP-SATRenderVercel

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.

Substitute repair dialog: five uncovered periods listed vertically, each with three ranked candidate teachers and a one-tap assign control.

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

Chose

Human-in-the-loop review with per-field confidence

Over

Trusting the extraction and writing straight to records

Because

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.

Chose

OR-Tools CP-SAT

Over

A greedy or genetic scheduler

Because

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.

Chose

One WebSocket event bus

Over

Per-feature polling

Because

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.

Chose

Transparent EWMA plus a seasonal baseline for staffing

Over

An ML forecasting model

Because

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.