feat: implement scanner diff engine (missing-release detection)

Add FindMissingReleases and MissingRelease to internal/scanner: skips
IsIgnored external releases, scopes matches per ArtistID, and reports
external releases with no local album above the fuzzy threshold.
This commit is contained in:
2026-07-19 18:16:58 +03:00
parent 92aafaab05
commit a4f0460664
5 changed files with 373 additions and 5 deletions

View File

@@ -67,13 +67,13 @@
- [x] run tests — must pass before task 4
### Task 4: Implement the diff engine (missing-release detection)
- [ ] add `type MissingRelease struct { RGID, ArtistID, Title, Type, ReleaseDate string }` in `internal/scanner`
- [ ] implement `FindMissingReleases(local []database.LocalAlbum, external []database.ExternalRelease, threshold float64) []MissingRelease`:
- [x] add `type MissingRelease struct { RGID, ArtistID, Title, Type, ReleaseDate string }` in `internal/scanner`
- [x] implement `FindMissingReleases(local []database.LocalAlbum, external []database.ExternalRelease, threshold float64) []MissingRelease`:
- skip external releases where `IsIgnored == true`
- for each external release, check if any local album (same ArtistID) is a match via `IsMatch`; if none matches, it is missing
- respect context cancellation if signature uses `ctx` (decide in impl; pure slice version preferred for testability)
- [ ] write tests `internal/scanner/scanner_test.go` (table-driven, using in-memory DB fixtures or hand-built slices): no local albums → all external are missing; exact title present → not missing; fuzzy title present (e.g. `The Wall` vs `The Wall (Remastered)`) → not missing; ignored external → never reported; different ArtistID → not matched across artists; threshold boundary (0.85) behaviour
- [ ] run tests — must pass before task 5
- [x] write tests `internal/scanner/scanner_test.go` (table-driven, using in-memory DB fixtures or hand-built slices): no local albums → all external are missing; exact title present → not missing; fuzzy title present (e.g. `The Wall` vs `The Wall (Remastered)`) → not missing; ignored external → never reported; different ArtistID → not matched across artists; threshold boundary (0.85) behaviour
- [x] run tests — must pass before task 5
### Task 5: Wire a DB-backed scanner entrypoint + `main.go` hook (compute-only)
- [ ] add `func ScanArtist(ctx context.Context, db *database.DB, artistID string, threshold float64) ([]MissingRelease, error)` that loads local + external by artist via `database.GetLocalAlbumsByArtist` / `database.GetExternalReleasesByArtist` and calls `FindMissingReleases`