
Dental case-management platform
Xera Lab
A dental X-ray lab's whole workflow — intake, assignment, review, delivery — as one platform: portal, admin dashboard, API, database and the servers it runs on, all built by one engineer.
The challenge
A dental lab receives cases from clinics, routes them to technicians, has a doctor review the result, and sends it back. That ran on email and phone calls, so nobody could answer where a case was without asking someone. It needed to be one system with three different kinds of user in it — and there was no team to split the work across.
What it had to do
- One system for intake, assignment, review and delivery, replacing email and phone calls
- Three kinds of user — Admin, Doctor, Technician — working on the same case
- Large X-ray files stored and served without weighing down the database
- Built, deployed and run by one engineer
My role
Sole engineer. Frontend, backend, database, deployment and the TLS certificate.
How I built it
- Built the customer portal and the admin dashboard, with role-based access for Admin, Doctor and Technician.
- Modelled the full case lifecycle — intake → assignment → review → delivery — so a case's state is a fact in the database rather than a conversation.
- Wrote the entire Node.js/Express + PostgreSQL backend with JWT authentication, and put X-ray uploads on AWS S3.
- Deployed it with Docker Compose behind Nginx with TLS.
Decisions, and why
Three roles in the data model, not three apps
Admin, Doctor and Technician see different things, but they see the same case. Splitting them into separate applications would have meant three codebases and a sync problem; putting the roles in the authorisation layer over one model meant a case has one state, and who can see or move it is a rule rather than a build.
The workflow is the schema
Intake, assignment, review and delivery are states a case moves between, so they live in the database with the transitions that are legal from each one. The alternative — a status string set by whichever screen was open — is how a case ends up delivered and unreviewed at the same time.
S3 for the X-rays, Postgres for everything else
Dental X-rays are large, numerous, and never queried by content. Keeping them out of the database kept backups small and restores fast, and meant the API serves references rather than proxying megabytes.
Stack
Building something like this?
Tell me what you are trying to ship and I will tell you, honestly, whether I am the right person to build it.