Stale lnw rows repair themselves on the next chapter visit #90
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent
#80 (spec) — implements part of #77.
What to build
Readers already hold Bookmarks created under the invented identity. Those rows keep 404ing on every Poll. Repair them in place the next time the Reader opens a chapter page of that novel — the Reader sees nothing: no second row, no lost Progress, no prompt.
No guessing is needed to spot one. A chapter page now yields both the Chapter Slug from its own address and the series slug from its pointer. If those differ and a row exists under the Chapter Slug identity, that row is the stale one.
The rewrite covers three storage sites and they must move together: the cached row's key, identity and address; the retry-queue entry, if one exists under the old key; and the per-device last-checked map. Then it syncs. The queue matters specifically because an entry under the old key can still replay successfully against the old server row, so leaving the two keys to coexist loses the write — a Reader whose repair happens while offline must find the queued change waiting under the repaired identity.
Write it as a pure transform — cached list, queue and last-checked map in, the same three rewritten out, no storage access inside. That keeps it inside the existing test harness with no new stubbing, and it is exactly the shape worth testing precisely, because the bug hides in one of the sites being missed.
A server-side migration is impossible and was rejected: the database holds no source for the correct slug and no endpoint on the Site maps one slug to the other. The repaired row leaves its old shared Series row behind; nothing deletes it, and the Poll's due-query is an inner join against Bookmarks, so a Series with no Bookmarks is never polled again — the orphan is permanently stored and permanently inert. A Reader who never opens a chapter page of an affected novel does not heal and continues exactly as today. That is the status quo for that row, not a regression.
Acceptance criteria
node --check userscript/novel-bookmark.user.jsandnode --test userscript/test/novel-logic.test.jspassBlocked by
Landed on main (merge of ticket/90-lnw-stale-row-repair; commits
8c172e3,e191155).repairLnwStaleRow is a pure transform — cached list, queue and last-checked map in, the same three out, no storage access, no module state, no clock — exported from the Node test hook. applyLnwStaleRowRepair drives it at both detect() sites (init and onNavigate) before render(), persists all three sites, and syncs through the queue-backed path with the outcome swallowed. No toast, no prompt.
Decisions worth recording:
29/29 tests passing, node --check clean.
On-device: verified with Playwright on a live chapter page. The stale row was rewritten to immortality-simulator across cache, queue and last-checked; the panel showed Tracked; auto-progress on dwell recorded Chapter 1 after ~32s. Console showed only the expected API 401s (no token in that browser) and no script exceptions.
Residual: the full server round-trip could not be demonstrated without a real credential — queue park and coalesce were observed instead. The client-side latest-chapter scan is still slug-scoped; that is #91.