Family finance app · Vienna, Austria

A budget app a real family
actually runs on.

A two-profile household budget planner with shared-home expense splits, monthly rollover, locale-aware demo data and a strict prod/demo split. Fully trilingual (TR · EN · DE). Built end-to-end on a modern, type-safe stack and deployed behind a Cloudflare Tunnel.

94
Automated tests passing
0
i18n keys · TR/EN/DE
0
Locales · TR / EN / DE
100%
Type-safe end to end
Overview

One codebase, two deployments.

A password-gated production app for one real family and a public showcase with hardcoded sample data — the same TypeScript codebase serves both, with a hostname-aware demo overlay that locks down all writes.

👨‍👩

Two profiles + shared home

Each spouse has their own income and expenses, the household has shared expenses split 50/50. Owner cards show "Own + Home share" so each person sees what they actually carry.

🔁

Monthly rollover

Fixed expenses and recurring income forward each month with status reset; one-off entries drop. Installments, annual payments and savings goals are amortised so monthly totals never lie.

📅

Annuals + installments

Yearly bills (Versicherung, Vignette, ÖAMTC) and multi-month installments contribute to the monthly view at amount / N, with a "Due tomorrow" widget that filters out past payment days.

🌍

Fully trilingual

589 typed locale keys across Turkish, English and German with parity-locked dictionaries. Hostname picks the default locale (demo → EN, prod → TR) and a single button switches it live.

🔒

Demo isolation

The public showcase shares the codebase but never the data: a server-side isGuest flag rejects every mutation, and a locale-aware overlay rewrites demo item names per language without touching production family data.

📱

PWA + offline cache

Installable on iOS, Android and desktop. Workbox runtime: network-first HTML so deploys propagate fast, stale-while-revalidate for static assets, with skipWaiting + clientsClaim on every release.

The dashboard

Everything that matters this month.

Net change, savings rate, top spending category, who carries what, what's due tomorrow — one screen, no drilling. Fixed-position locale popover and dark/light themes baked in.

demo.aileplan.uk
Lukas & Anna's Budget All Lukas Anna Home

Hello, Lukas! 👋

June 2026 · Viewing as Lukas

↑ Net change this month
+€1.1k
Income > Expense
Savings rate
0%
Saved this month
🏠 Top category
Housing
€1,155
This month net
€1,114.58
Total Income€3,600.00 ↑
Total Expense€2,485.42 ↓
Due tomorrow · 10€837.50
🏠 Wien Energie
in 12 days
€120.00
🤖 Claude Pro
in 12 days
€22.50
🤖 GitHub Copilot
in 12 days
€10.00
🚗 Eni Gas Station
in 17 days
€65.00
🐱 Lukas's Expenses
€1,308.46
Own: €356.50 · Home share: €951.96
🚗 Transport🤖 AI⚕️ Health
🐱 Anna's Expenses
€1,176.96
Own: €225.00 · Home share: €951.96
💇 Personal Care🛒 Food🚌 Transport
🏠 Shared Expenses
€1,903.92
Each: €951.96
🏠 Housing🚙 Car🛒 Food

An interactive recreation of the live dashboard — the deployment runs at demo.aileplan.uk.

Internationalisation

Truly trilingual — flip it.

589 typed dictionary keys, parity-locked across TR · EN · DE. Hostname picks the default locale; one button switches it live across every surface — including category names, status badges and even the Porsuk cat mascot.

Turkey · United Kingdom · Austria — rendered as inline SVG, so flags display correctly on every OS.
demo.aileplan.uk · EN

This month net

€1,114.58
Total Income€3,600.00 ↑
Total Expense€2,485.42 ↓
Top Category 🏠 Housing

Toggle the flag above — every leaf updates in place.

  • Every surface localised: dashboard, income/expense, debts, goals, reports, settings, login.
  • Hostname-aware default — demo serves EN, prod serves TR, both override with one click.
  • useMemo deps wired to i18n.language so memoised category names re-render on locale switch.
  • Locale-aware Intl number/date formatters via a shared useFormatters hook — no regex parsing.
  • Parity-locked dictionaries: 589 keys × 3 locales, mismatches break the build.
Walk the app

Six surfaces, fully localised.

Each tab below recreates a real page. Switch between them — the same interactions exist in the deployed product.

demo.aileplan.uk/*
+€1.1k
Net change this month
↑ Income > Expense
€16,200
Total savings
+€1,400 added
€837.50
Due tomorrow
10 items upcoming
Housing
Top spending category
€1,155 this month

Real-time aggregates over the family budget — incomes, expenses, installments, annual payments and budget limits all flow into one set of numbers per profile.

Three tabs in one page: Income, Expense, Budget Limits. Each entry has owner (Lukas/Anna/Home), type (Fixed/Variable), category + subcategory and a status (Paid/Pending/Overdue).

Expenses · Lukas · June 2026
DayItemCategoryAmountStatus
3Miete (Neubau 2BR)🏠 Housing€950.00● Paid
12Wien Energie⚡ Utilities€120.00● Pending
12Claude Pro🤖 AI€22.50● Pending
17Eni Gas Station⛽ Fuel€65.00● Pending
20Apotheke Burggasse⚕️ Pharmacy€28.00● Pending

Active debts on the left, multi-month installments on the right. Installments amortise into the monthly view automatically.

Active installments
ItemMonthlyMonths left
📱 iPhone 13 (Drei Plan)€10010 / 12
💻 MacBook Air M2 (Apple Edu)€10020 / 24
🍽️ Geschirrspüler (Saturn 0%)€1002 / 6
🛋️ Sofa (XXXLutz)€10013 / 18
🚲 E-Bike (Radwelt)€10021 / 24
Annual payments
🚗 Autoversicherung
Donau Versicherung · March
€890
🅿️ Parkpickerl 7. Bezirk
Neubau · January
€280
🛡️ ÖAMTC Jahresgebühr
Pannenhilfe · January
€170
🏠 Hausratversicherung
Home contents · April
€240
🎯 Urlaub 2026 (Italien)€8,000
€5,500 saved · 211 days left · €350/mo
PROGRESS69%
🎯 Used Car€18,000
€4,200 saved · 607 days left · €500/mo
PROGRESS23%
🎯 Emergency Fund€10,000
€4,500 saved · 577 days left · €200/mo
PROGRESS45%
🎯 Wedding Fund€5,000
€1,200 saved · 819 days left · €150/mo
PROGRESS24%

Month-over-month trend, top categories, biggest gainers/losers — driven by the same data source as the dashboard with locale-reactive labels.

Income vs Expense trend
Apr May Jun
Income Expense
Biggest gainer
🏠 Housing +6.4% vs prev month
€1,797.50
Lowest category
🍀 Lotto
€5.00
🌍 Language🇬🇧 EN
🌙 ThemeDark
💾 Backup history4 snapshots
📦 Monthly archiveMay 2026 → archived
🔔 Notifications
Demo isolation

A demo that never leaks.

  • isGuest flag set server-side from the request hostname — checked on every mutation.
  • All write paths return FORBIDDEN in demo mode; the UI hides destructive controls.
  • Demo data is hardcoded in server/demo/demoBudget.ts — never touches the production DB.
  • A locale-aware overlay rewrites demo item names per language at the context boundary, without mutating the source.
  • The production family password lives only in a hashed env var; CI never sees it.
Engineering discipline

Tests over assumptions.

  • 94 automated tests, Vitest — every feature ships with at least one new test.
  • Strict TS: noUnusedLocals + noUnusedParameters — builds fail on stale imports.
  • Sprint workflow: pre-flight check, single-commit PR per logical change, force-with-lease rollback.
  • Locale parity script: a missing key in any language is a compile-time error.
  • Production restart in one command (launchctl kickstart); short downtime accepted.
Under the hood

Architecture.

A monolithic TypeScript repo with shared types, deployed as a single process behind a Cloudflare Tunnel.

Client
React 19
Vite 7 · Tailwind v4
PWA
vite-plugin-pwa · Workbox
i18n
react-i18next · 589 keys × 3
API & logic
Express + tRPC v11
Type-safe end to end
Cookie auth
Single family password · hashed
Demo overlay
isGuest-gated read-only path
Data & infra
MySQL 8
Drizzle ORM · type-safe schema
Cloudflare Tunnel
Zero-Trust ingress
launchd
Single-process · auto-restart
Proof, not mockups

Straight from the live system.

The screens above are an interactive recreation. Below are real, unedited captures from demo.aileplan.uk running on actual sample data — click any to enlarge.

Dashboard

Dashboard

This-month net, top category, owner cards & "Due tomorrow" widget

Income & Expense

Income & Expense

Three tabs: Income, Expenses, Budget Limits — per-owner totals

Debt & Payments

Debt & Payments

Active debts, multi-month installments and annual bills in one place

Savings & Goals

Savings & Goals

Five active goals with progress bars, days left and "on track" projection

Reports

Reports & Analytics

Month-over-month trend, biggest gainers/losers, category breakdown

Mobile dashboard

Mobile · PWA

Top bar: Theme · Language · Bell · Avatar — installable on iOS, Android, desktop

Captured from demo.aileplan.uk · English locale · dark theme.

Stack

Built with.

React 19TypeScriptVite 7 Tailwind v4ExpresstRPC v11 Drizzle ORMMySQL 8react-i18next PWA + WorkboxVitestpnpm 10 Cloudflare Tunnellaunchd
0
Tests passing
0
i18n keys · TR/EN/DE
0
Pages, all localised
0
% type-safe