Skip to content

Bridge 2d-1: podcasts for players from 2.2.0 - #169

Merged
KodeStar merged 6 commits into
mainfrom
feat/bridge-2d-1
Oct 23, 2026
Merged

KodeStar merged 6 commits into
mainfrom
feat/bridge-2d-1

Conversation

@KodeStar

@KodeStar KodeStar commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Bridge Phase 2d-1, server side: players from 2.2.0 see podcast libraries.

What

  • auth.PodcastPlayerMinVersion = "2.2.0": the first player with podcast views. 2.1.x and older store builds, the Bridge, the manager, API keys and headerless clients stay hidden. Headerless ?token= media follows the token's stored client.
  • Data-loss fix that this makes reachable: a whole-list replace (PUT /me/queue, PUT /me/collections/{id}/items) from a client that cannot see podcasts now keeps the user's podcast-library entries it cannot see (catalog.GatedScopes, orderedList.replace). Each kept entry stays after the entry it followed; it falls back to stored order at the end when the new order would shuffle them, and counts toward the cap (oldest kept evicted). Entries hidden by a revoked share or an unfollowed private show are still deleted. A podcast-seeing caller's replace is unchanged.
  • No route, field or migration.

Tests

  • TestPodcastGate sweeps the minimum over "" and 2.2.0 with boundary rows; TestPodcastPlayerMinVersionShipped pins the value; gate matrix rows for released/newer (allowed) and 2.1.9 (denied); the headerless stored-client stream in the matrix.
  • lists_gate_test.go (catalog) and TestPodcastListReplaceKeepsEpisodesForOldPlayers (api), allowed and denied for queue and collection items.
  • Gate: build, vet, go test -race ./..., golangci-lint (0 issues). internal/backup TestStartRunsAtOnce flaked once under the full race suite: it predates this branch.

Verification (live, real server + Bridge + served /web 2.2.0)

  • Fresh tokens sending 2.1.0, 2.1.9 or no header see books only; 2.2.0 and the console see podcasts.
  • Two episodes queued from the 2.2.0 web player survive a reordered visible-only PUT /me/queue sent as AudioSilo/2.1.0 (ios); a 2.2.0 PUT leaving them out removes them.

Release: web image 2.2.0 first, then the server (CROSS-REPO §11).

Pairs with KodeStar/audiosilo-frontend#119, KodeStar/audiosilo-docs#160 and KodeStar/audiosilo#82.

Set auth.PodcastPlayerMinVersion to 2.2.0, the first player with podcast
views. Released 2.1.x and older players stay hidden. Tests pin the shipped
minimum, add released/newer/just-below rows to the client gate matrix, and
check a released player's stored client lets a headerless ?token= stream
through the gate.
Fold the stored-client stream check into the gate matrix's headerless block and the shipped-minimum boundaries into TestPodcastGate; the shipped test now only pins the value.
TestPodcastGate tests the shipped minimum itself and refuses other apps at a passing version.
A whole-list replace (PUT /me/queue, PUT /me/collections/{id}/items) from
a client the podcast gate hides podcasts from deleted the user's episodes,
since they were outside that caller's scopes. catalog.GatedScopes gives
the podcast scopes the gate alone hides; SetQueue and SetCollectionItems
take them as keep, and orderedList.replace keeps those rows after the
listed entry each followed (appended in stored order when the new order
would shuffle them), counting toward the cap like an add's hidden rows.
Revoked shares and podcast-seeing callers keep the delete rule.
@KodeStar
KodeStar merged commit 4422d9b into main Oct 23, 2026
3 checks passed
@KodeStar
KodeStar deleted the feat/bridge-2d-1 branch October 23, 2026 07:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant