This is a submission for the GitHub Finish-Up-A-Thon Challenge
What I Built
I built Kharcha which is a finance assistant that lives where I already spend my whole day: my chat app.
"Kharcha" just means expense in Nepali, and that's the entire pitch. You don't open an app, you don't tap through six screens to add a transaction, you don't promise yourself you'll "categorize it later." You message a bot the way you'd text a friend — रू50 tea, 1200 uber, 3k rent — and Kharcha logs it, categorizes it, and keeps a running tally you can actually ask questions about.
It connects through Telegram or WhatsApp, so logging an expense is literally one message from wherever you are. Then there's a web dashboard where you can chat with it properly: "how much did I spend on food this month?", "what's my biggest category?", upload a bank statement PDF and let it pull every transaction out automatically.
The thing I cared most about: it speaks Nepal. Amounts are in NPR with proper Nepali digit grouping (रू 1,25,000, not रू 125,000). It started life as a boring CRUD expense tracker months ago. It is now the one finance tool I'd actually use myself, which is the only metric I trust.
Links
Live Website:https://kharchaai.vercel.app/
Github:https://github.com/nepalankit/SpendLens/
Demo
The Comeback Story
This project had been sitting in my "I'll finish it someday" graveyard for a while, and "someday" is where projects go to die.
The original version was an expense tracker forms, a table, a submit button. Technically it worked. Emotionally, I never opened it. Adding an expense through a form is just enough friction that you stop doing it after week one, and a finance tracker you don't feed is worthless. So it stalled.
The finish-up sprint was deciding the form was the enemy. I tore the whole front of the product off and rebuilt it as a chatbot, and that one decision unlocked everything else. A few of the real fights along the way:
Bank statement parsing. People don't want to type three months of history, so I wanted PDF upload. I built it with pdfplumber plus a regex pre-classifier to pull rows out of statements. My first version was quietly hardcoded to one bank's layout it worked beautifully on exactly one PDF and fell apart on every other one. Reworking it to be bank-agnostic was the single most annoying and most important refactor of the whole sprint.
The LLM falling over. The chat brain runs on Groq (llama-3.3-70b) because it's fast, but free-tier rate limits are real. So I wired a fallback to Gemini 2.0 Flash — if Groq chokes, the request quietly fails over and the user never notices. Watching that fallback fire correctly for the first time was genuinely satisfying.
Tool-calling for real answers. Instead of letting the model hallucinate numbers, every "how much did I spend on X" goes through actual DB query tools the LLM calls. The answer is grounded in your real transactions, not vibes.
Then I doubled down. Once Telegram worked, I added WhatsApp too because the whole point is meeting people where they already are, and in my circle that's split between both.
The comeback wasn't a new feature. It was admitting the original design was the reason I never used my own app, and being willing to rip it out.
My Experience with GitHub Copilot
Copilot was most useful in the parts of this project that are necessary but not interesting and there were a lot of those.
The FastAPI backend is a pile of routers, async SQLAlchemy sessions, Pydantic models, and dependency-injected DB handles. Once I'd written the first router by hand, Copilot had the pattern cold I'd type a function name like unlink_whatsapp and it would scaffold the whole endpoint, error handling and all, in my existing style. That's hours of boilerplate I didn't have to think about.
Where it genuinely surprised me was the regex for statement parsing. Bank statement rows are a mess of dates, descriptions, and amounts in inconsistent formats, and Copilot was weirdly good at suggesting the next pattern variation once it saw what I was matching. It didn't get it right every time no chance but it got me to a working draft fast, and iterating on a draft beats staring at a blank line.
Top comments (0)