feat: add recommendation domain foundations

This commit is contained in:
Justin Visser 2026-08-10 11:59:02 +02:00
parent fad7884c42
commit 5c3ba8d6ec
10 changed files with 446 additions and 0 deletions

View file

@ -1,6 +1,7 @@
"""Pure domain models shared across application boundaries."""
from dataclasses import dataclass
from enum import StrEnum
@dataclass(frozen=True)
@ -14,3 +15,69 @@ class Track:
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