3.4 KiB
3.4 KiB
007 — MusicBrainz/ListenBrainz Explore Browser
Read-only remote catalog browser: search MB/LB, browse artist pages with ListenBrainz-ranked top tracks and similar artists, view album detail with release-version selection. Rate-limited (1 req/sec), SQLite-cached, with cover art from CAA. Lays the API client + cache foundation that v1.3 Autotagger builds on.
Shipped: 2026-03-24 · Slices: S01-S04 (M004 in GSD)
What landed
- S01 — API clients, cache, explore shell.
backend/explore/— MusicBrainz client (wrapsmusicbrainzws2, which provides its own internal rate limiter), ListenBrainz client (customRateLimiterviagolang.org/x/time/rate, 1 req/sec, burst=1), Cover Art Archive client (URL builders only). All clients follow cache-first pattern: check cache → call API → wrap → cache → return. Migration 11 addsexplore_cachetable (URL key, JSON body, datetime expiry, nullablembid+entity_typecolumns for future autotagger correlation).idx_explore_cache_mbidindex. TTLs: 24 h for search, 7 d for entity lookups. Sidebar "Explore" entry with globe icon. - S02 — Smart search. Unified
Search()runs concurrent sub-searches withWaitGroup+Mutex; frontend renders Top Results / Artists / Albums / Tracks with 300 ms debounce and stale-response discarding via version counter. CAA thumbnails for all result types. - S03 — Remote artist page.
explore-artist-details(904 LOC). Four independent sections viaPromise.allSettled: header, top tracks (ListenBrainzTopRecordingsForArtistwith formatted listen counts), discography (grouped Album/EP/Single/Compilation/Other, newest-first), similar artists (recursive navigation). ListenBrainz LabsSimilarArtistsfailures degrade silently to console.error (it's an experimental endpoint). - S04 — Album detail & release versions.
explore-album-details(828 LOC). Release fingerprinting (sort tracks by(discNumber, position), join MBIDs with|) collapses identical editions into one cluster; track-count min/max labelling shows differences across editions; default selection is the earliest-dated release. Disc separators when any track hasdiscNumber > 1.
Known gap (carried into v1.3 follow-up scope)
- R032 — offline visual indicator was in the milestone scope but never implemented. Cache infrastructure works (cached entries served when offline until TTL expires), but
Cache.Get()doesn't propagate a "from cache" flag to the frontend, and no component renders a "Cached" badge. Functional offline mode works; the UI cue is missing.
Key decisions retained
- Wrapper types in
backend/explore/types.gofor Wails bindings, not rawmusicbrainzws2types. Avoids ugly TS namespaces and serialization issues with unexported fields. - Dual rate limiters — accept it. The
musicbrainzws2library has its own that can't easily be disabled or shared; our limiter governs LB + CAA. Both enforce 1 req/sec independently. - MBID + entity_type columns in
explore_cache— scaffolding for the v1.3 autotagger. No autotagging logic in M004, just storage shape. CoverArtGroupURLis a synchronous inline string builder. Pure deterministic template; making it async via Wails would add per-render round-trips for nothing.- Detail components share design tokens via
tokens.css.tsbut are independent Lit components — no inheritance, no shared base. Data sources differ entirely (local SQLite vs remote API).