Exclude recurring parent templates from dashboard and upcoming queries

Parent template events (with recurrence_rule set) should only be visible
through their materialized children. The events router already filtered
them out, but dashboard and upcoming endpoints did not.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kyle 2026-02-22 02:21:00 +08:00
parent 56876841c7
commit a3fd0bb2f6

View File

@ -1,6 +1,6 @@
from fastapi import APIRouter, Depends, Query from fastapi import APIRouter, Depends, Query
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func from sqlalchemy import select, func, and_
from datetime import datetime, date, timedelta from datetime import datetime, date, timedelta
from typing import Optional, List, Dict, Any from typing import Optional, List, Dict, Any
@ -25,12 +25,13 @@ async def get_dashboard(
today = client_date or date.today() today = client_date or date.today()
upcoming_cutoff = today + timedelta(days=current_user.upcoming_days) upcoming_cutoff = today + timedelta(days=current_user.upcoming_days)
# Today's events # Today's events (exclude parent templates — they are hidden, children are shown)
today_start = datetime.combine(today, datetime.min.time()) today_start = datetime.combine(today, datetime.min.time())
today_end = datetime.combine(today, datetime.max.time()) today_end = datetime.combine(today, datetime.max.time())
events_query = select(CalendarEvent).where( events_query = select(CalendarEvent).where(
CalendarEvent.start_datetime >= today_start, CalendarEvent.start_datetime >= today_start,
CalendarEvent.start_datetime <= today_end CalendarEvent.start_datetime <= today_end,
CalendarEvent.recurrence_rule == None,
) )
events_result = await db.execute(events_query) events_result = await db.execute(events_query)
todays_events = events_result.scalars().all() todays_events = events_result.scalars().all()
@ -75,7 +76,8 @@ async def get_dashboard(
now = datetime.now() now = datetime.now()
starred_query = select(CalendarEvent).where( starred_query = select(CalendarEvent).where(
CalendarEvent.is_starred == True, CalendarEvent.is_starred == True,
CalendarEvent.start_datetime > now CalendarEvent.start_datetime > now,
CalendarEvent.recurrence_rule == None,
).order_by(CalendarEvent.start_datetime.asc()).limit(5) ).order_by(CalendarEvent.start_datetime.asc()).limit(5)
starred_result = await db.execute(starred_query) starred_result = await db.execute(starred_query)
starred_events = starred_result.scalars().all() starred_events = starred_result.scalars().all()
@ -152,10 +154,11 @@ async def get_upcoming(
todos_result = await db.execute(todos_query) todos_result = await db.execute(todos_query)
todos = todos_result.scalars().all() todos = todos_result.scalars().all()
# Get upcoming events (from today onward) # Get upcoming events (from today onward, exclude parent templates)
events_query = select(CalendarEvent).where( events_query = select(CalendarEvent).where(
CalendarEvent.start_datetime >= today_start, CalendarEvent.start_datetime >= today_start,
CalendarEvent.start_datetime <= cutoff_datetime, CalendarEvent.start_datetime <= cutoff_datetime,
CalendarEvent.recurrence_rule == None,
) )
events_result = await db.execute(events_query) events_result = await db.execute(events_query)
events = events_result.scalars().all() events = events_result.scalars().all()