diff --git a/backend/app/services/cleanup_service.py b/backend/app/services/cleanup_service.py index 3f749ad..99d2a6f 100644 --- a/backend/app/services/cleanup_service.py +++ b/backend/app/services/cleanup_service.py @@ -365,3 +365,47 @@ def prune_unused_tags(session: Session, *, dry_run: bool = False) -> dict: ) session.commit() return {"deleted": len(ids), "sample_names": sample} + + +# --------------------------------------------------------------------------- +# FC-Cleanup additions (2026-05-26): retroactive audit of import-filter rules. +# --------------------------------------------------------------------------- + +_MIN_DIM_SAMPLE_CAP = 50 + + +def project_min_dimension_violations( + session: Session, *, min_width: int, min_height: int, +) -> dict: + """Return {count, sample_ids} for image_record rows with width or + height below the thresholds. Synchronous SQL — no PIL inspection + needed since width/height are stored columns.""" + base = select(ImageRecord.id).where( + (ImageRecord.width < min_width) | (ImageRecord.height < min_height) + ) + count = session.execute( + select(func.count()).select_from(base.subquery()) + ).scalar_one() + sample_ids = session.execute( + base.order_by(ImageRecord.id).limit(_MIN_DIM_SAMPLE_CAP) + ).scalars().all() + return {"count": count, "sample_ids": list(sample_ids)} + + +def delete_min_dimension_violations( + session: Session, *, min_width: int, min_height: int, images_root: Path, +) -> int: + """Delete every image_record where width