Agenda refactor
This commit is contained in:
parent
0cdf3dd691
commit
631524b8a8
@ -378,14 +378,14 @@ export default async function CalendarPage() {
|
||||
|
||||
// Trigger sync for Microsoft calendars that need it (async, don't wait)
|
||||
for (const syncConfig of microsoftSyncConfigs) {
|
||||
// For Microsoft, use a more frequent check (2 minutes) for better reactivity
|
||||
// For Microsoft, use a more frequent check (1 minute) for better reactivity
|
||||
// This allows new events to appear faster without overloading the API
|
||||
const microsoftMinSyncInterval = 2; // minutes
|
||||
const microsoftMinSyncInterval = 1; // minutes (reduced from 2 to 1 for faster sync)
|
||||
const minutesSinceLastSync = syncConfig.lastSyncAt
|
||||
? (Date.now() - syncConfig.lastSyncAt.getTime()) / (1000 * 60)
|
||||
: Infinity;
|
||||
|
||||
// Sync if never synced, or if enough time has passed (use minimum of 2 min or configured frequency)
|
||||
// Sync if never synced, or if enough time has passed (use minimum of 1 min or configured frequency)
|
||||
const needsSync = !syncConfig.lastSyncAt ||
|
||||
minutesSinceLastSync >= Math.min(microsoftMinSyncInterval, syncConfig.syncFrequency);
|
||||
|
||||
|
||||
@ -98,22 +98,31 @@ export async function GET(req: NextRequest) {
|
||||
});
|
||||
|
||||
// Extract mission calendars (excluding those already in personalCalendars)
|
||||
// Use a Set to avoid duplicate calendars by ID
|
||||
const personalCalendarIds = new Set(personalCalendars.map(cal => cal.id));
|
||||
const missionCalendars = missionUserRelations
|
||||
.flatMap(mu => mu.mission.calendars)
|
||||
.filter(cal => cal.userId !== session.user.id); // Exclude calendars owned by user (already in personalCalendars)
|
||||
.filter(cal => !personalCalendarIds.has(cal.id)); // Exclude calendars already in personalCalendars
|
||||
|
||||
// Combine personal and mission calendars
|
||||
const calendars = [...personalCalendars, ...missionCalendars];
|
||||
|
||||
// Remove duplicate calendars by ID (in case same calendar appears multiple times)
|
||||
const uniqueCalendars = Array.from(
|
||||
new Map(calendars.map(cal => [cal.id, cal])).values()
|
||||
);
|
||||
|
||||
logger.debug('[CALENDAR] Fetched calendars with events', {
|
||||
userId: session.user.id,
|
||||
count: calendars.length,
|
||||
personalCount: personalCalendars.length,
|
||||
missionCount: missionCalendars.length,
|
||||
totalCount: uniqueCalendars.length,
|
||||
});
|
||||
|
||||
// Cache the results
|
||||
await cacheCalendarData(session.user.id, calendars);
|
||||
await cacheCalendarData(session.user.id, uniqueCalendars);
|
||||
|
||||
return NextResponse.json(calendars);
|
||||
return NextResponse.json(uniqueCalendars);
|
||||
} catch (error) {
|
||||
logger.error('[CALENDAR] Erreur lors de la récupération des calendriers', {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
|
||||
@ -477,6 +477,14 @@ export async function syncMicrosoftCalendar(
|
||||
? existingEventsByExternalId.get(microsoftId)
|
||||
: undefined;
|
||||
|
||||
if (existingEvent) {
|
||||
logger.debug('Matched event by externalEventId', {
|
||||
microsoftId,
|
||||
eventId: existingEvent.id,
|
||||
title: caldavEvent.summary,
|
||||
});
|
||||
}
|
||||
|
||||
// Priority 2: Fallback to checking description for [MS_ID:xxx] (backward compatibility)
|
||||
if (!existingEvent && microsoftId) {
|
||||
existingEvent = existingEvents.find((e) => {
|
||||
@ -487,23 +495,53 @@ export async function syncMicrosoftCalendar(
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (existingEvent) {
|
||||
logger.debug('Matched event by description [MS_ID]', {
|
||||
microsoftId,
|
||||
eventId: existingEvent.id,
|
||||
title: caldavEvent.summary,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Priority 3: Fallback to title + date matching for events without externalEventId
|
||||
// IMPORTANT: Only match if the event doesn't have an externalEventId (to avoid false matches)
|
||||
if (!existingEvent) {
|
||||
existingEvent = existingEvents.find(
|
||||
(e) => {
|
||||
// Access externalEventId safely (may not be in Prisma type if client not regenerated)
|
||||
const hasExternalId = !!(e as any).externalEventId;
|
||||
if (!hasExternalId && // Only match events that don't have externalEventId yet
|
||||
e.title === caldavEvent.summary) {
|
||||
// Only match events that don't have externalEventId yet (to avoid false matches)
|
||||
if (hasExternalId) {
|
||||
return false; // Skip events that already have externalEventId
|
||||
}
|
||||
|
||||
// Match by title and date (within 1 minute)
|
||||
if (e.title === caldavEvent.summary) {
|
||||
const timeDiff = Math.abs(new Date(e.start).getTime() - caldavEvent.start.getTime());
|
||||
return timeDiff < 60000; // Within 1 minute
|
||||
if (timeDiff < 60000) { // Within 1 minute
|
||||
logger.debug('Matched event by title + date (no externalEventId)', {
|
||||
eventId: e.id,
|
||||
title: caldavEvent.summary,
|
||||
timeDiff,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Log if no match found (new event)
|
||||
if (!existingEvent) {
|
||||
logger.debug('No match found, will create new event', {
|
||||
microsoftId,
|
||||
title: caldavEvent.summary,
|
||||
start: caldavEvent.start.toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
// Clean description (remove [MS_ID:xxx] prefix if present from previous syncs)
|
||||
const cleanedDescription = cleanDescription(caldavEvent.description);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user