/// // Where a user got to in the setup flow — **only the parts that cannot be // derived.** // // Everything else about their progress is already knowable from data that // exists: whether they have sources at all is a lookup in `addon_config`, which // the page loads anyway. Storing "sourcesDone" beside it would create a second // answer to a question that already has one, and the two would eventually // disagree — at which point the flow either nags someone who is finished or // congratulates someone who is not. // // So this holds three things and no more: // // { "skipped": true, // chose "nastavím později" // "chosen": ["prehrajto", "torbox"], // which services they picked // "pwChangedAt": "2026-08-12T09:00:00Z" } // they replaced the owner's password // // `pwChangedAt` is written by the web page when the change succeeds. It cannot be // derived: PocketBase records no password-changed timestamp, and `updated` moves // for any edit at all. Absent therefore means "as far as we know, still on the // password Richard generated" — which is the honest default for a reminder, and // the cost of being wrong is one dismissible nudge. // // **Per account, not localStorage.** Setup spans devices by nature — the flow is // read on a phone or laptop while the app is installed on a television — so // progress kept in one browser would ask someone who finished on their laptop to // start again on their phone. // // Json rather than three columns: it is one opaque blob the page reads and writes // whole, nothing filters or sorts on it, and adding a fourth thing later should // not need a migration. `users` update rules are unchanged — a user may already // PATCH their own record (that is how the rating default is set), and this rides // on that. // // Existing accounts are untouched and read as `{}`: no `skipped`, so the family // would be offered the flow — except they all have `addon_config` rows already, // which is what actually suppresses it. Nobody who is set up sees anything. migrate( (app) => { const users = app.findCollectionByNameOrId("users") users.fields.add(new Field({ type: "json", name: "onboarding", maxSize: 4000, })) app.save(users) }, (app) => { const users = app.findCollectionByNameOrId("users") users.fields.removeByName("onboarding") app.save(users) }, )