"""Dashboard status endpoint.""" from datetime import datetime, timezone from fastapi import APIRouter, Depends from sqlmodel import Session, select from ..database import get_session from ..models import Replica, SyncRun from ..sync.engine import get_progress router = APIRouter(prefix="/api", tags=["status"]) @router.get("/status") def get_status(session: Session = Depends(get_session)): replicas = session.exec(select(Replica)).all() progress = get_progress() now = datetime.now(timezone.utc) replica_data = [] for r in replicas: lag = None if r.last_sync_ts: ts = r.last_sync_ts if ts.tzinfo is None: ts = ts.replace(tzinfo=timezone.utc) lag = int((now - ts).total_seconds()) if r.suspended_at: status = "suspended" elif progress.running and progress.phase and r.name in progress.phase: status = "syncing" elif r.consecutive_failures > 0: status = "error" elif r.last_sync_ts: status = "synced" else: status = "pending" # Last run stats for this replica last_run = session.exec( select(SyncRun) .where(SyncRun.replica_id == r.id) .order_by(SyncRun.started_at.desc()) # type: ignore[attr-defined] .limit(1) ).first() replica_data.append( { "id": r.id, "name": r.name, "url": r.url, "enabled": r.enabled, "status": status, "lag_seconds": lag, "last_sync_ts": r.last_sync_ts.isoformat() if r.last_sync_ts else None, "consecutive_failures": r.consecutive_failures, "suspended": r.suspended_at is not None, "docs_synced_last_run": last_run.docs_synced if last_run else 0, "docs_failed_last_run": last_run.docs_failed if last_run else 0, } ) last_run = session.exec( select(SyncRun) .order_by(SyncRun.started_at.desc()) # type: ignore[attr-defined] .limit(1) ).first() return { "replicas": replica_data, "sync_progress": { "running": progress.running, "phase": progress.phase, "docs_done": progress.docs_done, "docs_total": progress.docs_total, }, "last_sync_run": { "id": last_run.id, "started_at": last_run.started_at.isoformat() if last_run and last_run.started_at else None, "finished_at": last_run.finished_at.isoformat() if last_run and last_run.finished_at else None, "docs_synced": last_run.docs_synced if last_run else 0, "docs_failed": last_run.docs_failed if last_run else 0, "timed_out": last_run.timed_out if last_run else False, } if last_run else None, }