feat(jobs): incremental scans, deep mode & folder selection #188

Merged
REDCODE merged 20 commits from feature/incremental-scans into develop 2026-08-20 14:04:34 +00:00
Collaborator

Implements the scan-infrastructure work tracked in #183, #184, #185, #186 and #187 (all in milestone v1.1).

Summary

Reworks the file-system crawl and person/album discovery jobs so unchanged data is never re-scanned, exposes a "deep" scan mode and folder selection, and merges Create Persons into a single discovery job.

Backend

  • Incremental file-system scans (#183, #184)
    • New DirectoryScanState table stores each directory's last-known mtime. The crawl always descends (directory mtime only reflects direct changes), but only enumerates files and reconciles the DB for directories whose mtime changed.
    • Batched inserts/updates/soft-deletes per directory (no more one Save() per file). Uses a dedicated asset context so the change tracker can be cleared per directory without detaching scan-state rows.
    • Deletion/rename sweep runs for changed directories.
    • New partial index IX_Assets_FolderId_Id on (FolderId, Id) filtered on DeletedAt IS NULL powers keyset pagination.
  • Merged, incremental discovery (#187)
    • CreateAlbumsJob is now the single "Create Persons & Albums" job and also covers person-only folders. CreatePersonsJob is deleted (scheduler method, controller case, Jobs page button removed; EJobType.CreatePersons kept so past JobRecords still deserialize).
    • Per-folder cursor Folder.LastDiscoveryScanAt; repeat runs scan only new assets. Auto-deep rescan when the folder's regex pattern changes (LastDiscoveryScannedRegex).
    • Keyset pagination over the new index, parallel regex matching per batch.
    • Single-pass assignment via a temporary AssetAlbumStaging table and bulk INSERT INTO "AlbumAsset" ... ON CONFLICT DO NOTHING (removes the second full scan and per-batch EXISTS queries).
    • Cover backfill via one grouped query instead of N+1.
  • Deep scan + folder selection (#185, #186)
    • JobRequestDto.Parameters conventions: literal deep and repeatable folder=<guid>. Applied to FileSystemScan and CreateAlbums; controller validates and scheduler/controller wired accordingly.

Frontend

  • Jobs page launch modal for Scan Files / Create Persons & Albums with a folder checkbox list and an Incremental/Deep toggle.
  • Settings → Folders: per-folder Scan (incremental) and Deep scan buttons.
  • JobsService.StartJob accepts parameters.

Migration

AddIncrementalScanState adds the Folder cursor columns, DirectoryScanState + AssetAlbumStaging tables, and the IX_Assets_FolderId_Id partial index (replacing the redundant IX_Assets_FolderId FK index).

Testing

  • Full solution builds clean (dotnet build MilkyShots.sln).
  • Manual verification pending: run incremental + deep scans and discovery on a live folder, confirm unchanged directories are skipped and repeat runs process only new assets.
Implements the scan-infrastructure work tracked in #183, #184, #185, #186 and #187 (all in milestone v1.1). ## Summary Reworks the file-system crawl and person/album discovery jobs so unchanged data is never re-scanned, exposes a "deep" scan mode and folder selection, and merges Create Persons into a single discovery job. ### Backend - **Incremental file-system scans** (#183, #184) - New `DirectoryScanState` table stores each directory's last-known mtime. The crawl always descends (directory mtime only reflects direct changes), but only enumerates files and reconciles the DB for directories whose mtime changed. - Batched inserts/updates/soft-deletes per directory (no more one `Save()` per file). Uses a dedicated asset context so the change tracker can be cleared per directory without detaching scan-state rows. - Deletion/rename sweep runs for changed directories. - New partial index `IX_Assets_FolderId_Id` on `(FolderId, Id)` filtered on `DeletedAt IS NULL` powers keyset pagination. - **Merged, incremental discovery** (#187) - `CreateAlbumsJob` is now the single "Create Persons & Albums" job and also covers person-only folders. `CreatePersonsJob` is deleted (scheduler method, controller case, Jobs page button removed; `EJobType.CreatePersons` kept so past `JobRecords` still deserialize). - Per-folder cursor `Folder.LastDiscoveryScanAt`; repeat runs scan only new assets. Auto-deep rescan when the folder's regex pattern changes (`LastDiscoveryScannedRegex`). - Keyset pagination over the new index, parallel regex matching per batch. - Single-pass assignment via a temporary `AssetAlbumStaging` table and bulk `INSERT INTO "AlbumAsset" ... ON CONFLICT DO NOTHING` (removes the second full scan and per-batch EXISTS queries). - Cover backfill via one grouped query instead of N+1. - **Deep scan + folder selection** (#185, #186) - `JobRequestDto.Parameters` conventions: literal `deep` and repeatable `folder=<guid>`. Applied to `FileSystemScan` and `CreateAlbums`; controller validates and scheduler/controller wired accordingly. ### Frontend - Jobs page launch modal for Scan Files / Create Persons & Albums with a folder checkbox list and an Incremental/Deep toggle. - Settings → Folders: per-folder Scan (incremental) and Deep scan buttons. - `JobsService.StartJob` accepts parameters. ## Migration `AddIncrementalScanState` adds the `Folder` cursor columns, `DirectoryScanState` + `AssetAlbumStaging` tables, and the `IX_Assets_FolderId_Id` partial index (replacing the redundant `IX_Assets_FolderId` FK index). ## Testing - Full solution builds clean (`dotnet build MilkyShots.sln`). - Manual verification pending: run incremental + deep scans and discovery on a live folder, confirm unchanged directories are skipped and repeat runs process only new assets.
Ai_Agent added 5 commits 2026-08-19 12:21:23 +00:00
REDCODE added 1 commit 2026-08-19 12:27:50 +00:00
REDCODE added 1 commit 2026-08-19 12:38:57 +00:00
REDCODE added 1 commit 2026-08-19 12:45:32 +00:00
REDCODE added 1 commit 2026-08-19 12:51:44 +00:00
REDCODE marked the pull request as ready for review 2026-08-19 13:04:23 +00:00
REDCODE added 1 commit 2026-08-19 13:04:27 +00:00
REDCODE added 3 commits 2026-08-19 22:51:23 +00:00
REDCODE added 1 commit 2026-08-19 23:52:13 +00:00
REDCODE added 1 commit 2026-08-20 00:32:07 +00:00
REDCODE added 2 commits 2026-08-20 13:14:17 +00:00
Local-only changes: refreshed .env, IDE data-source metadata, a new
VersionEnvGen run config, and the generate-version script.
REDCODE added 1 commit 2026-08-20 13:34:03 +00:00
REDCODE added 2 commits 2026-08-20 13:55:00 +00:00
REDCODE merged commit 05f3c40f60 into develop 2026-08-20 14:04:34 +00:00
REDCODE deleted branch feature/incremental-scans 2026-08-20 14:04:34 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MilkyShots/MilkyShots#188