Skip to content
technology
School operations In production

School Operations

bina teaches across time zones, so the working day is longer than any one team’s shift. Every child’s day is a set of appointments that has to be right, and every one of them has to change when a child moves class, a family signs up for a club, or a teacher stops being available. Without shared systems, the coordination work can grow with the roll. bina’s answer is a record: enrollments are dated rows that keep their history, a class roster is resolved from those rows at the moment somebody asks, schedules are authored once and published into every personal calendar, and the things families decide for themselves land without an administrator touching them. The people who run the school work that record with AI: a question about a cohort is asked in words and answered from the data platform bina built, with answers that can be checked against the source records. This is the system that decides whether the cost of running the school grows with the roll. bina is building it so that it doesn’t.

One move. A few things worth getting right.

Walk through a fictional class transfer. Resolve a timetable clash, approve a dated change and recover a delayed calendar update.

Illustrative workflow · fictional groups · no live school data

  1. Request
  2. Review
  3. Scheduled
  4. Applied

Transfer request

From / to
Group A → Group B
Effective date
Next Monday, 09:00 school time
Learning fit
Teacher review complete
Capacity
One place available in this example

Request received

The learner remains in Group A. Nothing changes before review and the effective date.

Calendar: unchanged.

Change history
  1. Request recorded. Existing placement retained.

What the operations engine is made of

This is one of bina’s longest-running systems, built around the work of carrying a working school from term to term. The administration, scheduling and family-facing services sit alongside newer work such as intake recommendations. Those recommendations still need review and their own production gates.

Dated enrollmentLive Every membership carries the day it starts and the day it ends.
A child’s place in a class, a discipline group, a club or an elective is a dated row on one shared contract, and a change writes a new row. A family that signs up for a later term gets a start date in the future and waits there quietly until it arrives. Nothing is overwritten, so the enrollment history of a child stays readable years later: which groups, in which order, between which dates. The database itself refuses the overlaps that matter: two homerooms covering the same day, two groups in the same discipline, two bookings in the same slot, including on a row somebody adds with a date in the past.
Live rostersLive The class list is worked out at the moment somebody asks for it.
There is no stored class list to fall out of step with reality. Ask which children are in a group on a given day and the answer is resolved from the memberships that cover that day, which is exactly why the same question has an answer for a day that has not arrived. Everything built on this rule resolves it one way: the list an interface hands back is the list a save will accept and the list a report will total. The alternative — a copy of the list kept in every surface that needs one — is where a year of this system’s hardest bugs came from, and ending it is what the current consolidation is for.
Schedule authoringLive The week is built on a grid, with repeats, amendments and undo.
The teaching week is authored on a Monday-to-Friday grid: place a block, give it a repeat rule, share it across two groups, drag it, drop it, take it back. Several people can hold the same week open at once and only the commit is serialized, so two people working on a shared group cannot overwrite one another, and a save that arrives while a deployment is running is refused with the reason on screen. A change to a single day and a change to every following week are different actions with different consequences, and the interface makes you say which one you mean.
Calendar publicationLive Every student and teacher gets their own week, in their own time zone.
Deployment builds each person’s calendar for them. A student’s week is assembled from every block they are assigned to anywhere in the school, so a child who takes one discipline with another group still sees one coherent day, labeled with their own class. Four time zones are handled at the point of publication, so nobody converts anything by hand. Events are written without firing a notification at each one, because a deployment that mails every family whenever a block moves is a deployment nobody dares run. Writes that fail are recorded and flagged for a person, and they are never quietly dropped.
Placement requestsLive A move is a request with a date, an approver and a trail.
A teacher raises a move for a child in their own class, with a reason. The family-success team reviews it on a roster view that shows pending and approved movements already in place, and a date picker previews the composition of any group on any future day before anybody commits to it. An approved request executes on its effective date and not a day earlier, as a resumable sequence: activate the membership, seat the child, rewrite the rosters, redeploy the calendars, sync the classroom. Each step records where it reached, so a run that stops partway carries on from there the next day and rewrites nothing behind it. One open request per child, enforced everywhere. This replaced a chat channel, in a term when a large share of the roll changed groups.
Family self-serviceLive Clubs and electives chosen by families, without an administrator.
Families enroll their own children into clubs from a portal of their own, with capacity, a waitlist and quiet promotion the moment a place opens. Electives run on the same machinery with the parts a course needs: a ranked set of preferences, so a child who misses a first choice still lands somewhere they chose; a minimum enrollment before a class opens at all; an automatic fall back to the next preference when it does not; and a window to switch, which then closes. Every enrollment change that touches a calendar records a work item, and the worker acts only on recorded work items: with an empty table it does nothing at all, which is what makes a self-service surface safe to point at a live timetable.
The teacher’s deskLive The daily surface: today, the class, the register, the materials.
Teachers work from a panel of their own: today’s agenda, the live class view, the register and the materials record. Signing in routes a teacher there with no path into the administrative surface, and they see the classes and homerooms they hold, enforced where the data is fetched. Clubs appear beside lessons, so a club leader takes a register the same way as a teacher. Most of the work here was persuading people out of a spreadsheet they liked, which is why the newest version of the register is a grid with keyboard entry, fill-down and paste. A surface has to be better than the sheet it replaces, or the sheet comes back.
Questions in wordsLive The team asks the record questions, in words, with AI.
The registries behind the student card were built to be read by more than a person clicking through filters. Because every operationally meaningful change is a dated row against a known child, a cohort question is one an assistant can answer straight off the record: which children moved twice this term, which families have gone longest without a check-in, how a group’s composition shifted after a teacher changed. The team does this today, over the same governed interface that automations use: keys carrying named scopes, a hard separation between reading a record and reading who the record is about, and a machine-readable description of exactly the routes a given key may call. It is the difference between an operations lead who can ask a question and an operations lead who files a request with engineering and waits.
Automatic placementIn build Seating a new intake without anybody drawing up a list.
Families arrive continuously, sign, and each child lands in a pool carrying the date the family wants them to start. The design fills existing classes first and opens a new one for whoever is left over, and it runs every day through the weeks before a term opens, so a family that signs late is seated by the next morning. It is built and it is held: what remains are gates on production access. Until they clear, seating an intake is a decision a person makes with the capacity view already in front of them: fill rate, free places and teacher assignment for every level, on one screen.

Three ways a school runs itself

Every school solves these problems somehow. What separates the columns is what a change costs once the term has started, what the record can tell you about a day that has not happened, and whether the people running the school can ask it a question nobody wrote a report for.

A spreadsheet and a shared calendarA packaged school systembina
Who builds the weekA coordinator, in a sheet, copying blocks across tabs and then into invites.An administrator, in the vendor’s timetable module, within the shapes it supports.Whoever owns the week, on a grid, with repeats, shared blocks across groups, undo, and several people able to hold it open at once.
Where the timetable is publishedIn whatever calendar each person happens to keep.In the portal or calendar integrations the package supports.Into every student’s and teacher’s own calendar, assembled per person and converted into their own time zone, with no notification storm when a block moves.
What a mid-term move costsA message in a channel, and somebody remembering to change five places.A form, and a rebuild of whatever the module recalculates.One request with an effective date. It executes on that date as a resumable sequence (membership, seat, rosters, calendars, classroom), recording each step it reaches.
What a future date can tell youOnly what its dated entries or saved snapshots preserve.What has been keyed in, once the term rolls over.The composition of any group on any day, resolved from dated memberships, with the movements still awaiting a decision applied, so a lead can see the class they are about to create.
What stops a double bookingSomebody noticing.A validation in the module that owns the timetable.A conflict check that refuses the save, and the database itself refusing overlapping memberships and overlapping bookings, including for rows backdated after the fact.
How a family joins a clubThey email, and somebody adds them.Through a parent module where available, or through the office.They do it themselves, in their own portal, with capacity, a waitlist that promotes quietly, ranked preferences for year-long courses, and the calendar following on its own.
What the people running it can askWhatever a formula reaches across the tabs somebody kept up to date.Built-in reports, supported queries and exports for further analysis.Questions within the caller’s authorized data scope, in words. Every operational change is a dated row against a known child, reachable through one governed interface, so the team puts AI on the record and asks a cohort question directly.
The tradeIt works until the roll grows, and then it needs people.The school fits the vendor’s idea of a school, and its data lives inside it.This is the oldest thing bina has built, and it grew in layers. For a long stretch a single lesson had several representations at once (the block that generated it, a mirrored row, the published calendar event), and most of the serious operational bugs of the past year trace to two of them drifting apart. The architecture that collapses them into one lesson row, with every consumer reading a projection of it, is designed in full and the migration is running phase by phase behind contract tests that keep the existing consumers answering throughout. Until it lands, a roster change arriving by an unusual path can still leave a stale list on somebody’s screen, and the team pays for that in investigations.

One change, and everywhere it has to land

Moving one child between two groups is a small decision that touches a surprising number of things: two rosters, two personal calendars, a teacher’s week, the register, the shared classroom. Doing it by hand means doing all of it, in order, without forgetting one. Half-done is the state that actually hurts, because it looks finished. Hover any checkpoint on the rail to see what stops that happening.

THE TEACHERFAMILY SUCCESSTHE DEPLOYERTHE SURFACESTHE WORK LEDGERANYTHING WITHOUT A TERMINAL STATE COMES BACKA CHANGEAPPROVEDSTUDENT CALENDARSTEACHER CALENDARSTHE LIVE ROSTERTHE TEACHER’S DESKTHE WORK LEDGERA REASON, WRITTEN DOWNAN EFFECTIVE DATEA RECORDED WORK ITEMONE ROSTER, RESOLVEDA TERMINAL STATE, OR A RETRYone open requestno double bookingthe past is read-onlyan effective daterecorded work onlyresumable by design
CheckpointsHover or tap any checkpoint on the rail to see what it guarantees.

Checkpoints. one open request: a child holds at most one open placement request at a time. no double booking: a conflict sweep refuses the save, and the database refuses overlapping memberships and bookings. the past is read-only: a day that has happened cannot be edited or redeployed. an effective date: a change executes on the day it takes effect, whatever day it was approved. recorded work only: the worker acts on recorded work items and does nothing when there are none. resumable by design: each execution records the step it reached and carries on from there.

The four surfaces are written in parallel, and the diagram lights them together for that reason. What holds the change together is the ledger on the right: a destination reports a receipt, and an item that has not reached a terminal state is handed back to be run again. A partial change must remain visibly unfinished, because the dangerous state is one that looks complete.

The commitments that shape it

A school’s operations record is only worth what it can be trusted to say a year later. Four commitments hold this one: the past is never recomputed, a fact is stored once and resolved everywhere, a change carries the day it takes effect, and unfinished work stays visible until it is resolved.

The past is never recomputed

A day that has happened is frozen: ordinary deployment does not rewrite it, a teaching period that has ended is read-only, and today itself needs a specific permission to touch. History accumulates by writing new dated rows over old ones, and historical entries are retained under the record’s lifecycle rules. This is what makes a movement record, an attendance mark or a roster from two terms ago something a person can rely on.

Stored once, resolved everywhere

A class list exists in exactly one form — dated memberships — and every surface that shows one resolves it the same way. The list an interface returns is the list a save accepts and the list a report totals. Copies of the list are the source of nearly every operational bug worth naming in this system, and the consolidation currently in flight exists to remove the last of them.

A change carries its own date

Approving a move and applying a move are separate events with separate days. A decision taken in week two for a change in week four sits visible in the preview and lands on the morning it was meant to. That separation is what allows a lead to work through a queue of movements in one sitting without having to time a single one of them by hand.

A partial change is not a finished change

Anything that has to reach a calendar records a work item first, and the worker acts only on recorded work items. Each execution records the step it reached, so a run that stops partway carries on from there and rewrites nothing behind it. An item that has not reached a terminal state stays visible as an item, which is the difference between a failure somebody fixes and a failure that looks like success.

Families do their own admin

Clubs and electives are chosen by families in a portal of their own, with capacity, waitlists, ranked preferences and a switch window. The guardrails sit underneath: enrollment changes record work items, additions land on a nightly batch, removals go through near-instantly, and a family flipping their mind three times in an evening leaves the calendar exactly as correct as if they had decided once.

The record is built to be asked

Every operationally meaningful change is a dated row against a known child, reachable through one governed interface: keys carrying named scopes, a hard split between reading a record and reading who it is about, and a machine-readable description of exactly what a given key may call. That shape is why the team can put AI on the data platform and get a cohort answer in a sitting, and it is why an automation and a person cannot see two different schools.

What compounds

Operating cost comes loose from the roll

A new class is rows and a deployment. A new time zone is a field on a class. A new club is a registry entry and a self-service link. They need not each bring a new coordinator or another standing meeting. The claim this direction has to support is that bina can teach several times as many children without an operations department several times the size, and every part of it is built against that claim.

A question costs a question

Because the record is dated, structured and reachable through one interface, the team asks it things nobody wrote a report for, and asks in words. New operational questions arrive constantly in a growing school; in most of them the cost is a ticket, a sprint and a dashboard nobody opens twice. The aim is to investigate directly, with an answer checkable against the rows it came from.

Running the school writes the history

Every movement, every seat, every register mark and every club sign-up is a dated fact the moment it happens, because that is simply how the work gets done. Nobody is asked to record anything twice for the sake of analysis. What accrues is a longitudinal record of how a school actually moves. It is the substrate the learning loop and the safeguarding work both read from.

Built on A Python application over a relational database holds the memberships, the timetable and the registries, with database-level constraints carrying the invariants that must never bend. A background worker fleet does the deployment, and everything that reaches an external calendar goes through a recorded work item with a terminal state, so nothing is redeployed on a guess. Reads and writes for automations run over a typed HTTP interface with per-key scopes, an explicit separation of personal data, and a machine-readable description generated per key. Families use a separate self-service surface on its own public edge; teachers use a panel of their own; and the newest surfaces are built on one typed contract that produces the interface, the API and the agent tool together.