feat: add DB-backed scanner entrypoint and compute-only main hook

Implements ScanArtist/ScanAll in internal/scanner loading local/external
releases via the database layer with ctx-cancellation checks, plus a
compute-only run() hook that logs missing-release counts. Add table-driven
tests using in-memory SQLite fixtures.
This commit is contained in:
2026-07-19 18:19:57 +03:00
parent a4f0460664
commit c2da8c2095
6 changed files with 348 additions and 8 deletions

View File

@@ -76,12 +76,12 @@
- [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`
- [ ] add `func ScanAll(ctx context.Context, db *database.DB, threshold float64) ([]MissingRelease, error)` iterating monitored artists (reuse `database.GetAllArtistSettings`) with `ctx.Err()` checks between artists
- [ ] write tests `internal/scanner/scan_test.go` using `newTestDB(t)` + `seedArtist` + seeded `local_albums`/`external_releases` rows; assert missing set matches expectations; test ctx-cancellation returns early
- [ ] extend `cmd/naviwatcher/main.go` `App` struct + `NewApp` to construct the scanner (or keep stateless) and add a compute-only call in `run()` (e.g. log count of missing releases for monitored artists) without starting notifier/web — keep `run()` non-blocking / goroutine-safe per spec concurrency note
- [ ] write/extend `cmd/naviwatcher/main_test.go` if `App`/wiring changed
- [ ] run full test suite (`go test ./...`) and `go vet ./...` — must pass before final task
- [x] 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`
- [x] add `func ScanAll(ctx context.Context, db *database.DB, threshold float64) ([]MissingRelease, error)` iterating monitored artists (reuse `database.GetAllArtistSettings`) with `ctx.Err()` checks between artists
- [x] write tests `internal/scanner/scan_test.go` using `newTestDB(t)` + `seedArtist` + seeded `local_albums`/`external_releases` rows; assert missing set matches expectations; test ctx-cancellation returns early
- [x] extend `cmd/naviwatcher/main.go` `App` struct + `NewApp` to construct the scanner (or keep stateless) and add a compute-only call in `run()` (e.g. log count of missing releases for monitored artists) without starting notifier/web — keep `run()` non-blocking / goroutine-safe per spec concurrency note
- [x] write/extend `cmd/naviwatcher/main_test.go` if `App`/wiring changed
- [x] run full test suite (`go test ./...`) and `go vet ./...` — must pass before final task
### Task 6: Verify acceptance criteria
- [ ] verify `FindMissingReleases`/`ScanArtist`/`ScanAll` meet spec: normalization + 0.85 fuzzy threshold, ignore `IsIgnored`, per-artist scoping