Personal Finance Tracker
One product, three clients: a Go API, a React web app, and a Flutter app. ~31,000 lines, built alone.

Overview
A personal and group finance tracker I built end to end for three platforms: a REST API in Go 1.25 with Fiber over PostgreSQL, a web client in React 19 with Redux Toolkit, and a mobile app in Flutter with Riverpod. Around 31,000 lines total. The repository layer is generated from SQL with sqlc rather than hand-written or hidden behind an ORM, auth uses JWT access and refresh tokens, and the Kubernetes manifests include real liveness and readiness probes. An AI insight feature calls Google Gemini on a schedule to read spending patterns — built with a feature flag, a timeout, and a versioned prompt, and covered by unit tests. The whole stack comes up with one Docker Compose command: PostgreSQL, the API, the Vite dev server, an nginx reverse proxy, and Adminer.
The problem
The hard part was not the code, it was one modelling question: when someone puts 500,000 rupiah into savings, does that money leave their balance? Book it as an expense and the monthly spending report becomes a lie — the money did not go anywhere, it moved. Book it wrong and every balance, every report, and three separate UIs inherit the mistake.
What I did
I wrote the design document before the code and settled the question first: savings are a transfer between pockets, not an expense. Total balance stays whole and the spending report stays honest. That single decision then shipped as one coordinated release across all three repositories, with matching commits in Go, React, and Flutter. On the engineering side, sqlc keeps the data layer type-safe, the frontend's nine Redux slices are tested separately in fourteen Vitest files, and nginx fronts everything on one origin during development so CORS never becomes a class of bug worth debugging.
In the build
- One API serving a React web client and a Flutter mobile app
- Savings modelled as a transfer, so balances stay truthful
- Type-safe repository layer generated from SQL with sqlc
- Scheduled Gemini insights with feature flag, timeout, prompt version
- JWT access and refresh tokens, bcrypt password hashing
- Group finances, instalments, calendar, and charted reports
- 14 Vitest files covering 9 Redux slices
- Five-service local stack in one Docker Compose command
Questions about this project
What is Personal Finance Tracker?
A personal and group finance app Jalu Pradipta built alone for three platforms: a REST API in Go, a web app in React, and a mobile app in Flutter — around 31,000 lines in total.
How does it handle savings?
Savings are recorded as a transfer between pockets, not as an expense, so the total balance stays whole and the monthly spending report stays honest across all three clients.
What is it built with?
Go 1.25 with Fiber, PostgreSQL and sqlc on the backend; React 19 with Redux Toolkit on the web; Flutter with Riverpod on mobile; plus Kubernetes manifests and scheduled Google Gemini spending insights.