11 Commits

Author SHA1 Message Date
bvandeusen 4fca0e66cb fix(listenbrainz): similarity hits Labs API, not the 404'ing main API
Root cause of zero LB recommendations (every similar-recordings AND
similar-artists call returned HTTP 404, worker logs):

- Wrong host/path: client called
  api.listenbrainz.org/1/explore/similar-{recordings,artists}/{mbid}.
  /explore/... is a WEBSITE route, not an API endpoint — it 308s then
  404s. Similarity datasets live on the separate Labs API.
- Invalid algorithm: the hardcoded
  session_…_session_30_…_limit_100_filter_True_… is not a permitted
  Labs enum member (400s) regardless of host.

Verified against the live Labs API:
  GET labs.api.listenbrainz.org/similar-recordings/json
      ?recording_mbids=<mbid>&algorithm=<algo>
  GET labs.api.listenbrainz.org/similar-artists/json
      ?artist_mbids=<mbid>&algorithm=<algo>
  algorithm=session_based_days_9000_session_300_contribution_5_threshold_15_limit_50_skip_30
  → 200 for both. Response field names (recording_mbid/artist_mbid/
  name/score) already match the existing structs — parsing unchanged.

- Add defaultLabsBaseURL + Client.LabsBaseURL (separate from the main
  BaseURL; scrobble submission still uses api.listenbrainz.org).
- Drop the count/limit query param — result size is encoded in the
  algorithm name (limit_50); caller still applies its own top-K.
- Tests: newTestClient sets LabsBaseURL; the two *_LimitParamSet tests
  become *_MbidParamSet (assert the Labs path + mbid query param).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 15:50:32 -04:00
bvandeusen be23ae488d feat(listenbrainz): expose Name on SimilarArtist for M5c suggestions 2026-05-01 05:51:29 -04:00
bvandeusen 937a1930ad test: add dbtest.ResetDB helper that preserves admin user
Integration tests previously TRUNCATEd the users table at setup,
which wiped the operator's admin login every time the suite ran
against a Postgres instance shared with their dev environment.

This commit:

- Adds internal/dbtest/reset.go exposing ResetDB(t, pool) and
  TestUserPrefix. ResetDB truncates every data table EXCEPT users,
  then deletes only users whose username starts with TestUserPrefix.
- Migrates 9 test files (subsonic/scrobble, subsonic/star,
  recommendation/candidates, scrobble/queue, similarity/worker,
  playevents/writer, playsessions/service, api/auth, api/me) to
  call ResetDB instead of issuing TRUNCATE-with-users.
- Renames hardcoded test usernames to use TestUserPrefix so ResetDB
  cleans them between runs. seedUser in api/auth_test now prefixes
  internally; existing call sites pass bare names.
- Leaves auth/bootstrap_test.go alone — it legitimately tests
  first-time admin bootstrap and must wipe users.

Verified locally: full integration suite with -p 1 runs cleanly
under the existing MINSTREL_TEST_DATABASE_URL setup, and the admin
row in the shared dev DB survives the run.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 11:55:06 -04:00
bvandeusen b0d1d6bb46 feat(listenbrainz): add SimilarArtists client method 2026-04-28 20:01:17 -04:00
bvandeusen 23d55a868b feat(listenbrainz): add SimilarRecordings client method 2026-04-28 19:59:38 -04:00
bvandeusen 9490bad360 feat(scrobble): add Worker with tickOnce, batched submit, retry/fail/auth handling
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 09:20:23 -04:00
bvandeusen 8ce39a8868 feat(scrobble): add backoffDelay schedule (1m, 5m, 30m, 2h, 6h, give up) 2026-04-28 09:14:08 -04:00
bvandeusen dba1deaad1 feat(scrobble): add MaybeEnqueue with idempotent insert + threshold gate
Bridges closed play_events to the scrobble_queue: loads the event,
applies the Qualifies() threshold, checks user LB config (enabled + token),
and inserts via ON CONFLICT DO NOTHING for idempotency. Best-effort —
callers (playevents.Writer hooks, Task 8) will log and swallow errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 09:13:11 -04:00
bvandeusen 767e246b73 feat(scrobble): add pure Qualifies threshold function 2026-04-28 09:10:39 -04:00
bvandeusen 5359a16091 style(scrobble): rename unused r *http.Request to _ in client tests
Caught by revive's unused-parameter check. The four error-path tests
don't read the request body, so the parameter is properly named _.
2026-04-28 09:09:45 -04:00
bvandeusen 3d23f4930c feat(scrobble): add pure ListenBrainz HTTP client with typed errors
Implements the HTTP client for ListenBrainz submit-listens with typed
sentinel errors (ErrAuth, ErrPermanent, ErrTransient, *RetryAfterError)
so the scrobble worker can branch on response semantics. All 9 httptest-
driven tests pass.
2026-04-28 08:45:13 -04:00