US01-07: Automate Phase A End-to-End Acceptance (#53)

This commit was merged in pull request #53.
This commit is contained in:
2026-07-15 22:15:30 +02:00
parent 3d5550b07f
commit 19d4ce3785
6 changed files with 372 additions and 1 deletions

View File

@@ -24,6 +24,13 @@ def _error(status: int, code: str, message: str) -> JSONResponse:
return JSONResponse(status_code=status, content={"error": {"code": code, "message": message}})
@router.post("/duplicates/detect")
def detect(request: Request) -> dict:
"""Run duplicate detection over the current assets (synchronous in Phase A)."""
report = _service(request).detect()
return {"clusters": len(report.clusters), "counts": report.counts}
@router.get("/duplicates/clusters")
def list_clusters(
request: Request,

View File

@@ -1,14 +1,29 @@
"""Inventory listing API for the review UI."""
"""Inventory listing and scan API for the review UI."""
from __future__ import annotations
from fastapi import APIRouter, Query, Request
from fastapi.responses import JSONResponse
from photo_pipeline.services.inventory import InventoryService
router = APIRouter(tags=["inventory"])
@router.post("/inventory/scan")
def scan(request: Request):
"""Discover and reconcile the configured library roots (synchronous in Phase A;
a durable job in Phase B)."""
config = request.app.state.config
if not config.library_roots:
return JSONResponse(
status_code=409,
content={"error": {"code": "no_roots", "message": "no library_roots configured"}},
)
result = InventoryService(request.app.state.session_factory).scan(config.library_roots)
return {"counts": result.counts, "total": len(result.asset_ids)}
@router.get("/inventory/assets")
def list_assets(
request: Request,