# Stalker Portal Architecture This document describes the Stalker portal implementation in IPTVnator and where each feature is integrated. ## Related Docs - [Stalker Portal EPG Architecture](./stalker-epg.md) - [Playlist Backup/Restore Architecture](./playlist-backup-restore.md) - [Portal Detail Navigation](./portal-detail-navigation.md) - [Embedded Inline Playback](./embedded-inline-playback.md) - [Remote Control Architecture](./remote-control.md) - [Download Manager](./download-manager.md) - [Category Management](./category-management.md) - [Stalker Store API Baseline](./stalker-store-api-baseline.md) ## Scope Stalker support covers: - Live TV (`itv`) - VOD (`vod`) - Series (`series`) - VOD-as-series flows (`is_series=1` and embedded `series[]`) - Favorites and recently viewed collections - Search - External player playback (shared Xtream player infrastructure) - Remote control for live ITV navigation ## Routing Structure Primary route tree lives in `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-feature.routes.ts`. - `/stalker/:id/vod` - `/stalker/:id/series` - `/stalker/:id/itv` - `/stalker/:id/favorites` - `/stalker/:id/recent` - `/stalker/:id/search` - `/stalker/:id/downloads` (shared downloads module from Xtream UI) ## Runtime Architecture 1. Angular Stalker screens call methods/resources in `StalkerStore`. 2. `StalkerStore` builds request params based on selected content type and current view state. 3. Requests go through `DataService.sendIpcEvent(STALKER_REQUEST, ...)` or `StalkerSessionService` (full portal auth). 4. Electron main process handles `STALKER_REQUEST` in `/Users/4gray/Code/iptvnator/apps/electron-backend/src/app/events/stalker.events.ts`. 5. Axios calls Stalker `load.php` API with required headers/cookies and returns normalized payloads to renderer. ## Main UI Components - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-main-container.component.ts` - Category + content layout for `vod` and `series` - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-live-stream-layout/stalker-live-stream-layout.component.ts` - ITV live playback, channel navigation, EPG panel integration - `/Users/4gray/Code/iptvnator/libs/ui/components/src/lib/stalker-series-view/stalker-series-view.component.ts` - Season/episode UI for all Stalker series modes - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-favorites/stalker-favorites.component.ts` - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/recently-viewed/recently-viewed.component.ts` - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-search/stalker-search.component.ts` ## Store and Data Flow Stalker store is now feature-composed: - Facade: `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/stalker.store.ts` - Feature slices: `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/stores/features/*` - Shared helpers: `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/*` Important store responsibilities: - Selected content/category/item state - Category and paginated content resources - ITV channel list + pagination - Regular series seasons resource - VOD-series (`is_series=1`) seasons + episodes resources - Playback link creation (`create_link` flow) - Favorites and recently viewed persistence helpers Internal structure to preserve: - `stalker.store.ts` stays as the thin facade that composes feature slices. - Cross-slice contracts live in `stores/stalker-store.contracts.ts` so feature dependencies are declared instead of repeated `unknown` casts. - Request execution is centralized in `stores/utils/stalker-request.utils.ts` for both authenticated full-portal calls and simple IPC-backed requests. - Playback link resolution and Stalker collection persistence live in dedicated `stores/utils/` helpers so player/favorites/recent slices stay focused on orchestration. - Category/content resources stay internal to the store slices. Feature consumers should read `getCategoryResource()` and `getPaginatedContent()`, which now always return arrays, and pair them with `isCategoryResourceFailed()` / `isPaginatedContentFailed()` for explicit error handling. Failure-handling rule: - Failed category or content requests must degrade into empty/error UI state, not `undefined` collections or renderer exceptions. The workspace Stalker context panel and live layout rely on this guarantee. ## VOD/Series Modes Stalker has multiple real-world data shapes. The current implementation supports all three: 1. Regular Series (`/series`): - Seasons come from API resource (`serialSeasonsResource`). - Episodes are derived from season payload. 2. VOD with Embedded `series[]`: - Item is opened under VOD, but already contains episodes. - `StalkerSeriesViewComponent` creates a pseudo-season and renders episodes directly. 3. VOD with `is_series=1` (Ministra plugin behavior): - Treated as series flow from VOD context. - Seasons are fetched lazily. - Episodes are fetched on season select. - Uses unique generated tracking IDs for episode playback position compatibility. Core decision logic and normalization are centralized in: - `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/stalker-vod.utils.ts` - `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/models/*.ts` ## Favorites and Recently Viewed Current implementation is shared via Stalker-specific helpers: - `createPortalCollectionResource(...)` generic collection loader - `createPortalFavoritesResource(...)` favorites wrapper - `createStalkerDetailViewState(...)` unified "open detail" decision - `toggleStalkerVodFavorite(...)` shared add/remove behavior - `normalizeStalkerEntityId(...)` and `normalizeStalkerEntityIdAsNumber(...)` for stable ID matching - `matchesFavoriteById(...)` for cross-shape favorite matching Where this is used: - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-favorites/stalker-favorites.component.ts` - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/recently-viewed/recently-viewed.component.ts` - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-search/stalker-search.component.ts` - `/Users/4gray/Code/iptvnator/libs/ui/components/src/lib/stalker-favorites-button/stalker-favorites-button.component.ts` Navigation rule to preserve: - Stalker favorites, recently viewed, and search stay in their current screen and open inline detail state. - They should not redirect into a canonical content/category/item route because Stalker detail rendering is currently store-state/inline driven, not route driven. - VOD-backed series favorites can be displayed in series collections, but detail opening must preserve their VOD origin: `is_series=1` favorites set the selected content type to `vod` so the lazy Ministra season/episode resources run, and embedded `series[]` favorites render through the embedded VOD-series branch. - See [Portal Detail Navigation](./portal-detail-navigation.md). ## Backup and Restore Versioned playlist backups include Stalker connection metadata plus playlist- scoped favorites/recent snapshots. Exported fields: - `portalUrl` - `macAddress` - `isFullStalkerPortal` - optional `username` / `password` - optional request headers (`userAgent`, `referrer`, `origin`) - full-portal serial/device/signature fields when present - favorites and recently viewed collections Excluded fields: - `stalkerToken` - `stalkerAccountInfo` - playback positions in backup v1 Import rule: - backups restore the saved portal definition and replace the stored favorites/recent state for the matched playlist - a fresh handshake must happen after import for full-portal sessions; imported backups never trust a serialized token ## Remote Control Integration Stalker live remote control is implemented in: - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-live-stream-layout/stalker-live-stream-layout.component.ts` Supported today: - Channel up/down - Numeric channel selection (list-position based) - Status publish for remote UI (portal/channel/current program) See full backend and web-remote flow in [Remote Control Architecture](./remote-control.md). ## EPG Integration Stalker ITV now splits EPG usage: - active channel panel: bulk `get_epg_info` cached once per playlist and rendered through shared `app-epg-list` - channel row preview: no pre-playback network requests; previews are derived from cached bulk EPG only after the first active-channel fetch succeeds - active panel fallback: `get_short_epg` when bulk EPG is missing or unsupported Full details are documented in [Stalker Portal EPG Architecture](./stalker-epg.md). ## Shared/Reusable Infrastructure Stalker reuses some Xtream UI infrastructure deliberately: - Category content rendering route uses Xtream category content component - Season container for episodes uses shared Xtream season UI component - Playback position handling for series episodes reuses Xtream store position mechanisms - Downloads route reuses shared downloads feature This reduces duplicate UI logic across portal types and keeps compatibility behavior aligned. ## Regression Coverage Focused regression tests for Stalker VOD mode branching live in: - `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/stalker-vod.utils.spec.ts` Covered scenarios include: - Embedded `series[]` opens series view state - `is_series=1` opens lazy series state - VOD-backed series favorites keep VOD-series loading semantics when opened from favorites/global favorites - Favorite toggle helper path invokes the expected add/remove flow