01
the challenge
The orthodontic laboratory ran its production on Monday.com. As a board it worked, but it carried three problems no amount of configuration fixes: it is billed per user, per month, indefinitely; the data — tied to patients — lives on someone else's server; and nothing specific to the trade exists in a generic tool. Material batches, expiry dates, medical barcode scanning, material consumed per job: either you bolt them on with fragile automations, or they are not there.
A legal obligation ran in parallel. A laboratory making custom-made medical devices must, under the European MDR, be able to link every device delivered to the exact batch of material it was made from: if a batch of resin turns out defective, you need to know which patients received it. That was kept in a spreadsheet and in the memory of whoever did the making.
So the brief had two halves: replace the subscription with something of their own, and make that something solve what the subscription could not.
02
the solution
A desktop application designed, built and deployed from scratch, installed on the clinic's workstations.
The product decision that shapes the whole interface: deliberately copy Monday's ergonomics — boards, status columns with coloured labels, inline editing — so that nobody had to relearn how to work. Changing tools was not supposed to feel like changing tools. Underneath, though, everything that was missing: batches and expiry dates, GS1 DataMatrix scanning that brings code, batch and expiry in a single trigger pull, automatic stock deduction, timestamped manufacturing stages, and the batch → consumption → case chain closed without extra manual work.
The structural decision: the core of the application never talks to a database, it talks to a single interface with two interchangeable implementations — SQLite locally, PostgreSQL when shared. That let the app start on one workstation and move months later to a shared database without being rewritten.
Scaling up is written down, not improvised: PostgreSQL in Docker on the practice's NAS and deliberately not on the domain server, workstations pointing at a DNS name and never at an IP address, per-user installation with no administrator rights, history migrated in a single verified transaction with rollback, and a commissioning manual in French covering hosting and fallbacks, network and firewall, backups and a restore test, and common symptoms.
03
the result
In production, six workstations, a shared database and live updates between them.
The subscription is gone and the clinic owns the software it uses; patient data stayed in-house; the regulatory requirement is closed — from a defective batch you reach the patients, and from a patient their batches. To date: 293 lab cases traced, 1,738 timestamped production stages, 8 tables and 20,807 lines of TypeScript.
What I take from it fits into three failures. Stock dropping to −6 because two workstations read before writing, fixed with row locking and verified with two instances against a real PostgreSQL. A network drop that closed the entire application instead of degrading it, turned into a backing-off reconnection that resynchronises on recovery. And absurd stock-out forecasts — nineteen years of runway on one sheet of plastic — born of the same naive formula copied three times and drifted apart. Since then, when the basis for a calculation is too thin, the panels refuse to answer and say why: an invented number someone is about to order material on is worse than a dash.