Favourite disciplines belong on the account, not the device
Picked once at onboarding, read from localStorage ever since - and gone the moment someone switched phones or cleared their browser. It was account state that had been living like a device preference.
At onboarding, PaceStreak asks which disciplines someone actually trains -
running, lifting, swimming, whatever they picked - and uses that to order
the log sheet’s suggestions until real history takes over and does the
ordering itself. That selection was stored in localStorage, next to things
like haptics-on-off and theme preference.
The bug is in that sentence: it isn’t like those things. Theme and haptics are genuinely per-device conveniences, correctly local. Favourite disciplines are a decision someone made about their training, once, that should follow them everywhere their account does - a new phone, a browser with storage cleared, signing in on a laptop to check something. None of those should reset a choice that was never meant to be re-made.
The fix is deletion, mostly
-export function favouriteDisciplines(): string[] {
- return read<string[]>("favDisciplines", []);
-}
-export function setFavouriteDisciplines(ids: string[]) {
- write("favDisciplines", ids);
-}
favourite_disciplines moves onto the profile - a real field, sent via
PATCH to /me/profile once at onboarding instead of written to localStorage - and
the log sheet reads it from the session’s profile object like everything
else account-level. The interesting part isn’t the field; it’s the deletion
above it. Fixing this meant removing code, not adding a sync layer, because
the right home for this data already existed - it just wasn’t being used
for this.
The general shape
The question worth asking about any localStorage write isn’t “does this
work,” it’s “would I be upset if this reset on a new device.” Haptics
resetting is a shrug. A choice made once at onboarding resetting silently,
with no error and no obvious cause, is the kind of small trust erosion that
never produces a bug report - it just produces an app that quietly asks the
same question twice and never explains why.
AlzyWelzy
Building PaceStreak. GitHub
Related
Security & PrivacyNotification buttons without a session
A habit reminder now has Done and Snooze buttons. The service worker that handles them has no access token, by design, so each button carries a signed, single-purpose link instead.
2 min
ProductA coach made of rules
The new daily coach is a few if-statements over your own data. Why that beats a generated paragraph, and why the app shows only the notes its existing cards don't already cover.
1 min
Security & PrivacyFixing the dead ends in sign-up and verification
Three real bugs found by using the OTP flow the way a person actually would: a stuck login, a false 'already registered' error, and a confirmation screen that didn't lead anywhere. Plus a status page that finally watches the whole stack.
3 min