Commit Graph

36 Commits

Author SHA1 Message Date
bvandeusen 94c60c0af2 fc3k: admin Celery tasks — delete_artist_cascade_task + bulk_delete_images_task on maintenance queue
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 00:40:03 -04:00
bvandeusen 718cc79905 fix(fc3h): split semicolon-stacked statements (E702) and bridge v-dialog v-model to avoid prop write
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 23:37:06 -04:00
bvandeusen d3d4320ed5 fc3h: retire backup + rollback from migrate API/task — moved to /api/system/backup/* per FC-3h
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:59:11 -04:00
bvandeusen 06d527cb92 fc3h: prune_backups (daily retention) + backup_db_nightly (hourly tick, settings-gated)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:55:19 -04:00
bvandeusen e9ea376aed fc3h: restore_db_task + restore_images_task — restore creates 'restoring' marker row linked via restored_from_id
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:53:50 -04:00
bvandeusen 882cb491ba fc3h: backup_db_task + backup_images_task Celery tasks
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:53:26 -04:00
bvandeusen 7782672a51 fc3i: recover_stalled_task_runs + prune_task_runs maintenance tasks + Beat entries
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 21:03:33 -04:00
bvandeusen be0f472894 fix(workers): worker-level recovery — autoretry on transient errors + tightened sweep (5min) + import_media_file body-wrap so no path leaves rows stuck in 'processing'
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 11:46:36 -04:00
bvandeusen 7a5a71471e fix(scan): auto-finalize empty scans + system_stats picks running batch with actual work
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 21:25:57 -04:00
bvandeusen f5efbea053 feat(fc5): /api/migrate/cleanup — delete every image attributed to one artist, files + thumbs + DB
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 12:09:56 -04:00
bvandeusen 061dc9e605 fix(tasks): collapse double blank line between imports and IMAGES_ROOT in import_file.py (ruff I001)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 11:05:35 -04:00
bvandeusen 7d8b9c3d90 fix(tasks): share one sync engine per worker process to stop connection-pool leak
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 10:44:16 -04:00
bvandeusen 8f25b27315 fix(import): scan_directory skips paths with existing non-failed ImportTask
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 10:25:27 -04:00
bvandeusen 599697c912 fix(fc5): ruff I001 — alphabetical order of import statements (backup < gs_ingest < rollback)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 14:04:10 -04:00
bvandeusen 9fb3d11412 fix(fc5): ruff I001 — consolidate unaliased imports + tests/test_gs_ingest credential_type assertion
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 13:29:09 -04:00
bvandeusen e5885f85c5 fix(fc5): ruff (E712, ASYNC230/240, I001) + Credential.credential_type + FileStorage in api_migrate test
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 13:20:42 -04:00
bvandeusen c880bf8259 fc5: run_migration Celery task on maintenance queue + dispatch by kind
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 09:02:41 -04:00
bvandeusen ec004933a5 fc3d: cleanup_old_download_events daily task (terminal-only, configurable retention)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 16:02:36 -04:00
bvandeusen 9d5793f0ce fc3d: tick_due_sources Celery task on the scan queue
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 16:01:59 -04:00
bvandeusen 772fb6f9d0 feat(fc3c): download_source Celery task + register in celery_app
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 20:43:16 -04:00
bvandeusen e28de547c7 feat(integrity): verify_integrity task (keyset, fail-soft) + weekly beat
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 17:51:33 -04:00
bvandeusen 5dfdbf5a60 feat(deep-scan): Importer(deep=) re-derive on sha-match; import_file wires batch.scan_mode
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 15:32:26 -04:00
bvandeusen 9535533385 feat(deep-scan): trigger accepts 'deep'; scan_directory(mode) + enqueue backfill_phash
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 15:31:26 -04:00
bvandeusen ae67e67299 feat(deep-scan): keyset-paginated backfill_phash task
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 14:59:04 -04:00
bvandeusen 89103c4570 feat(attachments): scan enumerates all; import_file maps 'attached' + member ML
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:14:49 -04:00
bvandeusen 4d5564c363 feat(phash): import task maps 'superseded' to complete + re-queues ML/thumbnail
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:06:46 -04:00
bvandeusen f7f75fcac6 refactor(fc2c-i): sweep blueprints + ml tasks onto shared get_session (covers tasks/ml.py, a survey gap) 2026-05-15 15:48:02 -04:00
bvandeusen b68a382b60 feat(fc2b): importer enqueues tag_and_embed + ml-worker model self-heal
import_media_file now enqueues tag_and_embed alongside generate_thumbnail
after a successful import. scripts/download_models.py snapshots Camie +
SigLIP into /models, idempotent (skips when present). The ml-worker
entrypoint runs it before starting the Celery worker so a fresh /models
volume self-heals on first boot. Downloader tests are pure-logic (no
network in CI).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 07:45:09 -04:00
bvandeusen 3e6cc8fffa feat(fc2b): add allowlist-apply + centroid recompute tasks + beat
apply_allowlist_tags: 4 modes (tag-only / image-only / both / full sweep),
matches a tag to a prediction either by direct name or via alias
(name, category) resolution, gates on per-tag min_confidence, skips
applied/rejected, applies source='ml_auto'. recompute_centroid /
recompute_centroids: async-bridged calls into CentroidService, delta-gated.
Beat: daily backfill, daily centroid recompute, daily allowlist sweep.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 07:43:39 -04:00
bvandeusen ac7e0d13bc feat(fc2b): add tag_and_embed + backfill Celery tasks
tag_and_embed: Camie + SigLIP on one image (video → 10-frame sample,
max-pool tags, mean-pool embeddings), stores predictions/embedding with
model versions, then enqueues per-image allowlist apply. backfill:
keyset-paginated discovery of images missing predictions/embeddings for
the current model versions (restart-safe). apply_allowlist_tags stub
included so .delay() resolves between commits (filled in Task 9).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 07:40:27 -04:00
bvandeusen 80a5690740 fix(fc2a): apply ruff autofix + skip vue-tsc check (no tsconfig)
Ruff:
The remaining I001 errors came from ruff treating `alembic` as a first-
party module (because the alembic/ directory exists in the repo root)
rather than third-party. Ran `ruff check --fix` locally — auto-sorted
import groupings to put alembic/sqlalchemy alongside backend.* as first-
party, and trimmed redundant blank lines after a few import blocks.

Frontend:
`npm run check` (vue-tsc --noEmit) was failing because vue-tsc has no
tsconfig.json to read against, and the frontend is pure JS without
JSDoc annotations — vue-tsc had nothing to do. Skipping the step until
we add a tsconfig + convert to TS or add JSDoc annotations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 14:24:25 -04:00
bvandeusen b4e0d680f1 fix(fc2a): satisfy ruff 0.15.13 lint — UP017, UP042, I001
Ruff lint surfaced 23 violations across three rules; all addressed:

UP017 (Use datetime.UTC alias):
  Replaced 13 sites of datetime.now(timezone.utc) with datetime.now(UTC),
  also adjusted from-imports accordingly. UTC is a Python 3.11+ alias for
  timezone.utc that ruff's pyupgrade rules prefer.

UP042 (StrEnum):
  Replaced `class TagKind(str, Enum)` and `class SkipReason(str, Enum)`
  with `class Foo(StrEnum)`. StrEnum was added in Python 3.11 stdlib and
  is the modern idiom. Behavior is equivalent for our usage (the .value
  attribute, str(member) semantics).

I001 (Import sorting):
  Added `known-first-party = ["backend"]` to ruff.toml's [lint.isort] so
  ruff groups `backend.*` imports correctly. Without it, ruff treated
  them as third-party and demanded a different grouping. The existing
  import order is stdlib → third-party → first-party → local relative,
  which ruff now accepts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 14:11:35 -04:00
bvandeusen 509c19ce86 feat(fc2a): add maintenance tasks (recovery + cleanup) with beat schedule
recover_interrupted_tasks runs every 5 minutes, finds ImportTask rows
stuck in 'processing' for >30 minutes (well above any legitimate import
duration), and re-queues them. cleanup_old_tasks runs daily and deletes
finished tasks older than 7 days so the task table stays an operational
view rather than an archive.

Both thresholds match ImageRepo's precedent. The 30-min stuck threshold
is documented inline so a future reader can adjust it intentionally
rather than mistaking it for a 'magic number'.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:09:09 -04:00
bvandeusen d3bb8c509a feat(fc2a): add Celery tasks — scan_directory, import_media_file, generate_thumbnail
scan_directory walks ImportSettings.import_scan_path, creates an
ImportBatch, enumerates supported files into ImportTasks, and enqueues
import_media_file per task. import_media_file moves the task through
its state machine (pending → queued → processing → complete/skipped/failed),
updates ImportBatch counters atomically (UPDATE ... SET col = col + 1),
enqueues a thumbnail task on success, and marks the batch complete when
the last task drains.

generate_thumbnail runs on its own queue (thumbnail) so big imports
don't starve thumbnail throughput; failure here is logged and does not
fail the import.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:08:37 -04:00
bvandeusen 8b5711abef docs: add module docstring to tasks package __init__ 2026-05-14 07:35:01 -04:00
bvandeusen 8773f2aae6 feat: configure Celery with per-feature queue lanes and a smoke task
Routes are pre-declared for FC-2/FC-3 task modules (import, ml, thumbnail,
download, scan, maintenance). Queue lanes match the ImageRepo pattern where
beat+maintenance run on a separate worker so long imports don't starve
periodic tasks. Smoke ping task confirms the wiring in eager mode for CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 07:34:47 -04:00