liseur-sync/docs
Chmouel Boudjnah 0a6d4167aa feat: sync annotations across devices (ADR-0028)
Highlights, notes and bookmarks are the first mutable kind of reading
state: each record carries a rev, and every write is a compare-and-set
against it. The server orders writes; it never merges.

Store: an annotations table with its own per-user seq counter
(migration 5 on both backends), batched push in one transaction under
the work-graph lock, a delta feed with tombstones, a per-work cap on
live records, split/merge reassignment, and an hourly sweep that drops
tombstones after the retention window.

API: four sync-scoped routes. POST /v1/annotations answers 200 with one
result per item (applied, duplicate, conflict carrying the server copy,
or invalid with the reason); one bad item fails alone, including an
item the decoder cannot type. The request cap is computed from the
documented field bounds with worst-case JSON escaping, and exceeding it
is a 413, not a misleading parse error. Tombstones carry identity, rev,
seq and timestamps, nothing else.

Web UI: the reader draws synced highlights through the foliate
overlayer, mapping palette tokens to fixed CSS. Notes, bookmarks and
highlights that no longer anchor appear in the drawer list. The work
page gains a read-only annotations panel.

The browser check now seeds three annotations and verifies the
highlight renders as an overlay rect in a real Chromium.
2026-08-25 12:04:15 +02:00
..
adr docs: record ADR-0028, annotation sync as mutable reading state 2026-08-25 07:39:29 +02:00
screenshots docs: Refresh dashboard screenshot 2026-08-24 16:04:05 +02:00
deployment.md feat: scope catalog access to explicit per-user folder grants 2026-08-22 10:43:41 +02:00
DESIGN.md feat: sync annotations across devices (ADR-0028) 2026-08-25 12:04:15 +02:00
integrating.md feat: sync annotations across devices (ADR-0028) 2026-08-25 12:04:15 +02:00
openapi.yaml feat: sync annotations across devices (ADR-0028) 2026-08-25 12:04:15 +02:00