# Catalog Backend Architecture (NexStream)

## Overview

The NexStream catalog system uses a **catalog-worker backend** as the single source of truth for catalog definitions. API keys live server-side — the APK never contains raw TMDB, Trakt, MDBList, or other provider keys.

```
Android APK (CatalogBackendRepository)
        │
        ▼
catalog-worker (Express, port 3090)
   ├── /api/catalogs       — all 92 catalog definitions
   ├── /api/catalog/:src/:id — proxied catalog items
   ├── /api/preferences/:device — per-device catalog prefs
   ├── /api/keys/:device/:provider — user API key overrides
   └── /api/health         — per-source status
        │
        ▼
Proxy Providers (server-side keys)
   ├── TMDB (api.themoviedb.org)
   ├── Trakt (api.trakt.tv)
   ├── MDBList (mdblist.com)
   ├── AniList (graphql.anilist.co)
   └── Jikan (api.jikan.moe)
```

## Key Design Decisions

1. **Backend is source of truth** — catalog definitions served from `catalog-worker/src/catalog-definitions.js`, loaded from AIOMetadata config blueprint
2. **Server-side API keys** — env vars in `.env`, never exposed to APK
3. **User key overrides** — stored hashed (SHA256), returned as `{hasOverride: true/false}`, never raw
4. **Device identity** — `Settings.Secure.ANDROID_ID` used as device fingerprint
5. **Aggressive caching** — `node-cache` with TTL per catalog definition
6. **In-flight dedup** — `CompletableDeferred` map in `CatalogBackendRepository` prevents duplicate network calls

## Android Data Layer Files

| File | Purpose |
|------|---------|
| `CatalogModels.kt` | 7 `@Serializable` data classes |
| `CatalogBackendApi.kt` | Retrofit interface (8 endpoints) |
| `CatalogBackendRepository.kt` | Cache + dedup + key masking |
| `CatalogLocalStore.kt` | Room entity + DAO for catalog prefs |
| `EncryptedKeyStore.kt` | Android Keystore encrypted API keys |
| `CatalogBackendModule.kt` | Hilt DI (provides API + DAO) |

## Catalog Manager UI

- **Settings → Catalog Manager** — embedded in Settings rail panel
- **8 category tabs**: Recommended, Movies, Shows, Anime, Kids, Genres, Streaming, Advanced
- Per-catalog toggles: enable/disable + show-in-home
- Health banner showing per-source status
- Reset to Recommended / Reset All actions

## Source Filter Chips

Home, Movies, and TV Shows pages have filter chips: `ALL | TMDB | Trakt | Anime | AIO`
- Filter persists via `PreferencesManager.homeSourceFilter`
- Movies/TV ViewModels load from `CatalogBackendRepository` first, fall back to hardcoded TMDB

## 92 Catalog Blueprint

Loaded from `aiometadata-config-2026-06-01.json` (49KB). Recommended defaults (enabled + showInHome):
- Trakt Trending Movies/Shows, Latest Digital Release, Latest Airing Shows
- TMDB Popular Movies/Shows
- Trending Kids Movies/Shows
- AniList Trending, MAL Airing Now
- Netflix/Disney+/HBO Max/Prime/Apple+/Paramount+/Hulu Latest
- Action/Comedy/Crime/Drama/Horror/Sci-Fi/Thriller/Animated
- Top Documentaries/Top Nature/Top Reality/Top Standup

Safety defaults: `includeAdult=false`, `sfw=true`, `hideUnreleasedDigital=true`, `language=en-US`
