diff --git a/app/routers/dashboard.py b/app/routers/dashboard.py index 0094131..c74ea31 100644 --- a/app/routers/dashboard.py +++ b/app/routers/dashboard.py @@ -28,6 +28,27 @@ async def dashboard(request: Request, db=Depends(get_db)): stats["qualys_active"] = db.execute(text("SELECT COUNT(*) FROM qualys_assets WHERE agent_status ILIKE '%active%' AND agent_status NOT ILIKE '%inactive%'")).scalar() stats["qualys_inactive"] = db.execute(text("SELECT COUNT(*) FROM qualys_assets WHERE agent_status ILIKE '%inactive%'")).scalar() stats["qualys_no_agent"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE etat='Production' AND NOT EXISTS (SELECT 1 FROM qualys_assets qa WHERE LOWER(qa.hostname) = LOWER(servers.hostname))")).scalar() + # Alias : template utilise stats.eol + stats["eol"] = stats["obsolete"] + # Zone DMZ + stats["dmz"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE zone_id = (SELECT id FROM zones WHERE is_dmz=true LIMIT 1)")).scalar() + # Patching depuis patch_history (Excel 2026) + stats["patched_history_2026"] = db.execute(text( + "SELECT COUNT(DISTINCT server_id) FROM patch_history WHERE EXTRACT(YEAR FROM date_patch)=2026" + )).scalar() + stats["patch_events_2026"] = db.execute(text( + "SELECT COUNT(*) FROM patch_history WHERE EXTRACT(YEAR FROM date_patch)=2026" + )).scalar() + stats["never_patched_2026"] = db.execute(text(""" + SELECT COUNT(*) FROM servers s + WHERE s.etat='Production' AND s.patch_os_owner='secops' + AND NOT EXISTS (SELECT 1 FROM patch_history ph + WHERE ph.server_id=s.id AND EXTRACT(YEAR FROM ph.date_patch)=2026) + """)).scalar() + # Semaine la plus recente + stats["last_patch_week"] = db.execute(text( + "SELECT MAX(TO_CHAR(date_patch, 'IW')) FROM patch_history WHERE EXTRACT(YEAR FROM date_patch)=2026" + )).scalar() # Par domaine domains = db.execute(text(""" diff --git a/app/templates/dashboard.html b/app/templates/dashboard.html index 5cecd5b..84e12e3 100644 --- a/app/templates/dashboard.html +++ b/app/templates/dashboard.html @@ -4,15 +4,26 @@