forked from akai/readest
* docs: design for syncing updated book data (cover + file) (#4544) Cover-change sync via a content hash (coverHash = partial MD5 of cover.png) plus a cover_updated_at field-level merge timestamp; file updates ride the existing re-import / metaHash dedupe. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(sync): sync updated book covers across devices (#4544) Editing a book's cover wrote cover.png locally but changed no hash (the cover is keyed by the file hash), so peers had no signal to re-download it and the change never propagated. Give the cover its own content-addressed version: - coverHash = partial MD5 of cover.png; a peer re-downloads the cover iff the synced hash differs from the local one (idempotent, no churn on identical/re-extracted covers — compatible with the metaHash dedupe). - coverUpdatedAt = field-level LWW timestamp so a page-turn that wins whole-row LWW on updated_at can't clobber a cover edit (mirrors the reading_status_updated_at fix for #4634). Editing a cover recomputes the hash, bumps coverUpdatedAt, and re-uploads only the cover; the server merges cover fields independently; peers re-download on a hash diff. File updates continue to ride the existing re-import / metaHash dedupe (changed file -> changed hash -> re-key). Migration 016 adds cover_hash / cover_updated_at to books. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,8 @@ CREATE TABLE public.books (
|
||||
progress integer[] NULL,
|
||||
reading_status text NULL,
|
||||
reading_status_updated_at timestamp with time zone NULL,
|
||||
cover_hash text NULL,
|
||||
cover_updated_at timestamp with time zone NULL,
|
||||
group_id text NULL,
|
||||
group_name text NULL,
|
||||
metadata json NULL,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
-- Migration 017: Add `cover_hash` / `cover_updated_at` to books
|
||||
--
|
||||
-- Cover-change sync (issue #4544). Editing a book's cover writes cover.png
|
||||
-- locally but changes no hash (the cover is keyed by the file hash), so peers
|
||||
-- had no signal to re-download it. Give the cover its own content-addressed
|
||||
-- version:
|
||||
--
|
||||
-- cover_hash = partial MD5 of cover.png. A peer re-downloads the cover
|
||||
-- iff its synced cover_hash differs from the local one.
|
||||
-- Content-addressed ⇒ a byte-identical (re-extracted /
|
||||
-- re-imported) cover yields the same hash ⇒ no re-sync
|
||||
-- churn (compatible with the metaHash dedupe mechanism).
|
||||
-- cover_updated_at = field-level last-writer-wins timestamp so a page-turn
|
||||
-- that wins whole-row LWW on updated_at cannot clobber a
|
||||
-- cover edit — the same hazard the 015
|
||||
-- reading_status_updated_at fix addressed for #4634.
|
||||
--
|
||||
-- Both additive + nullable; NULL cover_updated_at is treated as epoch 0
|
||||
-- (oldest) by the merge. Old clients ignore the columns, so they never break.
|
||||
|
||||
ALTER TABLE public.books
|
||||
ADD COLUMN IF NOT EXISTS cover_hash text NULL,
|
||||
ADD COLUMN IF NOT EXISTS cover_updated_at timestamp with time zone NULL;
|
||||
Reference in New Issue
Block a user