fix(494): reconcile removed music videos in Jellyfin scanner #495
2
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fdef908929 |
test(494): mixed-library zero-incoming regression + tighten removal test
Build ErsatzTV Image / CI image pin matches docker/ci (pull_request) Successful in 6s
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 7s
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 16s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 6m50s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 20s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 21s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 5m38s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 18m42s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Address the #493 session's field finding: a mixed Jellyfin library runs the music-video arm with a legitimately empty incoming set on every scan while Movies/Shows exist under the same LibraryPath (the real "Standup" case). Add ScanLibrary_Should_Not_Touch_Movies_Or_Shows_When_No_MusicVideos_Present — seeds a Movie (with a real MediaFile path) + Show, scans with zero incoming, asserts both survive and RemoveMediaItems is never called. This pins that the MusicVideo-joined FindMusicVideoPaths (not just the empty-fetch guard) is what keeps existing.Except([]) from wiping the movies/episodes. Also tighten the removal test to pin the trashed music-video id in the RemoveMediaItems assertion (cold-review nit), and name the deferred per-library identity follow-up (#496) in decisions.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
2351841ff4 |
fix(494): reconcile removed music videos in Jellyfin scanner
Build ErsatzTV Image / CI image pin matches docker/ci (pull_request) Successful in 10s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 14s
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 12s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 1m29s
Build ErsatzTV Image / decisions.md append-only (pull_request) Failing after 13m45s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 16m21s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 18m58s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 19m27s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
JellyfinMusicVideoLibraryScanner did add/update only, so a music video (or artist) deleted on the Jellyfin side lingered in ErsatzTV forever and could still be scheduled. Add a trash sweep at the end of ScanLibrary (TrashMissingMusicVideos) mirroring the MediaServer* base scanners' "gone upstream => remove" pattern. Identity is library-scoped by (LibraryPathId, path) rather than server itemId: music videos carry no JellyfinMusicVideo entity / ItemId, so the sweep diffs the incoming local paths against FindMusicVideoPaths(libraryPath) and hard-deletes the remainder via DeleteByPath + RemoveMediaItems, then cleans now-empty artists via DeleteEmptyArtists. Both repo queries filter LibraryPathId AND join the concrete MusicVideo table, so a Movie/Show sharing the same LibraryPath (a mixed library) can never be cross-deleted. Gated by the #477 MediaServerReconciliationGuard so a successful-but-empty fetch does not wipe the library. Known limitation: MusicVideoRepository.GetOrAdd dedups paths globally, so a file served by two libraries with overlapping local paths is a single row owned by the first library; a proper fix needs per-library music-video identity (deferred). Integration tests (real repos over in-memory SQLite) pin removal, empty-artist cleanup, cross-kind safety, and the empty-fetch guard. decisions.md records the identity choice and the deferred follow-up. fixes #494 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |