Surface cross-source duplicates on artist + album views with resolve actions
Summary
- Artist detail page and the main Albums list now recognize when the same release exists in both the Sort and Sorted directories at different qualities, and show a contextual badge on each row (Upgrade available / Upgrade target / Lower quality / Already sorted).
- Both right-hand panels (
AlbumOrganizePanel,SortedAlbumPanel) gain a side-by-side compare block with two end-to-end actions: Replace Sorted with Unsorted (existingexecuteSort+overwriteExisting=true) and Delete Unsorted copy (existingDELETE /api/albums/[id]). - A new
duplicate_groupcolumn onsorted_albumsplus the existing one onalbumslets the cross-table join run once per loader call. Scanner and sorter write the normalized key on every upsert; loaders fall back to in-memory computation when the column is still NULL so the UI works on day one.
Commit structure
-
d5c75b0Persist duplicate-group key on sorted albums — schema + persistence foundation. -
b7fd719Surface cross-source matches in loaders and album endpoints. -
08aad2bShow duplicate badge on album rows and cards. -
15b6eb7Compare versions and resolve duplicates from album panels.
Test plan
-
pnpm run buildpasses (verified locally). -
After deploy, PRAGMA table_info(sorted_albums)showsduplicate_group. -
Open an artist with a known dupe (e.g. an album in Sorted as MP3 + Unsorted as FLAC): both rows show the expected colored pill. -
Click the Sorted row → compare block appears with Replace and Delete Unsorted buttons. Replace removes the old sorted folder and copies the unsorted version in; the pair disappears on reload. -
Repeat where the unsorted copy is lower quality and click Delete Unsorted copy — unsorted folder removed, sorted untouched. -
Albums list page ( /) in grid and list view shows the pill on matching rows. -
Artist with no duplicates: no pills, no compare block.