Files
NaviWatcher/docs/FILTER_FLOW.md
Vladimir Zagainov cc04cad6e0 fix: CI/CD workflow for Gitea Actions - use proper authentication and fix checkout issues
Updated workflow to:
- Use Gitea token for repository checkout authentication
- Use Gitea repository owner as username for registry login
- Use PACKAGES_TOKEN secret for registry authentication
- Follow proven pattern from working repository
- Only build and push on main/master branches and version tags
- Added proper job dependencies (test → build → docker)
2026-08-05 23:33:27 +03:00

3.1 KiB

Filter Flow Documentation

This document explains how the ignore_singles and ignore_compilations settings propagate through the NaviWatcher system.

Overview

The application implements a dual-path filtering approach to balance storage efficiency with real-time responsiveness to user preference changes:

  1. MusicBrainz Sync Path (Store-time filtering):

    • Applies filtering when caching release groups from the MusicBrainz API
    • Stores only filtered results in the external_releases table
    • Reduces database size by excluding unwanted release types upfront
  2. Scanner Path (Read-time filtering):

    • Applies filtering when retrieving cached data for comparison
    • Ensures changes to ignore_singles/ignore_compilations take effect immediately
    • Provides real-time responsiveness without waiting for cache expiry

Data Flow

  1. Artist Settings Storage:

    • Navidrome artist sync populates the artist_settings table
    • Stores ignore_singles and ignore_compilations boolean flags per artist
  2. MusicBrainz Synchronization:

    • SyncArtistDiscography retrieves artist settings via getArtistFilterOptions
    • Applies filtering using ApplyTypeToggles before storing in external_releases
    • On cache hits, re-applies filter to ensure freshness of user preferences
  3. Scanning Process:

    • ScanArtist settings via GetArtistSettings`
    • Creates TypeFilter with current ignore_singles/ignore_compilations values
    • Applies filter during FindMissingReleases via filter.suppressed() check
    • Uses same musicbrainz.ApplyTypeToggles logic for consistency

Implementation Details

Shared Filtering Logic

Both paths use the same underlying filtering logic:

  • musicbrainz.ApplyTypeToggles for ExternalRelease filtering
  • musicbrainz.ApplyTypeTogglesToReleaseGroups for ReleaseGroup filtering
  • Consistent criteria:
    • IgnoreSingles: Type == "Single" OR Type == "EP" OR SecondaryTypes contains "Single"/"EP"
    • IgnoreCompilations: Type == "Compilation" OR SecondaryTypes contains "Compilation"

TypeFilter Structure

type TypeFilter struct {
	IgnoreSingles      bool
	IgnoreCompilations bool
}

Filter Application

  • MusicBrainz Path: ApplyTypeToggles(releases, FilterOptions{IgnoreSingles: s.IgnoreSingles, IgnoreCompilations: s.IgnoreCompilations})
  • Scanner Path: filter.suppressed(ext) which internally uses the same logic

Benefits

  1. Storage Efficiency: Only desired release types are cached in the database
  2. Immediate Responsiveness: User preference changes take effect in real-time
  3. Consistent Behavior: Both code paths produce identical filtering results
  4. Cache Efficiency: Existing cached data remains useful when preferences change
  • internal/scanner/diff.go: TypeFilter definition and suppressed() method
  • internal/scanner/scan.go: ScanArtist and ScanAll functions
  • internal/musicbrainz/sync.go: SyncArtistDiscography and getArtistFilterOptions
  • internal/musicbrainz/filter.go: ApplyTypeToggles and related filtering functions
  • internal/database/artist_settings.go: GetArtistSettings and GetAllArtistSettings