test(pins): widen whitelist for the episode-collections JSON shapes (item 2 series)

TestContractPin_CollectionsJSON tripped on the additive keys the
episode-collections work introduced — the tripwire worked exactly as
designed (additive keys must be whitelisted here AND in
docs/contract_pins.md first).

- Collections envelope gains rule_match_mode (item 2.4): the
  smart-collection match semantics on GET /api/collections/:id.
- BookInfo gains four STABLE keys (item 2.3): is_episode,
  feed_title, download_state, hidden — dropped omitempty so every
  card surface emits the same key set (the viewer_percentage
  precedent; adapters that predate episode awareness emit zero
  values).

docs/contract_pins.md changelog entry written. Nothing removed,
nothing renamed.
This commit is contained in:
John O'Keefe committed 2026-10-30 17:25:22 -04:00
1 parent 962f9089e0
commit bc91ce68d4
3 files changed
+24 -5

No files matched your search

+13
View File
@@ -468,3 +468,16 @@ never-queued episodes) is stamped from the `podcast_queue_seq` SEQUENCE
at enqueue time so claim order = enqueue order (the effective listening
order). Raw-row pins (TestContractPin_MediaListBothBranches →
rawRowKeys) whitelist the key. Nothing removed, nothing renamed.
## 2026-10-30 — episode collections (additive widening, plan item 2/2.3/2.4)
Two shapes widen, both ADDITIVE — nothing removed, nothing renamed:
- **Collections envelope** (`GET /api/collections/:id` → envelopeKeys)
gains `rule_match_mode` (smart-collection match semantics, 'any'
legacy default | 'all'). Static collections emit the default value.
- **BookInfo** (every card surface → bookInfoKeys) gains four STABLE
keys — `is_episode`, `feed_title`, `download_state`, `hidden` — the
episode-collections extras. Adapters that predate episode awareness
emit their zero values (`false`/`""`), matching the
viewer_percentage precedent (nil-representable, key always present).