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, such as 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.