This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle
What I Built
Every month I run the same tedious ritual: a wallet full of paper receipts and a phone full of payment screenshots (PalmPay transfers, data subscriptions, supermarket runs) that have to become accounting records for my freelance work. It eats hours.
Cloud AI could do the extraction, but read the fine print: you pay per receipt forever, you need reliable internet, and you hand a stranger's API your financial data. Receipt OCR text contains real names and phone numbers. I watched mine get extracted on day one.
So I built the tool I would actually pay for: KoboKeeper. Snap a receipt, and an open-weight model running on your own machine turns it into structured books. You review it, confirm it, and export an accountant-ready CSV or PDF. The side hustle math: charge freelancers around ₦2,000/month, keep inference costs at zero. That math is impossible with closed APIs and trivial with open weights.
First real extraction, day one: a PalmPay money transfer. Vendor, date, ₦500.00 total, currency, line item, all correct, in about 27 seconds on my CPU. Total API spend: ₦0, forever.
Demo
Live demo: https://kobokeeper.onrender.com (the instance sleeps when idle, so the first load takes 30 to 60 seconds to wake; extraction on the shared CPU takes 1 to 3 minutes)
Code
KoboKeeper
KoboKeeper is an offline-first receipt bookkeeper for freelancers and small businesses. It extracts structured receipt data locally with OCR + Gemma running through Ollama.
Quickstart
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
ollama pull gemma3:4b
uvicorn app.main:app --reload
Then open http://127.0.0.1:8000/dashboard.
The interesting files: app/services/extractor.py (the Gemma prompt and JSON handling), app/services/ocr.py (rapidocr + PyMuPDF), app/services/vendor_memory.py (the learning loop), app/services/export.py (CSV/PDF), AGENT_SESSION_TRANSCRIPT.md (the annotated Copilot build log, linked from My Agent Session below). 19 automated tests, mocked at the model boundary so CI runs green without Ollama.
How I Built It
Stack: Python, FastAPI, SQLAlchemy with SQLite, Jinja and HTMX (no build step, no CDN, because the offline story has to be real), reportlab for PDFs, Ollama serving Gemma locally.
Pipeline: receipt photo or PDF, then rapidocr (local OCR), then Gemma 3 via Ollama (strict JSON), then a human review form, then vendor memory, then SQLite, then CSV or PDF export. The extraction prompt is deliberately strict: temperature 0, JSON output format, one bounded repair attempt, and a rule that makes this a bookkeeping tool instead of a chatbot: "If a field is not present, use null. Never invent values." A guard rejects OCR text under 20 characters before any model call, and a wrapped validation layer turns bad model output into a manual-entry form instead of a crash.
My favorite piece is vendor memory: confirm a receipt once and KoboKeeper fuzzy-matches that vendor next time and pre-selects the category. Every receipt makes the next one faster.
About 70% of the code was written by the GitHub Copilot coding agent from a 6-phase spec, phase by phase, with my local verification between each phase (see My Agent Session). I wrote the remaining 30% (exports, seed script, Docker and Render deployment) by hand after the agent's quota died.
For the hosted demo I use a model split worth stealing: Ollama and gemma3:1b (about 0.8GB) run inside the Render container, so the demo literally performs inference on Render, on a 2GB instance paid with the $50 Hacktoberfest promo credit. Locally you run gemma3:4b (3.3GB). Same codebase, a MODEL_NAME environment variable picks the brain. Four honest deploy failures on the way (Ollama moved their download URL, zstd missing in the slim image, a background process hung the build layer, opencv's system libs missing at runtime), each a one-line fix, all in the commit history.
Measured results:
| Metric | Result |
|---|---|
| First real receipt (PalmPay transfer) | all fields correct |
| Image receipts | ~27s on CPU |
| PDF receipts | ~66s (rasterization plus OCR) |
| Live demo, 1 shared CPU | under 3 minutes including cold model load |
| Automated tests | 19 passing |
| API cost per extraction | ₦0.00 |
Why Does Open Innovation Matter?
The honest, architectural answer:
- It runs on a laptop with no internet. OCR, Gemma via Ollama, and SQLite all run locally. Airplane mode is a feature.
- It keeps data off servers nobody controls. Receipts, including other people's names, phone numbers, and transaction IDs, never leave the machine. The hosted demo exists so you can click it; the product is the local one.
- It lets you swap and fine-tune. Demo runs gemma3:1b, locally gemma3:4b. Tomorrow I can fine-tune on Nigerian receipts (PalmPay and OPay formats, naira amounts) and the model gets better at my market instead of averaging the world.
- It costs nothing to run. No API keys, no meter. The only line item is electricity.
Open weights are not ideology here. They are the difference between a business and a wrapper. A closed API makes the ₦2,000/month price impossible; an open-weight model makes it profitable.
My Agent Session
Three Copilot coding agent sessions, three human checkpoints, 14 agent commits. The condensed log: Session 1 scaffolded the project from spec and fixed its own template bug unprompted. Session 2 built the extraction core (strict Gemma prompt, OCR guard, bounded JSON repair) with 4 mocked tests passing. Session 3 applied my code review (a ValidationError bug and category normalization), then built the entire vendor memory and review-form workflow plus unrequested security hardening, and died on quota mid-hardening, right after committing the last important fix. My review checkpoints had already caught a hallucinated dependency pin (rapidocr-onnxruntime==1.3.24, a version that does not exist) before it reached production.
I believe agent-built software should ship with its build log, so the full annotated session transcript is in the repo: https://github.com/Prosperiko/kobokeeper/blob/main/AGENT_SESSION_TRANSCRIPT.md
My First User
Me, and that is not a dodge. The receipts in the dashboard are my actual freelance transactions, processed through the real pipeline, and the month-end CSV exported cleanly into my accounting spreadsheet. A freelancer friend tests it on their books this weekend, and I will update this section with their verdict, especially the answer to "would you pay ₦2,000 a month for this?" If they say no, that is the most valuable data this project will have produced.
Prize Categories
- Overall
- Best Use of Gemma (Gemma 3 via Ollama runs the entire extraction, locally)
- Best Use of Render (Ollama and the model run inside the Render container; the demo performs inference on Render, paid with Hacktoberfest promo credits)
- Best Use of GitHub Copilot (built with the Copilot coding agent, supervised; see My Agent Session)
- Best Use of Entire (full annotated agent session shared in the write-up and repo)

Top comments (0)