Fix QA findings: null guard on end_datetime, reminders in night briefing, extract filter
- W1: Guard end_datetime null checks in DayBriefing (lines 48, 95, 112) - W2: Include active reminders in pre-5AM night briefing fallback - S1: Extract _not_parent_template filter constant in dashboard.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b18fc0f2c8
commit
084daf5c7f
@ -14,6 +14,13 @@ from app.routers.auth import get_current_session
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
# Reusable filter: exclude parent template events (they have a real recurrence_rule).
|
||||
# Some legacy events have "" instead of NULL, so allow both.
|
||||
_not_parent_template = or_(
|
||||
CalendarEvent.recurrence_rule == None,
|
||||
CalendarEvent.recurrence_rule == "",
|
||||
)
|
||||
|
||||
|
||||
@router.get("/dashboard")
|
||||
async def get_dashboard(
|
||||
@ -31,7 +38,7 @@ async def get_dashboard(
|
||||
events_query = select(CalendarEvent).where(
|
||||
CalendarEvent.start_datetime >= today_start,
|
||||
CalendarEvent.start_datetime <= today_end,
|
||||
or_(CalendarEvent.recurrence_rule == None, CalendarEvent.recurrence_rule == ""),
|
||||
_not_parent_template,
|
||||
)
|
||||
events_result = await db.execute(events_query)
|
||||
todays_events = events_result.scalars().all()
|
||||
@ -77,7 +84,7 @@ async def get_dashboard(
|
||||
starred_query = select(CalendarEvent).where(
|
||||
CalendarEvent.is_starred == True,
|
||||
CalendarEvent.start_datetime > now,
|
||||
or_(CalendarEvent.recurrence_rule == None, CalendarEvent.recurrence_rule == ""),
|
||||
_not_parent_template,
|
||||
).order_by(CalendarEvent.start_datetime.asc()).limit(5)
|
||||
starred_result = await db.execute(starred_query)
|
||||
starred_events = starred_result.scalars().all()
|
||||
@ -158,7 +165,7 @@ async def get_upcoming(
|
||||
events_query = select(CalendarEvent).where(
|
||||
CalendarEvent.start_datetime >= today_start,
|
||||
CalendarEvent.start_datetime <= cutoff_datetime,
|
||||
or_(CalendarEvent.recurrence_rule == None, CalendarEvent.recurrence_rule == ""),
|
||||
_not_parent_template,
|
||||
)
|
||||
events_result = await db.execute(events_query)
|
||||
events = events_result.scalars().all()
|
||||
|
||||
@ -45,11 +45,13 @@ export default function DayBriefing({ upcomingItems, dashboardData, weatherData
|
||||
if (hour >= 21 || hour < 5) {
|
||||
// Before 5 AM, "today" still matters — mention remaining items
|
||||
if (todayItems.length > 0 && hour < 5) {
|
||||
const remainingToday = todayEvents.filter((e) => isAfter(new Date(e.end_datetime), now));
|
||||
const remainingToday = todayEvents.filter((e) => e.end_datetime && isAfter(new Date(e.end_datetime), now));
|
||||
if (remainingToday.length > 0) {
|
||||
parts.push(`${remainingToday.length} event${remainingToday.length > 1 ? 's' : ''} still on today.`);
|
||||
} else if (todayTodos.length > 0) {
|
||||
parts.push(`${todayTodos.length} task${todayTodos.length > 1 ? 's' : ''} due today.`);
|
||||
} else if (activeReminders.length > 0) {
|
||||
parts.push(`${activeReminders.length} reminder${activeReminders.length > 1 ? 's' : ''} set for today.`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +94,7 @@ export default function DayBriefing({ upcomingItems, dashboardData, weatherData
|
||||
}
|
||||
// Afternoon (12PM–5PM)
|
||||
else if (hour < 17) {
|
||||
const remainingEvents = todayEvents.filter((e) => isAfter(new Date(e.end_datetime), now));
|
||||
const remainingEvents = todayEvents.filter((e) => e.end_datetime && isAfter(new Date(e.end_datetime), now));
|
||||
const completedTodos = todayTodos.length === 0;
|
||||
if (remainingEvents.length === 0 && completedTodos) {
|
||||
parts.push('The rest of your afternoon is clear.');
|
||||
@ -109,7 +111,7 @@ export default function DayBriefing({ upcomingItems, dashboardData, weatherData
|
||||
}
|
||||
// Evening (5PM–9PM)
|
||||
else {
|
||||
const eveningEvents = todayEvents.filter((e) => isAfter(new Date(e.end_datetime), now));
|
||||
const eveningEvents = todayEvents.filter((e) => e.end_datetime && isAfter(new Date(e.end_datetime), now));
|
||||
if (eveningEvents.length === 0 && tomorrowItems.length === 0) {
|
||||
parts.push('Nothing left tonight, and tomorrow is clear too.');
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user