Address six QA findings on the offline-sync feature:
1. HIGH — silent data loss: a paused mutation persisted to IndexedDB and
reloaded while still offline never resumed on reconnect. Seed TanStack
onlineManager from navigator.onLine at boot (it defaults to online:true and
only flips on events, so a cold-boot-offline tab wrongly believed it was
online and never got a true online transition), and call
resumePausedMutations() in PersistQueryClientProvider onSuccess after the
persister rehydrates (defaults are registered before, so the restored
mutation has a mutationFn). New offline-resume.test.ts reproduces the full
persist -> reload -> reconnect path.
2. MEDIUM (security) — logout did not durably clear gitmost-rq-cache: the
throttled persister re-wrote the key ~1s after del() with the still-in-memory
snapshot, resurrecting the previous user's data. Freeze the persister
(persistClient becomes a no-op) before clearing/deleting so neither the
clear()-triggered nor any in-flight write can repopulate the key; re-enable
afterwards for the next sign-in session.
3. MEDIUM (UX) — offline create spun forever: the create-note button awaited a
mutateAsync that stays pending while paused. Detect offline, fire-and-forget
the (queued) mutation, show a "saved offline" notice, and gate the spinner on
!isPaused so it no longer hangs.
4. LOW — an uncached page opened offline showed the generic "Error fetching page
data." instead of the offline fallback (offline fetch yields no HTTP status).
Render OfflineFallback when navigator is offline or the error has no status.
5. LOW — logout teardown threw "Cannot read properties of null (reading
'settings')" in full-editor.tsx: optional-chain the (transiently null) user.
6. Tab title "Untitled": investigated — the tab-title derivation in page.tsx is
byte-identical to develop and already reads page.title from REST/cache (the
recommended source); live edits keep it in sync via updatePageData. Not a
tab-title-derivation regression introduced by this PR; no change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>