fix: show all events (including weekly recurring) in Telegram bot
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 20s

get_schedule_for_date, show_items_for_deletion, and send_reminders were
querying events with Event.date == date_str, which only matches one-off
events or a recurring event's anchor date. Recurring events on later
occurrences (and any per-date exception overrides) were silently
skipped, so /today could show just one event when several were
scheduled. Switched all three to materialize_events, already used by
the web frontends, which correctly expands recurring events.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
vrubel 2026-07-16 14:37:34 +00:00
parent c40a6569b4
commit 4dc060d8d6

View file

@ -12,7 +12,7 @@ import asyncio
import logging import logging
from backend.database import AsyncSessionLocal, Task, Event, TelegramUser from backend.database import AsyncSessionLocal, Task, Event, TelegramUser
from backend.utils import get_week_range, format_date_russian, check_event_overlap, get_weekday_from_date from backend.utils import get_week_range, format_date_russian, check_event_overlap, get_weekday_from_date, materialize_events
from backend.models import TaskCreate, EventCreate from backend.models import TaskCreate, EventCreate
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
@ -58,13 +58,10 @@ async def get_schedule_for_date(date_str: str, add_prefix: bool = False) -> str:
weekly_items = await materialize_weekly_tasks(db, date_str, date_str) weekly_items = await materialize_weekly_tasks(db, date_str, date_str)
weekly_tasks = [item for item in weekly_items if item.kind == "task"] weekly_tasks = [item for item in weekly_items if item.kind == "task"]
# Получаем events # Получаем events (включая еженедельные повторения и исключения)
result = await db.execute( events = await materialize_events(db, date_str, date_str)
select(Event).where(Event.date == date_str)
)
events = result.scalars().all()
events = sorted(events, key=lambda e: e.start_time) events = sorted(events, key=lambda e: e.start_time)
# Определяем префикс для даты # Определяем префикс для даты
date_prefix = "" date_prefix = ""
if add_prefix: if add_prefix:
@ -523,13 +520,10 @@ async def show_items_for_deletion(query, date_str: str):
weekly_items = await materialize_weekly_tasks(db, date_str, date_str) weekly_items = await materialize_weekly_tasks(db, date_str, date_str)
weekly_tasks = [item for item in weekly_items if item.kind == "task"] weekly_tasks = [item for item in weekly_items if item.kind == "task"]
# Получаем events # Получаем events (включая еженедельные повторения и исключения)
result = await db.execute( events = await materialize_events(db, date_str, date_str)
select(Event).where(Event.date == date_str)
)
events = result.scalars().all()
events = sorted(events, key=lambda e: e.start_time) events = sorted(events, key=lambda e: e.start_time)
keyboard = [] keyboard = []
items_list = [] items_list = []
@ -661,17 +655,11 @@ async def send_reminders():
target_time_str = target_time.strftime("%H:%M") target_time_str = target_time.strftime("%H:%M")
async with AsyncSessionLocal() as db: async with AsyncSessionLocal() as db:
# Находим события, которые начинаются через 5 минут # Находим события (включая еженедельные), которые начинаются через 5 минут
result = await db.execute( target_date_str = target_date.strftime("%Y-%m-%d")
select(Event).where( day_events = await materialize_events(db, target_date_str, target_date_str)
and_( events = [event for event in day_events if event.start_time == target_time_str]
Event.date == target_date.strftime("%Y-%m-%d"),
Event.start_time == target_time_str
)
)
)
events = result.scalars().all()
if events: if events:
# Получаем всех пользователей # Получаем всех пользователей
result = await db.execute(select(TelegramUser)) result = await db.execute(select(TelegramUser))