""" DocuLens - Runs & Stats API endpoints. Provides /api/v1/runs, /api/v1/runs/:id, and /api/v1/runs/stats for the dashboard and ingestion views. """ import logging from typing import Optional from fastapi import APIRouter, Query, HTTPException, Depends from db.supabase import list_runs, get_run, get_stats, is_enabled from middleware import check_rate_limit logger = logging.getLogger(__name__) runs_router = APIRouter() @runs_router.get("/api/v1/runs") async def api_list_runs( status: Optional[str] = Query(None, description="Filter by status: running|completed|failed"), result: Optional[str] = Query(None, description="Filter by result: passed|failed|needs_review"), use_case: Optional[str] = Query(None, description="Filter by use case slug"), search: Optional[str] = Query(None, description="Search by filename"), page: int = Query(1, ge=1), per_page: int = Query(25, ge=1, le=100), org_id: Optional[str] = Query(None), user_id: Optional[str] = Query(None), api_key: str = Depends(check_rate_limit), ): """List pipeline runs with filtering and pagination.""" if not is_enabled(): return { "runs": [], "pagination": {"page": 1, "per_page": per_page, "total": 0, "pages": 0}, } return list_runs( org_id=org_id, user_id=user_id, status=status, result=result, use_case=use_case, search=search, page=page, per_page=per_page, ) @runs_router.get("/api/v1/runs/stats") async def api_run_stats( period_days: int = Query(30, ge=1, le=365), org_id: Optional[str] = Query(None), user_id: Optional[str] = Query(None), api_key: str = Depends(check_rate_limit), ): """Get aggregate stats for the dashboard.""" return get_stats(org_id=org_id, user_id=user_id, period_days=period_days) @runs_router.get("/api/v1/runs/{run_id}") async def api_get_run(run_id: str, api_key: str = Depends(check_rate_limit)): """Get a single run with full stage details.""" if not is_enabled(): raise HTTPException(status_code=404, detail="Run not found") run = get_run(run_id) if not run: raise HTTPException(status_code=404, detail="Run not found") return run