Locks schema/code decisions for migrations 139-142 and downstream
sub-plans. Resolves open Risk questions from the absorption design spec.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First of six sub-plans for the absorption. Six tasks: a discovery
audit that resolves the spec's Risk questions, four idempotent SQL
migrations (abs_sessions, podcast_feeds, media_libraries.kind,
audiobooks.enabled feature flag), and an empty-but-compiling
internal/audiobooks package scaffolded into cmd/silo. Lands as a
strict no-op for users (feature flag defaults to false).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Plan to absorb silo-plugin-audiobooks into silo-server as a first-party
feature. Audiobooks land in silo's existing SPA; ABS clients connect
directly. Hard constraints: reuse existing tables (media_items,
media_files, user_watch_progress, user_playback_sessions, people,
item_people, library_collections); only two new tables (abs_sessions,
podcast_feeds) and at most one column add (media_libraries.kind);
silo's main :8080 listener handles ABS Socket.io natively. Out of
scope: audiobook requests flow, smart collections, share links,
external recommender, custom metadata providers, separate audiobook
SPA.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Firefox (and some download managers) issue a HEAD request before
starting a download. The route only registered GET, so HEAD returned
405 Method Not Allowed and the browser aborted the download.
Mirrors the pattern already used by /stream/{session_id}, which
registers both GET and HEAD on the same handler. ServeDirect is built
on http.ServeContent / ServeFile, which natively handle HEAD by
writing headers without a body, so no handler changes are needed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Map number words and ordinals (e.g. "Two"/"2nd") to digit tokens in both SQL normalize_search_text and the Go mirror so "Dune: Part Two" and "Dune Part 2" match
- Rebuild title_normalized generated column and title FTS GIN indexes (migration 138)
- reload introdb API key on setting updates
- support recap/preview markers in playback and next-episode flow
- add profile defaults for recap and preview auto-play settings
- Rename actor-oriented API, storage, and webhook fields to user/profile terminology
- Switch dev compose helpers to use docker-compose.yml
- Update frontend types and webhook sync settings for the new endpoints
- Wire introdb marker fetching into playback and Jellyfin compat
- Persist and expose recap/preview markers alongside intro and credits
- Add new playback/profile settings for recap and preview behavior
- Add admin job support for collection defaults applies
- Keep preview synchronous while real applies run via the job queue
- Show collection apply job status in the admin UI
- Store bundled template posters in public S3 when available
- Presign imported user collection posters in API responses
- Thread frontend assets into router and collection handlers
Agent F's code review surfaced a critical gap: every Phase 1-3 template
ships a non-zero `DefaultSortOrder` in the documented PMM-style bands
(1000s charts, 2000s best-of-year, 3000s awards, 4000s streaming,
5000s popular by genre, 6000s top rated by genre, 7000s franchises,
8000s seasonal, 9000s misc/kids) and the test suite pins those values,
but none of the four `createCollectionFromTemplate` dispatch paths
forwarded the rank into `catalog.CreateLibraryCollectionInput.SortOrder`.
Applying any template — bundled or one-off — landed the new collection at
SortOrder 0, defeating the band scheme entirely.
Fix: add `SortOrder int` to each request struct
(`importMDBListRequest`, `importTMDBRequest`, `importTMDBFranchiseRequest`,
`importTMDBDiscoverRequest`) and forward `tmpl.DefaultSortOrder` →
`req.SortOrder` → `CreateLibraryCollectionInput.SortOrder` end-to-end.
The pre-existing `SourceTrakt` path is unchanged — no Trakt template
currently sets a non-zero `DefaultSortOrder` so the gap is dormant
there; revisit if/when a Trakt template needs ordering.
No new unit test: the fix is a per-struct field forward whose
end-to-end exercise requires the live repository. Adding a fake repo
to test the propagation would be a refactor beyond this fix's scope.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Phase-3 of the collection-templates expansion. Adds ten curated movie
franchises plus a generic placeholder template, all backed by Agent B's
tmdb_collection source. Templates land in the 7000s sort-order band.
Verified TMDB collection IDs (via api.themoviedb.org/3/collection/{id}):
- 10 Star Wars Collection (9 films)
- 645 James Bond Collection (25 films)
- 1241 Harry Potter Collection (8 films) — used for "Wizarding World"
- 9485 The Fast and the Furious Collection (12 films)
- 119 The Lord of the Rings Collection (3 films)
- 121938 The Hobbit Collection (3 films)
- 328 Jurassic Park Collection (7 films)
- 295 Pirates of the Caribbean Collection (5 films)
- 87359 Mission: Impossible Collection (8 films)
- 535313 Godzilla Collection (3 films) — used for "MonsterVerse"
Plan corrections / skips:
- MCU (plan ID 86311) resolves to "The Avengers Collection" (6 films),
not the full Marvel Cinematic Universe. TMDB has no umbrella MCU
collection. Skipped per the no-invent-IDs rule. Sort slot 7001 left
open.
- DC Extended Universe (plan ID 573436) resolves to "Spider-Man:
Spider-Verse Collection" — unrelated. No DCEU umbrella exists on
TMDB. Skipped. Sort slot 7005 left open.
- Wizarding World (plan ID 1241) is TMDB's Harry Potter octalogy;
Fantastic Beasts lives in a separate collection (435259). Used as-is
with description noting the scope.
- MonsterVerse (plan ID 535313) is labelled "Godzilla Collection" but
contains the three Legendary MonsterVerse Godzilla films, which is
the closest TMDB representation. Used as-is.
The placeholder template ships with CollectionID=0 and an empty sync
schedule so it can be applied without a valid franchise ID; admins edit
the resulting collection's source_config before the first sync.
Append the Phase-2 catalog from the collection-templates expansion plan:
- 18 Popular by Genre (sort_order 5001..5018, daily 0 4 * * *,
popularity.desc with vote_count_gte=300)
- 18 Top Rated by Genre (sort_order 6001..6018, weekly 0 5 * * 0,
vote_average.desc with vote_count_gte=1000)
- 1 Kids Movies (sort_order 9050, weekly, Family genre with
certification_lte=PG)
Adds TestPhase2DiscoverTemplatesUseExpectedBands to pin the band ranges
and the TMDB query parameters that define each section.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>