SPB Git forge

spb/food-ka

Public

Food-Ka — agrégateur de produits d'épicerie du Québec — www.food-ka.com

55commits 1branches 0releases
10.2 MBsize
maindefault branch
9 days agolast push
Python 53.9% TypeScript 24% CSS 14.9% JavaScript 5.8% HTML 1.4%

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>
Simon-Pierre Boucher committed 1 mo ago (Aug 23, 2026) parent b3fb45d

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