Rebuilding a national sports federation, without switching it off
Thousands of children. Hundreds of schools. Seven seasons of history. One platform that could not stop.
The client runs inter-school sport nationally across India - hundreds of schools, thousands of children, seven-plus seasons of results already on record. I designed and rebuilt the platform they run on while it stayed in use: new portals for schools and students, a QR attendance system built for a venue rather than a demo, and a certificate engine anyone can verify.

The people
A nine-year-old, a parent, a coach at a venue desk, a school administrator, an official drawing fixtures, and the federation running the season. Pick one.
“I need 30 children through this desk quickly.”
What was wrong
Paper lists at the venue, then data entry afterwards.
Their path through the product
Surface: Mobile attendance
TL;DREvery hard problem on this project came from a person, not from the codebase.
The constraint
Not for a weekend, not for an evening. Schools were entering squads and officials were running events while the rewrite happened.
Meanwhile, the live season
Meanwhile, the rewrite
The platform changed completely. The users didn’t have to.
What users saw
What changed underneath
Keep the experience. Replace the engine.
People
cannot retrain mid-season
Data
cannot be lost
Operations
cannot stop
History
cannot change
Schools were entering squads and officials were running events while the rewrite happened. Seven seasons of results, medals and certificates were already in there. A clean-slate relaunch would have meant losing history the federation is judged on.
Design responseKeep the experience, replace the engine.
A student belongs to a school, but their results belong to the school they competed for. The legacy schema conflated the two, so anything that moved a student - a transfer, a correction - silently rewrote a school’s medal count.
Design responseModel identity and history as separate things.
Marking hundreds of children present at a venue meant paper lists and later data entry. The obvious digital fix - an app for each student - falls apart when the students are nine years old and the venue has no signal.
Design responseReverse the flow: the child is scanned, not scanning.
Participation and merit certificates for thousands of children, each needing the right name, school, event and rank. Any correction meant regenerating and re-sending by hand.
Design responseRender on demand from live records, never store files.
The hero problem
This is the design problem I am proudest of on this project - because the obvious solution is wrong, and the reason it is wrong is entirely human.
Reverse the flow.
The QR code identifies. The human verifies.
One phone per child
Excludes most of the children it is meant to serve.
One phone per squad
The school portal can show any of its students’ codes - identical at the scanner, because the child is standing there either way.
Designed for a venue, not a demo
TL;DRThe QR code identifies. The human verifies. Designed for a venue, not a demo.
The portals
An admin console running a national season and a parent checking a medal should not look like the same product.
The portal follows the order a school actually works in.
Start the season
The school opens the year and confirms its details.
The portal follows the way a school actually enters a season - not the way the database is arranged.
Parents were ringing schools, and someone was searching by hand.
The student portal exists because parents were phoning schools to ask about results.
Verifiable by anyone, private for the child, and correct years later.
Rendered at download time from live records - so a corrected name is right on every future copy, with nothing to regenerate or invalidate.
Anyone can verify
Never exposed
A certificate is only worth something if a third party can check it - without learning anything private about a child.
Years later
Because certificates are rendered rather than stored, they never become stale files. Parents come back years later asking for fixes - and they get one.
Both paths have to land in the same operational truth.
Online and offline money still has to end up in the same operational truth.
Where a school runs its season: enter squads by sport, age and gender, pay for entries, manage students and coaches, download entry sheets and certificates.
A student’s own record - the events they are entered in, their results and medals, their certificates, and the identity code they show at the venue.
The operational centre: events, sports and sub-games, capacities per age band, approvals, merits, reports and the release of certificates.
A mobile-first flow for marking hundreds of children present - built for a phone held one-handed at a desk with a queue in front of it.
Participation, merit and coach certificates generated on demand from live records, on the federation’s own artwork - and publicly verifiable by scanning the code on them.
Online payment for entries with receipts, plus a manual path for schools that pay offline - both landing in the same ledger so entries and money never disagree.
A student changing school, without disturbing a single past result. One approval, from the receiving school, with guardrails around unpaid and in-flight entries.
Consolidated entry sheets, per-sport draws and squad lists - the documents officials actually use on the day to build fixtures.
The modelling decision
The single most important decision on the project, and it starts as a human story rather than a schema.
A child changed schools. Their history should not.
School A
2024 · Gold medal, 100m
Stays here. Always. The result belongs to the school it was earned at.
History — never movesSchool B
Not yet
The student record moves here. Two columns change, and nothing else.
Identity — movesIdentity
History
Identity moves. History never does.
TL;DRSplitting identity from history is what made transfers, corrections and seven co-existing seasons possible at all.
Decisions
Each one starts with a person’s problem. The implementation is underneath, for anyone who wants it.
A student changes school. What happens to their medals?
Identity moves. History never does.
What it means for people
A school’s medal count, entry history and certificates are exactly as they were the day before a student left.
How do you replace a platform people are using today?
Migrate the users last, not first.
What it means for people
The federation never faced a rewrite and a retraining in the same week.
Should the attendance code expire, like every security guide says?
No. The code only has to identify.
What it means for people
A code that dies in thirty seconds fails precisely when a queue of children is waiting.
Most of these children do not own a phone.
A coach can hold the codes for the whole squad.
What it means for people
No child is excluded from attendance because of what their family can afford.
A parent asks for a name correction two years later.
Certificates are rendered, never stored.
What it means for people
They download it again and it is simply correct.
How does a college know a certificate is real?
Anyone can verify it, without seeing anything private.
What it means for people
The achievement is checkable; the child’s date of birth and contact details are not.
Seven seasons have to co-exist without overwriting each other.
A season is never overwritten.
What it means for people
Last year’s certificate keeps last year’s class on it.
A transfer request arrives with money already in play.
Guard rails where money is involved.
What it means for people
The refusal names the exact event, rather than failing vaguely.
Designing attendance around the venue instead of the idealised user.
Keeping the old interface alive while replacing the system underneath it.
Separating student identity from historical achievement.
Shaping the school portal around the season, not the schema.
Making certificates verifiable without exposing anything private about a child.
Giving schools, students, officials and administrators genuinely different interfaces.
Engineering
The architecture is here to serve everything above it. Pick a piece to see what it does.
Compatibility layer
Answers the legacy admin’s own endpoints from the new database. This is what made a live migration possible.
The decision the whole migration rests on.
Switch role and the navigation changes. The server changes too - and that is the part that counts.
The navigation changes per role, but that is presentation. Scope is resolved server-side on every request - four kinds of user share one system and none can read another’s rows.
Backend
Front ends
Infrastructure
Going live, and staying
Eight stages, in the order the risks needed answering. Pick one.
01
The old platform was the specification: a decade of rules about age bands, team minimums, merit eligibility and certificate wording lived only in PHP. Reproducing behaviour meant reading it, not guessing at it.
Three real incidents, told from what the user experienced.
Not design, handover, done. The attendance flow, the report that could not draw fixtures and the entries appearing on children nobody entered all came back around this loop after real use - which is only possible when the person who designed it is also the person who can fix it.
Outcome
Seven seasons carried across intact, the legacy PHP application retired, and the federation still operating without a pause.
The platform changed completely. The users didn’t have to.
Schools entering and paying through the new portal. Families reading results and downloading certificates without ringing anyone. Officials marking children present at the venue on a phone.
I did not just migrate a legacy application. I read a decade of undocumented rules out of the system that held them, understood six kinds of user with genuinely different needs, designed the portals and the interaction models they use, solved a constraint that only exists in a physical venue, moved seven seasons of real history without losing a record, and kept a national operation running the whole time - then stayed on to fix what only production reveals.