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 142 sources en rotation, LIMIT 20 ne montrait qu une fraction 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
autoka/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, FastAPI, HTTPException, Query |
@@ -257,7 +258,7 @@ def sources(): | ||
| 257 | 258 | |
| 258 | 259 | |
| 259 | 260 | @app.get("/api/stats") |
| 260 | −def stats(): | |
| 261 | +def stats(syncs_since_h: float | None = None): | |
| 261 | 262 | con = db.connect() |
| 262 | 263 | row = con.execute( |
| 263 | 264 | """SELECT COUNT(*) total, |
@@ -293,8 +294,18 @@ def stats(): | ||
| 293 | 294 | ORDER BY (p.prev_price - v.price) DESC LIMIT 12""")] |
| 294 | 295 | for d in drops: |
| 295 | 296 | d["images"] = json.loads(d.get("images") or "[]")[:1] |
| 296 | − log = [dict(r) for r in con.execute( | |
| 297 | − "SELECT * FROM sync_log ORDER BY ts DESC LIMIT 20")] | |
| 297 | + # fenêtre de sync paramétrable (supervision api-ka) : ?syncs_since_h=6 | |
| 298 | + # retourne toutes les entrées de la fenêtre (les ~20 dernières sinon) | |
| 299 | + if syncs_since_h is not None: | |
| 300 | + log = [dict(r) for r in con.execute( | |
| 301 | + "SELECT * FROM sync_log WHERE ts >= ? ORDER BY ts DESC LIMIT 4000", | |
| 302 | + (time.time() - syncs_since_h * 3600,))] | |
| 303 | + if len(log) < 20: # fenêtre trop courte -> minimum utile | |
| 304 | + log = [dict(r) for r in con.execute( | |
| 305 | + "SELECT * FROM sync_log ORDER BY ts DESC LIMIT 20")] | |
| 306 | + else: | |
| 307 | + log = [dict(r) for r in con.execute( | |
| 308 | + "SELECT * FROM sync_log ORDER BY ts DESC LIMIT 20")] | |
| 298 | 309 | # enrichissements vague 2 : doublons VIN masqués, rappels TC, dealers |
| 299 | 310 | extra = {"vin_duplicates_masked": con.execute( |
| 300 | 311 | "SELECT COUNT(*) c FROM vehicles WHERE active=1 AND dup_of IS NOT NULL" |
| 301 | 312 | |