ERPos
A full-stack inventory and operations ERP for a multi-front food business — tracking every gram from vendor delivery to the plate, with AI-assisted analysis, OCR bill processing, WhatsApp order ingestion, a six-state verified intake workflow, and per-outlet financial records that can reconstruct the truth at any point in time.
Started as a replacement for WhatsApp-and-memory procurement. Grew into a complete operations platform with an AI assistant, OCR, a WhatsApp bridge, and financial records that are auditable to the paise.
~890 test cases · 72 migrations · all phases shipped · currently in active use
Figure 1. Owner Console — procurement spend, inventory value at WAC, spend by category, biggest movers, and price drift tracking.
01. The problem
The business runs several customer-facing outlets — restaurants, a staff canteen, and a catering operation — all sourcing from two central stores. A primary store holds bulk and dry goods; a secondary store handles fresh and daily items.
Orders go to vendors over WhatsApp. Goods arrive and pool in the stores; the bills come per-outlet for accounting — but not at the same time as the goods. The gap can be hours, or months. Some categories (vegetables) never produce a bill at all.
Before this system: everything ran on memory and WhatsApp scroll-back. Errors compounded silently. Per-outlet cost was impossible to compute. There was no way to know what any outlet was actually spending until it was too late to act on it.
02. How inventory actually moves
Goods and bills are treated as two independent event streams that eventually get reconciled — operations never pause waiting on paperwork. Every transition through the intake lifecycle is enforced at the database level; no application code can skip a step.
For bill-less items: store manager enters the rate manually during Check 1. No matching step needed — the RM does a physical spot-check and freezes the intake directly.
Figure 2. Resource Manager overview — open flags, Check 1 / Check 2 approval queues, and the live WhatsApp order pipeline.
03. Owner Console and AI assistant
The owner's view of the system is built around a daily briefing rather than a dashboard full of numbers. Each morning, an AI-written narrative describes what changed since yesterday — which vendors delivered, what costs moved, what needs attention — in plain language, not charts.
Behind that is a read-only AI assistant (Claude) that can answer questions over live data: spend by category, vendor reliability trends, outlet cost comparisons, reconciliation status. It uses a manual tool loop across the data layer, and every call is cost-tracked and logged for audit. It doesn't claim more certainty than the data supports.
Money is stored as integer paise throughout — 1 INR = 100 paise, stored as an integer, rounded explicitly with Decimal/ROUND_HALF_UP. No floating-point money anywhere in the system.
04. What the system independently verifies
A separate verification service runs on a schedule — entirely independent of the request path — and re-derives truth from the ledger. Anomalies become rows in a flag inbox, not log lines.
Financial tables are bitemporal: a verified cost is never edited in place. Correcting it is a supersession that records the old and new versions with a reason, so "what did we believe the cost was on date X?" is always answerable.
Figure 3. Verification · Data Integrity — 5 ledger-integrity layers each with honest pass / fail / insufficient-data / never-run status.
05. Key capabilities
Figure 4. RM Pipeline — live WhatsApp → OCR → parse → draft order flow with per-message status and needs-review queue.
06. Tech stack
- Database Supabase — managed Postgres + Auth + Storage. Plain Postgres underneath, self-hostable.
- Backend FastAPI (Python 3.12), Pydantic models, repository → service → router. Multi-step writes go through Postgres RPC functions for atomicity.
- Workers Python + Redis — OCR, auto-matching, nightly jobs (orphans, rate drift, dead stock, exports).
- Verification Separate Python container, independent of the request path. Runs ledger-integrity layers on rotation.
- OCR Claude Vision (claude-sonnet-4-6) — structured JSON from bill images with fuzzy item matching.
- AI assistant Claude (claude-opus-4-8) with adaptive thinking, read-only tool registry, per-call cost ledger.
- WhatsApp Isolated Node/TypeScript container (whatsapp-web.js) with session persistence and idempotent message processing.
- Frontend Next.js (App Router), TypeScript strict, self-hosted fonts, role-aware shells. "Morning Ledger" design language.
- Deployment Docker Compose on a single VPS. nginx TLS + reverse proxy. Daily pg_dump + nightly spreadsheet export.
07. By the numbers
- Test Cases ~890
- DB Migrations 72
- Intake States 6 enforced
- Approval checks 2-box × 2 stages
- Money precision Integer paise
- Services 7 containers