Back to side projects

Personal PWA

Frictionless Expense Tracker

PWA Cloudflare Workers Neon PostgreSQL Offline queue CPF budgeting Multi-currency

A mobile-first personal finance PWA that helps users capture spending in seconds and manage budgets, accounts, goals, and shared bills from a single installable web app — deployed on Cloudflare edge with Neon Postgres.

Role
Solo developer
Timeline
2025 – present
Stack
Cloudflare Workers, Neon, PWA
Outcome
Sub-5-second expense entry
Frictionless Expense Tracker mobile keypad interface Frictionless Expense Tracker mobile keypad interface
Expense tracker architecture diagram Expense tracker architecture diagram

Click diagram to zoom

The Problem

Personal finance apps are often slow or fragmented — logging a coffee purchase means tapping through multiple screens, waiting for the OS keyboard, and switching between separate tools for budgeting, goals, and bill splitting.

The design goal is sub-5-second, one-handed expense entry while standing in line: type an amount on a custom keypad, tap a category chip, and save. Everything else — paycheck envelopes, savings projections, trip budgets, and shared expenses — lives in the same installable app without sacrificing capture speed.

Architecture

The frontend is a vanilla HTML/CSS/ES6+ hash-routed SPA on Cloudflare Pages with a service worker for shell caching and an offline expense queue. Two Cloudflare Workers handle concerns separately: auth (register, login, password reset) and the main expense API (CRUD, analytics, insights, scheduled tasks).

  • Auth Worker: Issues JWTs signed with Web Crypto HMAC-SHA256; passwords hashed with scrypt via crypto.subtle.
  • Expense API Worker: Validates Bearer tokens, routes to domain handlers, runs scheduled jobs for recurring rules, FX sync, insight generation, and balance snapshots.
  • Neon PostgreSQL: Serverless Postgres via HTTP driver — ledger, budgets, goals, FX cache, insights, and split metadata.
  • Offline resilience: Failed creates queue in localStorage with original timestamps; replayed on reconnect.

Core stack: Vanilla HTML, CSS, ES6+ JavaScript (hash-routed SPA, custom SVG charts) · Cloudflare Pages · Cloudflare Workers (ES modules) · Neon serverless PostgreSQL · Custom JWT (Web Crypto) and scrypt · PWA with service worker and install prompt.

  • Neon PostgreSQL — Primary persistent datastore for all user financial data; edge-compatible via HTTP driver.
  • Frankfurter FX API — Daily exchange rates cached in the database for multi-currency trips and splits.
  • Resend — Transactional password-reset emails.
  • Auth Worker — Separate service for register/login; shared secret for token verification by the main API.

Status: Deployed live at et.builtbyroger.com and in active development. Net worth and debt views exist in code but are not yet wired into navigation. Register OTP UI in the frontend is ahead of auth-backend implementation and should be aligned or removed.

Features & Outcome

Key capabilities delivered beyond the original MVP:

  • Frictionless transaction entry — Custom numeric keypad, category chips, account picker, and optimistic save with offline queue.
  • Paycheck-based budgeting — Salary profile with Singapore CPF calculations, spending envelopes, and budget-versus-actual status.
  • Savings goals with projections — Target amounts, deadlines, contribution tracking, and projection charts.
  • Multi-currency trips and bill splitting — Trip budgets with FX conversion, split groups, people balances, and settle-up flows.
  • Analytics and smart insights — Category and month dashboards plus server-generated alerts (budget burn pace, unsettled splits).

The app reduces daily logging friction while giving users consolidated visibility — they do not need separate apps for capture, budgeting, and splitting bills. Singapore-specific CPF and paycheck planning add localized value beyond generic expense trackers.

Personal project — full stack, architecture, and repository details shared openly.

Enlarged view