Skip to content

Enrich catalogue detail pages (games, books, movies/series, anime) - #141

Merged
Logan2234 merged 9 commits into
mainfrom
feat/igdb-extra-fields
Aug 27, 2026
Merged

Enrich catalogue detail pages (games, books, movies/series, anime)#141
Logan2234 merged 9 commits into
mainfrom
feat/igdb-extra-fields

Conversation

@Logan2234

Copy link
Copy Markdown
Owner

Summary

Adds a batch of provider fields that were fetched but unused (or not fetched at all) across every catalogue detail page, following a cross-provider inventory. One commit per domain:

  • Games (IGDB): franchise, age ratings, trailer (in the existing screenshot lightbox), multiplayer modes, vote counts, clickable IGDB rating. Along the way, fixes two pre-existing lightbox bugs (fragile hero button centering, video unclickable behind a positioned sibling).
  • Books (Open Library): ISBN, series, language, edition count, first sentence, "read online" link, Goodreads/LibraryThing/Amazon links, clickable rating. Fixes a data-quality bug where edition-scoped fields (language, first sentence, external links) were read off /search.json's aggregated-across-editions work document — now resolved via lang=+nested editions.*, plus a per-edition /books/{OLID}.json follow-up call. Links point at the concrete edition, not the abstract work page.
  • Movies/series (TMDB): native rating, tagline, director/creator, trailer, official content rating (FR→US fallback). Also introduces MediaItemTranslation, a minimal per-locale cache (title/overview/genres) so a French user no longer sees a stale English title/overview on an already-cached title — kept in sync with the library list and refreshed on the same cycle as the rest of the cached item.
  • Anime (AniList): voice actor ↔ character pairing in Distribution (with a split cast photo and a clickable voice-actor modal — bio, birth year/hometown, carousel of anime they've voiced in), credited director, trailer, studios, format/season, related titles, external links, non-spoiler tags, and the source's own siteUrl for the rating link. Also guards the new translation cache against AniList, which has no localization support.

Test plan

  • pnpm build:package
  • pnpm --filter @loomkeep/api exec tsc --noEmit
  • pnpm --filter @loomkeep/web check (0 errors)
  • Full API test suite (816 tests) — new coverage for IGDB/Open Library/TMDB/AniList getExtras, the translation cache, and the AniList getPerson staff lookup
  • AniList GraphQL queries verified against the live API directly (caught and fixed a tags(sort:) 400 before merge)
  • Manual pass in the browser across all four detail pages (games/books already verified live during the session; movies/series and anime not yet manually verified — no dev login available in this environment)

🤖 Generated with Claude Code

Logan2234 and others added 9 commits August 26, 2026 23:36
Add franchise name, age ratings, trailer, multiplayer modes and vote
counts to the game detail page, make the IGDB rating clickable, and
animate the collapsible "Histoire" section. The trailer now plays as
an extra slide inside the existing screenshot lightbox rather than a
separate modal, fixing two related bugs along the way: the play
button's fragile centering (inset-0 + margin:auto silently breaks
without inset-0) and the video being unclickable (a non-positioned
element always paints under its positioned siblings, so the
transparent lightbox backdrop button was swallowing clicks meant for
the player).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add ISBN, series, language, edition count, first sentence, a
"read online" link (public Internet Archive scans only) and
Goodreads/LibraryThing/Amazon links to the book detail page, and make
the Open Library rating clickable.

These are all edition-scoped fields, but Open Library's /search.json
work document aggregates them across every edition/translation ever
catalogued with no way to tell which array entry belongs to which
edition — picking e.g. language[0] surfaced an unrelated translation's
language at random. Fixed by having /search.json nest one concrete,
language-matched edition via `lang=`+`editions.*` (native to the API,
no extra request), then following up with a single /books/{OLID}.json
call for the fields that nested doc doesn't carry (series, first
sentence, cross-reference ids, an edition-specific description
override). The book's own page and the rating both link to that
edition's /books/ page instead of the abstract /works/ page.

`lang` now threads from the client's active UI locale through search
and the detail page, so search results and the description prefer an
edition in the reader's own language when Open Library has one.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds native rating (with link), tagline, director/creator, trailer and
official content rating to the media detail page, plumbing `lang` through
search/detail/extras to match the books/games locale work.

Also fixes a real bug this surfaced: the media detail page serves from the
DB cache once an item is referenced, so a cached English title/overview
stayed English forever even when browsing in French. Introduces
MediaItemTranslation, a minimal per-locale cache (title/overview/genres)
layered on the base MediaItem row and refreshed on the same sync cycle —
kept consistent between the library list and the detail page. The admin
cache page now shows how many locales are cached per item.
Adds Japanese voice actor pairing (replacing the character's plain
MAIN/SUPPORTING role tag), credited director(s) via staff, trailer,
main studio(s), release format/season, related titles (sequels/prequels,
filtered to anime-type nodes), external links and non-spoiler tags —
mirroring the TMDB extras added earlier this session. Also points the
AniList rating link at the source's own siteUrl instead of a hand-built
URL.

Also guards MediaItemService.translationFor() against AniList: it has no
localization support, so a "French" fetch would just duplicate the English
base row — skip it instead of wasting a live call and a DB row.
AniList's schema doesn't accept `sort` on Media.tags (confirmed against
the live API) — the getExtras call for anime was failing outright. Fetch
`rank` instead and sort client-side before filtering out spoiler tags.
Distribution still showed the character's name with the voice actor
tucked into the role subtext — backwards from the intent (and from
TMDB's actor→character pairing). Swap name/photo to the Japanese voice
actor when one is credited, character name as the role underneath;
falls back to the character alone otherwise.
Distribution now shows both faces on anime cards — the Japanese voice
actor on the left, the character on the right — instead of just one
photo, and clicking a voice actor opens the same cast modal TMDB actors
already get: bio, birth year/hometown, and a carousel of the anime
they've voiced characters in (AniList's `characterMedia`, filtered to
anime-type credits). AniList bios use a light markdown dialect, so strip
it before display instead of showing raw `**bold**`/`[link](url)` syntax.
@github-actions github-actions Bot added documentation Improvements or additions to documentation api apps/api (NestJS) web apps/web (SvelteKit) shared packages/shared labels Aug 27, 2026
@Logan2234
Logan2234 merged commit d13354c into main Aug 27, 2026
15 of 16 checks passed
@Logan2234
Logan2234 deleted the feat/igdb-extra-fields branch August 27, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api apps/api (NestJS) documentation Improvements or additions to documentation shared packages/shared web apps/web (SvelteKit)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant