Companion (main.py):
• NAVIDROME_TAGS whitelist — the single source of truth for what tags
survive
• enforce_tag_whitelist() — whitelist enforcer, replaces blacklist
approach
• All 5 write points updated: apply_tags, apply_tags_dict,
upload-track, upload-tracks, restructure_all
• preserve_composer and preserve_lyrics flags on both upload
endpoints (default False)
• /library/clean-tags now uses whitelist enforcer
iOS:
• UploadMetadata — preserveComposer and preserveLyrics fields
• buildMultipartBody — sends both flags as form fields
• BatchUploadView — two toggles, both off by default, wired end-to-end
• MultiAlbumEditorSheet — full rewrite matching
BatchAlbumEditorSheet: MusicBrainz search, swipe to exclude/include
tracks, Reset button, cover art widget with red glow
iOS — 6 fixes across 5 files:
Models.swift — Song, Album, AlbumWithSongs all now have albumArtist:
String?. CompanionSong.toSong() passes albumArtist.
CompanionAlbum.toAlbum() passes albumArtist to the new field.
TrackEditorView.swift — Album Artist field now initialises from
song.albumArtist ?? song.artist instead of just song.artist.
fetchCompanionDetails no longer requires companion: prefix — it
fetches for all songs using the album name, decodes properly using
CompanionLibraryResponse, and matches by relative_path.
BatchAlbumEditorSheet.swift — initialises from album.albumArtist ??
album.artist.
MultiAlbumEditorSheet.swift — pre-fills from first.albumArtist ??
first.artist.
AlbumDetailView.swift — buildAlbumWithSongs now passes albumArtist
from the companion songs.
Companion — 2 fixes:
apply_tags — now does full FLAC cleanup (removes all Picard legacy
variants) before writing, same as apply_tags_dict already did.
edit-metadata endpoint — no longer calls restructure_file. File
renaming only happens via /bulk-fix. This was the root cause of the
500 errors on compilation tracks with disc numbers.
The fix uses a single ./companion_data:/app/data bind mount instead.
The server’s init_db() already calls os.makedirs for cover_art and
artist_photos subdirectories on startup, so they’ll be created
automatically inside ./companion_data/ on first run.