Checkpoint: Correction du scheduler de remerciements pour éviter les envois multiples - la vérification des doublons est maintenant faite en base de données (table logsNotifications) au lieu de la mémoire, ce qui persiste entre les redémarrages du serveur
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { getDb } from "./db";
|
import { getDb } from "./db";
|
||||||
import { sequences, inscriptions, apprenants, formations, datesFormation, formateurs, questionnaires, envoisQuestionnaires } from "../drizzle/schema";
|
import { sequences, inscriptions, apprenants, formations, datesFormation, formateurs, questionnaires, envoisQuestionnaires, logsNotifications } from "../drizzle/schema";
|
||||||
import { eq, and, lte, sql } from "drizzle-orm";
|
import { eq, and, lte, sql } from "drizzle-orm";
|
||||||
import { sendRemerciementPostFormation } from "./emailService";
|
import { sendRemerciementPostFormation } from "./emailService";
|
||||||
import { logNotification } from "./notificationLogsDb";
|
import { logNotification } from "./notificationLogsDb";
|
||||||
@@ -79,24 +79,31 @@ async function getOrCreateQuestionnaireLink(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table pour suivre les remerciements déjà envoyés
|
* Vérifie si un remerciement a déjà été envoyé pour une inscription en vérifiant dans la base de données
|
||||||
*/
|
*/
|
||||||
const remerciementsEnvoyes = new Map<string, Date>();
|
async function remerciementDejaEnvoye(apprenantId: number, sequenceId: number): Promise<boolean> {
|
||||||
|
const db = await getDb();
|
||||||
/**
|
if (!db) return false;
|
||||||
* Vérifie si un remerciement a déjà été envoyé pour une inscription
|
|
||||||
*/
|
try {
|
||||||
function remerciementDejaEnvoye(inscriptionId: number, sequenceId: number): boolean {
|
const [existing] = await db
|
||||||
const key = `${inscriptionId}-${sequenceId}`;
|
.select({ id: logsNotifications.id })
|
||||||
return remerciementsEnvoyes.has(key);
|
.from(logsNotifications)
|
||||||
}
|
.where(
|
||||||
|
and(
|
||||||
/**
|
eq(logsNotifications.type, "remerciement"),
|
||||||
* Marque un remerciement comme envoyé
|
eq(logsNotifications.apprenantId, apprenantId),
|
||||||
*/
|
eq(logsNotifications.sequenceId, sequenceId),
|
||||||
function marquerRemerciementEnvoye(inscriptionId: number, sequenceId: number): void {
|
eq(logsNotifications.statut, "success")
|
||||||
const key = `${inscriptionId}-${sequenceId}`;
|
)
|
||||||
remerciementsEnvoyes.set(key, new Date());
|
)
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
return !!existing;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[Remerciements] Erreur lors de la vérification du log:", error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,8 +186,9 @@ async function processRemerciementSequence(
|
|||||||
let errorsCount = 0;
|
let errorsCount = 0;
|
||||||
|
|
||||||
for (const { inscription, apprenant } of inscriptionsConfirmees) {
|
for (const { inscription, apprenant } of inscriptionsConfirmees) {
|
||||||
// Vérifier si le remerciement a déjà été envoyé
|
// Vérifier si le remerciement a déjà été envoyé (vérification en base de données)
|
||||||
if (remerciementDejaEnvoye(inscription.id, sequence.id)) {
|
const dejaEnvoye = await remerciementDejaEnvoye(apprenant.id, sequence.id);
|
||||||
|
if (dejaEnvoye) {
|
||||||
console.log(`[Remerciements] Remerciement déjà envoyé pour ${apprenant.email}`);
|
console.log(`[Remerciements] Remerciement déjà envoyé pour ${apprenant.email}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -200,7 +208,7 @@ async function processRemerciementSequence(
|
|||||||
lienQuestionnaire: lienQuestionnaire || undefined,
|
lienQuestionnaire: lienQuestionnaire || undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Logger la notification
|
// Logger la notification (sert aussi de marqueur pour éviter les doublons)
|
||||||
await logNotification({
|
await logNotification({
|
||||||
type: "remerciement",
|
type: "remerciement",
|
||||||
sequenceId: sequence.id,
|
sequenceId: sequence.id,
|
||||||
@@ -211,7 +219,6 @@ async function processRemerciementSequence(
|
|||||||
metadata: { lienQuestionnaire },
|
metadata: { lienQuestionnaire },
|
||||||
});
|
});
|
||||||
|
|
||||||
marquerRemerciementEnvoye(inscription.id, sequence.id);
|
|
||||||
envoyesCount++;
|
envoyesCount++;
|
||||||
console.log(`[Remerciements] Email envoyé à ${apprenant.email}`);
|
console.log(`[Remerciements] Email envoyé à ${apprenant.email}`);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -289,6 +296,13 @@ export async function envoyerRemerciementsSequence(sequenceId: number): Promise<
|
|||||||
let failed = 0;
|
let failed = 0;
|
||||||
|
|
||||||
for (const { inscription, apprenant } of inscriptionsConfirmees) {
|
for (const { inscription, apprenant } of inscriptionsConfirmees) {
|
||||||
|
// Vérifier si le remerciement a déjà été envoyé
|
||||||
|
const dejaEnvoye = await remerciementDejaEnvoye(apprenant.id, sequenceId);
|
||||||
|
if (dejaEnvoye) {
|
||||||
|
console.log(`[Remerciements] Remerciement déjà envoyé pour ${apprenant.email}, ignoré`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Générer le lien questionnaire
|
// Générer le lien questionnaire
|
||||||
const lienQuestionnaire = await getOrCreateQuestionnaireLink(apprenant.id, sequenceId);
|
const lienQuestionnaire = await getOrCreateQuestionnaireLink(apprenant.id, sequenceId);
|
||||||
|
|||||||
Reference in New Issue
Block a user