Add per-episode breakdown to guest-star filmography credits
CI / lint (push) Canceled after 0s
CI / typecheck (push) Canceled after 0s
CI / unit-tests (push) Canceled after 0s
CI / integration-tests (push) Canceled after 0s
CI / container-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s

FilmographyCreditOut already aggregated a guest star's episode
appearances into one row per series with an episode_count, but never
exposed which episodes those were even though the individual episode
Credit rows exist in the database. Adds an `episodes` list (season/
episode number, title, air date, sorted chronologically) alongside the
existing count -- closes a known limitation tracked in docs/api.md.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
NixReaper
2026-09-05 09:19:52 -05:00
co-authored by Claude Sonnet 5
parent 20f5e82d1b
commit 606d2532c4
5 changed files with 55 additions and 13 deletions
+12
View File
@@ -18,6 +18,14 @@ class PersonSummaryOut(BaseModel):
popularity: float | None = None
class GuestEpisodeOut(BaseModel):
id: str
season_number: int
episode_number: int
title: str | None = None
air_date: date | None = None
class FilmographyCreditOut(BaseModel):
id: str
media_id: str
@@ -33,6 +41,10 @@ class FilmographyCreditOut(BaseModel):
# those are aggregated to one row per series rather than one per
# episode. None for movie credits and regular (non-guest) series roles.
episode_count: int | None = None
# The individual episodes behind episode_count, sorted by (season,
# episode) -- empty for movie credits and regular (non-guest) series
# roles, same as episode_count.
episodes: list[GuestEpisodeOut] = []
class PersonDetailOut(BaseModel):
+15
View File
@@ -14,6 +14,7 @@ from app.models.tv import Series
from app.repositories import movie_repository, person_repository, polymorphic, tv_repository
from app.schemas.person import (
FilmographyCreditOut,
GuestEpisodeOut,
PersonCreditsOut,
PersonDetailOut,
PersonSummaryOut,
@@ -156,6 +157,10 @@ async def get_person_credits(session: AsyncSession, person_aurora_id: str) -> Pe
if series is None:
continue
representative = group[0]
guest_episodes = sorted(
(episodes[c.entity_id] for c in group if c.entity_id in episodes),
key=lambda ep: (ep.season_number, ep.episode_number),
)
_bucket(department).append(
FilmographyCreditOut(
id=aurora_id("credit", str(representative.id)),
@@ -168,6 +173,16 @@ async def get_person_credits(session: AsyncSession, person_aurora_id: str) -> Pe
release_date=series.first_air_date,
poster_path=await _series_poster_path(session, series.id),
episode_count=len(group),
episodes=[
GuestEpisodeOut(
id=aurora_id("episode", str(ep.id)),
season_number=ep.season_number,
episode_number=ep.episode_number,
title=ep.title,
air_date=ep.air_date,
)
for ep in guest_episodes
],
)
)