PENNY

How Penny is built

Penny is a personal-finance SaaS I designed and built end-to-end as a portfolio project - from the Claude Design mock-ups to the database schema, billing and AI assistant. It started life as OWL, a private tool I use for my own transactions, and was rebuilt as a multi-user product with a public demo. - Ramiz, Senior DevOps / Cloud Engineer, Mississauga ON

Open the live demo - no sign-up needed. It runs on generated sample data.

Stack

  • Next.js 16 (App Router, React 19 Server Components, Server Actions, Turbopack) with strict TypeScript
  • Tailwind CSS 4 design system recreated from my Claude Design file (glass cards, pill controls, striped data marks)
  • Clerk for authentication; Supabase Postgres (Canada region) for data, in a dedicated path schema
  • Stripe Checkout, Customer Portal and signed webhooks for the Pro subscription
  • Anthropic Claude tool-use agent for Ask Oreo, streamed to the browser
  • Voice: Web Speech API push-to-talk and hands-free mode, with ElevenLabs speech when configured
  • Twilio SMS bill reminders sent by a daily Vercel Cron job
  • Zod validation on every write, deployed on Vercel

Architecture decisions

  • Multi-tenant by construction. Every table carries the Clerk user_id; every query in the server layer filters on it, and writes that reference another row (e.g. a transaction’s account) check ownership in the same SQL statement. The schema has row-level security enabled with no public policies, and the Supabase Data API roles are revoked - only the server can reach it.
  • Demo mode without a backdoor. The recruiter demo is a signed cookie that swaps the data source for a deterministic generator (seeded PRNG, dated relative to today). Demo edits are applied optimistically in the browser only, so the demo can’t touch real data or be vandalised.
  • Every integration is optional. Feature flags derived from environment variables let the app build and run with zero secrets; /api/health reports which integrations are live.
  • Grounded AI coach. Ask Oreo receives a compact JSON summary (monthly totals, category spend, budgets, upcoming bills, goals) and can search transactions by merchant, date or amount through a tool - never raw bank descriptions. It proposes edits through typed tools; the server checks every id belongs to you, and nothing changes until you confirm the card (or say “yes” in voice mode). If the model is unavailable, a rule-based answer engine responds instead. Usage is metered per user per day and gated by plan.
  • Idempotent imports & billing. CSV rows are hashed (account, date, amount, normalised description, occurrence) behind a partial unique index, so re-importing a statement never duplicates. Stripe webhooks are recorded by event id before processing.
  • Soft deletes + audit log. Deleted transactions can be restored (the Undo toast), and every mutation writes an audit row with the actor (web, AI, import, Stripe, system).

Features

  • Home dashboard: 6-month cash flow, earnings and expenses with period comparison, spending by weekday and category, budget pace, cash calendar, goals, recurring bills
  • Transactions: search, filters, bulk re-categorise/delete with undo, CSV import for Canadian bank formats, CSV export
  • Budgets with pace markers and suggested limits from your 3-month average
  • Recurring bills with SQL-based detection from transaction history, and a bill picker that pre-fills amount, schedule and account from your past payments
  • Bill reminders by text: 1 week, 3 days and 1 day before by default, customizable per bill, with a live preview of the messages. A secret-protected cron route sends them, and a unique send log makes re-runs safe
  • Accounts: net-worth trend rebuilt from transaction history, 90-day balance sparklines and an asset mix
  • Goals and loans with projected finish dates
  • Insights: rule-based findings (spending jumps, unusual charges, savings rate) plus the AI assistant
  • Free vs Pro plan limits enforced on the server

What I’d build next

  • Bank connections through an aggregator (read-only OAuth), replacing CSV import
  • Email reminders alongside SMS, and two-way replies (“paid” marks the bill done)
  • An MCP server so Claude or other assistants can read and edit Penny data with the user’s consent