The dhowden/tag library returns ID3v2 TXXX frames as *tag.Comm
structs (key='TXXX_N', Description='MusicBrainz Artist Id',
Text='uuid'), not plain strings. Vorbis comments are plain strings
(key='musicbrainz_artistid', value='uuid').
Previous code only handled the string case — all MP3 files silently
got empty MBIDs. Now handles three value types:
- string: Vorbis comments (FLAC/OGG) — key is the tag name
- *tag.Comm: ID3v2 TXXX frames (MP3) — Description is the tag name
- *tag.UFID: ID3v2 UFID frame (MP3) — MusicBrainz recording ID
Requires a full rescan to backfill MBIDs for MP3 files.
Migration 13 adds nullable mbid TEXT columns to artists,
release_groups, and recordings with partial indexes.
Metadata extraction (tags.go) now reads MusicBrainz IDs from Raw()
tags — handles both Vorbis (musicbrainz_artistid) and ID3v2
(MusicBrainz Artist Id) key formats.
Scan pipeline (library.go) updates MBIDs after entity upsert via
raw SQL UPDATE. Only sets mbid if currently NULL (preserves existing
values on rescan).
LibraryMBIDIndex (librarymbid.go) provides:
- CheckMBIDs: batch lookup for 'In Library' badges
- GetArtistMBID: single artist name→MBID lookup
- AllArtistMBIDs: full dump for search index Tier 3
MBIDs will be populated on next library rescan. Existing files
need a rescan to backfill.
- Fix 10 err113 violations: extract dynamic errors to package-level sentinels
- Fix 12 errcheck violations: handle unchecked error returns in player,
metadata, and config packages
- Fix 4 revive stutter warnings: rename player.PlayerState to player.State,
player.PlayerVolume to player.Volume, queue.QueueTrack to queue.Track,
queue.QueueState to queue.State
- Fix 2 staticcheck SA4001: simplify *&x to x in assets handler
- Fix 5 unused constants: remove dead AudioFileType iota block in models
- Fix gci/gofumpt/wsl formatting issues across multiple files
- Add gofumpt module-path setting to .golangci.yml for correct import grouping
- Fix player test: gate integration test behind YELLOWJACKET_INTEGRATION env var
instead of only skipping in CI, and replace t.Errorf+t.Failed with t.Fatalf
- Remove continue-on-error from golangci-lint CI step so linting is now required