From a32e5601d0050c095f8fc5ae3279b5c8fd632650 Mon Sep 17 00:00:00 2001 From: mARTin Date: Mon, 16 Mar 2026 22:22:58 +0100 Subject: [PATCH] fix: push scheduler handles all-day events and adds debug logging - Query both timed (startDateTime) and all-day (startDate) events - All-day events treated as starting at 07:00 UTC (~09:00 CET) - Log number of events found per user for debugging - Skip already-passed events to avoid unnecessary checks v1.37.2 --- package.json | 2 +- scripts/push-scheduler.ts | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index c7fc7c1..87f8b1a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.37.1", + "version": "1.37.2", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/scripts/push-scheduler.ts b/scripts/push-scheduler.ts index 1c2acf8..49fabd3 100644 --- a/scripts/push-scheduler.ts +++ b/scripts/push-scheduler.ts @@ -66,23 +66,42 @@ async function run() { const windowEnd = new Date(now); windowEnd.setDate(windowEnd.getDate() + 7); + // Find events with reminders: both timed and all-day const events = await prisma.cachedCalendarEvent.findMany({ where: { userId: user.id, - startDateTime: { gte: now, lte: windowEnd }, reminders: { not: null }, + OR: [ + { startDateTime: { gte: now, lte: windowEnd } }, + { startDate: { not: null } }, + ], }, select: { externalId: true, title: true, startDateTime: true, + startDate: true, reminders: true, calendarTitle: true, }, }); + console.log(`[Push Scheduler] Found ${events.length} events with reminders for user ${user.id}`); + for (const event of events) { - if (!event.startDateTime || !event.reminders) continue; + // Determine the event start time + let eventStart: Date | null = event.startDateTime; + if (!eventStart && event.startDate) { + // All-day events: treat as starting at 09:00 local time (user timezone) + // Parse the date string and set to 09:00 UTC as approximation + // (for CET/CEST this means ~10:00/11:00 local, close enough for day-before reminders) + eventStart = new Date(event.startDate + 'T07:00:00.000Z'); + } + if (!eventStart || !event.reminders) continue; + + // Skip events that already passed + const maxReminderMinutes = 10080; // 1 week + if (eventStart.getTime() + maxReminderMinutes * 60 * 1000 < now.getTime()) continue; let reminders: Reminder[] = []; try { @@ -96,7 +115,7 @@ async function run() { if (reminder.minutes < 0) continue; // Calculate when notification should fire - const notifyAt = new Date(event.startDateTime.getTime() - reminder.minutes * 60 * 1000); + const notifyAt = new Date(eventStart.getTime() - reminder.minutes * 60 * 1000); // Check if we're within the 1-minute window const diffMs = Math.abs(now.getTime() - notifyAt.getTime()); @@ -116,7 +135,7 @@ async function run() { if (alreadySent) continue; // Build notification payload - const timeStr = event.startDateTime.toLocaleTimeString('en-US', { + const timeStr = eventStart.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: false,