AnthonyTlei
← All work

Case study

/

Product systems · Platform & data

Mizan

A private multi-currency household finance system built around an immutable ledger, explicit planning, and explainable balances.

Mizan's household overview: a combined USD reporting balance beside separate IDR, KWD and USD native balances, each split into bucketed and spendable, with ledger health showing as reconciled.
What exists
Status
In production
Access
Private product · Public overview
Coverage
Architecture · Data model · Data flow · Worker design · Failure design · Workflow · Screenshots
Stack
TypeScript · Next.js · React · PostgreSQL · Drizzle ORM

01
Overview

What this is

Mizan is a private household finance system built for two people managing money across USD, KWD, and IDR. It combines everyday transactions, accounts, budgets, reserved buckets, recurring commitments, scheduled payments, and reporting without flattening every number into a single currency or hiding how a balance was produced.

The interface is intentionally calm; the harder work lives beneath it. Transactions are modeled through immutable revisions and balanced ledger postings, currency conversions keep their rates and provenance, and planned items remain plans until an explicit settlement creates financial history.

Built for my household and used by two people across three currencies. Any public screenshot uses synthetic data only.

The problem

Generic trackers did not match the household’s combination of shared ownership, multi-currency balances, reserved money, and future commitments. A useful replacement had to be simple in daily use while making corrections, conversions, and automation trustworthy enough to explain later.

What I built and owned

I defined the product and accounting semantics, designed the responsive interface, built the modular Next.js application and PostgreSQL schema, implemented authorization, automation, reporting, and recovery controls, and operate the private deployment.

Disclosure

The running application and source are private. Any public screenshot is captured from a disposable database containing only synthetic people and transactions; no production data, account names, balances, or URLs are shown.

02
Detail

How it works

Trust comes from the model

Mizan treats the original currency as canonical and preserves settlement and reporting conversions as separate, traceable facts. Monetary values use exact decimals rather than binary floating point. A correction never rewrites history in place: it creates a new revision and new balanced postings, preserving the path from what was entered to what is now considered current.

That exactness is deliberately kept out of the way during ordinary use. The interface speaks in accounts, expenses, transfers, buckets, budgets, and upcoming commitments; the ledger remains available as the reason a balance can be trusted.

Everyday on top, exact underneath

  • 01

    Native currency stays visible

    USD, KWD, and IDR balances remain first-class while reporting conversions retain their rate and provenance.

  • 02

    Planning cannot become history by accident

    Recurring and scheduled commitments affect forecasts, but only an explicit settlement creates a financial transaction.

  • 03

    Buckets reserve; they do not mint money

    Allocations change what is spendable without changing the underlying account balance.

  • 04

    Every request is household-scoped

    Authorization follows the household and member context rather than trusting a record identifier from the browser.

Synthetic evidence

Any public screenshots are captured from a fresh disposable PostgreSQL database populated with fictional people, accounts, balances, budgets, buckets, and transactions. No production database, development database, private URL, or real financial record is used.

03
Result

What came of it

shippedA private two-person household can record expenses, income, transfers, refunds, adjustments, budgets, buckets, and future commitments in one system while preserving each amount’s native currency.Private household deployment; public screenshots use synthetic data.
reproducibleCorrections create new immutable revisions; balanced postings and FX provenance make the resulting balances traceable rather than silently overwritten.
reproducibleRecurring and scheduled items remain planning records until an explicit settlement creates financial history, so forecasts cannot masquerade as posted money.
reproducibleThe outbox and worker path is idempotent and records failures for recovery instead of relying on one request to complete every side effect.

04
Links

Where to look

productionRunning application — private household deploymentsourceSource code — private

Something similar in mind?

If this is close to a problem you have, the fastest thing is usually a short conversation about what you are actually trying to change.

Discuss a project