"""User-settings request/response schemas. Enums are enforced at the API boundary (Pydantic ``Literal`` → 422 on bad input), so the service can trust the values it receives. """ from typing import Literal from pydantic import BaseModel, model_validator Theme = Literal["system", "light", "dark"] # Playback quality preference. ``original`` = no transcode; the lower tiers are # consumed by the (upcoming) transcoding pipeline. StreamQuality = Literal["original", "high", "medium", "low"] ScrobbleProvider = Literal["lastfm", "listenbrainz"] class SettingsOut(BaseModel): theme: Theme stream_quality: StreamQuality class SettingsUpdate(BaseModel): """Partial update — omitted fields keep their current value.""" theme: Theme | None = None stream_quality: StreamQuality | None = None class ScrobblingOut(BaseModel): enabled: bool provider: ScrobbleProvider | None username: str | None # Whether a session key is stored. The key itself is never returned. configured: bool class ScrobblingUpdate(BaseModel): enabled: bool = False provider: ScrobbleProvider | None = None username: str | None = None # Write-only scrobbler session key / user token. Omit to keep the stored one. session_key: str | None = None @model_validator(mode="after") def _provider_required_when_enabled(self) -> ScrobblingUpdate: if self.enabled and self.provider is None: raise ValueError("provider is required when scrobbling is enabled") return self