# Models (app/models/) ## OVERVIEW SQLModel/Pydantic models combining database tables (SQLModel) and API schemas (Pydantic). Each domain has a Base → Table → Schema pattern. ## STRUCTURE ``` models/ ├── __init__.py # Core: DownloadStatus, DownloadTask, DownloadRequest, AnimeMetadata, AnimeSearchResult ├── auth.py # User, UserCreate, UserLogin, Token, UserTable, UserInDB ├── watchlist.py # WatchlistItem, WatchlistSettings, AutoDownloadResult (+ Table variants) ├── sonarr.py # SonarrWebhookPayload, SonarrMapping, SonarrConfig, SonarrSeries (+ Table variants) ├── favorites.py # Favorites-related models └── settings.py # AppSettings, AppSettingsUpdate (+ Table variant) ``` ## WHERE TO LOOK | Need | File | Key Classes | |------|------|-------------| | Download task | `__init__.py` | `DownloadTask`, `DownloadStatus`, `DownloadRequest` | | Anime metadata | `__init__.py` | `AnimeMetadata`, `AnimeSearchResult` | | User/auth | `auth.py` | `User`, `UserCreate`, `UserLogin`, `Token`, `UserTable` | | Watchlist | `watchlist.py` | `WatchlistItem`, `WatchlistSettings`, `WatchlistItemTable` | | Sonarr | `sonarr.py` | `SonarrWebhookPayload`, `SonarrMapping`, `SonarrConfig`, `SonarrSeries` | | App settings | `settings.py` | `AppSettings`, `AppSettingsUpdate` | ## CONVENTIONS **Triple-class pattern** (for DB-backed models): 1. `*Base` — Pydantic base with shared fields 2. `*Table` — SQLModel table class (`__tablename__`, `id`, FK columns) 3. Final class — API schema (inherits from both, adds Config) **Enums**: PascalCase class, UPPER_SNAKE values (e.g., `DownloadStatus.PENDING`, `WatchlistStatus.ACTIVE`). **JSON columns**: Stored as JSON strings in SQLite, accessed via `@property` methods (e.g., `WatchlistItemTable.genres` parses `genres_json`). **Config classes**: Each API schema has `class Config: from_attributes = True` for ORM mode. ## ANTI-PATTERNS - Do NOT add new fields to `*Base` without updating corresponding `*Table` and schema classes - Do NOT use `Optional` for required API fields — use Pydantic defaults - Empty `except:` in `settings.py:22` — known tech debt