# App Core (app/)

## OVERVIEW
FastAPI application core — config, auth, download management, providers, and business logic. Routes are in `routers/`, scrapers in `downloaders/`, models in `models/`.

## STRUCTURE
```
app/
├── config.py              # Pydantic Settings (loads .env)
├── database.py            # SQLModel engine (created at import time)
├── download_manager.py    # Async download queue (semaphore-based)
├── auth.py                # JWT + bcrypt, JSON-backed UserManager
├── providers.py           # ANIME_PROVIDERS, FILE_HOSTS registries
├── utils.py               # sanitize_filename(), is_safe_filename()
├── watchlist.py           # WatchlistManager (JSON + SQLModel hybrid)
├── episode_checker.py     # New episode detection for watchlist
├── auto_download_scheduler.py  # APScheduler periodic checks
├── sonarr_handler.py      # Sonarr webhook processing
├── favorites.py           # FavoritesManager (JSON-backed)
├── recommendation_engine.py   # Download history analysis
├── recommendations.py     # Latest releases fetcher
└── kitsu_api.py           # Kitsu anime metadata API
```

## WHERE TO LOOK

| Need | File | Notes |
|------|------|-------|
| Add env var | `config.py` | Add to Settings class, update `.env.example` |
| Add provider domain | `providers.py` | ANIME_PROVIDERS or FILE_HOSTS dict |
| Download queue logic | `download_manager.py` | Semaphore-limited parallel downloads |
| Auth/token logic | `auth.py` | UserManager, JWT create/verify |
| Filename safety | `utils.py` | ALWAYS use sanitize_filename() |

## CONVENTIONS

**Circular import avoidance**: `episode_checker.py` uses lazy init (`set_download_manager()`) — called from `main.py:47` after both modules loaded.

**Dual storage**: Some features use JSON files (favorites, users) + SQLModel tables (watchlist, sonarr mappings). JSON is legacy, SQLModel is newer.

**Module-level side effects**: `database.py` creates engine on import. `main.py` creates `download_manager` on import (line 44). `restore_completed_downloads()` runs at module level (line 108).

## ANTI-PATTERNS

- Do NOT import `download_manager` from `main.py` in other app/ modules — causes circular imports
- Do NOT use `requests` — always `httpx.AsyncClient`
- Do NOT store secrets in `config/*.json` — use `.env`
