This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle I kept hearing the same complaint from shop owners: bills. Piles of paper purchase bills from distributors, typed into a notebook or handed to the CA at month end, and nobody noticing that the atta got ₹30 more expensive three bills ago.
Munim (named after the traditional Indian bookkeeper) is a bill diary that runs on the shop's own computer. The owner photographs a supplier bill with their phone, a local vision model reads it, and Munim gives them three things:
The person who would pay is a shop owner with a handful of regular suppliers and a monthly stack of paper. For them the price alerts are the hook: spotting one quiet 8% increase on a fast-moving item can cover a monthly subscription by itself.
Powered by Gemma, running on this computer.
Named after the traditional Indian bookkeeper, Munim is a local-first bill diary and price-alert engine tailored for small Indian shop owners (kirana, pharmacy, hardware, clothing).
The shopkeeper photographs supplier bills when goods arrive. Munim reads them using Google's open-weight Gemma 3 vision model served locally via Ollama, validates the GST and arithmetic deterministically, and provides three critical business safeguards:
Price-Change Alerts: "Parle-G 12-pack is 4.2% higher than on your last bill from Sharma Distributors (₹118 -> ₹123)." Supplier Dues Tracker: Running balance, credit cycles, and overdue payment alerts. Month-End CA & Tally Pack: Clean CSVs ready to hand over to Chartered Accountants or import directly into Tally Prime. Core Promise: Supplier pricing and trade terms never leave the owner's laptop/PC. Zero per-bill API cost.
The README has a 60-second quickstart. You need Go, Ollama and one ollama pull gemma3:12b.
The design rule I followed: the model reads, the code decides. Gemma turns a photo into fields. Everything that touches someone's money, such as validation, matching and alerts, is ordinary code I can test.
My first demo dashboard flagged 29 of 30 bills as "Needs Review." I assumed Gemma was struggling. It wasn't. The reason was "GSTIN checksum mismatch", and the checker was right: my synthetic bill generator was producing fake GST numbers with invalid check digits, so my own validator was rejecting my own test data. The validator was doing its job. I was testing it with bad inputs.
After fixing the generator I left three deliberately broken bills in the dataset (a wrong GSTIN, a total that does not add up, a hard-to-read handwritten total) so the review queue has real things to catch. The dashboard went from 29 flagged bills to 3.
The next bug was quieter: the spend card showed exactly double what the ledger added up to, because my seeder had inserted every bill twice. A "that number is suspiciously round" moment is now a unique constraint and a test.
On the synthetic dataset (30 bills across three fictional distributors over roughly two months), I planted five price hikes and one case where another supplier sells the same item cheaper. Munim surfaced all six, one alert each, with both invoices as evidence.
That tests the matching logic, not how well Gemma reads a crumpled bill. I'm not claiming extraction accuracy beyond what I measured, and these bills are generated, not photographed in a real shop.
Three reasons, specific to this product:
Open models also mean the thing I'd want to promise a shop owner, "your data stays with you", is true by construction rather than by trust.
The honest gap is real bills. Everything here ran on synthetic data, so the next step is putting Munim in front of an actual shop owner, with their suppliers' messy formats, and seeing what breaks.