"""Pure domain models shared across application boundaries.""" from dataclasses import dataclass from enum import StrEnum @dataclass(frozen=True) class Track: """A Spotify track expressed without transport-specific data.""" id: str uri: str title: str artists: tuple[str, ...] album_name: str album_art_url: str | None external_url: str | None @dataclass(frozen=True) class TrackCandidate: """A title and artist pair proposed for Spotify resolution.""" title: str artist: str class Familiarity(StrEnum): """How strongly a request should favor known or unknown music.""" FAMILIAR = "familiar" MIX = "mix" NEW = "new" @dataclass(frozen=True) class Intent: """Structured interpretation and candidate set for a discovery query.""" mood: tuple[str, ...] activity: str | None era: tuple[str, ...] languages: tuple[str, ...] genres: tuple[str, ...] familiarity: Familiarity is_refinement: bool intent_summary: str candidates: tuple[TrackCandidate, ...] @dataclass(frozen=True) class RerankSelection: """One grounded track selected by the recommender.""" track_id: str justification: str @dataclass(frozen=True) class TasteProfile: """Bounded Spotify taste signals collected for one session.""" short_term_artists: tuple[str, ...] long_term_artists: tuple[str, ...] short_term_tracks: tuple[Track, ...] long_term_tracks: tuple[Track, ...] saved_tracks: tuple[Track, ...] @dataclass(frozen=True) class CompressedTasteProfile: """Prompt-ready taste text plus exact known Spotify track identifiers.""" text: str known_track_ids: frozenset[str] @dataclass(frozen=True) class CreatedPlaylist: """The application-owned result of creating a Spotify playlist.""" id: str url: str