Case files / PAN-131
Shelf to charge sheet
A medical unit needed to know what is on the shelf, what went into which patient, and how to tell the billing office. Stock is kept by lot and expiry and leaves first-expiry-first when a case is charged. A mistake is never fixed in place: the sheet is cancelled with a reason, the stock goes back, and a new version goes out.
Control flow
- Receive: stock in by lot and expiry
- Book: a case on the day diary
- Charge: the kit prefills the sheet
- Deduct: first expiry out first
- Notify: the sheet goes to billing
- Reorder: a draft order at the reorder point
Industry: Medical · Stack: Next.js 16 · TypeScript · PostgreSQL 16 · Prisma · AWS SES · Seed species: Vial
Problem
A medical unit’s stock lives in three places that disagree: the shelf, the list, and whatever was charged. Charge sheets were corrected by hand, and a correction left no trace.
How it works
Stock comes in by lot and expiry. A case is booked on the day’s diary. When it is charged, its kit prefills the charge sheet and stock leaves first-expiry-first. The sheet goes to the billing office by email. When a product reaches its reorder point, a purchase order is drafted. Nothing is sent until a person presses Send.
Stock moves through one function, inside one transaction: the product count, the batch and the ledger move together or not at all. The audit log and the stock ledger reject updates and deletes at the database. Users are suspended, never deleted, because a delete would cascade into those tables.
A charge sheet is never edited. A correction is a cancellation, with a typed reason and the signed-in user, and a resubmission as the next version. Prices and product codes are copied onto each line at the time of charging.
Product codes from old accounts are never matched by name: a near match puts the wrong code on a bill. Unmatched items load as their own products. The catalogue was parsed from supplier PDFs; surgical items that arrived with no code show “code pending”.
Patient ID and member numbers are encrypted per field. Diagnosis codes are too, decrypted only on the edit form, and each view is logged without them.
Method
A verify script checks that stock equals batches equals movements, that every cancelled sheet was reversed exactly, that the ledgers refuse edits, and that no booking holds two live sheets. Built with AI: every commit is co-authored by Claude, in a repo set up for an agent, with a trap list, a do-not-read list and gates.
What broke
Renaming a procedure in settings quietly dropped its diary colour and its combined duration. On Windows, a running dev server locked the database engine and blocked every build. Editing files during sign-in re-minted the one-time-code secret.
Limitations
Proven locally only. Not deployed.
Next
Deployment, once the client says go. Production still needs a verified mail domain and the 07:00 stock digest.