Pagos
Local-first personal finance PWA for Peru: log payments, income and expenses in two taps, never miss a due date, and see where your money goes — even offline.

Sobre el Proyecto
Pagos is a personal finance PWA built for the Peruvian context: log payments, income, and expenses in two taps, get reminded before every due date, and see clearly where the household's money goes.
As Full-Stack Lead, I designed the entire architecture: a Next.js 16 frontend with Dexie (IndexedDB) for a local-first model that always reads and writes to the device's local mirror, and a NestJS 12 backend with a cursor-based sync protocol (push/pull) that resolves conflicts with last-write-wins and never hard-deletes data.
The system supports shared households with capability-based roles (manage/write/read), multi-currency support with a daily SUNAT exchange rate, scheduled payments with push reminders, credit cards with statement/due dates, installments, loans between people, flexible budgets with goals, and automatic detection of recurring expenses.
Detalles Técnicos
- RoleFull-Stack Lead
- Year2026
- FrontendNext.js 16, Dexie (IndexedDB)
- BackendNestJS 12, Prisma 7
- StatusIn Production
- ArchitectureLocal-First PWA
STACK TECNOLÓGICO —
Stack Completo:
Next.js 16, Dexie (IndexedDB), TanStack Query, shadcn/ui
NestJS 12 (ESM), Prisma 7, Zod, BullMQ
Cursor-based push/pull protocol, last-write-wins conflict resolution
Google OAuth, local PIN, and passkeys (@simplewebauthn)
FUNCIONALIDADES —
Adding payments, income, and expenses is optimized to complete in two taps, with templates for frequent movements.
The app always reads and writes to a local mirror (IndexedDB); a cursor-based sync engine pushes and pulls changes without blocking the UI, even offline.
Invitations, capability-based permissions (manage/write/read), and private transactions marked as 'mine' that don't affect the shared total.
Push reminders before every due date, a payments calendar, projected end-of-month balance, and credit cards with statement/due dates.
Flexible per-category budget, savings goals with a target date, alerts at 80% and 100% of a limit, and an inline warning on likely duplicates.
Automatic categorization rules and recurring-expense detection after 3 similar occurrences, creating the scheduled payment in one tap.
Desafíos Técnicos y Soluciones
I designed an idempotent cursor-based sync protocol (POST /sync/push, GET /sync/pull) where the client always reads from its local mirror and conflicts resolve by last-write-wins, with no hard deletes (deletedAt).
Every amount is handled as amountMinor (cents) with its ISO 4217 currency, completely avoiding floating-point rounding errors in split, installment, and multi-currency balance calculations.
The system checks for capabilities (household.manage | write | read) instead of fixed role names, letting each household name its own roles without touching code.
IMPACTO —
Notas Técnicas
pnpm + Turborepo monorepo (apps/web, apps/api, packages/shared). Next.js 16 frontend with Dexie (IndexedDB) for the local mirror and TanStack Query; NestJS 12 (ESM) backend with Prisma 7 over PostgreSQL 16, WebSockets via Socket.IO, queues with BullMQ and Redis 7. Authentication with Google OAuth, local PIN, and passkeys via @simplewebauthn. Deployed in production on a dedicated VPS behind Cloudflare and Caddy, with CI/CD through GitHub Actions.