Replaced manual XElement building + fragile InferJsonValue with typed DTOs and proper System.Text.Json serialization — no more album titles like "21" being serialized as numbers
All numeric fields (duration, songCount, year, bitRate, etc.) now proper integers in JSON responses
XML responses now include <?xml?> declaration
Content-Type changed from application/xml to text/xml
Fixed .view suffix middleware — added explicit app.UseRouting() so routing sees the stripped path
getBookmarks JSON format fixed: "bookmarks":{"bookmark":[]} (was incorrectly wrapped in "error")
Artist coverArt attribute now included in getArtist and search3 responses
Playlist responses now include public attribute (both JSON and XML)
Genre element emits both name and value attributes for backward compatibility
Safe handling of empty artist names in getIndexes/getArtists
Flacify.Server — Performance
Song search with empty query (%% matching all songs) now uses projection query — ~4.3s → ~0.23s (18x faster)
SearchSongsLightAsync added with .Select(projection) to avoid loading full navigation graph
Flacify.Server — OpenSubsonic
Removed blanket openSubsonic="true" from all responses (was causing premature OpenSubsonic detection)
getOpenSubsonicExtensions endpoint still advertises subsonic-compat and transcoding extensions correctly
Tests
All 37 Subsonic API tests passing (36 pass + 1 intentionally skipped)
1.0.1 — May 23, 2026
Flacify.Server — Album Pagination
Albums page (/albums) now paginated server-side — no longer loads all 2000+ albums into memory
Page size selector (20/50/100), prev/next + page number navigation with ellipsis
Sort (Title/Artist/Year/Recently Added) and genre filter applied in SQL, not client-side
Current page button visually highlighted with primary class
Flacify.Server — No Startup Scan
Removed await RunScan() from FileWatcherService.ExecuteAsync — server starts instantly without scanning
Scans only trigger on file changes (watcher) or manual startScan endpoint
Scans and enrichment disabled in Testing environment — tests no longer contaminated with real music data
Flacify.Server — Admin Gate
IsAdminAsync helper on SubsonicController — reusable for admin-only endpoints
startScan now returns Subsonic error 50 ("User is not authorized") for non-admin users
Flacify.Server — Subsonic Fixes
offset parameter in getAlbumList/getAlbumList2 wired up for all list types
getSimilarSongs2 now returns <similarSongs2> element (was incorrectly returning <similarSongs>)
getArtist now returns <album> children (was returning <child>)
Fixes
EF Core LINQ translation errors in all album list queries — replaced entity projection (.Select(a => new Album { Artist = a.Artist })) with anonymous type + manual mapping; no CoverArt loaded in list queries, no translation failures
GetAlbumByReleaseGroupIdAsync, GetTopPlayedAlbumsAsync, GetHomeStatsAsync — same projection fix
UpdateArtistAsync and UpdateAlbumAsync no longer use DbSet.Update() (which writes all columns, potentially overwriting enriched data with nulls). Now only writes fields that actually changed — enrichment data (Biography, CoverArt, ReleaseType, etc.) can never be overwritten by a rescan
All 36 Subsonic API tests passing (35 pass, 1 intentionally skipped)
1.0.0 — May 21, 2026
Flacify.Console
Ripper now writes DISCNUMBER Vorbis comment tag during rip
Ripper now writes MUSICBRAINZ_ARTISTID tag (artist MBID in addition to album MBID)
Flacify.Server — Audio Analysis & Tagging
Scanner reads MUSICBRAINZ_ARTISTID from FLAC file tags; sets Artist.MusicBrainzId directly without API lookup
Scanner treats missing DISCNUMBER tag (0) as null, allowing directory-based disc number fallback
Album enrichment now also stores MusicBrainzReleaseGroupId for matching
Album enrichment skips already-enriched albums (MusicBrainzLastQueried guard)
Artist enrichment only runs for artists still missing bio or cover art (not every scan)
Flacify.Server — Play Tracking
Song PlayCount incremented on each Subsonic stream call
Listening history table records (SongId, UserId, PlayedAt) per play
Recently played page (/history) — last 50 plays
Most played page (/popular) — top 50 songs by play count
Album detail: Plays column per track, top 3 most-played songs get gold 1/2/3 badges
Frequent albums sorted by sum of song play counts (not song count)