forked from akai/readest
a72f535346
The library.json index already carries full Book objects, but the metadata merge overlay dropped tags and readingStatus on apply, so tagging or marking a book Finished never reached peers syncing via WebDAV or Google Drive (the same overlay gap that hit group membership in #4942): - mergeBookMetadata carries tags with the metadata LWW subset (raw assignment, so tag removal clears on peers) and merges readingStatus on its own readingStatusUpdatedAt clock, the client-side mirror of the native field-level server merge. This survives the asymmetric race where one device edits metadata after a peer changes the status; whole-book LWW alone would drop the status change. - New shouldApplyRemoteBookMetadata reconciliation predicate triggers on either clock; the engine's index reconcile uses it so a status-only change propagates without a metadata edit. - Merge-law tests (direction, removal, idempotence, asymmetric races) plus engine-level propagation tests for both fields. Prerequisite for gating native sync when a third-party provider is selected (#4380): third-party sync should reach metadata parity before it becomes the only channel. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>