fix: calendar check-in digest drops events 7-8 days out (#1249)

* fix: close 1-day gap in calendar digest windows (events ~7-8 days out)

* test: calendar digest windows are contiguous and cover 7-8 day events
This commit is contained in:
Afonso Coutinho
2026-06-02 17:03:58 +01:00
committed by GitHub
parent 44e0259163
commit 311f226d44
2 changed files with 37 additions and 5 deletions

View File

@@ -203,6 +203,20 @@ RETIRED_HOUSEKEEPING_ACTIONS = frozenset({
})
def _digest_windows(now):
"""(label, start, end) buckets for the calendar check-in digest.
The windows are contiguous so no event is dropped between buckets — an
earlier version started the 30-day window at now+8d while the week window
ended at now+7d, so events ~7-8 days out fell into no bucket.
"""
return [
("today_tomorrow", now, now + timedelta(days=2)),
("this_week", now + timedelta(days=2), now + timedelta(days=7)),
("next_30_days", now + timedelta(days=7), now + timedelta(days=30)),
]
class TaskScheduler:
def __init__(self, session_manager):
self._session_manager = session_manager
@@ -1082,11 +1096,7 @@ class TaskScheduler:
from core.database import SessionLocal as _SL, CalendarEvent as _CE
_db = _SL()
try:
for label, start, end in [
("today_tomorrow", now, now + timedelta(days=2)),
("this_week", now + timedelta(days=2), now + timedelta(days=7)),
("next_30_days", now + timedelta(days=8), now + timedelta(days=30)),
]:
for label, start, end in _digest_windows(now):
# Strip timezone for naive DB comparison
_s = start.replace(tzinfo=None) if start.tzinfo else start
_e = end.replace(tzinfo=None) if end.tzinfo else end

View File

@@ -0,0 +1,22 @@
"""Tests for the calendar check-in digest windows (src/task_scheduler.py)."""
from datetime import datetime, timedelta
from src.task_scheduler import _digest_windows
def test_windows_are_contiguous_with_no_gap():
now = datetime(2026, 6, 2, 9, 0, 0)
windows = _digest_windows(now)
# Each window starts exactly where the previous ended — no gap between
# buckets (the old code jumped from now+7d to now+8d, dropping events).
for (prev, cur) in zip(windows, windows[1:]):
assert cur[1] == prev[2]
assert windows[0][1] == now
assert windows[-1][2] == now + timedelta(days=30)
def test_event_seven_and_a_half_days_out_is_covered():
now = datetime(2026, 6, 2, 9, 0, 0)
event = now + timedelta(days=7, hours=12) # fell in the old 7-8 day gap
buckets = [label for label, start, end in _digest_windows(now) if start <= event <= end]
assert buckets, "event ~7.5 days out should land in a digest window"