FinTrack
Personal finance tracker: income, expenses, budgets and reports
A Spring Boot REST API with stateless JWT auth and a vanilla JavaScript front end. Users log income and expenses, set monthly budgets by category, and see a dashboard and monthly reports. It runs as a Docker container on Render with Neon PostgreSQL.
- 8 REST controllers
- Stateless JWT
- Swagger UI
- Fits a 256 MB heap
§1
The problem
People who track money in spreadsheets lose sight of where it goes each month and only find out they've overspent a budget afterwards.
§2
My role
Sole developer: API, security, data model, front end and deployment.
§3
Architecture
§4
Key decisions
D/01
Stateless auth
A JWT filter in the Spring Security chain, no server sessions, and CORS set up for a front end served from a different origin.
D/02
Totals in the query
Monthly income and expense totals are JPQL SUMs wrapped in COALESCE, so an empty month returns 0, not null.
D/03
Shared and personal categories
Default categories have no owner; a user's own categories are added on top, fetched in one query.
D/04
H2 locally, PostgreSQL in production
The same JPA code runs on both, so local setup needs no database server.
§5
Challenges
- The JVM was OOM-killed on start on a 512 MB free instance. Capping the heap with -Xmx256m fixed it.
- Supabase direct connections are IPv6-only and Render is IPv4-only, and the pooler failed with a tenant error. The database moved to Neon, which connects directly over IPv4.
- Free instances sleep after 15 minutes, so a @Scheduled job pings the health endpoint every 10. The public root returned 403 until it was added to permitAll with a health controller.
§6
Stack
- Java 17
- Spring Boot
- Spring Security
- JWT
- Spring Data JPA
- PostgreSQL
- JavaScript
- Docker
Next case study
Marine Edge
Edtech platform for Merchant Navy exam prep, on web and Android