RouteLedger: route sales, truck stock and shop credit for Bismi Foods
FMCG Distribution & Food Wholesale
- Client
- Bismi Foods
- Year
- 2026
- Status
- Live in daily use
The intro and the screens
A 24-second intro and 5 screens — scroll sideways





Every figure shown is real output from the application, running against a seeded demonstration database. Shop names, phone numbers and staff names are fixtures, not Bismi Foods' customer data.
The Challenge
Bismi Foods sells to grocery shops from vans across coastal and interior Kerala. Sales, collections, samples, returns and damages were written in a book and keyed in later, so the office was a day or two behind the money, stock on the truck was reconstructed from memory, and shop credit grew quietly across a stack of bills. Large parts of the route have no mobile signal at all.
The Goal
Let the driver bill, collect and print at the shop counter whatever the signal is doing — and let the office see the stock and the credit as soon as he does, instead of the next morning.
Our Strategy
We treated no-signal as the normal case rather than the edge case, and built the driver app around its own write queue first. Everything else followed from two rules: stock is never a stored number, and nothing happens outside a trip.
The Solution
LeafOne built RouteLedger: an installable driver app that prices a sale off that truck's own stock, takes payment and prints the receipt at the counter with no connection at all, and a full back-office console covering products, shops, trucks, routes, trips, warehouse and truck stock, payments, samples, damages, returns and seven reports.
Key Features
Decisions worth talking about
Stock is never a stored number. It is always a sum.
RouteLedger never keeps a column saying "this truck has 73 bottles of oil". It keeps the movements — loaded, sold, returned, damaged, sampled — and adds them up every time it needs the figure. A stored number can be quietly edited and nobody will know; a list of movements cannot be. It costs a little performance on every read and buys a stock figure you can defend in an argument with a driver.
Everything happens inside a trip.
A sale is not a free-floating event. It happens on a trip, at a shop that is on that trip, from the truck of that trip, by the driver of that trip. So the system refuses to sell to a shop that isn't on today's route, from a truck that isn't the trip's truck, or onto a trip that's already closed. Those refusals aren't friction for its own sake — they are the reason the stock figures stay true.
Offline is the normal case, and the app says what it doesn't know.
A sale made with no signal is saved on the phone, the receipt prints immediately, and the queue drains by itself the moment the connection returns. The part we're proudest of is smaller: when it can't read the ledger, the payment screen doesn't guess. It shows "Can't check while offline" where the shop's balance would be, and caps what it will accept to the bill in front of it. A field app that invents a number to look complete is worse than one that admits the gap, because the driver is standing in front of a shopkeeper who remembers what he owes.
Technology Stack
Design & Infrastructure
The driver app is built to be used one-handed, at a counter, in a hurry, possibly with no signal — large targets, one decision per screen, and a visible sync status he can tap to inspect, retry or discard. The console is the opposite: data-dense, scannable, with every report exportable.
Deployed as a Node.js service against MySQL, with the driver app installable from the browser as a PWA and a desktop wrapper for the office. Schema changes ship as numbered migrations, and the system carries its own backup and restore.
Engineering notes
- Node.js, Express and MySQL with five production dependencies in total — dependencies are a liability, and this one has to keep running in a shop with nobody on call.
- Around 6,200 lines of backend across 16 route modules, and 27 tables including an append-only audit log.
- 28 SQL migrations as plain numbered files applied in order — no ORM, no migration framework, nothing between the schema and the person reading it.
- Zero frontend dependencies: both apps are hand-written HTML, CSS and JavaScript with no framework, no bundler and no build step. The charts are hand-drawn SVG.
- The service worker caches the shell and never the data, so the app always opens without a connection but a figure on screen is never a stale cached one.
- JWT auth with bcrypt-hashed passwords, and every permission check on the server — clearing the phone or typing a URL changes nothing.
- A 77,000-word operations manual ships with the system and is served inside the app, written for staff rather than developers.
Results
RouteLedger is live and in daily use. Sales are recorded at the counter with no mobile signal and the receipt printed on the spot; every stock figure traces back to the movement that produced it; and shop credit is visible by shop and by age on demand, without anyone adding it up by hand.