# MoneyKoi – Budget book app

> A budget book that works fully offline, reads receipts on the phone and syncs a whole household in real time – my own product, from the idea to the store.

Own product · since 2024 · https://www.geraldgmainer.com/en/projects/moneykoi

## Context

After more than ten years of managing my own finances I wanted a budget book without a bank login, without cloud AI and without ads, that does everything in airplane mode. Today MoneyKoi comes as Free, Pro and Cloud plans: without an account the whole book lives on the phone; with Cloud a household shares one book across phones, tablets and the browser.

## My role

- **Product** – scope, plans and roadmap
- **Design** of the app, the web app and the website
- **Development** of the Flutter app, the Next.js web app, the Supabase backend and the admin dashboard
- **Marketing** – website with blog and SEO, store listing and releases

## Decisions

- **The local database is the source of truth:** The app reads and writes only to SQLite. Changes go into a persistent outbox that pushes them one at a time, coalesced and with retries. Changes from other devices come back through a single delta sync; realtime events only trigger a pull, and the data itself always arrives the same way.
- **A budget book is a tenant:** Before every request a PostgREST hook checks that the user is a member of the book. Row-level security is deliberately asymmetric: reads are limited to the active book, writes are checked against the row's own book. Bookings queued offline still go through after the user has switched to another book.
- **The receipt scanner stays on the device:** ML Kit reads text and QR codes on the phone, shop-specific parsers for SPAR, BILLA, Lidl and others extract the line items, and a reconciler checks that they add up to the total. All rule-based, no LLM – the photo and its text are never sent to an AI service.
- **No floats for money:** Amounts are NUMERIC on the server and a Decimal value object in Dart; triggers maintain balances incrementally. The forecast, recurrence rules and loan maths exist in both Dart and TypeScript – shared test fixtures make sure app and web return exactly the same numbers.

## Key facts

- lines of Dart in 40 feature modules: ~210k
- tests in the app: ~10k
- server migrations: 100+
- languages: German, English, Japanese: 3

## Stack

Flutter, Supabase, PostgreSQL, Next.js, Nuxt, ML Kit, Offline-First

## Links

- https://www.moneykoi.com
- https://play.google.com/store/apps/details?id=com.psyren.moneykoi
