In-house product · personal finance
FinanzasApp
Multi-currency personal finance, with installment debts and budgets that warn you before you overspend.
This is a private app: I can walk you through it on a video call.
Where did the money go?
Installment 3 of 12?
45.90
Groceries
?
Payment in another currency
120.00
Monthly budget?
—

- Before:
- Money going out unrecorded, in several currencies.
- After:
- Every expense, installment and budget in one place.
The problem
With no records at all, money went out with no idea where. There was no way to see how much was left on an installment debt or whether the month was within budget.
And not everyone keeps their accounts in soles: several currencies had to be supported from day one.
The solution
A web app where each person creates an account and picks a currency: soles, dollars or riyals. They log expenses and income, and recurring ones (salary, rent, subscriptions) are entered once and show up on their own when they're due.
Installment debts show their schedule: pay an installment or make an early payment and the app recalculates what's left. Budgets per category warn you when you're far from the limit, close to it or past it, and a monthly PDF report is one click away.
The result
It's an in-house product in use, with real users, including users outside Peru who keep their accounts in another currency.
Expenses, income, savings, debts and budgets live in one place, with a dashboard that shows where the money goes month by month.
On screen
Under the hoodTechnical details
Stack
- .NET 10 + ASP.NET Core
- EF Core 10 + PostgreSQL
- React 19 + TypeScript
- TanStack Query and Zustand
- QuestPDF
- Docker
- Recurring entries generated when they come due by a BackgroundService, so history and budgets don't fill up with future transactions.
- Debts with partial payments: the payment counts toward the current installment, later ones adjust and each payment is also recorded as an expense.
- Short-lived session tokens: brief JWTs, refresh tokens that rotate on every use and are stored only as hashes, and a revocation list on logout.
- A hardened API: per-IP rate limiting, temporary lockout after repeated failed attempts and messages that never reveal whether an email exists.
- Server-side PDF reports and per-user multi-currency.




