Comparaison même semaine 2026 vs 2025: barres, écart pts, objectif, données incomplètes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalid MOUTAOUAKIL 2026-04-06 23:47:01 +02:00
parent 340970c108
commit e11714c421
3 changed files with 50 additions and 26 deletions

View File

@ -0,0 +1 @@
{"1": 319, "2": 321, "3": 339, "4": 352, "5": 359, "6": 380, "7": 388, "8": 477, "9": 521, "10": 581, "11": 598, "12": 648, "13": 674, "14": 681, "15": 710, "16": 776, "17": 810, "18": 835, "19": 850, "20": 851, "21": 864, "22": 868, "23": 872, "24": 873, "25": 878, "26": 879, "27": 882, "28": 882, "29": 882, "30": 882, "31": 882, "32": 882, "33": 882, "34": 882, "35": 883, "36": 883, "37": 883, "38": 886, "39": 887, "40": 888, "41": 888, "42": 893, "43": 898, "44": 910, "45": 915, "46": 915, "47": 924, "48": 929, "49": 934, "50": 943, "51": 956, "52": 956}

View File

@ -272,11 +272,25 @@ async def audit_full_patching(request: Request, db=Depends(get_db)):
f" AND saf.{_latest}" f" AND saf.{_latest}"
)).fetchone() )).fetchone()
# Comparaison Y-1 # Comparaison Y-1 a meme semaine
compare = None compare = None
from datetime import datetime as _dt from datetime import datetime as _dt
current_week = _dt.now().isocalendar()[1] current_week = _dt.now().isocalendar()[1]
if year == 2026: if year == 2026:
# Cumulatif 2025 a la meme semaine (pre-calcule)
import json as _json, os as _os
cumul_2025_path = _os.path.join(_os.path.dirname(_os.path.abspath(__file__)), "..", "data", "cumul_2025_by_week.json")
prev_at_same_week = 0
prev_total = 1045
prev_data_ok = False
try:
with open(cumul_2025_path) as f:
cumul_2025 = _json.load(f)
prev_at_same_week = cumul_2025.get(str(current_week - 1), cumul_2025.get(str(current_week), 0))
prev_data_ok = True
except Exception:
pass
compare = db.execute(text( compare = db.execute(text(
f"SELECT" f"SELECT"
f" COUNT(*) FILTER (WHERE patch_count_2026 >= 1) as current_patched," f" COUNT(*) FILTER (WHERE patch_count_2026 >= 1) as current_patched,"
@ -284,14 +298,15 @@ async def audit_full_patching(request: Request, db=Depends(get_db)):
f" COUNT(*) as total" f" COUNT(*) as total"
f" FROM server_audit_full WHERE status IN ('ok','partial') AND {_latest}" f" FROM server_audit_full WHERE status IN ('ok','partial') AND {_latest}"
)).fetchone() )).fetchone()
elif year == 2025: compare = {
compare = db.execute(text( "current_patched": compare.current_patched,
f"SELECT" "current_total": compare.total,
f" COUNT(*) FILTER (WHERE patch_count_2025 >= 1) as current_patched," "prev_year_total": compare.prev_year_total,
f" 0 as prev_year_total," "prev_at_same_week": prev_at_same_week,
f" COUNT(*) as total" "prev_total": prev_total,
f" FROM server_audit_full WHERE status IN ('ok','partial') AND {_latest}" "prev_data_ok": prev_data_ok,
)).fetchone() "compare_week": current_week - 1,
}
patch_by_domain = db.execute(text( patch_by_domain = db.execute(text(
f"SELECT d.name as domain, d.code," f"SELECT d.name as domain, d.code,"

View File

@ -57,41 +57,49 @@
<!-- Comparaison Y-1 --> <!-- Comparaison Y-1 -->
{% if compare and year == 2026 %} {% if compare and year == 2026 %}
{% set pct_current = (compare.current_patched / compare.total * 100)|int if compare.total > 0 else 0 %} {% set pct_current = (compare.current_patched / compare.current_total * 100)|int if compare.current_total > 0 else 0 %}
{% set pct_prev = (compare.prev_year_total / compare.total * 100)|int if compare.total > 0 else 0 %} {% set pct_prev_same = (compare.prev_at_same_week / compare.prev_total * 100)|int if compare.prev_total > 0 else 0 %}
{% set diff = compare.current_patched - compare.prev_year_total %} {% set pct_prev_total = (compare.prev_year_total / compare.current_total * 100)|int if compare.current_total > 0 else 0 %}
{% set diff_pct = pct_current - pct_prev %} {% set diff_same = pct_current - pct_prev_same %}
<div class="card p-3 mb-4"> <div class="card p-3 mb-4">
<div class="text-xs text-gray-500 mb-2">Comparaison 2026 (S14) vs 2025 (année complète)</div> <div class="text-xs text-gray-500 mb-2">
Comparaison à même semaine (S{{ compare.compare_week }})
{% if not compare.prev_data_ok %}<span class="text-cyber-yellow ml-2">Données 2025 incomplètes</span>{% endif %}
</div>
<div style="display:flex;gap:12px;align-items:center;"> <div style="display:flex;gap:12px;align-items:center;">
<!-- 2026 en cours -->
<div style="flex:1;"> <div style="flex:1;">
<div class="flex justify-between text-xs mb-1"> <div class="flex justify-between text-xs mb-1">
<span class="text-cyber-accent font-bold">2026 (en cours)</span> <span class="text-cyber-accent font-bold">2026 (S{{ compare.compare_week }})</span>
<span class="font-bold {% if pct_current >= 80 %}text-cyber-green{% elif pct_current >= 50 %}text-cyber-yellow{% else %}text-cyber-red{% endif %}">{{ compare.current_patched }} / {{ compare.total }} ({{ pct_current }}%)</span> <span class="font-bold {% if pct_current >= 80 %}text-cyber-green{% elif pct_current >= 50 %}text-cyber-yellow{% else %}text-cyber-red{% endif %}">{{ compare.current_patched }} / {{ compare.current_total }} ({{ pct_current }}%)</span>
</div> </div>
<div style="height:10px;background:#1f2937;border-radius:4px;overflow:hidden;"> <div style="height:10px;background:#1f2937;border-radius:4px;overflow:hidden;">
<div style="height:100%;width:{{ pct_current }}%;background:#22c55e;border-radius:4px;"></div> <div style="height:100%;width:{{ pct_current }}%;background:#22c55e;border-radius:4px;"></div>
</div> </div>
</div> </div>
<!-- 2025 meme semaine -->
<div style="flex:1;"> <div style="flex:1;">
<div class="flex justify-between text-xs mb-1"> <div class="flex justify-between text-xs mb-1">
<span class="text-gray-400">2025 (total)</span> <span class="text-gray-400">2025 (S{{ compare.compare_week }})</span>
<span class="text-gray-400">{{ compare.prev_year_total }} / {{ compare.total }} ({{ pct_prev }}%)</span> <span class="text-gray-400">{{ compare.prev_at_same_week }} / {{ compare.prev_total }} ({{ pct_prev_same }}%)</span>
</div> </div>
<div style="height:10px;background:#1f2937;border-radius:4px;overflow:hidden;"> <div style="height:10px;background:#1f2937;border-radius:4px;overflow:hidden;">
<div style="height:100%;width:{{ pct_prev }}%;background:#6b7280;border-radius:4px;"></div> <div style="height:100%;width:{{ pct_prev_same }}%;background:#6b7280;border-radius:4px;"></div>
</div> </div>
</div> </div>
<div style="min-width:120px;text-align:center;"> <!-- Ecart -->
<div class="text-lg font-bold {% if diff >= 0 %}text-cyber-green{% else %}text-cyber-red{% endif %}"> <div style="min-width:110px;text-align:center;">
{% if diff >= 0 %}+{% endif %}{{ diff }} <div class="text-lg font-bold {% if diff_same >= 0 %}text-cyber-green{% else %}text-cyber-red{% endif %}">
{% if diff_same >= 0 %}+{% endif %}{{ diff_same }} pts
</div> </div>
<div style="font-size:10px;" class="{% if diff_pct >= 0 %}text-cyber-green{% else %}text-cyber-red{% endif %}"> <div style="font-size:10px;" class="text-gray-500">vs 2025 même semaine</div>
{% if diff_pct >= 0 %}+{% endif %}{{ diff_pct }} pts vs 2025
</div>
<div style="font-size:9px;" class="text-gray-600">S14 vs année complète</div>
</div> </div>
</div> </div>
<!-- Ligne 2025 total -->
<div class="mt-2 flex justify-between text-xs text-gray-500">
<span>2025 année complète : {{ compare.prev_year_total }} patchés ({{ pct_prev_total }}%)</span>
<span>Objectif 2026 : dépasser {{ compare.prev_year_total }}</span>
</div>
</div> </div>
{% endif %} {% endif %}