From 2864a15817ef5f48e58f1e8c9deec2dd02108217 Mon Sep 17 00:00:00 2001 From: Khalid MOUTAOUAKIL Date: Mon, 6 Apr 2026 16:29:52 +0200 Subject: [PATCH] KPIs audit complet: reboot, disque 90%/80%, uptime > 4 mois, filtres cliquables Co-Authored-By: Claude Opus 4.6 (1M context) --- app/routers/audit_full.py | 53 +++++++++++++++++++++++++++++- app/templates/audit_full_list.html | 28 ++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/app/routers/audit_full.py b/app/routers/audit_full.py index 7323683..b2bf73b 100644 --- a/app/routers/audit_full.py +++ b/app/routers/audit_full.py @@ -25,9 +25,60 @@ async def audit_full_list(request: Request, db=Depends(get_db)): return RedirectResponse(url="/dashboard") audits = get_latest_audits(db) + filtre = request.query_params.get("filter", "") + + # KPIs + kpis = db.execute(text(""" + SELECT + COUNT(*) as total, + COUNT(*) FILTER (WHERE reboot_required = true) as needs_reboot, + COUNT(*) FILTER (WHERE EXISTS ( + SELECT 1 FROM jsonb_array_elements(disk_usage) d + WHERE (d->>'pct')::int >= 90 + )) as disk_critical, + COUNT(*) FILTER (WHERE EXISTS ( + SELECT 1 FROM jsonb_array_elements(disk_usage) d + WHERE (d->>'pct')::int >= 80 AND (d->>'pct')::int < 90 + )) as disk_warning, + COUNT(*) FILTER (WHERE + uptime LIKE '%month%' OR uptime LIKE '%year%' + OR uptime LIKE '%week%' AND ( + CASE WHEN uptime ~ '(\d+) week' THEN (substring(uptime from '(\d+) week'))::int ELSE 0 END >= 17 + ) + ) as uptime_long + FROM server_audit_full + WHERE status = 'ok' + AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) + """)).fetchone() + + # Filtrer si demande + if filtre == "reboot": + audits = [a for a in audits if a.reboot_required] + elif filtre == "disk_critical": + ids = db.execute(text(""" + SELECT saf.id FROM server_audit_full saf + WHERE saf.status = 'ok' AND EXISTS ( + SELECT 1 FROM jsonb_array_elements(saf.disk_usage) d WHERE (d->>'pct')::int >= 90 + ) AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) + """)).fetchall() + id_set = {r.id for r in ids} + audits = [a for a in audits if a.id in id_set] + elif filtre == "disk_warning": + ids = db.execute(text(""" + SELECT saf.id FROM server_audit_full saf + WHERE saf.status = 'ok' AND EXISTS ( + SELECT 1 FROM jsonb_array_elements(saf.disk_usage) d WHERE (d->>'pct')::int >= 80 + ) AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) + """)).fetchall() + id_set = {r.id for r in ids} + audits = [a for a in audits if a.id in id_set] + elif filtre == "uptime": + audits = [a for a in audits if a.uptime and ("month" in a.uptime or "year" in a.uptime)] + ctx = base_context(request, db, user) ctx.update({ - "app_name": APP_NAME, "audits": audits, + "app_name": APP_NAME, "audits": audits, "kpis": kpis, + "filter": filtre, "msg": request.query_params.get("msg"), }) return templates.TemplateResponse("audit_full_list.html", ctx) diff --git a/app/templates/audit_full_list.html b/app/templates/audit_full_list.html index f0c770e..74a5044 100644 --- a/app/templates/audit_full_list.html +++ b/app/templates/audit_full_list.html @@ -24,6 +24,34 @@ {% endif %} +{% if kpis %} + +{% if filter %} +
Filtre actif : {{ filter }} ({{ audits|length }} serveurs) — Tout voir
+{% endif %} +{% endif %} + {% if audits %}