- Fix All Day checkbox positioning in CalendarEventModal (own row) - Add provider name to calendar dropdown (Google/Apple/Outlook) - Optimistic UI updates after event save/delete (no reload needed) - Force-refresh calendar cache after event mutations - Reduce background sync interval from 5min to 2min - Support forceRefresh in background-sync API - Use shared Prisma singleton in tasks sync route - Add per-provider task list fetching and sync checkboxes - Add allDay support to event creation and editing v1.4.0
64 lines
2.4 KiB
TypeScript
64 lines
2.4 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { getServerSession } from 'next-auth';
|
|
import { authOptions } from "@/lib/auth";
|
|
import { prisma } from '@/lib/prisma';
|
|
import { isCacheStale, refreshConnectionCache, RefreshableConnection } from '@/lib/calendar-cache';
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const session = await getServerSession(authOptions);
|
|
if (!session?.user?.email) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
const body = await request.json().catch(() => ({}));
|
|
const { timeMin, timeMax, forceRefresh } = body;
|
|
|
|
const user = await prisma.user.findUnique({
|
|
where: { email: session.user.email },
|
|
include: { calendarConnections: true },
|
|
});
|
|
|
|
if (!user || user.calendarConnections.length === 0) {
|
|
return NextResponse.json({ queued: 0 });
|
|
}
|
|
|
|
const now = new Date();
|
|
const tMin = timeMin ? new Date(timeMin) : new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
const tMax = timeMax ? new Date(timeMax) : new Date(now.getTime() + 14 * 24 * 60 * 60 * 1000);
|
|
|
|
const staleChecks = await Promise.all(
|
|
user.calendarConnections.map(async conn => ({
|
|
conn,
|
|
stale: forceRefresh || await isCacheStale(conn.id, tMin),
|
|
}))
|
|
);
|
|
|
|
const toRefresh = staleChecks.filter(c => c.stale).map(c => c.conn);
|
|
|
|
if (toRefresh.length > 0) {
|
|
// Fire-and-forget
|
|
Promise.allSettled(
|
|
toRefresh.map(conn => {
|
|
const rc: RefreshableConnection = {
|
|
dbId: conn.id,
|
|
userId: user.id,
|
|
id: conn.id,
|
|
provider: conn.provider as 'google' | 'apple' | 'outlook',
|
|
accessToken: conn.accessToken,
|
|
refreshToken: conn.refreshToken ?? undefined,
|
|
expiresAt: conn.expiresAt ?? undefined,
|
|
calendars: conn.calendars as any,
|
|
};
|
|
return refreshConnectionCache(rc, tMin, tMax);
|
|
})
|
|
).catch(e => console.error('[BG SYNC]', e));
|
|
}
|
|
|
|
return NextResponse.json({ queued: toRefresh.length });
|
|
} catch (error) {
|
|
console.error('[BG SYNC] Error:', error);
|
|
return NextResponse.json({ queued: 0 });
|
|
}
|
|
}
|