Files
bookorbit/server/src
neon eba1640df4 fix(kobo): acknowledge device state pushes so hub progress reaches the reader
PUT /v1/library/{id}/state answered with the stored ReadingState instead of the
RequestResult/UpdateResults envelope the device expects. The device leaves an
unacknowledged push pending and treats its own copy as authoritative, so it
re-pushes every sync and opens the book at its local bookmark no matter what the
pull path delivered. That is why a first download honours the hub position while
an already-synced book only picks up the percentage.

Three smaller defects produced the same reversion on their own:

Hub progress kept the device's previous CurrentBookmark.Location when no KoboSpan
described the new position, shipping a bookmark whose position contradicted its own
percent. Drop the Location instead; the pull path re-adds one whenever it can
convert the cfi.

Both hub-side writers stamped last_modified_kobo, priority_timestamp and the
bookmark at wall-clock time while device timestamps are stored verbatim. A Kobo
clock running ahead therefore won every conflict. Stamp strictly past whatever is
stored, mirroring what upsertState already did for the envelope.

A conversion that gave up was invisible: getRawState swallowed throws and the
converter logged reasons at debug level, so an operator could not tell a healthy
bookmark from one that silently degraded to percent-only.

Closes #749
2026-08-16 17:45:20 +00:00
..