* refactor(xtream): split the series details page into focused services
serial-details.component.ts sat at the 400-line max-lines limit and its
playback service and spec were close behind. Move cohesive concerns out
without changing behavior:
- route params, the provider-only flag and the (re)load of the addressed
series go to SerialDetailsRouteService; the component still registers
the effect, so effect order is unchanged
- season descriptions, posters and the TMDB season enrichment go to
SerialDetailsSeasonsService
- actor, Similar and Discover navigation go to injectXtreamDetailNavigation,
shared with the movie page
- the watched toggles and the episode playback payload leave
SerialDetailsPlaybackService for SerialDetailsWatchToggles and
buildSerialEpisodePlayback
- the spec's TestBed moves to a harness and the watched-toggle cases to
serial-details.season-watch.spec.ts
Counted lines: component 400 -> 318, playback service 388 -> 342,
component spec 1196 -> 674.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* refactor(xtream): move VOD route selection and position state out of the page
vod-details-route.component.ts grew from 618 to 741 counted lines and
vod-details-playback.service.ts reached 395. Extract without changing
behavior:
- the route-derived read model (selected movie, category, catalog item,
fallback view, multi-source identity, session and content keys) goes to
VodDetailsSelectionService; the component keeps the same member names
- trailer state and the Similar-rail click move into the hero presenter,
the cancel-download prompt and the progress-ring geometry into the
downloads service, navigation into injectXtreamDetailNavigation
- stored positions (last seen, route row, guarded load) become
VodDetailsPositionState and the external-launch bookkeeping becomes
VodExternalLaunchClaim
- drop the unused MatTooltip import (NG8113) and eight unused imports
Counted lines: route component 741 -> 492, playback service 395 -> 344.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* refactor(stalker): extract series-view positions and watched toggles
stalker-series-view.component.ts grew from 1601 to 1813 counted lines and
its spec reached 1198 of 1200. Move code out verbatim:
- saved positions, their reconcile and the persist/clear writes go to the
component-provided StalkerSeriesPositionsService; the ordering of reads
and writes goes to StalkerSeriesPositionQueue
- episode, season and series watched toggles go to
StalkerSeriesWatchToggleService, the batch core to
runStalkerWatchToggleBatch
- the lazy VOD season loads go to StalkerVodSeasonEpisodeLoader
Every effect stays registered in the component constructor in its original
order; template bindings and public member names are unchanged.
The spec setup moves to a shared harness and the spillover-prefetch and
TMDB season cases to their own specs; the 184 cases of the directory are
unchanged.
Counted lines: component 1813 -> 1136, component spec 1198 -> 670.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* refactor(stalker): extract catalog-detail position and search paging
- stalker-catalog-detail.component.ts (397): the stored VOD position and
its runtime updates become StalkerCatalogVodPosition, the Play/Resume
start becomes startStalkerCatalogVodPlayback
- stalker-search.component.ts (776, baselined): the paging resource, the
accumulated results and the parental-lock bookkeeping become
StalkerSearchPagingController, with pure helpers in
stalker-search-results.util.ts. The spec reaches the moved members
through component.paging; its cases and assertions are unchanged.
Counted lines: catalog detail 397 -> 317, search 776 -> 482.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* refactor(ui): give season-container and vod-details real line headroom
- season-container.component.ts (396): season auto-selection and the
seasonSelected emission move to createSeasonAutoSelectState, called at
the same place in the constructor so effect order is unchanged; the
episode subline becomes buildEpisodeSubline
- vod-details.component.ts (393): the cross-portal Similar loader, the
provider-only download state and the actor/Similar route helpers move to
sibling modules
Inputs, outputs, selectors and public members are unchanged.
Counted lines: season container 396 -> 341, vod details 393 -> 337.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* test(web-e2e): move Stalker portal helpers into fixtures
stalker.e2e.ts was at 1196 of 1200 counted lines. Move the mock endpoints,
scenario MACs and page helpers to stalker-portal.fixture.ts and the
embedded-series steps three tests repeated to
stalker-embedded-series.fixture.ts. Every test stays in stalker.e2e.ts in
the same order, with the same serial mode and OWNED_MACS reset.
Counted lines: 1196 -> 981.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* docs: follow the detail-page extractions
Name the Stalker watched-toggle and position services that now own the
batch and reconcile code, point AUTH_REJECTED_MAC and the scenario MACs at
stalker-portal.fixture.ts, and drop two stale statements about components
sitting at the max-lines cap.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* docs(xtream): note why the seasons service is injected last
Its TMDB enrichment effect keeps the position it had as the first effect
of the component constructor only while it is created after the other
services' effects.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: 4gray <fourgray@proton.me>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* docs(tmdb): record the TMDB capability roadmap
Backlog for the TMDB subsystem produced by a multi-agent audit that
cross-checked our code against the official API reference and against how
Plex/Jellyfin/Emby/Stremio/Kodi present metadata: unused API surface,
zero-extra-call wins already sitting in cached payloads, effort-ranked
themes, a top-8 shortlist, implementation sketches, and an explicit
"deliberately not building" section with reasons.
Three entries are defects in shipped code rather than features and are
sequenced first: a broken provider tmdb_id suppresses enrichment
entirely, series cast is latest-season-only (needs aggregate_credits),
and cache retention exceeds the six-month TMDB ToS limit.
Cross-linked from tmdb-metadata-enrichment.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs(tmdb): correct the A1 sketch to match what shipped
The sketch proposed discarding details on a title mismatch and recording
a bad-id verdict on any failure. Neither survived review: TMDB returns
titles in the request language, so a localized provider title fails the
check legitimately, and the badProviderId row is keyed by id alone and
shared across playlists.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>