PlotWise
An internal inventory platform for agricultural R&D field operations, built on an immutable transaction ledger. Live across 10+ sites in two countries.
PlotWise is built on one rule: never edit a balance. Stock, value, expiry, and usage all derive from an immutable transaction log, so every number traces back to who moved what, and when. It replaces the disconnected spreadsheets that field operations ran on, used daily by operators working on their feet, not at a desk.
The whole interface is built on the ledger, not on editable fields. You never type a new quantity; you record a movement (receive, use, check out, or adjust) and the balance is derived. The history stays intact and auditable, and a mistake is corrected with another transaction rather than a silent overwrite.
The primary field actions live in a persistent bottom bar sized for a thumb: home, scan, receive, checkout, usage. For someone entering twenty records between rows of plants, the common path stays one tap away instead of buried in a menu.
Scanning is tuned for the field, not the warehouse. The scanner looks up a container's own label before falling back to a product barcode, because in trial operations the thing in your hand is a specific container, and that is what the user actually needs to find.
A Postgres ledger sits at the core: immutable transaction rows, balances derived through views like an on-hand rollup rather than stored, and a schema of items, categories, locations, lots, checkouts, and import tracking around them. Row-level security enforces per-site and per-region access at the database, through a can-access-site check, so the rules hold no matter which client is talking to it. Server components read through request-scoped Supabase clients while the interactive forms write transactions directly, and the same access model is mirrored in middleware.
Shipped and in daily use across the operation. It replaced the spreadsheet sprawl and surfaced inventory that had never been tracked in one place before. The working surface runs the full loop: role-aware onboarding and site selection, inventory listing, receiving, usage and checkout, a barcode scanner, activity history with export, notifications, and analytics, all installable as a PWA.
The append-only guarantee was earned, not designed in: early migrations still allowed updating and deleting transactions, and it took a later one to drop those policies and truly lock the ledger. Starting again, I'd commit to immutability from the first migration. There is also real cleanup waiting: the scanner and a number of catch blocks lean on any in an otherwise strict codebase, a couple of forms read the current site two different ways, and the PWA manifest and README still carry stale copy from an earlier iteration. The ledger-first model itself, deriving every balance instead of storing it, is the decision I'd keep without question.