stats : fenetre de sync parametrable ?syncs_since_h pour la supervision api-ka
GET /api/stats?syncs_since_h=<heures> retourne toutes les entrees de sync_log de la fenetre (ts >= now - h*3600, DESC, max 4000) au lieu des 20 dernieres — corrige les faux "stale" du moniteur central : avec 57 sources en rotation, LIMIT 20 ne montrait qu un tiers du cycle. Si la fenetre contient moins de 20 entrees, fallback aux 20 dernieres. Sans parametre : comportement inchange. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 changed file +14 −3
modified
foodka/web.py
+14 −3
@@ -7,6 +7,7 @@ from __future__ import annotations | ||
| 7 | 7 | |
| 8 | 8 | import json |
| 9 | 9 | import threading |
| 10 | +import time | |
| 10 | 11 | from pathlib import Path |
| 11 | 12 | |
| 12 | 13 | from fastapi import BackgroundTasks, Body, FastAPI, HTTPException, Query, Request |
@@ -195,7 +196,7 @@ def sources(): | ||
| 195 | 196 | |
| 196 | 197 | |
| 197 | 198 | @app.get("/api/stats") |
| 198 | −def stats(): | |
| 199 | +def stats(syncs_since_h: float | None = None): | |
| 199 | 200 | con = db.connect() |
| 200 | 201 | row = con.execute( |
| 201 | 202 | """SELECT COUNT(*) total, |
@@ -216,8 +217,18 @@ def stats(): | ||
| 216 | 217 | """SELECT * FROM products |
| 217 | 218 | WHERE active=1 AND regular_price IS NOT NULL AND price IS NOT NULL |
| 218 | 219 | ORDER BY (regular_price - price) / regular_price DESC LIMIT 24""")] |
| 219 | − log = [dict(r) for r in con.execute( | |
| 220 | − "SELECT * FROM sync_log ORDER BY ts DESC LIMIT 20")] | |
| 220 | + # fenêtre de sync paramétrable (supervision api-ka) : ?syncs_since_h=6 | |
| 221 | + # retourne toutes les entrées de la fenêtre (les ~20 dernières sinon) | |
| 222 | + if syncs_since_h is not None: | |
| 223 | + log = [dict(r) for r in con.execute( | |
| 224 | + "SELECT * FROM sync_log WHERE ts >= ? ORDER BY ts DESC LIMIT 4000", | |
| 225 | + (time.time() - syncs_since_h * 3600,))] | |
| 226 | + if len(log) < 20: # fenêtre trop courte -> minimum utile | |
| 227 | + log = [dict(r) for r in con.execute( | |
| 228 | + "SELECT * FROM sync_log ORDER BY ts DESC LIMIT 20")] | |
| 229 | + else: | |
| 230 | + log = [dict(r) for r in con.execute( | |
| 231 | + "SELECT * FROM sync_log ORDER BY ts DESC LIMIT 20")] | |
| 221 | 232 | # rapprochement inter-bannières + enrichissement nutritionnel (vague 2) |
| 222 | 233 | matching_stats = { |
| 223 | 234 | "groups": con.execute( |
| 224 | 235 | |