A learning platform built to a formal specification, and documented to match
Web and mobile clients on a single API, built against a written requirements specification with every requirement traced into the code that satisfies it.
- Client
- A national entrepreneurship training institute
- Services
- Learning platforms, Web development
- Stack
- TypeScript · Node.js · PostgreSQL · Prisma · Flutter · React · Docker
The problem
Admissions ran on paper. Payment slips went missing, contact numbers were transcribed incorrectly, registration numbers collided or skipped, and there was no record of who had approved what.
The institute did not only need software. It needed a system that could be audited, handed to a different team, and maintained for years — which meant the documentation mattered as much as the code.
How we approached it
We began from a written software requirements specification rather than a feature list, giving every requirement an identifier.
Those identifiers are cited in the code comments where each requirement is satisfied. If the code and the specification ever disagree, one of them is a defect — and it is immediately obvious which.
Delivery was phased deliberately. Foundations that cannot be retrofitted safely came first; admissions came next, because it was the institute's most error-prone process and therefore the fastest place to show value.
What we built
A single API, three clients
One backend serving a web application and a mobile app, with shared packages so business rules exist in exactly one place.
Admissions, end to end
Applications, payment verification, collision-free registration numbering, and an approval trail recording who decided what and when.
Role-scoped access
Separate experiences for students, teachers, administrators and super-administrators, with permissions designed before implementation rather than added afterwards.
Four manuals and a QA pack
Separate written guides for each role, plus a test pack the institute's own team can re-run after any change.
Decisions worth explaining
- 01
Requirement IDs in the code
Unusual, and worth it. Anyone can trace any behaviour back to the requirement that asked for it — which makes audits straightforward and onboarding a new developer far faster.
- 02
A monorepo with shared packages
Web, mobile and API share types and validation. A rule change happens once, and the mobile client cannot silently drift from the web one.
- 03
Admissions first, not the course catalogue
The catalogue is more visible; admissions was where the errors and the cost were. We built the painful thing first.
Have a problem shaped like this one?
We will tell you honestly whether we are the right people for it.