August 2026 · Build notes
Building ZephyrLifeOS alone: what broke, and what I fixed
I built ZephyrLifeOS by myself — no team, no funding, just me and a growing list of things that quietly didn't work the way I assumed they did. This isn't a highlight reel. It's the three bugs that actually scared me, and what fixing them looked like.
The payments that weren't actually happening
For weeks, real purchases were failing with a generic "unknown backend error." Everything looked configured correctly on the surface — Stripe was verified, RevenueCat was set up, the paywall rendered fine. People just couldn't actually pay.
The real cause, once I found it: the app's active RevenueCat offering was a test-only one with no real Stripe products attached. It wasn't a typo or a missed step so much as a wrong default that never got questioned until purchases kept failing. Fixing it meant switching the correct offering to "active" and swapping a sandbox API key for the real one. The first genuine live purchase went through right after.
A bug that could have shown one person's data to another
While auditing the login/logout flow for something unrelated, I found something worse than what I was looking for. A function I'd written earlier to fix a premium-status leak between accounts only ever reset premium flags and settings — never the actual financial data. That meant switching accounts in the same browser tab, without a page reload, could leave one person's real expenses and balances sitting in memory, visible to whoever logged in next, and in the worst case pushed into their cloud record via auto-sync.
I hadn't shipped it to real users when I found it, but it's exactly the kind of bug that's invisible until it isn't. The fix touched every place a session can start or end — both signup paths, both login paths, and logout — to make sure a clean slate actually means clean.
The refresh that could erase everything
Cloud sync only ever ran from a manual "Sync Now" button, or as a courtesy save on logout. Nothing saved automatically after just logging an expense. A normal page refresh — without remembering to hit that button first — had nothing to reload from.
I fixed it two ways: an automatic, debounced cloud sync for Premium accounts, so nothing waits on a manual click anymore, and a local-device cache for every account, free or paid, so a refresh never loses what you just typed in.
Why write this down
None of these were exotic bugs. They were the ordinary cost of building alone — nobody to catch what you don't think to check. I'm writing them down because the next one is probably just as boring, and just as capable of mattering.