Agenda refactor

This commit is contained in:
alma 2026-01-14 16:58:04 +01:00
parent 16757ea90e
commit cb967a0ca6
2 changed files with 105 additions and 10 deletions

View File

@ -132,18 +132,29 @@ export default async function CalendarPage() {
});
// For each Infomaniak account, ensure there's a synced calendar
for (const account of infomaniakAccounts) {
// Check if a calendar sync already exists for this account
// Skip if no Infomaniak accounts exist (user may only have Microsoft accounts)
if (infomaniakAccounts.length > 0) {
for (const account of infomaniakAccounts) {
// Check if a calendar sync already exists for this account (enabled or disabled)
// This prevents creating duplicate calendars for the same account
const existingSync = await prisma.calendarSync.findFirst({
where: {
mailCredentialId: account.id,
syncEnabled: true
mailCredentialId: account.id
},
include: {
calendar: true
}
});
// If sync exists but is disabled, re-enable it instead of creating a new calendar
if (existingSync && !existingSync.syncEnabled) {
await prisma.calendarSync.update({
where: { id: existingSync.id },
data: { syncEnabled: true }
});
continue; // Skip to next account
}
if (!existingSync) {
// Try to discover calendars for this account
try {
@ -199,25 +210,36 @@ export default async function CalendarPage() {
}
}
} catch (error) {
console.error(`Error auto-setting up sync for Infomaniak account ${account.email}:`, error);
// Log error but don't fail the page - account may not have calendar access or credentials may be invalid
console.log(`Infomaniak calendar sync not available for ${account.email} - ${error instanceof Error ? error.message : 'Unknown error'}`);
// Continue with other accounts even if one fails
}
}
}
}
// For each Microsoft account, ensure there's a synced calendar
for (const account of microsoftAccounts) {
// Check if a calendar sync already exists for this account
// Check if a calendar sync already exists for this account (enabled or disabled)
// This prevents creating duplicate calendars for the same account
const existingSync = await prisma.calendarSync.findFirst({
where: {
mailCredentialId: account.id,
syncEnabled: true
mailCredentialId: account.id
},
include: {
calendar: true
}
});
// If sync exists but is disabled, re-enable it instead of creating a new calendar
if (existingSync && !existingSync.syncEnabled) {
await prisma.calendarSync.update({
where: { id: existingSync.id },
data: { syncEnabled: true }
});
continue; // Skip to next account
}
if (!existingSync) {
// Try to discover calendars for this account
try {
@ -282,7 +304,72 @@ export default async function CalendarPage() {
}
}
// Refresh calendars after auto-setup
// Clean up duplicate calendars for the same mailCredentialId
// Keep only the most recent one with syncEnabled=true, delete others
const allSyncs = await prisma.calendarSync.findMany({
where: {
calendar: {
userId: session?.user?.id || ''
}
},
include: {
calendar: true,
mailCredential: true
},
orderBy: {
createdAt: 'desc'
}
});
// Group by mailCredentialId and provider
const syncsByAccount = new Map<string, typeof allSyncs>();
for (const sync of allSyncs) {
if (sync.mailCredentialId) {
const key = `${sync.mailCredentialId}-${sync.provider}`;
if (!syncsByAccount.has(key)) {
syncsByAccount.set(key, []);
}
syncsByAccount.get(key)!.push(sync);
}
}
// For each account, keep only the most recent enabled sync, disable or delete others
for (const [key, syncs] of syncsByAccount.entries()) {
if (syncs.length > 1) {
// Sort by syncEnabled first (enabled first), then by createdAt (newest first)
syncs.sort((a, b) => {
if (a.syncEnabled !== b.syncEnabled) {
return a.syncEnabled ? -1 : 1;
}
return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
});
const keepSync = syncs[0];
const duplicates = syncs.slice(1);
// Disable or delete duplicate syncs
for (const duplicate of duplicates) {
if (duplicate.syncEnabled) {
// Disable the duplicate sync
await prisma.calendarSync.update({
where: { id: duplicate.id },
data: { syncEnabled: false }
});
}
// Delete the calendar if it has no events
const eventCount = await prisma.event.count({
where: { calendarId: duplicate.calendarId }
});
if (eventCount === 0) {
await prisma.calendar.delete({
where: { id: duplicate.calendarId }
});
}
}
}
}
// Refresh calendars after auto-setup and cleanup
// Exclude "Privée" and "Default" calendars that are not synced
calendars = await prisma.calendar.findMany({
where: {
@ -336,6 +423,11 @@ export default async function CalendarPage() {
const hasActiveSync = cal.syncConfig?.syncEnabled === true && cal.syncConfig?.mailCredential;
// Exclude "Privée"/"Default" calendars that are not actively synced
// Also log for debugging if Infomaniak calendar is missing
if (isPrivateOrDefault && cal.syncConfig?.provider === 'infomaniak' && !hasActiveSync) {
console.log(`Infomaniak calendar found but sync is disabled: ${cal.id}, syncEnabled: ${cal.syncConfig?.syncEnabled}`);
}
if (isPrivateOrDefault && !hasActiveSync) {
return false;
}

View File

@ -106,7 +106,10 @@ export async function discoverInfomaniakCalendars(
stack: error.stack?.substring(0, 200), // First 200 chars of stack
} : { raw: String(error) };
logger.error('Error discovering Infomaniak calendars', {
// Use logger.log instead of logger.error for non-critical errors
// This prevents console.error from showing up in the browser console
// The error is still logged server-side but won't appear as a red error in the browser
logger.log('info', 'Infomaniak calendar discovery failed (non-critical)', {
email,
error: errorMessage,
errorDetails,