A live channelling board and administration system running in a Sri Lankan hospital.

Full-stack engineer — system design, admin platform, display interface, deployment
- Next.js
- React
- TypeScript
- Tailwind CSS
- Server-Sent Events
- Nginx
- Ubuntu
Deployed real-world system
The problem
Patients arriving for channelling had no reliable way to know which doctor was consulting, in which room, on which floor. Sessions were added and moved during the day, so a printed board was wrong within hours and the counter absorbed every question the board failed to answer.
The thinking
Two surfaces over one source of truth. Staff maintain reality — doctors, specialties, rooms, sessions — and the public board is a read-only projection of it, pushed to the screen the moment it changes. Nothing is authored twice, and nothing on the board is older than the last edit.
A public display is a read model. Once that was settled the architecture stopped being two applications and became one source of truth with two renderings — one for the staff who edit it, one for the patients who only read it. Every hard decision after that was about keeping the read side honest: pushed rather than polled, and never showing yesterday because today happens to be empty.
The system
- Schedule layer — sessions bound to a doctor, a specialty, a time and, when it is known, a room
- Location layer — the building as data: wing, floor, channelling room
- Language layer — English, Sinhala and Tamil as first-class content, not a translation pass
- Live layer — server-sent events push every change to every screen without a refresh
- Screen layer — multiple displays, each able to override what it shows
- Access layer — capability-based roles, so a receptionist and an administrator see different systems
The experience
The reader is standing several metres away, in a queue, possibly not reading the same language as the person beside them. That set the type size, the contrast and the language rotation before any code was written. The staff side has the opposite constraint — one hand, a phone, a doctor already walking in — so adding a session is a search field and a time, not a form.
The details
Live board
A change saved in admin reaches the corridor screen immediately. No polling, no refresh cycle, no stale screen.
Trilingual rotation
The board cycles English, Sinhala and Tamil in turn, so every patient waiting sees their own language within one cycle.
Sessions before rooms
A doctor can be announced before a room is free. The session exists now; the location fills in when it is known.
Location column
Wing, floor and room number stacked as one instruction, with the room number set largest — the part a patient actually needs.
Multi-screen control
Several displays run from one system, each with its own overrides for what it shows and how.
Phone-first admin
Installable as an app. Staff add a session from a phone at the counter, in the seconds after a doctor arrives.
Capability-based access
Permissions are granted per capability rather than per job title, so access matches what someone actually does.
Atomic deployment
Releases are built beside the running one and swapped by symlink. A bad build never reaches the screen, and rollback is one command.
The result
The board runs in production on a single small server and is the thing patients read when they walk in. Schedule changes reach the screen in the time it takes to save them, and the counter stops being the only place to ask where a doctor is sitting.
Lessons
- Design for the reading distance, not for the design tool.
- Multilingual support is a content model decision, not a translation step at the end.
- The schema has to allow the messy real case — a doctor with no room yet — or staff work around the system instead of inside it.
- In a hospital, a stale screen is worse than a blank one.