GET /movies and GET /series accept a genre filter (an Aurora genre id),
but nothing exposed what those ids actually are -- genres otherwise
only ever appear embedded in a movie/series response's own genres
list. This is the resolve-by-name-first-then-filter step the frontend
needs to build real genre browsing.
No filter, no sort_by -- always alphabetical by name, same pattern as
collections/companies (genres have no categorical field or popularity/
date to sort by). page_size defaults to 50 (max 200) rather than the
20/50 used elsewhere, since genres are a small, fixed reference set
(TMDb has ~19-20 total) a client typically wants in full for a filter
dropdown, not paginated like a catalog of millions of movies.
Also fixed two stale "behind Traefik" mentions in app/main.py's module
docstring while touching this file, left over from the earlier
cPanel/host-webserver deployment change.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Completes browse/discover across all five entity types: movies, series,
people, companies, and now collections. No filter (no categorical field
like company_type exists for a collection) -- just page/page_size,
always alphabetical by name.
While adding poster_path to CollectionBriefOut for the browse listing,
found the same class of bug fixed earlier for company logo_path:
movie_service's embedded `collection` field never looked up its poster
artwork either, so it stayed null even after ingest_collection populated
one. Fixed alongside since it's the same schema field this feature was
already touching.
Also removed PageMeta from schemas/common.py -- scaffolding from early
spec work that was never actually wired into any endpoint; all five
browse endpoints shipped this session use a flat page/page_size/
total_results/total_pages shape instead.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Completes the browse/discover set across all four entity types.
Companies have no popularity or date field, so unlike movies/series/
people there's no sort_by choice -- always alphabetical by name.
Filters are company_type (validated against the enum) and country
(a plain ISO 3166-1 code comparison, nothing to validate).
build_company_summary refactored to share row-to-summary logic with
the new list path, same pattern used for movies/series/people.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Extends the browse/discover pattern already built for movies/series
to the fourth major entity type. No genre/year/status equivalent for
people -- known_for_department is the one categorical filter that
actually means something for a cast/crew list, and sort_by is just
popularity (default) or name. No invalid-filter case either: unlike
genre/status, known_for_department is a plain string compared
directly, nothing to parse or validate.
build_person_summary refactored to share row-to-summary logic with
the new list path, same pattern used for movies/series/companies.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Movies have separate /credits, /images, /videos sub-endpoints; series
only had /seasons. Adds the matching three for series, reusing the
same cast/crew/creators three-way split series detail already does
(extracted into _split_series_credits so both share it).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
GET /companies/{id} showed only the company's own info. Adds movies
and series lists (any role: production, distribution, network),
ordered by release/first-air date, read straight off the existing
movie_companies/series_companies junction rows -- no separate sync
needed since those only ever exist as a side effect of ingesting the
movie or series itself.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
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]>
The complement to /search for browsing without a query: paginated,
filterable (genre, year, status) and sortable (popularity,
release/air date, rating, title) listings. Offset-based pagination
rather than the Aurora ID cursor scheme, since sorting by
popularity/rating/date doesn't line up with creation-order cursors.
Total count is computed via a window function in the same query as
the page of results, avoiding a second round trip per request. An
invalid filter (malformed genre id, unknown status) is a 422 via a
per-service InvalidMovieFilterError/InvalidSeriesFilterError, caught
before any DB query runs.
build_movie_summary/build_series_summary refactored to share their
row-to-summary logic with the new list path, avoiding a redundant
get_by_id lookup when the row is already in hand.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Ingestion already stored movie_recommendations edges from TMDb's
recommendations list (linking only to movies already ingested into
Aurora, per the never-fabricate-a-stub rule), but nothing exposed them.
Adds the repository lookup, service assembly, and route to read them
back in ranked order.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
/people/{id}/credits only ever looked at entity_type == "movie",
silently dropping the series-level cast/crew and episode-level
guest-star Credit rows that series_ingestion.py has been writing all
along -- a person ingested via a TV show would show an empty or
movie-only filmography no matter how much TV work was actually in the
database.
Regular series credits map straight to a filmography row, same shape
as movies. Guest-star episode credits are aggregated to one row per
(series, department/job/character) with an episode_count, rather than
one row per episode -- a prolific guest actor would otherwise flood
the list with dozens of near-identical entries. Added
tv_repository.get_series_by_ids/get_episodes_by_ids (bulk, mirroring
the existing movie_repository pattern) to support it.
Co-Authored-By: Claude Sonnet 5 <[email protected]>