Reparto — Multi-tenant SaaS for van sales
Route accounting for delivery businesses. The interesting part is how stock is stored.
The problem
Van sales businesses — a driver, a truck full of product, a route of customers — run on paper or on spreadsheets. They need stock tracking, pricing per unit type, and multiple businesses on the same system without seeing each other’s data.
Architecture decisions
Tenant isolation at the database, not the application.
PostgreSQL row-level security with SECURITY DEFINER helper functions. If
isolation lives in application code, one forgotten WHERE tenant_id = ?
leaks a customer’s entire dataset. At the database it’s enforced whether or
not the developer remembers.
Stock as a ledger, not a counter.
The obvious design is a quantity column you increment and decrement. I used
an append-only stock_movements table instead.
The reason is offline sync. Drivers work in places with no signal. If stock is a counter and two drivers sell offline, whoever syncs last overwrites the other. If stock is a ledger, both movements are recorded and the quantity is derived. The conflict disappears because there’s nothing to conflict over.
I don’t have offline sync yet. But the ledger is the decision that makes it possible later without a rewrite.
Units of measure: one base unit, N presentations. A product is stocked in a base unit and sold in presentations — each with its own conversion factor and its own price. A 12-pack isn’t 12× the price of one unit, and the model has to allow that.
The trade-off
Negative stock is allowed at the database level, with a warning only in the UI. Blocking it at the database sounds correct, but in practice a driver loading the truck before the count is registered would be hard-blocked from working. The system should describe reality, not refuse it.
Result
Schema, RLS, auth, product and presentation management shipped.