Cleanup: split scanner.ts into focused modules
Third of six cleanup MRs from the codebase review. The 1116-line `scanner.ts` had become a junk drawer: unsorted scanning, sorted indexing, artist enrichment, album/artist queries, and library config all lived in one file. Each commit moves one responsibility into its own module and retargets every caller atomically — no re-export shim, no barrel.
What changes
Five new modules, scanner.ts deleted:
- `src/lib/server/services/artistQueries.ts` — `getArtistIndex`, `getArtistDetail`, `artistKey`, plus `ArtistIndexEntry`/`QualityCounts` types (130 lines).
- `src/lib/server/services/albumQueries.ts` — `getAlbumById`, `getAlbumFiles`, `getAllAlbums`, `deleteAlbum`, `getRandomPendingAlbum` (51 lines).
- `src/lib/server/services/artistEnrichment.ts` — `fetchArtistDataForSorted` (56 lines).
- `src/lib/server/services/sortedIndexer.ts` — `scanSortedDirectory`, `upsertSortedAlbum`, `indexSortedAlbumFiles`, `getArtistCategoryMap`, `getSortedAlbumIndex`, the in-memory `artistCategoryMap` state, and the local `normalizeArtistName` helper (395 lines).
- `src/lib/server/services/unsortedScanner.ts` — `scanUnsortedDirectory`, `scanDirectory`, `classifyDirectory`, `scanAlbumFiles`, `scanAlbumWithSubfolders`, `findAlbumArt`, plus `ScanResult` (510 lines). This is the result of renaming the trimmed-down scanner.ts.
- `libraryPaths.ts` gains `IGNORE_DIRS` (shared between the two indexer modules).
Caller updates: 7 callers retargeted for `artistQueries` (page server loads, /api/artists routes, ArtistCard/ArtistListRow), 4 retargeted for `albumQueries` (album/artwork API routes), `watcher.ts` retargeted for the two scanner modules.
Behavior
No intentional behavior changes. The unsorted scanner now reads `artistCategoryMap` via the exported `getArtistCategoryMap()` getter (it previously closed over the module-level variable; the getter returns the same Map by reference). `pnpm run build` passes after every commit; full pnpm build passes at HEAD.
Why
The review flagged scanner.ts as the highest-priority code-quality issue. Splitting it makes future changes safer — the artist photo/bio enrichment, the sorted indexer, and the unsorted scanner have distinct failure modes and were tangled together. Now they're independently reviewable.
Builds on MR !47 (merged) and MR !48 (merged).