Checkpoint: Checkpoint saved: Ajout de l'enregistrement des tests de rappel dans l'historique (table logsRappels) :
- Ajout du champ typeEnvoi (enum 'automatique', 'test') dans le schéma Drizzle de la table logsRappels - Ajout de la fonction createLogRappel dans server/db.ts pour enregistrer les logs - Modification de la procédure testerRappel pour enregistrer chaque envoi de test avec typeEnvoi='test' - Enregistrement des succès et des échecs dans l'historique - Les tests n'interfèrent pas avec les rappels automatiques (typeEnvoi='automatique') - Migration SQL appliquée sur le VPS : ALTER TABLE logsRappels ADD COLUMN typeEnvoi - Déployé sur le VPS de production (https://formations.itinova.org) - Mise à jour du fichier todo.md Les envois de test apparaissent maintenant dans l'historique des rappels et sont distingués des envois automatiques programmés.
This commit is contained in:
2163
drizzle/meta/0002_snapshot.json
Normal file
2163
drizzle/meta/0002_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,13 @@
|
|||||||
"when": 1768464808933,
|
"when": 1768464808933,
|
||||||
"tag": "0001_dark_shadow_king",
|
"tag": "0001_dark_shadow_king",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 2,
|
||||||
|
"version": "5",
|
||||||
|
"when": 1768553182073,
|
||||||
|
"tag": "0002_concerned_karma",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -277,6 +277,8 @@ export const logsRappels = mysqlTable("logsRappels", {
|
|||||||
email: varchar("email", { length: 320 }).notNull(),
|
email: varchar("email", { length: 320 }).notNull(),
|
||||||
/** Type de rappel (rappel, rappelJ1, rappel3, rappel4, rappel5, rappel6) */
|
/** Type de rappel (rappel, rappelJ1, rappel3, rappel4, rappel5, rappel6) */
|
||||||
type: mysqlEnum("type", ["rappel", "rappelJ1", "rappel3", "rappel4", "rappel5", "rappel6"]).notNull(),
|
type: mysqlEnum("type", ["rappel", "rappelJ1", "rappel3", "rappel4", "rappel5", "rappel6"]).notNull(),
|
||||||
|
/** Type d'envoi (automatique, test) - les tests ne bloquent pas les envois automatiques */
|
||||||
|
typeEnvoi: mysqlEnum("typeEnvoi", ["automatique", "test"]).default("automatique").notNull(),
|
||||||
statut: mysqlEnum("statut", ["succes", "echec"]).notNull(),
|
statut: mysqlEnum("statut", ["succes", "echec"]).notNull(),
|
||||||
messageErreur: text("messageErreur"),
|
messageErreur: text("messageErreur"),
|
||||||
/** Nombre de tentatives d'envoi */
|
/** Nombre de tentatives d'envoi */
|
||||||
|
|||||||
35
server/db.ts
35
server/db.ts
@@ -30,7 +30,8 @@ import {
|
|||||||
rappels,
|
rappels,
|
||||||
InsertRappel,
|
InsertRappel,
|
||||||
Rappel,
|
Rappel,
|
||||||
rappelDates
|
rappelDates,
|
||||||
|
logsRappels
|
||||||
} from "../drizzle/schema";
|
} from "../drizzle/schema";
|
||||||
import { ENV } from './_core/env';
|
import { ENV } from './_core/env';
|
||||||
|
|
||||||
@@ -1292,3 +1293,35 @@ export async function updateUtilisateurPassword(userId: number, hashedPassword:
|
|||||||
.set({ password: hashedPassword })
|
.set({ password: hashedPassword })
|
||||||
.where(eq(users.id, userId));
|
.where(eq(users.id, userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== LOGS RAPPELS ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crée un log de rappel dans l'historique
|
||||||
|
*/
|
||||||
|
export async function createLogRappel(logData: {
|
||||||
|
rappelId: number;
|
||||||
|
sequenceId: number;
|
||||||
|
apprenantId: number;
|
||||||
|
email: string;
|
||||||
|
type: string;
|
||||||
|
typeEnvoi: 'automatique' | 'test';
|
||||||
|
statut: 'succes' | 'echec';
|
||||||
|
messageErreur?: string;
|
||||||
|
dateEnvoi: Date;
|
||||||
|
}) {
|
||||||
|
const db = await getDb();
|
||||||
|
if (!db) throw new Error("Database not available");
|
||||||
|
|
||||||
|
await db.insert(logsRappels).values({
|
||||||
|
rappelId: logData.rappelId,
|
||||||
|
sequenceId: logData.sequenceId,
|
||||||
|
apprenantId: logData.apprenantId,
|
||||||
|
email: logData.email,
|
||||||
|
type: logData.type as any,
|
||||||
|
typeEnvoi: logData.typeEnvoi,
|
||||||
|
statut: logData.statut,
|
||||||
|
messageErreur: logData.messageErreur || null,
|
||||||
|
dateEnvoi: logData.dateEnvoi,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -1461,10 +1461,40 @@ export const appRouter = router({
|
|||||||
attachmentFilename: rappelAUtiliser.nomFichier || undefined,
|
attachmentFilename: rappelAUtiliser.nomFichier || undefined,
|
||||||
attachmentMimeType: rappelAUtiliser.typeFichier || undefined,
|
attachmentMimeType: rappelAUtiliser.typeFichier || undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Enregistrer dans l'historique avec typeEnvoi = 'test'
|
||||||
|
await db.createLogRappel({
|
||||||
|
rappelId: rappelAUtiliser.id,
|
||||||
|
sequenceId: input.sequenceId,
|
||||||
|
apprenantId: apprenant.id,
|
||||||
|
email: apprenant.email,
|
||||||
|
type: rappelAUtiliser.templateType,
|
||||||
|
typeEnvoi: 'test',
|
||||||
|
statut: 'succes',
|
||||||
|
dateEnvoi: new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
nbEnvoyes++;
|
nbEnvoyes++;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
nbEchecs++;
|
nbEchecs++;
|
||||||
erreurs.push(`${apprenant.email}: ${error.message}`);
|
erreurs.push(`${apprenant.email}: ${error.message}`);
|
||||||
|
|
||||||
|
// Enregistrer l'échec dans l'historique
|
||||||
|
try {
|
||||||
|
await db.createLogRappel({
|
||||||
|
rappelId: rappelAUtiliser.id,
|
||||||
|
sequenceId: input.sequenceId,
|
||||||
|
apprenantId: apprenant.id,
|
||||||
|
email: apprenant.email,
|
||||||
|
type: rappelAUtiliser.templateType,
|
||||||
|
typeEnvoi: 'test',
|
||||||
|
statut: 'echec',
|
||||||
|
messageErreur: error.message,
|
||||||
|
dateEnvoi: new Date(),
|
||||||
|
});
|
||||||
|
} catch (logError) {
|
||||||
|
console.error('[LogRappel] Erreur lors de l\'enregistrement du log:', logError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
todo.md
1
todo.md
@@ -831,3 +831,4 @@
|
|||||||
- [x] Modifier la page AdminSequences pour ouvrir en vue réduite par défaut
|
- [x] Modifier la page AdminSequences pour ouvrir en vue réduite par défaut
|
||||||
- [x] Modifier le DashboardLayout pour réduire tous les menus sauf "Gestion" à la connexion
|
- [x] Modifier le DashboardLayout pour réduire tous les menus sauf "Gestion" à la connexion
|
||||||
- [x] Supprimer les boutons "Aperçu rappel J-7", "Envoyer rappel J-7", "Aperçu rappel J-1", "Envoyer rappel J-1" de la fenêtre de détails des séquences
|
- [x] Supprimer les boutons "Aperçu rappel J-7", "Envoyer rappel J-7", "Aperçu rappel J-1", "Envoyer rappel J-1" de la fenêtre de détails des séquences
|
||||||
|
- [x] Corriger le bouton "Tester le rappel" pour enregistrer les envois dans l'historique des rappels (table logsRappels)
|
||||||
|
|||||||
Reference in New Issue
Block a user