What building this taught me
A few real takeaways from shipping a full-stack household finance app solo.
RLS does more than app code ever could
Household isolation lives in Postgres policies, not if statements: a bug in a Server Action can't leak another household's data.
Hand-rolled validators, for now
Zod would be a natural upgrade, but installing a new dependency couldn't be verified in the environment this was built in, so hand-rolled validators cover the same cases in the meantime.
Two flows RLS can't express
Accepting an invite before membership exists, and deleting a household as its last member, both go through SECURITY DEFINER functions instead.
A CI budget catches what code review misses
A bundle-size gate in CI has caught regressions that lint and type-checking never would have.
Idempotency needs a database precondition
Two concurrent "mark as paid" clicks both read the same stale row and both wrote, fixed with a single conditional UPDATE instead of a faster read-then-write.
Logged in isn't the same as verified
The password-reset page is gated on a short-lived, single-use cookie set at code-exchange time; without it, any signed-in session could reach it and change a password with no current-password check.
Two destructive actions, two blast radii
Wiping your data and deleting your account needed separate flows: one keeps your login and household intact, the other removes both.
Editing history means closing a row, not rewriting it
Changing a recurring entry's amount doesn't touch its past rows. It closes the old one out and starts a new one, so a March rent increase never quietly changes what February looked like.
Curious what it's built with?
Tech StackWhat Mero Kosh is built with, and why.