work/godam

Built for FMCG trade operations

Godam

FMCG trade-operations app for Nepal distributors. Next.js 15 + Supabase/Postgres: party ledgers with VAT/PAN, billing, collections, supplier payments, credit, sauda, godown stock, DSR, and field-visit logging. Built solo. No revenue claim on this page.

Problem

Distributor operations split across spreadsheets: who owes what, what left the godown, which cheque is out, which salesman visited which outlet. The failure mode is not “no app.” It is two numbers for the same party.

The data model has to look like trade ops — parties that are supplier, customer, or both; items with reorder levels; NPR amounts — not a generic CRUD starter.

Constraints

Built solo. The UI is a phone-width shell (max 480px) because DSR and collections are entered in the field.

Roles matter: admin / staff / viewer. Viewers must not alter ledgers.

Architecture

AuthLedgersBillingStockField ops

Next.js App Router on Vercel, Supabase/Postgres as the store. Screens map to operations: ledger (parties and items), godown, cash, collections, supplier payments, outgoing cheques, sauda, DSR, field visits, reports.

Party records carry VAT and PAN. Amounts format as NPR. Session roles gate who can insert or update.

There is no LLM in the critical path. Reliability here is referential integrity and role checks, not a prompt.

Reliability / eval

Postgres is the ledger. Client state is a cache of queries, not the books.

Role flags (admin / staff / viewer) are checked before mutations. That is application-level enforcement on top of Supabase auth — not a substitute for row-level policies, which I would tighten.

I have not published a labelled eval for Godam. The honest test is reconciling a day’s collections and godown movement against the rows, not a model score.

Known failure modes

  • App-level roles vs database policies

    If a client bypasses the UI, viewer restrictions only hold if Postgres RLS matches the same rules. I would not defend this in an interview as fully locked down without showing the policies.

  • No committed eval harness

    Unlike Stacksift, there is no golden set of ledger cases. Dual-entry mistakes would be caught by a human reconciling, not by a script.

What I would do differently

  • Move invariants into Postgres (RLS, cheque uniqueness, credit vs invoice balance) so the UI cannot be the only gate.
  • Add a replayable fixture of a trading day and assert balances — the analogue of eval_labels.json for a ledger.

Stack

  • Next.js 15
  • TypeScript
  • Supabase

Links