Agenda refactor

This commit is contained in:
alma 2026-01-15 13:22:43 +01:00
parent 0cdf3dd691
commit 631524b8a8
3 changed files with 57 additions and 10 deletions

View File

@ -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);

View File

@ -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),

View File

@ -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);