From c37a3c9b552a5a5fdd2ddf1010551e9251e75154 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Tue, 19 May 2026 17:53:12 -0400 Subject: [PATCH] feat(integrity): /api/system/stats exposes integrity counts Co-Authored-By: Claude Opus 4.7 (1M context) --- backend/app/api/settings.py | 19 +++++++++++++++++++ tests/test_api_settings.py | 25 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/backend/app/api/settings.py b/backend/app/api/settings.py index a91bd60..f5067e4 100644 --- a/backend/app/api/settings.py +++ b/backend/app/api/settings.py @@ -83,6 +83,17 @@ async def system_stats(): ).all() status_counts = {row[0]: row[1] for row in status_rows} + # Integrity counts — FC-2e. + integrity_rows = ( + await session.execute( + select( + ImageRecord.integrity_status, + func.count(ImageRecord.id), + ).group_by(ImageRecord.integrity_status) + ) + ).all() + integrity_counts = {row[0]: row[1] for row in integrity_rows} + # Active batch (most recent running) active_batch_row = ( await session.execute( @@ -116,5 +127,13 @@ async def system_stats(): "skipped": status_counts.get("skipped", 0), "failed": status_counts.get("failed", 0), }, + "integrity": { + "unknown": int(integrity_counts.get("unknown", 0)), + "ok": int(integrity_counts.get("ok", 0)), + "corrupt": int(integrity_counts.get("corrupt", 0)), + "failed_verification": int( + integrity_counts.get("failed_verification", 0) + ), + }, "active_batch": active_batch, }) diff --git a/tests/test_api_settings.py b/tests/test_api_settings.py index a7f30b1..5872a81 100644 --- a/tests/test_api_settings.py +++ b/tests/test_api_settings.py @@ -80,3 +80,28 @@ async def test_system_stats_shape(client): assert key in body for status in ("pending", "queued", "processing", "complete", "skipped", "failed"): assert status in body["tasks"] + + +@pytest.mark.asyncio +async def test_system_stats_integrity_counts(client, db): + from backend.app.models import ImageRecord + + base = "stats_" + "0" * 56 + for i, status in enumerate( + ["ok", "ok", "corrupt", "failed_verification"] + ): + db.add(ImageRecord( + path=f"/images/i/{i}.jpg", sha256=base + f"{i:02d}", + size_bytes=1, mime="image/jpeg", width=1, height=1, + origin="imported_filesystem", integrity_status=status, + )) + await db.commit() + + resp = await client.get("/api/system/stats") + assert resp.status_code == 200 + body = await resp.get_json() + integ = body["integrity"] + assert integ["ok"] >= 2 + assert integ["corrupt"] >= 1 + assert integ["failed_verification"] >= 1 + assert "unknown" in integ