Update Conductarr TV contracts and ratings reads
This commit is contained in:
parent
9dd321f07e
commit
f53defad90
13 changed files with 600 additions and 36 deletions
|
|
@ -1,10 +1,10 @@
|
|||
# Conductarr TV client
|
||||
|
||||
A UI-free JVM module for the TV operations in the [approved TV spec](https://pages.justinvisser.org/wolfskin/tv-spec), sections 3 and 8. The Android app depends on this module; no screen, navigation, login flow or production service is changed.
|
||||
A UI-free JVM module for the TV operations in the [approved TV spec](https://pages.justinvisser.org/wolfskin/tv-spec), sections 3 and 8. The Android app supplies the currently selected Jellyfin login through its person-scoped `ConductarrSession`.
|
||||
|
||||
## Pinned contract and generator decision
|
||||
|
||||
`openapi/openapi.json` is the unmodified OpenAPI 3.1.0 document from Conductarr commit `481492d3a8a0651a89901de548cd511218c0562e`. `openapi/commit.sha` records the source. It was read with `git show <commit>:openapi.json` from the Conductarr clone, not downloaded from a running service.
|
||||
`openapi/openapi.json` is the unmodified OpenAPI 3.1.0 document from Conductarr commit `7e8f3f0a1c9a88d67b2a9518c1161db84ade531a`. `openapi/commit.sha` records the source. It was read with `git show <commit>:openapi.json` from the Conductarr clone, not downloaded from a running service.
|
||||
|
||||
The approved fallback is used: checked-in, maintained kotlinx.serialization data classes and a thin typed TV API, rather than build-time generation.
|
||||
|
||||
|
|
@ -18,8 +18,8 @@ Thus the generator does **not** handle every construct in this pinned document.
|
|||
|
||||
`ContractTest` checks:
|
||||
|
||||
- All 20 TV method/path pairs against the pinned paths, including response and mutation body schemas.
|
||||
- All 68 maintained schemas through their actual serialization descriptors: fields, references, primitive widths, collections, maps, enum wire values and requiredness. Read-only `$schema` metadata is intentionally ignored. Optional scalar properties use nullable Kotlin fields to represent absence; encoding omits them.
|
||||
- All 22 TV method/path pairs against the pinned paths, including response and mutation body schemas.
|
||||
- All 70 maintained schemas through their actual serialization descriptors: fields, references, primitive widths, collections, maps, enum wire values and requiredness. Read-only `$schema` metadata is intentionally ignored. Optional scalar properties use nullable Kotlin fields to represent absence; encoding omits them.
|
||||
- A separately reviewed schema snapshot, `src/test/resources/model-contracts.json`, so changes to formats, limits, defaults or other schema constraints also require explicit review. Models preserve those wire shapes; Conductarr remains responsible for business validation and authority.
|
||||
|
||||
When updating the pin, update the models and reviewed schema snapshot together. Do not regenerate the Seerr client into this module or substitute a running server's schema.
|
||||
|
|
@ -28,7 +28,7 @@ When updating the pin, update the models and reviewed schema snapshot together.
|
|||
|
||||
Create a `ConductarrClient(baseUrl, jellyfinToken, cache)` for the selected person's Jellyfin session. The caller supplies the token; the client sends exactly `Authorization: MediaBrowser Token="<token>"`. The token must match the pinned contract's 32-hex Jellyfin access-token shape. HTTPS is required except for loopback fake servers. Base URL credentials, query strings and fragments are rejected. A path prefix is preserved.
|
||||
|
||||
`TvRoutes` provides typed calls for operator, profiles, feed, dismissals, catalogue options/discovery/title/cast/related/enrichment/seasons, performers/filmography, activity/readiness, requests and library audiences. Request actors cannot be supplied: only the authenticated operator establishes the actor. The request body's requester selects the beneficiary.
|
||||
`TvRoutes` provides typed calls for operator, profiles, feed, dismissals, catalogue options/discovery/title/cast/related/enrichment/ratings/display/seasons, performers/filmography, activity/readiness, requests and library audiences. Request actors cannot be supplied: only the authenticated operator establishes the actor. The request body's requester selects the beneficiary.
|
||||
|
||||
`client.read(call, trigger)` is a cold `Flow<ReadResult<T>>`: collect it once per screen-level read. It emits saved data before starting network work, then a revalidation result when due. `ReadResult.Failure.saved` retains LKG on transport, HTTP and decoding failure. A 401 returns `NeedsSignIn` **without** fallback, invalidates that client's identity-scoped saved data, and prevents further calls on that instance. Create a new instance after sign-in/person switch. No Seerr fallback exists.
|
||||
|
||||
|
|
@ -49,9 +49,9 @@ Cache keys partition by normalized server URL, credential digest, endpoint, path
|
|||
| Feed | Server `expires_at`; conditional ETag revalidation |
|
||||
| Catalogue options | `FOREGROUND` refreshes |
|
||||
| Discovery pages | 30 minutes per parameterized lane/page |
|
||||
| Enrichment ratings | 6 hours; 300 entries per movie/TV group; 404 means saved absence, failures never overwrite LKG |
|
||||
| Title, cast, related, performer, filmography, dismissals, readiness | `OPEN` refreshes |
|
||||
| Seasons | `OPEN` on season focus; retained per season, 300 entries |
|
||||
| Ratings-only read | 6 hours; 300 entries per movie/TV group; 404 means saved absence, failures never overwrite LKG |
|
||||
| Title, cast, related, enrichment, display, performer, filmography, dismissals, readiness | `OPEN` refreshes |
|
||||
| Seasons | 6 hours for episode scores; `OPEN` refreshes on title-season focus; retained per season, 300 entries |
|
||||
| Activity | 30 seconds for caller-driven `POLL`, or `FOREGROUND` |
|
||||
| Title requests and request mutations | No cache |
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue