A multi-tenant trip-planning app that runs entirely on Cloudflare's edge. First-party auth, a data layer that isolates every group from every other, and a settle-up engine that does the who-owes-whom math in integer cents. Built solo, end to end.
The whole app is a single Cloudflare Worker in front of a D1 database. There's no origin server to keep alive and no region to be far from. The frontend is hand-written HTML, CSS, and JavaScript with no framework and no build step, so it loads fast and there's very little that can break between me and the browser.
Sign-in is an emailed magic link (single-use, stored only as a hash, expires in 15 minutes) or Google. The session is a signed token that lasts a year, because the worst thing this app knows is a door code, so the right tradeoff is to almost never make people re-auth. I dropped Cloudflare Access on purpose: its free tier caps at 50 seats across the whole account, and a friend group plus partners blows past that.
Every group is a tenant. A single data-access layer binds every query to one group's id, enforced in one place so no route can forget it and read across tenants. Balances and household weights are never stored; they're derived on read, so they can't fall out of sync with the expenses and people they come from.
The same email can belong to a friends trip and a separate family trip, each fully walled off, with a switcher in the corner. Identity stays in the signed token and never changes; a separate cookie picks which group you're looking at. So switching groups is instant and never touches the login.
Splits can be weighted by household size, even, or exact amounts, and all of it is computed in integer cents so floating-point rounding never leaks a penny. Then a greedy pass collapses everyone's net position into the fewest payments that settle the group. It only ever does the math. It never moves money, connects to a bank, or holds a balance.
It's API-first, so the same JSON endpoints that serve the web app could serve a native app later. The database sits behind one small driver, which keeps a future D1-to-Postgres swap contained. And deploys run through a script that applies database migrations first and only ships the new code if they succeed, so new code never lands on an old schema.
A coordination tool, not a payment app. It tracks who owes whom and shows the cleanest way to settle, then gets out of the way. It never connects to a bank or moves a dollar, and it's invite-only by design.