Abdullah MohamedSenior Software Engineer
All work

Dental case-management platform

Xera Lab

Independent · sole engineer, full stack

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.

3 rolesAdmin, Doctor, Technician
4 stagesintake → assignment → review → delivery
1 engineerfrontend, backend, infra

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

  • Flutter Web
  • Node.js / Express
  • PostgreSQL
  • JWT
  • Docker Compose
  • Nginx (TLS)
  • AWS S3

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.