From consultation to bill: designing atomic clinical workflows
A consultation that ends should leave behind a prescription and a bill — both, or neither. Here's why atomicity is the quiet feature that keeps clinical data trustworthy.
The most reassuring features in clinical software are the ones nobody notices: the prescription that's always there when the bill is, the bed that can't be double-booked, the total that never drifts by a rupee. None of that is luck — it's atomicity, applied deliberately.
Completing a consultation should do everything, or nothing
In MedOps, a doctor starts a consultation from an appointment, records clinical notes and a follow-up date, and marks it complete. On completion, two things must happen: a prescription is generated and a consultation-fee bill is created. The important word is “and.”
If those were two independent writes, a failure between them would leave a prescription with no bill, or a bill with no prescription — exactly the kind of inconsistency that erodes trust in a record. MedOps wraps them in a single database transaction, so completing a consultation either produces both artefacts or rolls back cleanly and produces neither.
“Both or neither” is a small phrase that prevents a large class of support tickets.
Admitting a patient is a race you have to win
Inpatient care has its own atomicity problem: two operators trying to admit different patients to the same vacant bed at the same moment. Without protection, both succeed and you have a conflict on the ward.
MedOps treats admission as a transactional operation with explicit guards:
- The bed's vacancy is checked and claimed inside the same transaction that creates the admission.
- A duplicate-admission guard prevents admitting a patient who is already admitted.
- Discharge and bed transfer follow the same discipline, so the bed map always reflects reality.
Money lives in paise
Floating-point currency is a classic source of drift: add enough 0.1 + 0.2 and your
totals stop matching. MedOps stores every monetary amount as an integer number of paise,
and only formats to rupees at the edges for display. A ₹773.00 bill is 77,300 paise in the
database — exact, addable, and immune to rounding surprises.
// Store and compute in the smallest unit…
const totalPaise = items.reduce((sum, i) => sum + i.amountPaise, 0);
// …format only when showing it to a human.
const display = `₹${(totalPaise / 100).toFixed(2)}`;
Status, not deletion
Bills carry a type (consultation or prescription) and a status (unpaid, paid or cancelled). Cancelling is a status change, not a delete — the record stays, the history stays, and the tenant-scoped audit log captures who changed it. Operations can update status inline from a filtered, paginated list, and nothing of value is ever quietly erased.
The principle underneath
Every example here is the same idea wearing different clothes: group the writes that must agree into one unit of work, and make money exact. Get those two right and the system feels trustworthy, because the data simply never contradicts itself.
Want to walk a real consultation-to-bill flow on seeded data? Book a demo — we'll spin one up for your roles.
More from the blog
The Steel Medical palette: a design language for MedOps HMS
How every color token in the Steel Medical theme was chosen to reflect the precision, trust and humanity of modern healthcare.
What is hospital management software? A complete guide (2026)
What hospital management software actually is, the core modules every HMS needs, the benefits, and a practical checklist for choosing the right system.