Rewrites the internal/api comment blocks to rule 32: task, milestone and
rule ids gone, the stories behind them restated as the constraint they
left, stale references corrected (the stream secret is wired from config,
the timezone handler already refreshes the scheduler, the Android app is
the native client, the design docs cited are not in the repo). Also
rewraps comment lines over 80 columns left by the earlier batches.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seedUser stores users as test-<name>, so the assertion compares against
alice.Username rather than the literal "alice".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/admin/requests showed "by user f7e1ec86" — the first eight characters of
the requester's id, a placeholder from the first build. The admin list now
sends each requester's username, looked up for the whole page in one query,
and the row reads "by <username>". The id stays as the fallback for a list
that comes back without names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Migration 0091 drops lidarr_config and renames the quarantine tables, types,
indexes and the history column off the Lidarr name. The Integrations Lidarr
card, the Reports "Delete via Lidarr" action, the merge and remove-track
unmonitor options, the Lidarr audit actions and error codes go, on the
server, web and Android. The README describes acquisition as it is now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Minstrel keeps its own list of what it is to get, keyed by MusicBrainz
release group. A want comes from an approved request, a new release by a
followed artist, or an album whose files went missing, and is held once the
library has a full edition of it.
- Migration 0081: release_type_profiles (Standard seeded: Album, EP,
Single, studio only), follows, follow_seen_groups and wants.
lidarr_requests becomes requests with plain *_mbid columns; approved
album and track requests move onto the wanted list, approved artist
requests become follows, and the library's album artists start out
followed. missing_reacquisitions and the retry settings go.
- internal/wanted: follows are checked against MusicBrainz discographies
daily. The first check sets a baseline, and only releases after it are
wanted unless the follow asked for what already exists. Profiles filter
by primary and secondary type, so live recordings stay out unless a
profile ticks Live.
- internal/requests (was lidarrrequests): approving puts the request on
the wanted list, and an artist request can be approved on a chosen
profile. A request completes when its want is held.
- The re-acquisition sweeper wants a missing album back instead of asking
Lidarr; searching for it is the search schedule's (#5521).
- Web: an admin Wanted page (Wanted, Missing files, Held, Following), a
follow control on artist pages, a release-type profiles card on
Integrations, "Approve on a profile" on Requests, and want state on
Missing files. The artist detail API returns the artist's MBID.
- Android: the request body sends artist_mbid, album_mbid and track_mbid.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
player: setQueueFromTracks fast-starts a single source at player-index 0
while the full queue is broadcast, so the transient currentIndexStream→0
emission clobbered the correct mediaItem with queue.value[0] (the first
track). Mini bar / playlist marker pinned to the wrong track until a
later index event (~the "passive ~30s recovery"). Track a logical-index
base so the player→queue mapping stays correct during the fill window;
also fixes the latent forward-fill auto-advance off-by-base.
lidarr #50: approving no longer fails when Lidarr is down. Approve
records the decision durably first, then best-effort adds; the
reconciler idempotently (re)sends unconfirmed adds every tick until they
stick (new additive lidarr_add_confirmed_at; AddArtist/AddAlbum map
Lidarr's "already exists" 400 → ErrAlreadyExists). No failed-state or
expiry by design — Lidarr keeps trying, operator monitors.
lidarr #51: Create() is now idempotent — a non-terminal request for the
same MBID returns the existing row instead of inserting a duplicate.
Rewrites the obsolete LidarrUnreachable_503 test to assert the durable-
approve contract; threads a client factory into NewReconciler.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A2 — migration 0030: the albums/artists art `*_source` CHECK was a
fixed provider-ID allowlist fighting the extensible coverart.Register
registry (per-provider migration churn at 0016/0018/0020; rejected
test stub providers → ~11 enricher tests failed). Relax to "NULL or
non-empty"; the registry is the source of truth. Same brittleness
class as the #433 discovery-mix CHECK.
D — lidarr Approve resolves metadata/quality profiles (JSON arrays)
before the add; the test stubs returned {"id":1} for every path, so
ListMetadataProfiles failed to unmarshal → 500/Approve errors. Make
the lidarrrequests + admin_requests stubs path-aware (arrays for
/metadataprofile, /qualityprofile).
E:
- auth: requireUser (prelude.go) emitted code "auth_required"; the
canonical code is "unauthenticated" (operator decision). Change the
code; drop the now-dead "auth_required" web error-copy key
("unauthenticated" already has copy).
- playlists_system_test wrapped the real auth.RequireUser middleware
but only injected withUser() context → 401. Like every other api
handler test, drop the middleware and rely on requireUser().
- admin_users dup-username test seeded "test-existing" (seedUser
prefixes) but POSTed "existing" → no collision; POST the prefixed
name.
- me_timezone test decoded a top-level {"code"} but the envelope is
{"error":{"code"}}; decode the nested shape.
- audit test asserted compact JSON; Postgres jsonb::text is spaced.
- put-lidarr-config tests predated the missing_defaults gate (correct
handler behavior); supply the required defaults in the bodies.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three admin-gated handlers: GET /admin/requests (list by status),
POST /admin/requests/:id/approve (with optional overrides), and
POST /admin/requests/:id/reject. testHandlers updated to inject a
real clientFn so Approve exercises Lidarr in integration tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>