Skip to main content

PROJECT CASE STUDY · HOUSEHOLD FINANCE

Yukidoke

A private household personal-finance product built with Angular 22 and a modular .NET 10 API, designed to support shared finances without making every financial record visible to the whole household.

Private source Active

PROBLEM

Shared household money still contains private information

A household finance product has to represent obligations that are genuinely shared while preventing one member’s private financial records from becoming household-wide data by default. Cards, debts, income, budgets and recommendations also need one authoritative calculation path instead of slightly different formulas in every client.

Yukidoke therefore treats authentication, household membership and per-record financial visibility as separate boundaries rather than one generic “logged-in user” check.

SYSTEM

Presentation is separated from financial authority

Yukidoke V1 system boundary. Angular owns interaction and transient client state. Keycloak establishes identity. The .NET 10 API owns household authorization and financial rules, while PostgreSQL is the durable system of record. Worker and migrator processes share the modular-monolith codebase.

ARCHITECTURE

A modular monolith keeps V1 transactions understandable

BOUNDARY 01

KEYCLOAK OWNS IDENTITY

The browser is a public OIDC client using Authorization Code + PKCE. Global identity is deliberately separated from household membership and financial permissions.

BOUNDARY 02

THE API OWNS FINANCIAL RULES

The Angular client expresses intent and renders state. Household permissions, accounting behavior, financial-health calculations and durable read models belong to the API rather than being duplicated in the browser.

BOUNDARY 03

POSTGRESQL OWNS DURABLE STATE

Modules persist through PostgreSQL with EF Core migrations and optimistic concurrency. The database migrator is the process responsible for applying migrations instead of every application process mutating schema on startup.

DATA FLOW

REST recovers truth; realtime is incremental

The Angular client uses typed REST clients, normalized pagination and ProblemDetails handling. Notification state is loaded from REST and SignalR adds incremental updates, so reconnecting does not change where durable state comes from.

This distinction matters in finance: a websocket event can improve responsiveness, but it should not be the only record that a balance, notification or household action exists.

CURRENT IMPLEMENTATION

What the V1 beta includes today

WEB

ANGULAR 22 · 0.9.0-RC.1

The web client runs on Angular 22 and identifies version 0.9.0-rc.1. It includes household context and capability guards, typed API clients, debts/cards/payoff flows, income, Planning consolidation, invitations and household administration, EN/ES localization and a browser harness against the real supporting stack.

API

.NET 10 MODULAR MONOLITH

The API targets .NET 10 and organizes Users, Households, Accounting, Cards, Debts, Incomes, Planning, Notifications and Overview as modules. It uses PostgreSQL 16, Keycloak authentication, Worker and Database Migrator processes, with integration paths against real PostgreSQL and Keycloak services.

PRIVACY

Resource existence is part of the authorization model

Household-scoped endpoints can hide a resource from non-members instead of revealing that it exists and then returning “forbidden”. This keeps resource existence inside the privacy boundary.

The beta is still being worked on around privacy, exports, balances, authentication and clean-stack acceptance before I would consider it ready for real household financial data.

CURRENT BOUNDARY

V1 remains a private beta

PRODUCT STATUS

PRIVATE BETA · ACTIVE DEVELOPMENT

The code remains private. Current work is focused on authorization, financial consistency, persistence, exports, privacy and clean-stack acceptance before real household financial data is in scope.

LEARNINGS

What I learned from the household boundary

LEARNING 01

AUTHENTICATION IS NOT AUTHORIZATION

Identity, household membership and visibility of a specific financial record need independent rules and independent tests.

LEARNING 02

REALTIME SHOULD NOT OWN DURABILITY

SignalR is useful for incremental updates; recoverable REST state remains the safer authority when a realtime connection drops or reconnects.

LEARNING 03

A MODULAR MONOLITH CAN BE A DELIBERATE CHOICE

Domain boundaries, migration ownership and transaction consistency can be explicit without paying the operational cost of distributed services before V1 needs them.