This commit includes:
1. Live/Remix Filtering Feature:
- Added ignore_live and ignore_remix columns to artist_settings table (migration 010)
- Updated ArtistSettings struct with IgnoreLive and IgnoreRemix fields
- Modified SaveArtistSettings and UpdateArtistSettings to handle new fields
- Extended FilterOptions struct with IgnoreLive and IgnoreRemix
- Updated ApplyTypeToggles and ApplyTypeTogglesToReleaseGroups to filter Live/Remix types
- Added toggleIgnoreLive and toggleIgnoreRemix handlers in web layer
- Updated ArtistData view model and artist.html template with new toggle UI
- Comprehensive test coverage for all new functionality
2. CI/CD Pipeline with Gitea Actions:
- Added .gitea/workflows/docker-build.yml for automated Docker builds
- Workflow triggers on pushes to main/master and tags, plus PRs
- Runs Go tests before building
- Builds and pushes multi-architecture Docker images to gitea.mrixs.me
- Includes caching for faster subsequent builds
- Proper tagging strategy (branch, semver, SHA)
- CI-CD-GUIDE.md documentation
3. Cleanup:
- Removed temporary build artifacts and coverage files
- Honor ignore_singles/ignore_compilations at scanner read time so toggles
take effect immediately on the dashboard, artist page, and digest instead
of waiting for the MusicBrainz cache to expire and prune rows.
- Run notifier notify synchronously in the scheduler loop to avoid overlapping
read-send-mark runs double-sending the digest.
- Show artist name (with ID fallback) on the archive page instead of raw IDs.
- Select last_synced in GetAllArtistSettings for contract consistency.
- Fix stale startPeriodicSync comment and remove redundant error var.
- Remove dead ignored-branch from the artist template (never rendered).
- Add tests: CSRF sameOrigin, ArtistCacheFresh, secondary_types round-trip,
and scanner type-toggle filtering.
- Update Specification.md schema/config to reflect mbid, last_synced,
secondary_types, sync.interval, and server.public_url.
Task 8's ignore/restore/ignore-singles actions live on the artist detail
page, but the dashboard rendered artist names as plain text with no link,
making those actions unreachable through normal UI navigation. Wrap the
name in an anchor to /artist/{id} and assert the link in the dashboard test.
- Preserve MBID and last_synced across periodic artist syncs (INSERT OR
REPLACE was wiping them, forcing MusicBrainz re-resolution every cycle)
- Exclude unmonitored artists from unnotified-release digest query
- Require telegram.cron_schedule when telegram.enabled is true
- Add same-origin CSRF defense to state-changing web POST routes
- Skip WAL/busy_timeout pragmas for :memory: databases (no-op there)
- Scan mbid as sql.NullString in GetAllArtistSettings to tolerate NULLs
- notifier: show artist display names (not internal IDs) in digest; resolve
names from artist_settings and fall back to ID when unavailable
- notifier: skip sending an empty digest to avoid daily spam
- config: require telegram token/chat_id when enabled
- web: warn loudly when auth is disabled on a non-loopback bind; add HTTP
server timeouts
- web: treat SetReleaseIgnored "release not found" as benign redirect (0 rows)
- musicbrainz: reject low-score/name-mismatched MBID resolutions instead of
silently caching the wrong artist
- database: remove dead duplicate err check; harden DSN param appending
- musicbrainz: check rows.Err() after iterating existing releases
- Fix duplicate Telegram notifications: SyncArtistDiscography no longer wipes
notifications_sent for the whole artist on every cache-miss re-sync; only
markers for releases that disappear are pruned (FK-safe via INSERT OR REPLACE
+ rgid NOT IN (...)).
- Cache empty MusicBrainz discographies via a new artist_settings.last_synced
column (migration 009) so zero-release artists honor the TTL instead of being
re-fetched every cycle.
- Wire the Web UI server and Telegram notifier scheduler into main.run/NewApp.
- Guard startPeriodicSync against overlapping syncs with a done-channel slot.
- Add server.public_url config; NewServerWithConfig derives reachable links
and no longer advertises the 0.0.0.0 bind address.
- Web handlers: use scanner.ScanArtist per artist, drop always-false
releaseIgnored lookup and dead endsWith, thread configured threshold.
- Limit :memory: DB pool to one connection so migrations and queries share the
same in-memory store.
Implements Task 8: artist detail page (local albums + found-missing
with ignore buttons), ignored-releases archive with restore, and POST
handlers toggling ignore flags and ignore_singles. Adds ErrArtistNotFound
sentinel so callers can distinguish missing artists, and wires routes via
the enhanced ServeMux path wildcard.