Wire real Conductarr data into Wolfskin TV #36
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fm/tv-conductarr-wiring"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Outcome
Wire the default Wolfskin TV surfaces to Conductarr using the currently selected Jellyfin user's existing access token. Debug fixtures remain explicit opt-in; this is not a fixture-only TV build.
AI-assisted (fork-internal)
Refs: TV specification, especially §§3.1, 3.3–3.6, 7.8–7.9 and 8; production seams, configuration and manual smoke. The server's dedicated-hostname TV authority remains a separate deployment: Conductarr TV operation authorization.
Seams wired
Authentication, cache and configuration
BuildConfig.CONDUCTARR_BASE_URL = https://wolfskin-tv.justinvisser.org.Authorization: MediaBrowser Token="<token>"; no second credential store, API key or cookie. Person/token/server/endpoint changes replace the client and in-memory providers.7e8f3f0a1c9a88d67b2a9518c1161db84ade531a; expose exactly the 22 TV operations, including ratings and display, with ETag/If-None-Match/304 reuse.Test inventory
Loopback fake HTTP only; no live Conductarr/Jellyfin or device access:
ConductarrSessionTest: exact credential header, person/client replacement, disk separation even for equal tokens, offline reopen, 401 and retry.ConductarrProjectionTest: Home/Discover/services/dismissals/activity projections, actor-safe uncertain requests, ratings dwell supplier and conditional reads.ConductarrTitlePagesTest: no invented playback, saved title facts, cross-season episode votes, 401 rating removal and source/vote boundaries.ConductarrSurfaceTest,ConductarrHomeSurfaceTest,ConductarrTitleSurfaceTest: native shipped surfaces from real HTTP-shaped data, request-on-behalf receipt, saved Requests, and sign-out recovery. Fake/decoded one-pixel art keeps these transport smoke captures off external image hosts; the existing fixture capture suites retain full approved artwork.TitleReadFacadeTest: reject an unrelated TMDB identity or media type before granting catalogue playback; existing held title/person/playback regressions remain.WolfskinArtworkTest: actual Coil image decoding against Jellyfin, another hostname and a same-host/different-port server; an authenticated upstream parent cannot leak Authorization, and Jellyfin still receives its credential.ConductarrAudienceRecoveryTest: operator 200 plus audiences 503 without saved data, empty audience success, retained Jellyfin destination mappings and successful foreground recovery without replacing the client.make testalso selects the client's contract/route/cache tests and loopback socket smoke.Upstream files changed
Within the fork's permitted upstream touch points:
app/build.gradle.kts: base-URL BuildConfig default and fake-server test dependency.app/src/main/java/com/github/damontecres/wholphin/preferences/AppPreference.kt: Advanced URL override and debug fixture switch.Other production changes are in fork-owned
app/src/wolfskin, debug/default flavor resources,wolfskin-design,conductarr-clientand existing fork tests/docs.Not done / manual gate
docker/README.mdcovers person switching, real title/person traversal, Saved/401 recovery and an uncertain Shared-on-behalf request with one POST.Review blockers fixed
Final verification
Run once each on final merged head
ec32346c71f6fcbb966653959ab31acbff3db399; no source changes after the gates. The artwork fixture saves and restores Coil's process singleton, including when earlier screen tests initialized it.make testmake apk-debugThe loopback client smoke observed profile data, disk reopen, ETag 304 reuse and
HTTP 503 retaining the last good profile in three requests. Packaged branding
checks passed for all four APKs, inspecting 1016 string/plural/array resources
per APK with legal attribution preserved.
Native Home, saved Requests and Shared-on-behalf receipt captures were opened
and visually inspected. A measured Home diagnosis established Jellyfin-only
publication at 3.577 s and real catalogue Ready at 4.657 s; the apparent stall
was Robolectric Main-loop scheduling. Home retry authentication and disk writes
were also moved off the first-paint path, and initial-loading Discover read-ahead
no longer warms a fallback hero's ratings before the focused-card dwell.
Builds and captures are preserved for firstmate under
/root/.treehouse/firstmate-7bab20/2/firstmate/data/tv-conductarr-wiring/(
apk-build-b/,captures/, andhome-layer-diagnostic.txt). Build B contains the reviewed fixes and its checksum manifest. The olderapk/bundle is superseded and explicitly marked DO NOT INSTALL.Code review (Claude) of head
09f1d72f30f6035910a7adf7749f52680a2c2d9f: BLOCK, two small fixes.Checked by reading the code and tests (no builds, no live calls): token handling, person identity and cache isolation, request safety, failure modes, contract pin, regressions, smoke note.
Blocking
@AuthOkHttpClient(MainActivity.kt:103-105,260,AppModule.kt:101-122). That client addsAuthorization: MediaBrowser Client=..., Token="<jellyfin token>"to every request with no host check. This PR makeshttps://image.tmdb.org/...(ConductarrProjection.catalogueImage) and Conductarr-suppliedposter_url/profile_urlthe default artwork source, so the token goes to those hosts. Fix: inWolfskinImages.loader, stripAuthorizationunless the host is the Jellyfin server; add a two-host MockWebServer test.ConductarrProvider.audiences()returnsemptyList()on failure;WolfskinApp.loadHouseholdassigns it tolibraries.audiences;LibraryReadFacade.destination()then returns null for every library, so Home library rows and the Movies/Shows/Anime grids are empty (no automatic retry). Spec 3.x/7.9 says name rule until audiences are known and Jellyfin must always work. Fix: keepaudiences = nullwhen the read failed; add a test (operator 200, audiences 503, no LKG).Verified OK: exact
Authorization: MediaBrowser Token="<token>"only, no redirects followed, HTTPS-or-loopback, 32-hex token, no logging, noBackup disk store; person switch rebuilds client and provider, cache keyed by person + base URL + token (test proves A is never served to B); actor is the token's operator, requester limited tocapabilities.requesters, dismissals use the operator profile;post-request-intentlooks up receipts first and never resubmits an uncertain outcome (test: GET, POST, GET, one POST); 401 flips every screen to signed-out; timeouts 3/5/8 s; Jellyfin Home rows publish without awaiting Conductarr; route allowlist is exactly the 22 operations and the contract test pins operationIds; pinned openapi equals Conductarrmain(PR 921 merge9efd508f) apart from description/security text; no existing test deleted or weakened; upstream edits onlyapp/build.gradle.ktsandAppPreference.kt.Non-blocking: request ledger ignores seasons and RETIRED receipts skip the POST;
RetryPeopleresets the ledger; failed person switch leaves a null identity; extra sequential Jellyfin calls and repeated Home reloads; Home person guard relies on name==requester after a 401; orphan LKG files after sign-out; smoke note should say the override host must be in the server'sallowed_hosts.Full report:
/root/.treehouse/firstmate-7bab20/2/firstmate/data/review-wolfskin-wiring/report.md.