From 866f514f102ed92721f707d78981a1db6ad34880 Mon Sep 17 00:00:00 2001 From: mARTin Date: Tue, 24 Feb 2026 00:26:04 +0100 Subject: [PATCH] fix: detect iCloud all-day events and bypass cache on manual refresh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Apple calendar parser now checks ICAL.js isDate flag and emits date-only strings (YYYY-MM-DD) for all-day events instead of full ISO datetime — fixes all-day detection in the frontend - Calendar events mapper routes date-only Apple events to the date field instead of always using dateTime - Manual refresh button now sends forceRefresh=true which makes the sync endpoint wait for live data instead of returning stale cache - Automatic background syncs still use fire-and-forget for performance v1.2.2 Co-Authored-By: Claude Opus 4.6 --- package.json | 2 +- src/app/api/calendar/sync/route.ts | 22 +++++++++++++++++++--- src/components/WeeklyView.tsx | 5 +++-- src/lib/apple-calendar.ts | 16 ++++++++++------ src/lib/calendar-events.ts | 16 ++++++++++------ 5 files changed, 43 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index af5b4b4..85bfb5c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.2.1", + "version": "1.2.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/src/app/api/calendar/sync/route.ts b/src/app/api/calendar/sync/route.ts index c9740a7..2f844e2 100644 --- a/src/app/api/calendar/sync/route.ts +++ b/src/app/api/calendar/sync/route.ts @@ -47,9 +47,9 @@ export async function POST(request: NextRequest) { ); const staleConnections = staleChecks.filter(c => c.stale).map(c => c.conn); - // BACKGROUND REFRESH: fire-and-forget for stale connections + // Refresh stale connections if (staleConnections.length > 0) { - const refreshWork = Promise.allSettled( + const doRefresh = () => Promise.allSettled( staleConnections.map(conn => { const rc: RefreshableConnection = { dbId: conn.id, @@ -64,7 +64,23 @@ export async function POST(request: NextRequest) { return refreshConnectionCache(rc, timeMinDate, timeMaxDate); }) ); - refreshWork.catch(e => console.error('[CACHE] Background refresh error:', e)); + + if (forceRefresh) { + // BLOCKING: wait for fresh data when user explicitly requests refresh + await doRefresh(); + const freshEvents = await readCachedEvents(user.id, timeMinDate, timeMaxDate); + return NextResponse.json({ + success: true, + events: freshEvents, + count: freshEvents.length, + fromCache: false, + staleConnectionCount: 0, + }); + } else { + // BACKGROUND: fire-and-forget for automatic refresh + const refreshWork = doRefresh(); + refreshWork.catch(e => console.error('[CACHE] Background refresh error:', e)); + } } return NextResponse.json({ diff --git a/src/components/WeeklyView.tsx b/src/components/WeeklyView.tsx index 2c458d1..f8f6d61 100644 --- a/src/components/WeeklyView.tsx +++ b/src/components/WeeklyView.tsx @@ -857,7 +857,7 @@ export default function WeeklyView() { const workingHoursEnd = endHour; // Fetch calendar events - const fetchCalendarEvents = useCallback(async () => { + const fetchCalendarEvents = useCallback(async (forceRefresh = false) => { setIsSyncing(true); try { const response = await fetch("/api/calendar/sync", { @@ -868,6 +868,7 @@ export default function WeeklyView() { timeMax: new Date( currentWeekStart.getTime() + 7 * 24 * 60 * 60 * 1000, ).toISOString(), + forceRefresh, }), }); @@ -3394,7 +3395,7 @@ export default function WeeklyView() {
) : (