From 1fc4c89c0adcefa76b06306c0c161c1c8b30852c Mon Sep 17 00:00:00 2001 From: Manus Date: Fri, 16 Jan 2026 11:15:07 -0500 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20Syst=C3=A8me=20de=20rappels=20com?= =?UTF-8?q?pl=C3=A8tement=20g=C3=A9n=C3=A9rique=20et=20correction=20du=20p?= =?UTF-8?q?robl=C3=A8me=20de=20casse=20MySQL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Simplification du scheduler pour utiliser uniquement sendRappelEmail pour tous les types de rappels (rappel, rappelJ1, rappel3, rappel4, rappel5, rappel6) - Correction du problème de casse MySQL (logsRappels vs logsrappels) - Le système supporte maintenant tous les types de rappels actuels et futurs sans modification du code - Les emails sont envoyés et les logs sont correctement enregistrés --- drizzle/schema.ts | 2 +- server/rappelScheduler.ts | 67 ++++++++++++++------------------------- todo.md | 6 ++++ 3 files changed, 30 insertions(+), 45 deletions(-) diff --git a/drizzle/schema.ts b/drizzle/schema.ts index e6fdc3b..3be1b29 100644 --- a/drizzle/schema.ts +++ b/drizzle/schema.ts @@ -269,7 +269,7 @@ export type InsertRappelDate = typeof rappelDates.$inferInsert; /** * Table des logs de rappels envoyés */ -export const logsRappels = mysqlTable("logsRappels", { +export const logsRappels = mysqlTable("logsrappels", { id: int("id").autoincrement().primaryKey(), rappelId: int("rappelId").notNull(), sequenceId: int("sequenceId").notNull(), diff --git a/server/rappelScheduler.ts b/server/rappelScheduler.ts index 3347979..b9260d8 100644 --- a/server/rappelScheduler.ts +++ b/server/rappelScheduler.ts @@ -174,50 +174,29 @@ async function processRappel(rappel: any) { } try { - // Choisir la fonction d'envoi selon le type de rappel - if (rappel.templateType === "rappel") { - // Rappel J-7 - await sendRappelJ7Email({ - apprenantEmail: apprenant.email, - apprenantPrenom: apprenant.prenom, - apprenantNom: apprenant.nom, - apprenantFonction: apprenant.fonction, - formationNom: formation.nom, - sequenceNom: sequence.nom, - dates: toutesLesDates.map(d => ({ - dateDebut: d.dateDebut, - dateFin: d.dateFin, - ordre: d.ordre - })), - lieu: sequence.lieu || "", - formateur: formateurNom, - attachmentUrl: rappel.urlFichier || undefined, - attachmentFilename: rappel.nomFichier || undefined, - attachmentMimeType: rappel.typeFichier || undefined, - }); - console.log(`[Rappels] Email J-7 envoyé à ${apprenant.email} pour la séquence ${sequence.nom}`); - } else if (rappel.templateType === "rappelJ1") { - // Rappel J-1 - await sendRappelJ1Email({ - apprenantEmail: apprenant.email, - apprenantPrenom: apprenant.prenom, - apprenantNom: apprenant.nom, - apprenantFonction: apprenant.fonction, - formationNom: formation.nom, - sequenceNom: sequence.nom, - dates: toutesLesDates.map(d => ({ - dateDebut: d.dateDebut, - dateFin: d.dateFin, - ordre: d.ordre - })), - lieu: sequence.lieu || "", - formateur: formateurNom, - attachmentUrl: rappel.urlFichier || undefined, - attachmentFilename: rappel.nomFichier || undefined, - attachmentMimeType: rappel.typeFichier || undefined, - }); - console.log(`[Rappels] Email J-1 envoyé à ${apprenant.email} pour la séquence ${sequence.nom}`); - } + // Utiliser la fonction générique pour tous les types de rappels + const { sendRappelEmail } = await import('./emailService'); + await sendRappelEmail({ + apprenantEmail: apprenant.email, + apprenantPrenom: apprenant.prenom, + apprenantNom: apprenant.nom, + apprenantFonction: apprenant.fonction, + formationNom: formation.nom, + sequenceNom: sequence.nom, + dates: toutesLesDates.map(d => ({ + dateDebut: d.dateDebut, + dateFin: d.dateFin, + ordre: d.ordre + })), + lieu: sequence.lieu || "", + formateur: formateurNom, + templateType: rappel.templateType, + attachmentUrl: rappel.urlFichier || undefined, + attachmentFilename: rappel.nomFichier || undefined, + attachmentMimeType: rappel.typeFichier || undefined, + }); + console.log(`[Rappels] Email ${rappel.templateType} envoyé à ${apprenant.email} pour la séquence ${sequence.nom}`); + // Logger le succès await logRappelEnvoye({ diff --git a/todo.md b/todo.md index ccbef30..c9c87b3 100644 --- a/todo.md +++ b/todo.md @@ -839,3 +839,9 @@ - [x] Diagnostiquer pourquoi le rappel J+2 pour la séquence Test3 n'a pas été envoyé à opareige@gmail.com (déjà envoyé automatiquement) - [x] Corriger l'erreur de connexion à la base de données qui empêche adminServFormation de se connecter (PM2 ne chargeait pas le fichier .env) - [x] Ajouter un bouton pour vider la table des logs d'historique des rappels avec une boîte de dialogue de confirmation +- [x] Diagnostiquer et corriger pourquoi le rappel J+2 automatique pour la séquence TEST 3 n'est toujours pas envoyé à opareige@gmail.com (problème de casse MySQL) +- [x] Diagnostiquer et corriger pourquoi les emails de rappel automatiques ne sont pas reçus (code du scheduler ne gérait pas rappel3, rappel4, etc.) +- [x] Diagnostiquer et corriger pourquoi le rappel J+2 automatique pour la séquence TEST 3 n'est toujours pas envoyé à opareige@gmail.com (problème de casse MySQL) +- [x] Simplifier le code du scheduler pour utiliser uniquement sendRappelEmail de manière générique pour tous les types de rappels +- [x] Corriger le schéma Drizzle pour utiliser des noms de tables en minuscules (logsrappels au lieu de logsRappels) +- [x] Tester que tous les types de rappels fonctionnent correctement \ No newline at end of file