This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend
What I Built
The book that takes hours
My friend Yaswanth runs Mini Mart, a neighbourhood shop. Like most small shops, it runs on credit (udhaar), and every customer's balance lives in a handwritten book.
The book isn't the problem. The time is. When the shop is busy, he can't write down every entry, and when he needs to know what a customer owes, finding and adding up the entries takes hours.
I asked what he needed. His answer was simple: an app to enter ledgers and data, one that his dad could also use.
That last part shaped everything. If someone who has used a paper book all his life can't use it, it isn't done.
So I built Kirana Khata.
What it does
- Say it or type it the way you'd say it. For example "ramesh ne 500 uda diya", in Hindi or English. Gemma reads the sentence into a customer, an entry type (credit or payment) and an amount. Yaswanth or his dad checks it and presses Save. Nothing is saved without confirmation.
- Speak button. Entries can be spoken, not just typed, which matters when your hands are busy at the counter.
- Balances in one view. Total owed, number of customers, total collected, and each customer's balance with no adding up by hand, plus a list of recent entries.
- "Who may pay late?" Each payment is matched to the customer's oldest open credit. Anything unpaid after 14 days counts as late. The app shows each customer's average time to pay and a risk bar, so Yaswanth knows whom to remind first.
- Import CSV, so old records don't have to be typed in again.
Demo
🎥 Video demo: https://youtu.be/pgAJx0Mwspc
🌐 Live app: https://khataapp-qtof.onrender.com
Heads up: the live site runs on a free server that sleeps when idle, so the first load can take about a minute. The hosted version has no AI model attached, so it reads entries with built-in rules. The video shows the full Gemma-powered version running locally.
Code
Kirana Khata
A voice-friendly credit ledger (khata) for small shops. Local Gemma reads entries in English, Hindi, Telugu or mixed; code checks every amount and does all the maths; the shopkeeper confirms each entry.
pip install -r requirements.txt
ollama pull gemma3:4b
uvicorn app.main:app --reload # http://127.0.0.1:8000
python -m pytest -q
Optional: MONGODB_URI=... stores entries in MongoDB Atlas. KHATA_LLM=none skips Gemma (instant, rules only).
Stage 2: TabPFN, voice, import
-
pip install tabpfn(orpip install tabpfn-client) turns on the "Who may pay late?" screen. Without it a simple baseline runs and the page says so. - Import: CSV with columns date, customer, kind (credit/payment), amount.
python scripts/make_synthetic_csv.pymakes FAKE data for trying the screen only. - Deploy:
render.yaml(setMONGODB_URIin Render).
How I Built It
Reading a sentence like "ramesh ne 500 uda diya"
"ramesh ne 500 uda diya" (typed or spoken, Hindi or English)
│
▼
Gemma (gemma3:4b) via Ollama, running locally
│ └── if the model isn't available → rule-based parser
▼
{ customer: "Ramesh", kind: "payment", amount: 500 }
│
▼
Shopkeeper checks the fields → Save → MongoDB Atlas
The rule-based backup matters. If the model isn't running, the app still works. That's why the hosted Render version, which has no Ollama server, still reads entries.
Predicting who pays late
Each customer's payment history is turned into simple signals, and scikit-learn and NumPy produce a "chance of paying late" for each customer. The bars are colour-coded: under 40% low, 40–70% medium, over 70% high. Customers are sorted by risk, so the first name on the list is the first person to remind.
Tools I used
| Part | Tool |
|---|---|
| Backend | FastAPI + Uvicorn |
| Open-source AI | Gemma (gemma3:4b) via Ollama, with rules as backup |
| Voice | ElevenLabs |
| Late-payment prediction | scikit-learn, NumPy |
| Database | MongoDB Atlas (free tier), with in-memory fallback |
| Hosting | Render, deployed from GitHub |
| Development | GitHub Copilot as my coding assistant |
What went wrong while deploying
- My first deploy failed because uvicorn couldn't find my app. The code lives in an
app/folder, so the start command had to point into it instead of a top-levelmain. - MongoDB Atlas refused Render's connection until I added
0.0.0.0/0to the IP Access List. After that, the logs showed "Connected to MongoDB". - Render has no Ollama server, so the hosted version uses the rule-based parser by design.
Why Does Open Innovation Matter?
- Privacy. A shop's credit book lists who owes how much, which is sensitive in a neighbourhood. Because Gemma is open-weight and runs locally, customer names and amounts don't need to go to a third-party API to be read.
- Cost. There is no per-entry fee. For a small shop, a pay-per-request API would eat into the margins this tool is meant to protect.
- Resilience. Because the parser falls back to rules, the ledger keeps working even when the model or the internet isn't available.
A closed API wouldn't have given me all three.
Prize Categories
I'm entering the categories that match the tools I used:
- Best use of Render: the app is deployed on Render from a GitHub repo, connected to MongoDB Atlas, with a live demo link.
- Best use of ElevenLabs: ElevenLabs powers the voice entry, so a shopkeeper can speak an entry instead of typing it.
- Best use of MongoDB Atlas: all ledger entries and balances are stored in Atlas, with an in-memory fallback if it's unreachable.
- Best use of GitHub Copilot: Copilot helped me write and debug the code during the weekend.
Building for a Friend
Yaswanth's first reaction was that it would make his days easier and more efficient.His Dad was obsessed with this.
Building for a real person gave me one simple test for every decision: can his dad use this without help? That kept the screen plain, the buttons clear, and the main action to one sentence.
If you run a shop or know someone who does, how do you keep track of credit today? I'd like to hear in the comments.
Top comments (2)
Nice Innovation brooooo😍
Nice initiative, Changing the other part of india