From 58204e621e10834d54e775519cc502b1b5b6b3d5 Mon Sep 17 00:00:00 2001 From: Spark Date: Sun, 11 Oct 2026 20:15:23 -0400 Subject: [PATCH] =?UTF-8?q?fix(forecast):=20semaines=20cal=C3=A9es=20sur?= =?UTF-8?q?=20le=20r=C3=A9f=C3=A9rentiel=20UTC=20du=20journal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les horodatages board_events sont en UTC (SQLite): une fermeture en soirée locale tombait hors des semaines locales et faussait le débit hebdomadaire. --- app/forecast.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/forecast.py b/app/forecast.py index e3cac4f..e6e6c13 100644 --- a/app/forecast.py +++ b/app/forecast.py @@ -7,7 +7,15 @@ date, and are withheld entirely when the journal has no closures to learn from — "not enough history" is an answer, too. """ -from datetime import date, datetime, timedelta +from datetime import date, datetime, timedelta, timezone + + +def _journal_today() -> date: + """'Today' in the journal's frame: board_events stamps are UTC + (SQLite datetime('now')), so week buckets anchor to UTC — + otherwise closures logged in the local evening (already + tomorrow in UTC) fall outside every bucket.""" + return datetime.now(timezone.utc).date() MONTHS_FR = [ "janvier", "février", "mars", "avril", "mai", "juin", @@ -35,7 +43,7 @@ def _event_date(event: dict) -> date | None: def weekly_closures(events: list[dict], weeks: int = 8, today: date | None = None) -> list[dict]: """Closure counts per ISO week, oldest first, current week last.""" - today = today or date.today() + today = today or _journal_today() current_monday = today - timedelta(days=today.weekday()) buckets: list[dict] = [] for i in range(weeks - 1, -1, -1): @@ -83,7 +91,7 @@ def estimate(remaining: int, weekly: list[dict], no throughput to project from, else dates: central (avg rate), earliest (best week), latest (worst nonzero week, if any). """ - today = today or date.today() + today = today or _journal_today() if remaining <= 0: return {"done": True} stats = throughput_stats(weekly)