Checkpoint: Correction de l'erreur "Cannot convert undefined or null to object" sur la page /admin/notifications :
**Problème identifié :** - Incohérence entre le schéma Drizzle (`drizzle/schema.ts`) et le code (`notificationLogsDb.ts`) - Le schéma utilisait des noms de colonnes et des types d'enum différents de ceux utilisés dans le code - Cela causait l'erreur "Cannot convert undefined or null to object" lors de la récupération des données **Corrections appliquées :** 1. **Mise à jour du schéma Drizzle (drizzle/schema.ts) :** - Renommé `destinataire` en `emailDestinataire` pour correspondre au code - Ajouté la colonne `sujet` (VARCHAR 500) - Ajouté la colonne `formateurId` (INT NULL) - Ajouté la colonne `metadata` (TEXT NULL) - Mis à jour l'enum `type` avec les bonnes valeurs : `remerciement`, `notification_formateur_inscription`, `notification_formateur_annulation`, `alerte_capacite`, `notification_liste_attente` - Mis à jour l'enum `statut` avec les bonnes valeurs : `success`, `failed` 2. **Amélioration de la gestion des valeurs null (notificationLogsDb.ts) :** - Ajout de vérifications null-safe dans `getNotificationStats()` pour éviter les erreurs lors du calcul du taux de succès - Ajout de valeurs par défaut pour `parType` et `evolutionParJour` (tableaux vides si undefined) - Ajout d'un mapping des logs pour s'assurer que tous les champs sont bien définis (null au lieu d'undefined) **Tests réussis :** - ✅ Onglet "Statistiques" : affiche correctement 24 envois, 100% de succès, répartition par type et évolution par jour - ✅ Onglet "Historique" : affiche correctement les 24 notifications avec toutes les colonnes (Date, Type, Destinataire, Sujet, Formation/Séquence, Statut) - ✅ Pagination fonctionnelle (Page 1 sur 2) - ✅ Filtres disponibles (Type, Statut, Email, Date début, Date fin) **Résultat :** ✅ L'erreur "Cannot convert undefined or null to object" est complètement résolue ✅ La page notifications fonctionne correctement avec toutes ses fonctionnalités
This commit is contained in:
106
.manus/db/db-query-1768928750826.json
Normal file
106
.manus/db/db-query-1768928750826.json
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
{
|
||||||
|
"query": "DESCRIBE logsNotifications;",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute DESCRIBE logsNotifications;",
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"Field": "id",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "PRI",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": "auto_increment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "type",
|
||||||
|
"Type": "enum('remerciement','notification_formateur_inscription','notification_formateur_annulation','alerte_capacite','notification_liste_attente')",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "sequenceId",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "apprenantId",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "formateurId",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "emailDestinataire",
|
||||||
|
"Type": "varchar(320)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "sujet",
|
||||||
|
"Type": "varchar(500)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "dateEnvoi",
|
||||||
|
"Type": "timestamp",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "CURRENT_TIMESTAMP",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "statut",
|
||||||
|
"Type": "enum('success','failed')",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "messageErreur",
|
||||||
|
"Type": "text",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "metadata",
|
||||||
|
"Type": "text",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "createdAt",
|
||||||
|
"Type": "timestamp",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "CURRENT_TIMESTAMP",
|
||||||
|
"Extra": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [],
|
||||||
|
"stdout": "Field\tType\tNull\tKey\tDefault\tExtra\nid\tint(11)\tNO\tPRI\tNULL\tauto_increment\ntype\tenum('remerciement','notification_formateur_inscription','notification_formateur_annulation','alerte_capacite','notification_liste_attente')\tNO\t\tNULL\t\nsequenceId\tint(11)\tYES\t\tNULL\t\napprenantId\tint(11)\tYES\t\tNULL\t\nformateurId\tint(11)\tYES\t\tNULL\t\nemailDestinataire\tvarchar(320)\tNO\t\tNULL\t\nsujet\tvarchar(500)\tNO\t\tNULL\t\ndateEnvoi\ttimestamp\tNO\t\tCURRENT_TIMESTAMP\t\nstatut\tenum('success','failed')\tNO\t\tNULL\t\nmessageErreur\ttext\tYES\t\tNULL\t\nmetadata\ttext\tYES\t\tNULL\t\ncreatedAt\ttimestamp\tNO\t\tCURRENT_TIMESTAMP\t\n",
|
||||||
|
"stderr": "",
|
||||||
|
"execution_time_ms": 57
|
||||||
|
}
|
||||||
130
.manus/db/db-query-1768928761210.json
Normal file
130
.manus/db/db-query-1768928761210.json
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
{
|
||||||
|
"query": "SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_TYPE \nFROM INFORMATION_SCHEMA.COLUMNS \nWHERE TABLE_NAME = 'logsNotifications' \nORDER BY ORDINAL_POSITION;",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_TYPE \nFROM INFORMATION_SCHEMA.COLUMNS \nWHERE TABLE_NAME = 'logsNotifications' \nORDER BY ORDINAL_POSITION;",
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "id",
|
||||||
|
"DATA_TYPE": "int",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "int(11)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "id",
|
||||||
|
"DATA_TYPE": "int",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "int(11)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "type",
|
||||||
|
"DATA_TYPE": "enum",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "enum('remerciement','notification_formateur_inscription','notification_formateur_annulation','alerte_capacite','notification_liste_attente')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "type",
|
||||||
|
"DATA_TYPE": "enum",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "enum('inscription','annulation','capacite_atteinte','place_disponible','remerciement','formateur_inscription','formateur_annulation')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "sequenceId",
|
||||||
|
"DATA_TYPE": "int",
|
||||||
|
"IS_NULLABLE": "YES",
|
||||||
|
"COLUMN_TYPE": "int(11)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "destinataire",
|
||||||
|
"DATA_TYPE": "varchar",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "varchar(320)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "apprenantId",
|
||||||
|
"DATA_TYPE": "int",
|
||||||
|
"IS_NULLABLE": "YES",
|
||||||
|
"COLUMN_TYPE": "int(11)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "sequenceId",
|
||||||
|
"DATA_TYPE": "int",
|
||||||
|
"IS_NULLABLE": "YES",
|
||||||
|
"COLUMN_TYPE": "int(11)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "formateurId",
|
||||||
|
"DATA_TYPE": "int",
|
||||||
|
"IS_NULLABLE": "YES",
|
||||||
|
"COLUMN_TYPE": "int(11)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "apprenantId",
|
||||||
|
"DATA_TYPE": "int",
|
||||||
|
"IS_NULLABLE": "YES",
|
||||||
|
"COLUMN_TYPE": "int(11)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "emailDestinataire",
|
||||||
|
"DATA_TYPE": "varchar",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "varchar(320)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "statut",
|
||||||
|
"DATA_TYPE": "enum",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "enum('succes','echec')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "sujet",
|
||||||
|
"DATA_TYPE": "varchar",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "varchar(500)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "messageErreur",
|
||||||
|
"DATA_TYPE": "text",
|
||||||
|
"IS_NULLABLE": "YES",
|
||||||
|
"COLUMN_TYPE": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "dateEnvoi",
|
||||||
|
"DATA_TYPE": "timestamp",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "timestamp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "dateEnvoi",
|
||||||
|
"DATA_TYPE": "timestamp",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "timestamp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "statut",
|
||||||
|
"DATA_TYPE": "enum",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "enum('success','failed')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "messageErreur",
|
||||||
|
"DATA_TYPE": "text",
|
||||||
|
"IS_NULLABLE": "YES",
|
||||||
|
"COLUMN_TYPE": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "metadata",
|
||||||
|
"DATA_TYPE": "text",
|
||||||
|
"IS_NULLABLE": "YES",
|
||||||
|
"COLUMN_TYPE": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "createdAt",
|
||||||
|
"DATA_TYPE": "timestamp",
|
||||||
|
"IS_NULLABLE": "NO",
|
||||||
|
"COLUMN_TYPE": "timestamp"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [],
|
||||||
|
"stdout": "COLUMN_NAME\tDATA_TYPE\tIS_NULLABLE\tCOLUMN_TYPE\nid\tint\tNO\tint(11)\nid\tint\tNO\tint(11)\ntype\tenum\tNO\tenum('remerciement','notification_formateur_inscription','notification_formateur_annulation','alerte_capacite','notification_liste_attente')\ntype\tenum\tNO\tenum('inscription','annulation','capacite_atteinte','place_disponible','remerciement','formateur_inscription','formateur_annulation')\nsequenceId\tint\tYES\tint(11)\ndestinataire\tvarchar\tNO\tvarchar(320)\napprenantId\tint\tYES\tint(11)\nsequenceId\tint\tYES\tint(11)\nformateurId\tint\tYES\tint(11)\napprenantId\tint\tYES\tint(11)\nemailDestinataire\tvarchar\tNO\tvarchar(320)\nstatut\tenum\tNO\tenum('succes','echec')\nsujet\tvarchar\tNO\tvarchar(500)\nmessageErreur\ttext\tYES\ttext\ndateEnvoi\ttimestamp\tNO\ttimestamp\ndateEnvoi\ttimestamp\tNO\ttimestamp\nstatut\tenum\tNO\tenum('success','failed')\nmessageErreur\ttext\tYES\ttext\nmetadata\ttext\tYES\ttext\ncreatedAt\ttimestamp\tNO\ttimestamp\n",
|
||||||
|
"stderr": "",
|
||||||
|
"execution_time_ms": 66
|
||||||
|
}
|
||||||
13
.manus/db/db-query-1768928770313.json
Normal file
13
.manus/db/db-query-1768928770313.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"query": "SELECT COUNT(*) as total FROM logsNotifications;",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT COUNT(*) as total FROM logsNotifications;",
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"total": "24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [],
|
||||||
|
"stdout": "total\n24\n",
|
||||||
|
"stderr": "",
|
||||||
|
"execution_time_ms": 57
|
||||||
|
}
|
||||||
22
.manus/db/db-query-1768928779053.json
Normal file
22
.manus/db/db-query-1768928779053.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"query": "SELECT COLUMN_NAME \nFROM INFORMATION_SCHEMA.COLUMNS \nWHERE TABLE_NAME = 'logsNotifications' \nAND COLUMN_NAME IN ('emailDestinataire', 'sujet', 'formateurId', 'metadata');",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT COLUMN_NAME \nFROM INFORMATION_SCHEMA.COLUMNS \nWHERE TABLE_NAME = 'logsNotifications' \nAND COLUMN_NAME IN ('emailDestinataire', 'sujet', 'formateurId', 'metadata');",
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "formateurId"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "emailDestinataire"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "sujet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "metadata"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [],
|
||||||
|
"stdout": "COLUMN_NAME\nformateurId\nemailDestinataire\nsujet\nmetadata\n",
|
||||||
|
"stderr": "",
|
||||||
|
"execution_time_ms": 66
|
||||||
|
}
|
||||||
8
.manus/db/db-query-error-1768928739341.json
Normal file
8
.manus/db/db-query-error-1768928739341.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"query": "-- Renommer la colonne destinataire en emailDestinataire\nALTER TABLE logsNotifications CHANGE COLUMN destinataire emailDestinataire VARCHAR(320) NOT NULL;\n\n-- Ajouter la colonne sujet\nALTER TABLE logsNotifications ADD COLUMN sujet VARCHAR(500) NOT NULL DEFAULT '';\n\n-- Ajouter la colonne formateurId\nALTER TABLE logsNotifications ADD COLUMN formateurId INT NULL;\n\n-- Ajouter la colonne metadata\nALTER TABLE logsNotifications ADD COLUMN metadata TEXT NULL;\n\n-- Modifier l'enum type pour ajouter les nouveaux types\nALTER TABLE logsNotifications MODIFY COLUMN type ENUM('remerciement', 'notification_formateur_inscription', 'notification_formateur_annulation', 'alerte_capacite', 'notification_liste_attente') NOT NULL;\n\n-- Modifier l'enum statut\nALTER TABLE logsNotifications MODIFY COLUMN statut ENUM('success', 'failed') NOT NULL;",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute -- Renommer la colonne destinataire en emailDestinataire\nALTER TABLE logsNotifications CHANGE COLUMN destinataire emailDestinataire VARCHAR(320) NOT NULL;\n\n-- Ajouter la colonne sujet\nALTER TABLE logsNotifications ADD COLUMN sujet VARCHAR(500) NOT NULL DEFAULT '';\n\n-- Ajouter la colonne formateurId\nALTER TABLE logsNotifications ADD COLUMN formateurId INT NULL;\n\n-- Ajouter la colonne metadata\nALTER TABLE logsNotifications ADD COLUMN metadata TEXT NULL;\n\n-- Modifier l'enum type pour ajouter les nouveaux types\nALTER TABLE logsNotifications MODIFY COLUMN type ENUM('remerciement', 'notification_formateur_inscription', 'notification_formateur_annulation', 'alerte_capacite', 'notification_liste_attente') NOT NULL;\n\n-- Modifier l'enum statut\nALTER TABLE logsNotifications MODIFY COLUMN statut ENUM('success', 'failed') NOT NULL;",
|
||||||
|
"returncode": 1,
|
||||||
|
"logs": [
|
||||||
|
"ERROR 1054 (42S22) at line 2: Unknown column 'destinataire' in 'logsNotifications'"
|
||||||
|
]
|
||||||
|
}
|
||||||
2186
drizzle/meta/0004_snapshot.json
Normal file
2186
drizzle/meta/0004_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,13 @@
|
|||||||
"when": 1768924576044,
|
"when": 1768924576044,
|
||||||
"tag": "0003_calm_frog_thor",
|
"tag": "0003_calm_frog_thor",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 4,
|
||||||
|
"version": "5",
|
||||||
|
"when": 1768928661188,
|
||||||
|
"tag": "0004_absent_wallow",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -477,24 +477,28 @@ export const logsNotifications = mysqlTable("logsNotifications", {
|
|||||||
id: int("id").autoincrement().primaryKey(),
|
id: int("id").autoincrement().primaryKey(),
|
||||||
/** Type de notification */
|
/** Type de notification */
|
||||||
type: mysqlEnum("type", [
|
type: mysqlEnum("type", [
|
||||||
"inscription",
|
|
||||||
"annulation",
|
|
||||||
"capacite_atteinte",
|
|
||||||
"place_disponible",
|
|
||||||
"remerciement",
|
"remerciement",
|
||||||
"formateur_inscription",
|
"notification_formateur_inscription",
|
||||||
"formateur_annulation"
|
"notification_formateur_annulation",
|
||||||
|
"alerte_capacite",
|
||||||
|
"notification_liste_attente"
|
||||||
]).notNull(),
|
]).notNull(),
|
||||||
/** Email du destinataire */
|
/** Email du destinataire */
|
||||||
destinataire: varchar("destinataire", { length: 320 }).notNull(),
|
emailDestinataire: varchar("emailDestinataire", { length: 320 }).notNull(),
|
||||||
|
/** Sujet de l'email */
|
||||||
|
sujet: varchar("sujet", { length: 500 }).notNull(),
|
||||||
/** ID de la séquence concernée */
|
/** ID de la séquence concernée */
|
||||||
sequenceId: int("sequenceId"),
|
sequenceId: int("sequenceId"),
|
||||||
/** ID de l'apprenant concerné */
|
/** ID de l'apprenant concerné */
|
||||||
apprenantId: int("apprenantId"),
|
apprenantId: int("apprenantId"),
|
||||||
|
/** ID du formateur concerné */
|
||||||
|
formateurId: int("formateurId"),
|
||||||
/** Statut de l'envoi */
|
/** Statut de l'envoi */
|
||||||
statut: mysqlEnum("statut", ["succes", "echec"]).notNull(),
|
statut: mysqlEnum("statut", ["success", "failed"]).notNull(),
|
||||||
/** Message d'erreur en cas d'échec */
|
/** Message d'erreur en cas d'échec */
|
||||||
messageErreur: text("messageErreur"),
|
messageErreur: text("messageErreur"),
|
||||||
|
/** Métadonnées supplémentaires (JSON) */
|
||||||
|
metadata: text("metadata"),
|
||||||
dateEnvoi: timestamp("dateEnvoi").defaultNow().notNull(),
|
dateEnvoi: timestamp("dateEnvoi").defaultNow().notNull(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -124,8 +124,20 @@ export async function getNotificationLogs(filters?: {
|
|||||||
.from(logsNotifications)
|
.from(logsNotifications)
|
||||||
.where(whereClause);
|
.where(whereClause);
|
||||||
|
|
||||||
|
// S'assurer que les logs sont bien définis et que tous les champs sont valides
|
||||||
|
const safeLogs = (logs || []).map(log => ({
|
||||||
|
...log,
|
||||||
|
sequenceNom: log.sequenceNom || null,
|
||||||
|
formationNom: log.formationNom || null,
|
||||||
|
apprenantNom: log.apprenantNom || null,
|
||||||
|
apprenantPrenom: log.apprenantPrenom || null,
|
||||||
|
formateurNom: log.formateurNom || null,
|
||||||
|
messageErreur: log.messageErreur || null,
|
||||||
|
metadata: log.metadata || null,
|
||||||
|
}));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
logs,
|
logs: safeLogs,
|
||||||
total: countResult?.count || 0,
|
total: countResult?.count || 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -186,15 +198,21 @@ export async function getNotificationStats(filters?: {
|
|||||||
.orderBy(sql`DATE(dateEnvoi)`)
|
.orderBy(sql`DATE(dateEnvoi)`)
|
||||||
.limit(30);
|
.limit(30);
|
||||||
|
|
||||||
|
// Vérifier que globalStats existe et a des valeurs valides
|
||||||
|
const total = globalStats?.total || 0;
|
||||||
|
const success = globalStats?.success || 0;
|
||||||
|
const failed = globalStats?.failed || 0;
|
||||||
|
const tauxSucces = total > 0 ? Math.round((success / total) * 100) : 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
global: {
|
global: {
|
||||||
total: globalStats?.total || 0,
|
total,
|
||||||
success: globalStats?.success || 0,
|
success,
|
||||||
failed: globalStats?.failed || 0,
|
failed,
|
||||||
tauxSucces: globalStats?.total ? Math.round((globalStats.success / globalStats.total) * 100) : 0,
|
tauxSucces,
|
||||||
},
|
},
|
||||||
parType: statsByType,
|
parType: statsByType || [],
|
||||||
evolutionParJour,
|
evolutionParJour: evolutionParJour || [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
todo.md
6
todo.md
@@ -1086,3 +1086,9 @@
|
|||||||
- [x] Analyser l'erreur "Impossible de récupérer le statut Fail2Ban"
|
- [x] Analyser l'erreur "Impossible de récupérer le statut Fail2Ban"
|
||||||
- [x] Corriger l'erreur SQL DATE_FORMAT dans getInscriptionsByMonth
|
- [x] Corriger l'erreur SQL DATE_FORMAT dans getInscriptionsByMonth
|
||||||
- [x] Tester les corrections sur sandbox
|
- [x] Tester les corrections sur sandbox
|
||||||
|
|
||||||
|
## Correction erreur page notifications
|
||||||
|
|
||||||
|
- [x] Analyser l'erreur "Cannot convert undefined or null to object"
|
||||||
|
- [x] Corriger l'erreur dans le code
|
||||||
|
- [x] Tester la correction sur sandbox
|
||||||
|
|||||||
Reference in New Issue
Block a user