Skip to work
Melbin Kuriakose
Back to work

Schools Sports Platform

Rebuilding a national sports federation, without switching it off

  • Product
  • UX
  • UI design
  • Full-stack
  • Data migration
  • AWS
  1. Schools
  2. Students
  3. Events
  4. Attendance
  5. Results
  6. Certificates
Watched byParentsCoachesOfficialsFederation staff

Thousands of children. Hundreds of schools. Seven seasons of history. One platform that could not stop.

35k+
participation records
400+
schools
7+
seasons of history
50+
database tables

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.

My role
Product, UX, UI, full-stack engineering and deployment
The client
A national schools sports federation in India (confidential)
Who uses it
Schools, students, parents, coaches, officials, federation staff
Stack
Node, Express, Prisma, Postgres, Next.js, Angular, AWS
The Schools Sports Platform - school portal, attendance and results

The people

Six kinds of user, and none of them want the same thing

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

  1. Hold squad codes
  2. Child shows code
  3. Scan
  4. Verify photo
  5. Present

Surface: Mobile attendance

TL;DREvery hard problem on this project came from a person, not from the codebase.

The constraint

The platform could not go offline

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

  • Schools entering squads
  • Officials running events
  • Parents checking results
  • Certificates being issued

Meanwhile, the rewrite

  • Being designed
  • Being built
  • Being migrated
  • Being tested

The platform changed completely. The users didn’t have to.

What users saw

  • The same admin screens
  • The same URLs
  • The same workflows
  • No forced migration
  • No retraining mid-season

What changed underneath

  • A new API
  • A new database
  • A new data model
  • New AWS infrastructure
  • New portals
  1. Old admin UI
  2. Compatibility layer
  3. New API
  4. New database

Keep the experience. Replace the engine.

Which made migration a design problem, not just an infrastructure one

People

cannot retrain mid-season

Data

cannot be lost

Operations

cannot stop

History

cannot change

The four problems, and the response to each

A live platform that could not be switched off

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.

The data model fought the organisation

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.

Attendance assumed children carry phones

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.

Certificates were a bottleneck

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

Marking 300 children present, at a venue, on one phone

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.

  1. 1Child shows their code
  2. 2Coach or official scans
  3. 3Photo appears
  4. 4Human verifies
  5. 5Marked present

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

  • 01One-handed on a phone at a desk
  • 02The next child appears immediately
  • 03A photo, so a human can check
  • 04Almost nothing to read or decide
  • 05A code that does not expire mid-queue

TL;DRThe QR code identifies. The human verifies. Designed for a venue, not a demo.

The portals

Four audiences, four different interfaces

An admin console running a national season and a parent checking a medal should not look like the same product.

A school’s season, start to finish

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.

Why the student portal exists at all

Parents were ringing schools, and someone was searching by hand.

  1. Parent
  2. Log in
  3. Student profile
  4. Results & medals
  5. Certificate

The student portal exists because parents were phoning schools to ask about results.

Certificates worth something

Verifiable by anyone, private for the child, and correct years later.

  1. 1Result recorded
  2. 2Merit or participation decided
  3. 3Certificate rendered
  4. 4QR code on it
  5. 5Publicly verifiable

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

  • Student name
  • Event
  • Placing

Never exposed

  • Date of birth
  • ID number
  • Contact details

A certificate is only worth something if a third party can check it - without learning anything private about a child.

Years later

  1. 2024 certificate
  2. 2026 correction requested
  3. Name corrected
  4. Download again
  5. Correct certificate

Because certificates are rendered rather than stored, they never become stale files. Parents come back years later asking for fixes - and they get one.

Money, online and off

Both paths have to land in the same operational truth.

  1. Select entries
  2. Payment
  3. Receipt
  4. Entry confirmed

Online and offline money still has to end up in the same operational truth.

What shipped

School portal

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.

Student & parent portal

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.

Federation admin

The operational centre: events, sports and sub-games, capacities per age band, approvals, merits, reports and the release of certificates.

QR attendance at venues

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.

Certificate engine

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.

Payments & reconciliation

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.

Student transfers

A student changing school, without disturbing a single past result. One approval, from the receiving school, with guardrails around unpaid and in-flight entries.

Reports for running events

Consolidated entry sheets, per-sport draws and squad lists - the documents officials actually use on the day to build fixtures.

The modelling decision

A child changed schools. Their history should not.

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 moves

School B

Not yet

The student record moves here. Two columns change, and nothing else.

Identity — moves

Identity

  • Student ID
  • Current school
  • Name
  • Parentage

History

  • School at the event
  • Class that year
  • Event
  • Result
  • Medal

Identity moves. History never does.

TL;DRSplitting identity from history is what made transfers, corrections and seven co-existing seasons possible at all.

Decisions

Eight decisions, and who they were for

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.

Design decisions I am proud of

  1. 01

    Designing attendance around the venue instead of the idealised user.

  2. 02

    Keeping the old interface alive while replacing the system underneath it.

  3. 03

    Separating student identity from historical achievement.

  4. 04

    Shaping the school portal around the season, not the schema.

  5. 05

    Making certificates verifiable without exposing anything private about a child.

  6. 06

    Giving schools, students, officials and administrators genuinely different interfaces.

Engineering

What made the designed experience possible

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.

Access control, from both sides

Switch role and the navigation changes. The server changes too - and that is the part that counts.

  • Squads
  • Entries
  • Payments
  • Entry sheets
  • Our students
  • Other schools
  • Merit decisions
  • Certificate release

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.

The stack

Backend

  • Node.js + Express
  • Prisma ORM
  • PostgreSQL
  • JWT auth, role-scoped
  • PDF generation (pdfkit)

Front ends

  • Next.js - school portal
  • Next.js - student portal
  • Angular - federation admin
  • Tailwind design system
  • Mobile-first attendance

Infrastructure

  • AWS EC2 + RDS Postgres
  • S3 for media & documents
  • CloudFront + Amplify
  • Staging → production pipeline
  • Automated migrations

Going live, and staying

How it was actually done

Eight stages, in the order the risks needed answering. Pick one.

01

Read the legacy system before touching it

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.

Designing for reality

Three real incidents, told from what the user experienced.

Entries appearing on children nobody entered

What users experienced
Schools reported relay events on students they had never picked for them.
Why it happened
A save path resolved sub-games without scoping them correctly, so a previous entry could leak into a new one.
What changed
Fixed at the cause, then the affected season was cleaned - leaving prior years untouched.

Schools that could log in but did not exist

What users experienced
A school reported being approved, yet missing from every list, while its login still worked.
Why it happened
Two admin screens each filtered on a different approval flag, so a school in one particular state appeared in neither.
What changed
Fixed the form binding at the source, and gave the list a view that can surface those records at all.

Reports that could not produce fixtures

What users experienced
Officials could not draw fixtures on the day of an event.
Why it happened
The consolidated report read a table that only paid entries ever reach, so it silently showed a partial picture.
What changed
Re-sourced from the entry records, so short teams drop out correctly rather than being judged on who had paid.

Design and build, in a loop

  1. User problem
  2. UX decision
  3. Design
  4. Build
  5. Real-world use
  6. New problemback to the top

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

A national season, running on it

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.

35k+
participation records
400+
schools
7+
seasons of history
50+
database tables

What I did on it

  • Product definition - what each portal is for, and who is allowed to do what
  • Domain modelling - identity versus history, seasons, age categories, team rules
  • Data migration - seven seasons of legacy records into a new relational schema
  • Backend engineering - Node, Express, Prisma, 37 route groups, one service
  • Compatibility layer - the legacy admin kept working, unchanged, against the new API
  • UX and UI - school portal, student portal and the admin screens that were rebuilt
  • Mobile-first attendance - the QR flow used at venues, on a phone, one-handed
  • Document generation - certificates, entry sheets and reports as generated PDFs
  • Payments - gateway integration, receipts, reconciliation with entries
  • Access control - schools, students, staff and admins in one system, isolated
  • DevOps - AWS infrastructure, staging and production pipelines, releases
  • Production support - live incidents, data forensics, corrective scripts

What this project demonstrates

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.