# ============================================================ # routers/dashboard.py — Vue consolidée (VUE_CONSO) # ============================================================ from typing import Optional from fastapi import APIRouter, Depends, Query from auth import get_current_user from config import get_cursor from helpers import row_to_dict, rows_to_list router = APIRouter(dependencies=[Depends(get_current_user)], tags=["Dashboard"]) @router.get("") def get_dashboard( service : Optional[str] = Query(None, description="Filtrer par service"), categorie : Optional[str] = Query(None, description="Filtrer par catégorie"), ): """Vue consolidée — source principale du dashboard.""" query = ( "SELECT id_monito, nom_monito, nb_erreurs, service, categorie, bdd_source " "FROM VUE_CONSO WHERE 1=1" ) params = [] if service: query += " AND service = ?" params.append(service) if categorie: query += " AND categorie = ?" params.append(categorie) query += " ORDER BY nb_erreurs DESC" with get_cursor() as cursor: cursor.execute(query, *params) return rows_to_list(cursor, cursor.fetchall()) @router.get("/filtres") def get_dashboard_filtres(): """ Valeurs de filtre réellement présentes dans VUE_CONSO. Les référentiels SERVICE / CATEGORIE contiennent des entrées auxquelles aucun monitoring actif n'est rattaché (ex. « Business Intelligence »). Les proposer dans les menus déroulants du dashboard mène à un écran vide : cet endpoint ne renvoie que les valeurs qui ramènent au moins un monitoring. `combinaisons` permet au frontend de restreindre les catégories proposées au service sélectionné. """ with get_cursor() as cursor: cursor.execute( "SELECT DISTINCT service, categorie FROM VUE_CONSO " "ORDER BY service, categorie" ) combinaisons = [{"service": r[0], "categorie": r[1]} for r in cursor.fetchall()] return { "services" : sorted({c["service"] for c in combinaisons}), "categories" : sorted({c["categorie"] for c in combinaisons}), "combinaisons" : combinaisons, } @router.get("/summary") def get_dashboard_summary(): """KPI globaux pour les 4 cartes du dashboard.""" with get_cursor() as cursor: cursor.execute(""" SELECT COUNT(*) AS nb_monitorings, SUM(nb_erreurs) AS total_erreurs, MAX(nb_erreurs) AS max_erreurs, SUM(CASE WHEN nb_erreurs = 0 THEN 1 ELSE 0 END) AS monitorings_ok, SUM(CASE WHEN nb_erreurs > 0 THEN 1 ELSE 0 END) AS monitorings_en_erreur FROM VUE_CONSO """) summary = row_to_dict(cursor, cursor.fetchone()) cursor.execute( "SELECT TOP 1 id_monito, nom_monito, nb_erreurs, service, bdd_source " "FROM VUE_CONSO ORDER BY nb_erreurs DESC" ) top = cursor.fetchone() summary["monitoring_critique"] = row_to_dict(cursor, top) if top else None return summary