Fold stale missing tracks into their on-disk replacement (M485) #141

Merged
bvandeusen merged 2 commits from dev into main 2026-10-07 18:17:51 -04:00
Owner

A track marked missing whose replacement is already on disk under another row is now folded into that replacement. Its likes, plays, playlist entries and tags move across, and the stale row goes. On the operator's library this applies to about 355 of 451 missing tracks, nearly all Lidarr mp3 → flac upgrades. Move adoption could not link them: a re-encode never shares the audio hash, and the new files had no recording MBID at import.

  • 2df28345 refactor: the per-copy fold is now a helper (foldTrackInto) that the duplicate merge calls. No behaviour change.
  • 865a3176 feat: ListMissingTrackPairs and PairMissingTracks.
    • Matching: the same recording MBID within the album group, or the same album plus the same title ignoring case. Each side must have exactly one candidate, and conflicting MBIDs refuse a pair.
    • When it runs: after each full scan, each watcher batch, and each AcoustID pass that matched a track.

The first scan after deploy repairs the existing rows. No migration.

CI is green on dev at 865a3176 (run 8607).

🤖 Generated with Claude Code

A track marked missing whose replacement is already on disk under another row is now folded into that replacement. Its likes, plays, playlist entries and tags move across, and the stale row goes. On the operator's library this applies to about 355 of 451 missing tracks, nearly all Lidarr mp3 → flac upgrades. Move adoption could not link them: a re-encode never shares the audio hash, and the new files had no recording MBID at import. - `2df28345` refactor: the per-copy fold is now a helper (`foldTrackInto`) that the duplicate merge calls. No behaviour change. - `865a3176` feat: `ListMissingTrackPairs` and `PairMissingTracks`. - **Matching:** the same recording MBID within the album group, or the same album plus the same title ignoring case. Each side must have exactly one candidate, and conflicting MBIDs refuse a pair. - **When it runs:** after each full scan, each watcher batch, and each AcoustID pass that matched a track. The first scan after deploy repairs the existing rows. No migration. CI is green on dev at 865a3176 (run 8607). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bvandeusen added 2 commits 2026-10-07 18:17:48 -04:00
MergeDuplicateGroup's loop body — repoint and copy every FK from a removed
copy onto the survivor, inherit its MBID, delete its row, tidy an emptied
album — moves into foldTrackInto, so the missing-pair pass can fold a stale
missing row into its replacement with the same mechanics. The group lock,
file removal and group bookkeeping stay in the merge. No behaviour change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(library): fold a missing track into its on-disk replacement (M485 #5286 #5287)
release / web (push) Successful in 2m21s
release / go (push) Successful in 2m34s
release / govulncheck (push) Successful in 40s
release / integration (push) Successful in 6m17s
release / android (push) Successful in 6m36s
release / Build signed APK (releases and dev) (push) Successful in 6m6s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 1m19s
release / Verify release artifacts (tag releases only) (push) Skipped
865a3176c9
A track marked missing whose replacement is already on disk under another
row — on the operator's library 355 of 451 missing tracks, nearly all Lidarr
mp3 -> flac upgrades — is folded into the replacement: likes, plays, playlist
entries and tags move across and the missing row goes. Move adoption could
not catch these: the replacements were re-encodes (no shared audio hash) with
no recording MBID at import.

Pairs (ListMissingTrackPairs): the same recording MBID within the album
group, or the same album row and title ignoring case. Each side must have
exactly one candidate; conflicting MBIDs refuse a pair. No duration or track
position gate: on the 142 pairs known to be one recording, 18% differed by
over 2s and the poorly tagged set is where numbering is broken (spike #5274).

Each pair folds in its own transaction after locking both rows and checking
the pair still holds. Runs automatically (operator, 2026-10-07) after a full
scan, after a watcher batch that added or updated tracks, and after an
AcoustID pass that matched any track. The first scan after deploy repairs the
existing rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bvandeusen merged commit 54b2720d76 into main 2026-10-07 18:17:51 -04:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/minstrel#141