from __future__ import annotations from fastapi import APIRouter, Depends from findata_core.db import connection from findata_api import auth as A from findata_api.health import cached_evaluate as evaluate router = APIRouter(tags=["health"]) @router.get("/health") def health(p: A.Principal = Depends(A.get_principal)): """Public liveness (no details) — authenticated callers get the full report.""" h = evaluate() if p.kind == "anonymous": return {"status": h["status"], "service": "findata-os"} return h @router.get("/health/summary") def summary(p: A.Principal = Depends(A.require("read:market"))): with connection() as conn: ds = conn.execute("SELECT count(*) FILTER (WHERE status='active') active, count(*) FILTER (WHERE status='planned') planned, " "count(*) FILTER (WHERE status='unsupported') unsupported, count(*) FILTER (WHERE status='pending_configuration') pending FROM datasets").fetchone() inst = conn.execute("SELECT count(*) n, count(*) FILTER (WHERE status='active') active FROM instruments").fetchone() cov = conn.execute("SELECT count(DISTINCT symbol) symbols, count(DISTINCT session_date) sessions, sum(bar_count) bars, max(session_date) last FROM coverage WHERE dataset_id='market_bars.stock.1m.raw'").fetchone() jobs = conn.execute("SELECT status, count(*) n FROM ingest_jobs GROUP BY status").fetchall() recent = conn.execute("SELECT id, kind, dataset_id, status, started_at, finished_at, left(last_error,120) last_error, result FROM ingest_jobs ORDER BY created_at DESC LIMIT 8").fetchall() fund = conn.execute("SELECT count(DISTINCT entity_id) entities, count(*) facts FROM fundamentals_facts WHERE superseded_at IS NULL").fetchone() an = conn.execute("SELECT severity, count(*) n FROM quality_anomalies WHERE created_at > now() - interval '7 days' GROUP BY 1").fetchall() return {"datasets": ds, "instruments": inst, "bars_1m": cov, "jobs": {r["status"]: r["n"] for r in jobs}, "recent_jobs": recent, "fundamentals": fund, "anomalies_7d": {r["severity"]: r["n"] for r in an}, "health": evaluate()}