Beam backfilled list/get/create/update/delete media-item, search, ratings
CRUD, progress GET/PUT. Beam correctly identified create/update/delete as
jwt+admin (admin group in the router — verified).
Claude registry: 12 entries. Notable pins:
- get_media_item: hand-built ~44-key map pinned verbatim from the handler
- create/update return the full database.MediaItems row (74 columns) —
examples merged up to the real shape via gate-driven merge script
- search returns []SearchMediaItemsRow (sqlc row — Real type pinned)
- rating scale is 1-10 int (odd = half-star); GET returns {rating: null} when
absent; update reuses the create handler (201)
- progress GET: 25 base keys + 4 CONDITIONAL position-authority keys
(css_selector/anchor_href/char_offset/context_text — added by the handler
for convertible formats with a valid CFI); PUT progress binds
sync.SaveProgressRequest and returns database.ReadingProgress
- Beam's examples were missing entirely on 4 files (list/search/progress
GET/PUT) — relabeled existing fences or inserted contract-shaped blocks
Gate-driven merge scripts (object + array variants) brought all examples to
the exact handler key sets. make test 9/9.
The progress documentation described GET/POST /api/progress/:id —
endpoints that do not exist in the router — while the endpoint every
client actually uses (GET/PUT/DELETE /api/media-items/:id/progress) had
no field-level docs at all.
New:
- progress/position-contract.md: the canonical position model — server
as position authority, the three-tier submission (percentage /
context_text / epubcfi), ingest verification and healing, the restore
handles, the OPF spine numbering hazard (canonical CFI spine steps
include linear="no" items; clients resolve documents by anchor_href
and land by css_selector + char_offset, never by spine step), the
offset currencies (UTF-16 at the wire, runes internal), and
context_text rules.
- progress/get_media_progress.md and update_media_progress.md: the real
endpoints with full field tables, conditionality of the restore
handles, the first-page anti-clobber guard, and healed-response
semantics.
- progress/delete_media_progress.md: the real DELETE route.
- koreader/sync_progress.md and koreader/get_metadata.md rewritten to
the actual payloads: the plugin sends a single-book array whose
"epubcfi" field is a CRE xpointer; the metadata response navigates
via koreader_xpointer (canonical CFI converted back to CRE), with
page as the canonical locator for fixed-layout books.
Removed: the five files documenting the nonexistent /api/progress/:id
GET/POST/DELETE endpoints. Kept get_progress_history.md (that route
exists). The legacy developer/api-reference.md and the indexed
api/api-reference.md progress sections now match the wire and link the
new docs; the duplicate "Universal Progress" section points at Reading
Progress.