four things got done: Removed the new UI and went back to the old one. Tap any of these to read the whole thing.
A while back we started building a brand-new look for the app, a clean 3-tab design with a fresh "Today" home screen. It was never switched on for real; it sat behind an off-switch while we built it. When we finally looked at it running, it didn't look good: the Progress screen was basically empty, the Train screen showed leftover placeholder text and a scratchy diagonal pattern that looked broken instead of like a calendar, and workout names were cut off. It just didn't feel finished, or as nice as the old app.
I removed all of the new-UI work, the new shell, the new Today, Train, and Progress screens, the new "look" system (colours, fonts, custom drawings), the embedded fonts, and all their tests. About 9,000 lines gone. The app now always shows the old, familiar 4-tab screen. I kept the behind-the-scenes "smart coach" features (the ones that set your targets and show the review banners) because the old app uses those too, they're not part of the look.
I rebuilt the whole app and the tests on a clean simulator, everything compiled with no errors. I also kept one small test that checks the app's start-up safety gate and confirmed it still passes.
When a brand-new person finished setting up the app, we made their training plan and saved it on their phone, but we forgot to also save it to the server. So the moment they tried to log a workout, the server said "I've never heard of this plan" and the save failed. Every fresh account was effectively broken: the plan existed only on the phone, never in the database.
After the plan is built and cached on the phone, we now also write it to the server, but only after we've confirmed the real account it belongs to. If we can't confirm the account (sign-in still pending, or offline), we skip the server write and keep the phone copy, rather than saving it under a fake placeholder owner that the security rules would reject. Same "figure out who owns it before stamping it" rule the rest of the new auth work follows.
Wrote a test that fails before the fix and passes after (proves a real account triggers the server save, and a missing/placeholder account does not). Full suite green (506 tests, 0 failures).
When the app is missing its keys it shows a "needs setup" screen instead of a doomed onboarding. The new shell's review pointed out the test for this was checking a hand-copied version of the rule, not the real one, so if someone broke the real check, the test would still pass. Pulled the rule into one tiny shared function that both the app and the test call, so the test now guards the actual production code. No behaviour change; the new shell still stays off.
Checked: full suite green (575 + 506 tests).
A clean rebuild of the app failed to build at all. The recent "long-absence re-anchor" change (#418) added a new inTransition flag to a Progress data row, but wrote it as a constant with a built-in default. Swift quietly leaves that kind of field OUT of the automatic initializer, so the code that set the flag failed with "extra argument." The app hadn't compiled since that change merged; it slipped in because that work merges past the flaky iOS build check.
One character: changed the field from a constant to a variable, which puts it back into the initializer (still defaulting to off, so nothing else changes). Caught by the clean full-suite re-verify done as part of the shell go-live prep.
Full suite green again (575 + 506 tests, 0 failures). Fixed in PR, main compiles.