Commit Graph

7 Commits

Author SHA1 Message Date
34ea84fc77 feat: verify MusicBrainz provider acceptance criteria
- All 6 tasks complete: client/models, rate limiting/caching, API
  endpoints/filtering, sync orchestration, app wiring, verification
- Full test suite passes (all packages green)
- go vet clean, no issues
- Coverage: musicbrainz 92.5%, config 100%, navidrome 79.5%, database 53.1%
- Edge cases verified: HTTP errors, rate limit blocking, context
  cancellation, NULL handling, XML parse errors
2026-05-26 13:17:49 +03:00
da49d12bb6 feat: wire up MusicBrainz provider in application entry point
- Add App struct with Config, DB, and MusicBrainz client dependencies
- NewApp() initializes database and MusicBrainz client from config
- App.Close() cleans up resources (MB client + DB) on shutdown
- App.run() blocks until context cancelled (goroutine-ready for future tasks)
- Config validation already requires musicbrainz.user_agent
- Add 6 tests: graceful shutdown, config integration, NewApp creation,
  shutdown cleanup, app.run shutdown, UserAgent validation
- All tests pass (6/6 in cmd, full suite green)
2026-05-26 13:14:47 +03:00
15b05b57fb feat: implement MusicBrainz sync orchestration with caching and upsert
Creates internal/musicbrainz/sync.go with SyncArtistDiscography function
that orchestrates the full flow: cache check via GetCachedReleases, fetch
from MusicBrainz API on cache miss, filter via FilterReleaseGroups, and
upsert into external_releases via database.SaveExternalRelease. Includes
SyncArtistDiscographyWithFilter variant for per-artist type filtering. All
functions support context cancellation. 14 new tests cover cache hit/miss,
status/type filtering, context cancellation, idempotency, API errors, and
full XML pipeline integration.
2026-05-26 13:04:20 +03:00
e624bb0eaf feat: implement MusicBrainz API endpoints, filtering, and normalization
- Add GetArtistReleaseGroups method with pagination support
- Implement status filtering (exclude Bootleg/Promotion/Pseudo-Release)
- Implement type filtering (include Album/Single/EP/Compilation)
- Add per-artist type filtering hooks (ArtistTypeFilter) for Web UI
- Add NormalizeString and NormalizeArtistName for fuzzy matching prep
- Add ReleaseGroup.ToExternalRelease conversion method
- Write comprehensive table-driven tests for filtering logic
- Write tests for normalization functions (18 cases)
- Write tests for GetArtistReleaseGroups (success, pagination, empty, errors)
- All tests pass (47 total across project), go vet clean
2026-05-26 12:31:07 +03:00
b0f69d3a4f feat: implement rate limiting and caching layer for MusicBrainz provider
- Add golang.org/x/time/rate dependency for token-bucket rate limiting
- Replace custom channel-based rate limiter with rate.NewLimiter(1, 1)
- Add context.Context support to doGet for cancellation
- Add cached_at column to external_releases via migration 005
- Implement cache hit/miss queries with TTL-based filtering
- Add CacheStats type for tracking cached RGIDs
- Update ExternalRelease struct with CachedAt field
- Add rate limiting tests (1 req/sec enforcement, burst behavior)
- Add cache tests (hit, miss, expired, mixed, empty artist)
- Update migration count test for new migration
2026-05-26 12:15:28 +03:00
674daed93b feat: create MusicBrainz client and data models
Add internal/musicbrainz/ package with:
- client.go: MusicBrainzClient struct wrapping net/http.Client with
  channel-based rate limiter (1 req/sec), doGet method with proper
  User-Agent header, and Close for cleanup
- model.go: ReleaseGroup, Artist, ExternalRelease, and Parsed* structs
- XML parsing functions for release-group list and artist responses
- Comprehensive tests: XML parsing (success, empty, malformed),
  client constructor, doGet (success, non-200, unreachable server),
  rate limiter behavior
2026-05-26 11:52:17 +03:00
60ecc3f904 Add MusicBrainz provider plan and ignore coverage output 2026-05-26 11:33:30 +03:00