feat: auto-chain vision backfill + face recluster after scan, show progress in UI

Scan now automatically queues backfill_vision (+90s) and recluster_faces
(+300s) after dispatching folder scans. Face extraction also schedules a
debounced recluster via Redis so incremental file-watcher imports get
clustered without manual intervention.

The ScanProgress widget now tracks worker queue activity beyond the scan
phase, showing a "Processing Photos" indicator with vision queue counts
while background tasks (embeddings, faces, tags, OCR) are running.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
root
2026-04-12 18:51:38 +02:00
parent 6457dc9da5
commit d933ea3842
3 changed files with 202 additions and 80 deletions

View File

@@ -409,6 +409,7 @@ async def _scan_all_source_roots_async():
still hit Settings → Re-detect duplicates to force a fresh pass.
"""
from app.tasks.thumbs import regroup_duplicates_task
from app.tasks.vision import backfill_vision, recluster_faces
async with AsyncSessionLocal() as session:
result = await session.execute(
@@ -433,6 +434,21 @@ async def _scan_all_source_roots_async():
except Exception as e:
logger.warning(f"Could not queue post-scan regroup: {e}")
# 90s lets thumbnails finish so photos reach processing_status
# 'completed', which backfill_vision uses as its filter.
try:
backfill_vision.apply_async(countdown=90)
except Exception as e:
logger.warning(f"Could not queue post-scan vision backfill: {e}")
# 300s gives face extraction time to run before reclustering.
# Fires even if some faces are still in-flight — the task is
# idempotent and the user can re-trigger from Settings.
try:
recluster_faces.apply_async(countdown=300)
except Exception as e:
logger.warning(f"Could not queue post-scan face recluster: {e}")
@shared_task(name='watch_folders')
def watch_folders():