E frontend reconciliation (2/2): align consumers to generated bindings; svelte-check clean
Traceability Validation / Check Requirement Traces (push) Failing after 21s
🏗️ Build and Test JellyTau / Run Tests (push) Successful in 13m21s
🏗️ Build and Test JellyTau / Build Android APK (push) Failing after 2m14s

Reconcile the ~50 frontend files that consumed the old hand-written types against
the stricter generated bindings (141 -> 0 svelte-check errors):

- Nullable strictness: null-coalesce/guard at consumer sites; widen shared helpers
  (CachedImage.tag, ticksToSeconds, formatDuration, getSessionIcon, session store
  send*/transferToRemote) to accept null.
- Field-name fixes exposed by codegen: userData.played -> isPlayed; remote
  NowPlayingItem uses album (not albumName); ArtistItem id/name.
- player.ts: normalize remote NowPlayingItem -> MediaItem in mergedMedia.
- ArtistItem now serializes camelCase (PascalCase alias retained for Jellyfin
  deserialize); update its serialize test.
- Update downloads.test.ts to the bundled { request } shape; complete the
  sessions.test.ts NowPlayingItem mock.

Frontend: svelte-check 0 errors, vitest 448 passing. Backend: 387 passing.
This commit is contained in:
2026-06-20 20:49:20 +02:00
parent 76c78e2edc
commit 14e9d7e03a
21 changed files with 85 additions and 68 deletions
+8 -8
View File
@@ -456,7 +456,7 @@
<div class="space-y-2">
{#if item.people.some(p => p.type === "Director")}
<CrewLinks
people={item.people}
people={item.people ?? undefined}
roleFilter={["Director"]}
label="Directed by"
maxShow={3}
@@ -465,7 +465,7 @@
{#if item.people.some(p => p.type === "Writer")}
<CrewLinks
people={item.people}
people={item.people ?? undefined}
roleFilter={["Writer"]}
label="Written by"
maxShow={3}
@@ -474,7 +474,7 @@
{#if item.people.some(p => p.type === "Composer")}
<CrewLinks
people={item.people}
people={item.people ?? undefined}
roleFilter={["Composer"]}
label="Music by"
maxShow={2}
@@ -486,13 +486,13 @@
<!-- Genre Tags -->
{#if item.genres?.length}
<div>
<GenreTags genres={item.genres} maxShow={6} />
<GenreTags genres={item.genres ?? undefined} maxShow={6} />
</div>
{/if}
<!-- Cast Section - for Movies, Series, and Episodes -->
{#if (item.type === "Movie" || item.type === "Series" || item.type === "Episode") && item.people?.length}
<CastSection people={item.people} />
<CastSection people={item.people ?? undefined} />
{/if}
<!-- Related Items Section - for Movies and Series -->
@@ -500,8 +500,8 @@
<RelatedItemsSection
currentItemId={item.id}
itemType={item.type}
genres={item.genres}
people={item.people}
genres={item.genres ?? undefined}
people={item.people ?? undefined}
limit={12}
/>
{/if}
@@ -528,7 +528,7 @@
<RelatedItemsSection
currentItemId={item.id}
itemType="MusicAlbum"
genres={item.genres}
genres={item.genres ?? undefined}
artistIds={item.artistItems?.map(a => a.id)}
limit={12}
/>