# Gestion des Formations Manager Itinova - TODO ## Phase 1 : Planification et initialisation - [x] Initialiser le projet avec architecture full-stack - [x] Créer le plan de développement - [x] Créer le fichier todo.md ## Phase 2 : Modèle de données - [x] Créer la table des formations (nom, description, lien unique) - [x] Créer la table des sessions (dates, lieu, capacité max 12, statut blocage J-15) - [x] Créer la table des inscriptions (apprenant, session, statut) - [x] Créer la table des apprenants (nom, prénom, email, code établissement) - [x] Implémenter les relations entre tables - [x] Ajouter les contraintes d'unicité pour éviter les doubles inscriptions ## Phase 3 : Interface d'administration - [x] Créer le dashboard administrateur avec navigation - [x] Créer l'interface de gestion des formations (CRUD) - [x] Créer l'interface de gestion des sessions (CRUD) - [x] Créer l'interface de gestion des apprenants (CRUD) - [x] Afficher les listes d'inscrits par session - [x] Implémenter la gestion des rôles (admin DRH, responsable, stagiaire) ## Phase 4 : Système d'inscription - [x] Créer la page d'inscription publique avec lien unique par formation - [x] Implémenter la validation de capacité maximale (12 participants) - [x] Implémenter la validation anti-double inscription - [x] Implémenter le blocage des inscriptions/désinscriptions à J-15 - [x] Créer le système de liste d'attente si session complète - [x] Afficher les sessions disponibles avec places restantes ## Phase 5 : Invitations et emails automatiques - [x] Implémenter la génération d'invitations Outlook (.ics) avec statut " occupé " - [x] Inclure le lieu de formation dans les invitations - [x] Créer le système d'envoi d'emails automatiques - [x] Créer le template email de confirmation d'inscription - [x] Créer le template email teaser pour chaque groupe - [x] Créer le template email de rappel à J-7 - [x] Implémenter l'envoi automatique des emails selon les événements ## Phase 6 : Exports - [x] Implémenter l'export Excel des listes d'inscrits par session - [x] Implémenter l'export PDF des listes d'inscrits par session - [x] Créer la génération de feuille de présence PDF (nom, prénom, code établissement) - [x] Ajouter les boutons d'export dans l'interface admin ## Phase 7 : Tests et documentation - [x] Tester le flux complet d'inscription - [x] Tester les validations et contraintes - [x] Tester la génération des invitations et emails - [x] Tester les exports PDF/Excel - [x] Créer la documentation utilisateur - [x] Créer la documentation d'administration ## P## Phase 8 : Livraison - [x] Vérifier toutes les fonctionnalités - [x] Créer un checkpoint final - [x] Présenter l'application à l'utilisateur ## Corrections à apporter - [x] Corriger la mise à jour de la liste des apprenants après inscription - [x] Implémenter l'envoi effectif des emails de confirmation ## Nouvelles fonctionnalités - [x] Ajouter des filtres de tri sur la page des sessions (date, lieu, places restantes) - [x] Ajouter des filtres de recherche sur la page des formations - [x] Ajouter des filtres de recherche sur la page des apprenants - [x] Ajouter des filtres complets sur la page de gestion des inscrits (recherche, statut, établissement, tri par date) - [x] Ajouter le champ "Fonction" (Directeur, Chef de service, Autre) dans la fiche apprenant - [x] Mettre à jour le schéma de base de données - [x] Mettre à jour les formulaires d'inscription et de gestion - [x] Ajouter la fonction dans les exports PDF/Excel ## Améliorations supplémentaires - [x] Ajouter un filtre par fonction sur la page des apprenants - [x] Ajouter un filtre par fonction sur la page des inscrits - [x] Créer des statistiques de répartition par fonction sur le tableau de bord - [x] Ajouter des graphiques de visualisation des données - [x] Personnaliser les templates d'emails avec la fonction de l'apprenant ## Refonte : Sessions → Séquences avec dates multiples - [x] Renommer "Session" en "Séquence" dans le schéma de base de données - [x] Créer une table pour gérer jusqu'à 4 dates par séquence - [x] Mettre à jour toutes les procédures tRPC pour utiliser "séquence" - [x] Renommer toutes les interfaces et pages (AdminSessions → AdminSequences) - [x] Adapter le formulaire de création/édition pour gérer 4 dates - [x] Mettre à jour la page d'inscription pour afficher toutes les dates d'une séquence - [x] Modifier la logique d'inscription pour inscrire à toutes les dates - [x] Mettre à jour les exports PDF/Excel avec toutes les dates - [x] Adapter les emails pour inclure toutes les dates de la séquence - [x] Mettre à jour les invitations Outlook pour créer 4 événements si nécessaire - [x] Renommer partout dans l'interface utilisateur (labels, titres, descriptions) ## Corrections urgentes - [x] Corriger l'erreur React "Cannot update a component while rendering" dans Home.tsx - [x] Corriger le bug de modification des horaires des séquences - [x] Corriger le décalage d'une heure lors de l'enregistrement des dates (15h00 saisi devient 16h00 en base) - [x] Corriger la mise à jour du nombre d'inscrits sur la page d'inscription publique - [x] Corriger le décalage d'une heure entre la saisie et l'affichage des dates de séquences - [x] Corriger le décalage d'une heure à l'affichage des dates (problème de formatage lors de la récupération) - [x] Corriger les fonctions formatDate pour gérer les objets Date JavaScript en plus des chaînes MySQL - [x] Forcer le fuseau horaire Europe/Paris dans la connexion MySQL pour éliminer le décalage d'une heure - [x] Corriger le décalage horaire persistant dans parseLocalDateTime (09:48 envoyé devient 10:48 en base) - [x] Corriger l'erreur "toISOString is not a function" lors de la modification de séquences - [x] Ajouter le champ "Public cible" dans la fiche formation avec liste déroulante (Directeur, Chef de service, Autre) - [x] Mettre à jour le schéma de base de données pour les formations - [x] Mettre à jour les formulaires de gestion des formations - [x] Afficher le public cible dans les listes et exports - [x] Déplacer le champ "Public cible" des formations vers les séquences - [x] Retirer publicCible du schéma formations - [x] Ajouter publicCible au schéma sequences - [x] Mettre à jour les procédures tRPC pour sequences - [x] Mettre à jour le formulaire de création/édition de séquences - [x] Afficher le public cible dans la liste des séquences - [x] Afficher le public cible par séquence sur la page d'inscription publique - [x] Corriger le formulaire de modification des séquences pour afficher le champ Public cible ## Bugs critiques à corriger - [x] La validation d'une inscription ne fonctionne pas (déjà corrigé dans la version restaurée) - [x] Lorsqu'un apprenant s'inscrit, il n'apparaît pas dans la liste des apprenants (déjà corrigé dans la version restaurée) ## Nouvelle fonctionnalité - Alerte public cible - [x] Analyser le code d'inscription pour identifier où ajouter l'alerte - [x] Implémenter la logique de vérification du public cible dans le formulaire d'inscription - [x] Afficher une alerte d'information (non bloquante) si le public cible ne correspond pas - [x] Tester l'alerte avec différents scénarios (correspondance, non-correspondance) ## Inclusion du public cible dans les exports - [x] Analyser le code des exports Excel et PDF - [x] Ajouter le public cible dans l'export Excel des listes d'inscrits - [x] Ajouter le public cible dans l'export PDF des listes d'inscrits - [x] Ajouter le public cible dans l'export PDF des feuilles de présence - [x] Tester tous les exports pour vérifier l'affichage correct ## Ajout du filtre par public cible - [x] Analyser la page AdminSequences pour comprendre le système de filtres existant - [x] Ajouter un état pour le filtre publicCible - [x] Ajouter le composant Select pour le filtre publicCible dans l'interface - [x] Implémenter la logique de filtrage par public cible - [x] Tester le filtre avec différentes valeurs ## Badges de couleur pour le public cible - [x] Créer un composant Badge pour afficher le public cible avec des couleurs distinctes - [x] Intégrer le Badge dans le tableau des séquences (AdminSequences) - [x] Intégrer le Badge dans la page des inscrits (AdminSequenceInscrits) - [x] Tester l'affichage des badges avec différents publics cibles ## Rapport d'analyse public cible vs fonction appre- [x] Créer une nouvelle page AdminRapportPublicCible - [x] Ajouter la route dans App.tsx - [x] Ajouter un lien dans le menu de navigation (DashboardLayout- [x] Créer une procédure tRPC pour récupérer les données d'analyse - [x] Implémenter la logique de comparaison public cible vs fonction apprenants - [x] Afficher les statistiques et écarts dans l'interface - [x] Tester le rapport avec différentes données ## Gestion des utilisateurs de l'application - [x] Analyser le schéma actuel de la table users - [x] Ajouter les champs nécessaires (statut actif/inactif, date de création compte) - [x] Créer les procédures tRPC pour la gestion des utilisateurs (liste, création, modification, désactivation) - [x] Créer la page AdminUsers avec tableau des utilisateurs - [x] Implémenter le formulaire de création d'utilisateur - [x] Implémenter le formulaire de modification d'utilisateur - [x] Ajouter la fonctionnalité d'activation/désactivation des comptes - [x] Ajouter des filtres de recherche (nom, email, rôle, statut) - [x] Ajouter la gestion des rôles (admin, user) - [x] Intégrer la page dans le menu de navigation - [x] Tester toutes les fonctionnalités de gestion des utilisateurs ## Ajout de la fonctionnalité de création d'utilisateurs - [x] Ajouter une procédure tRPC pour créer un nouvel utilisateur - [x] Ajouter un bouton "Ajouter un utilisateur" dans la page AdminUsers - [x] Créer un dialogue de création avec formulaire (nom, email, rôle) - [x] Tester la création d'un nouvel utilisateur ## Réinitialisation de mot de passe - [x] Créer une table password_reset_tokens dans le schéma - [x] Ajouter les fonctions de gestion des tokens dans db.ts - [x] Créer une procédure tRPC pour générer un token et envoyer l'email - [x] Ajouter un bouton "Réinitialiser le mot de passe" dans AdminUsers - [x] Créer un dialogue de confirmation pour la réinitialisation - [x] Tester la génération de token et l'envoi d'email ## Correction affichage menu latéral - [x] Intégrer la page AdminUsers dans le DashboardLayout - [x] Vérifier l'affichage du menu latéral sur la page utilisateurs ## Correction de l'envoi d'emails pour réinitialisation de mot de passe - [x] Analyser le service d'envoi d'emails actuel - [x] Rechercher l'API d'envoi d'emails disponible dans Manus - [x] Intégrer un vrai service d'envoi d'emails (Resend) - [x] Créer la documentation de configuration EMAIL_SETUP.md ## Interface de personnalisation des templates d'emails - [x] Créer la table email_templates dans le schéma - [x] Créer les procédures backend pour CRUD des templates - [x] Créer la page AdminEmailTemplates - [x] Implémenter l'éditeur de template (logo, couleurs, textes) - [x] Ajouter la prévisualisation en temps réel - [x] Modifier le service d'envoi pour utiliser les templates personnalisés - [x] Ajouter le lien dans le menu de navigation - [x] Tester la personnalisation et l'envoi avec templates personnalisés ## Configuration SMTP via interface - [x] Créer la table email_config dans le schéma - [x] Créer les procédures backend pour CRUD de la configuration - [x] Ajouter une procédure de test d'envoi d'email - [x] Modifier le service d'envoi pour utiliser la config en base - [x] Créer la page AdminEmailConfig - [x] Implémenter le formulaire de configuration (API key, email expéditeur, mode) - [x] Ajouter le test d'envoi immédiat avec feedback - [x] Ajouter la validation de domaine - [x] Ajouter le basculement simulation/production - [x] Ajouter le lien dans le menu de navigation - [x] Tester la configuration et l'envoi d'emails ## Amélioration disposition formulaire modification séquences - [x] Réorganiser les champs du formulaire pour éviter tout chevauchement - [x] Ajouter les champs Public cible et Formateur dans le formulaire de modification - [x] Séparer Public cible et Formateur sur une ligne dédiée - [x] Tester la disposition sur différentes tailles d'écran ## Correction bug FormateurCombobox - [x] Recréer le fichier FormateurCombobox.tsx manquant - [x] Ajouter l'import de FormateurCombobox dans AdminSequences.tsx - [x] Redémarrer le serveur pour détecter le nouveau fichier ## Recréation des fichiers manquants - [x] Recréer le composant CapacityProgressBar avec barre de progression colorée - [x] Recréer la page AdminCalendrier avec vue calendrier mensuel - [x] Recréer la page AdminRappels avec gestion des rappels automatiques - [x] Intégrer CapacityProgressBar dans AdminSequences - [x] Redémarrer le serveur pour détecter tous les nouveaux fichiers - [ ] Vérifier que tous les imports et routes sont corrects - [ ] Créer un checkpoint complet avec toutes les fonctionnalités ## Correction affichage page calendrier - [x] Ajouter la route /admin/calendrier dans App.tsx - [x] Ajouter la route /admin/rappels dans App.tsx - [x] Ajouter le lien "Calendrier" dans DashboardLayout - [x] Ajouter le lien "Rappels" dans DashboardLayout - [x] Ajouter les imports CalendarDays et Bell - [x] Redémarrer le serveur - [x] Tester l'accès aux pages calendrier et rappels ## Vérification des trois fonctionnalités principales - [x] Vérifier que CapacityProgressBar est bien utilisé dans AdminSequences - [x] Vérifier que la page AdminCalendrier existe et est accessible - [x] Vérifier que la page AdminRappels existe et est accessible - [x] Ajouter les procédures tRPC manquantes pour les rappels - [x] Créer un rapport de vérification complet ## Corrections de bugs - Calendrier et taux de remplissage - [x] Corriger l'affichage des séquences dans le calendrier de novembre (seq.dates au lieu de seq.datesFormation) - [x] Vérifier la logique de filtrage des séquences par mois dans AdminCalendrier - [x] Corriger le calcul du taux de remplissage (ajout de nbInscrits dans sequences.list) - [x] Vérifier que sequences.list retourne bien le nombre d'inscrits ## Correction bug calendrier - parseISO - [x] Corriger l'erreur "e.split is not a function" dans AdminCalendrier - [x] Ajouter une vérification du type de dateDebut avant parseISO - [x] Gérer le cas où dateDebut est déjà un objet Date ou une chaîne ## Trois corrections demandées - [x] Ajouter "Tous" dans la liste des publics cible du formulaire "Nouvelle séquence" - [x] Ajouter "Tous" dans les fonctions de badge et label - [x] Corriger le composant Progress pour supporter indicatorClassName - [x] Corriger les couleurs de la barre de progression (vert/orange/rouge) selon le taux de remplissage - [x] Compléter les informations des séquences affichées dans le calendrier (lieu, formateur, nb inscrits) ## Trois nouvelles corrections - [x] Ajouter le champ formateur dans le formulaire "Nouvelle séquence" - [x] Modifier le placeholder du formateur : "Sélectionner un formateur" (déjà correct par défaut) - [x] Afficher le nom de la séquence ET le nom de la formation dans le calendrier ## Vérification des trois corrections - [ ] Vérifier que le champ formateur apparaît bien dans le formulaire "Nouvelle séquence" - [ ] Vérifier le texte du placeholder du formateur - [ ] Vérifier que le nom de la séquence ET le nom de la formation apparaissent dans le calendrier - [ ] Corriger les problèmes trouvés ## Corrections affichage nom de formation dans calendrier - [x] Modifier getSequences() pour récupérer les informations de formation via jointure - [x] Créer getSequencesWithFormation() pour éviter les conflits avec le spread operator - [x] Mettre à jour la procédure sequences.list pour utiliser getSequencesWithFormation() - [x] Corriger AdminCalendrier.tsx pour utiliser formation.nom au lieu de formation.titre - [x] Vérifier que le placeholder du FormateurCombobox est correct (sans "(optionnel)") - [x] Tester l'affichage du nom de formation dans le calendrier - [x] Tester l'affichage du nom de formation dans le dialog de détails ## Corrections affichage formateur - [x] Corriger le placeholder "Sélectionner un formateur (optionnel)" en "Sélectionner un formateur" dans le formulaire de modification de séquence - [x] Ajouter l'affichage du formateur dans la liste des séquences (AdminSequences) - [x] Tester les modifications ## Nettoyage de la table utilisateurs - [x] Vérifier les utilisateurs existants dans la base de données - [x] Supprimer tous les utilisateurs sauf les 4 spécifiés (IDs: 1110110, 2010001, 2040001, 2070001) - [x] Vérifier que la suppression a réussi ## Correction erreur formateurs.create - [x] Identifier le code qui appelle formateurs.create - [x] Ajouter la procédure formateurs.create manquante dans le routeur - [x] Tester la correction ## Correction affichage du formateur dans les séquences - [x] Vérifier comment getSequencesWithFormation récupère les informations du formateur - [x] Corriger la jointure pour inclure les données du formateur - [x] Vérifier l'affichage dans AdminSequences.tsx - [x] Ajouter formateurId dans le schéma de validation de sequences.create - [x] Ajouter formateurId dans le schéma de validation de sequences.update - [x] Corriger le schéma Zod pour accepter null (formateurId: z.number().nullable().optional()) - [x] Modifier FormateurCombobox pour stocker l'ID au lieu du nom - [x] Tester les modifications dans la liste et dans le dialog de modification ## Améliorations des feuilles de présence - [x] Copier le logo Itinova dans le dossier public du projet - [x] Ajouter le logo Itinova en haut à droite de chaque page de feuille de présence - [x] Ajouter le nom du formateur dans l'en-tête de la feuille de présence - [x] Modifier le tableau pour avoir deux signatures par apprenant et par journée (matin et après-midi) - [x] Mettre à jour l'interface FeuillePresenceInfo pour inclure le formateur - [x] Tester la génération des feuilles de présence avec toutes les modifications ## Signature du formateur sur les feuilles de présence - [x] Ajouter un champ de signature pour le formateur en bas de chaque page de feuille de présence ## Détail par apprenant - [x] Créer une procédure tRPC pour récupérer toutes les inscriptions d'un apprenant avec les informations de formation et séquence - [x] Créer la page AdminApprenantDetail affichant la liste des inscriptions par apprenant - [x] Ajouter un bouton "Détail par apprenant" dans la page AdminApprenants - [x] Ajouter la route /admin/apprenants/:id dans App.tsx - [x] Tester l'affichage des détails d'un apprenant ## Problème de création excessive d'utilisateurs - [x] Analyser la table users pour identifier les utilisateurs en double - [x] Examiner le code d'authentification OAuth - [x] Identifier la cause de la création excessive d'utilisateurs - [x] Corriger le problème - [x] Tester la correction ## Identifiant de connexion et modification du mot de passe - [ ] Ajouter le champ username (identifiant de connexion) dans le schéma de la base de données - [ ] Générer et appliquer la migration de la base de données - [x] Mettre à jour les procédures tRPC pour gérer username et password - [ ] Afficher l'identifiant de connexion dans la liste des utilisateurs - [ ] Permettre la modification de l'identifiant et du mot de passe dans la fenêtre d'édition - [x] Tester les modifications ## Utilisateur administrateur spécial - [x] Créer l'utilisateur "adminServFormation" avec mot de passe "Itinova69!" dans la base de données - [x] Modifier l'interface pour désactiver le bouton de suppression pour cet utilisateur - [x] Modifier le formulaire d'édition pour rendre les champs nom, email et identifiant en lecture seule pour cet utilisateur - [x] Tester les modifications ## Email modifiable pour administrateur - [x] Modifier l'interface pour rendre le champ email modifiable pour l'utilisateur adminServFormation - [x] Tester la modification ## Authentification locale avec username/password - [x] Créer la route d'authentification locale dans le backend (POST /api/auth/local/login) - [x] Créer la page de connexion locale avec formulaire username/password - [x] Ajouter la route /login dans App.tsx - [x] Créer un lien vers la page de login depuis la page d'accueil - [x] Écrire des tests pour l'authentification locale - [x] Tester la connexion avec adminServFormation/Itinova69! ## Ajouter un lien visible vers la connexion locale - [x] Modifier la page d'accueil pour afficher un bouton "Connexion locale" - [x] Tester l'accès à la page de connexion locale depuis la page d'accueil ## Corriger la redirection de /login vers OAuth - [x] Identifier pourquoi /login redirige vers OAuth au lieu d'afficher le formulaire local - [x] Corriger la page Login.tsx pour empêcher la redirection automatique - [x] Tester que /login affiche bien le formulaire username/password ## Désactiver la redirection OAuth pour /login - [ ] Identifier le middleware qui force la redirection vers OAuth - [ ] Exclure la route /login de la redirection automatique - [ ] Tester que /login affiche bien le formulaire local même après publication ## Créer une page de choix de connexion - [ ] Créer une page LoginChoice avec boutons "Connexion Manus" et "Connexion locale" - [ ] Modifier les routes pour afficher cette page en premier - [ ] Tester le choix et les redirections ## Créer une page de choix de connexion - [x] Créer une page LoginChoice avec boutons "Connexion Manus" et "Connexion locale" - [x] Modifier les routes pour afficher cette page en premier - [x] Tester le choix et les redirections ## Correction redirection après déconnexion - [x] Modifier la procédure de déconnexion pour rediriger vers la page de choix (/) - [x] Tester la déconnexion et vérifier la redirection ## Correction page de choix au lancement - [x] Analyser pourquoi la page de choix ne s'affiche pas au lancement - [x] Corriger la redirection automatique - [x] Tester l'affichage de la page de choix ## Sauvegarde complète avec corrections authentification - [x] Appliquer toutes les corrections d'authentification locale - [x] Créer un checkpoint final - [x] Créer un package de déploiement complet ## Configuration HTTPS avec Let's Encrypt - [x] Créer le guide de configuration HTTPS complet - [x] Créer le script d'installation automatique de nginx et certbot - [x] Créer la configuration nginx optimisée - [x] Créer le script de renouvellement automatique des certificats - [x] Tester la configuration HTTPS ## Ajout du logo Itinova sur la page de choix de connexion - [ ] Modifier la page LoginChoice pour afficher le logo en haut - [ ] Tester l'affichage du logo ## Script de correction VPS - [ ] Créer un script de correction complet pour appliquer toutes les modifications sur le VPS - [ ] Tester le script ## Correction interface templates d'emails - [x] Permettre la modification du corps du message dans les templates d'emails ## Correction erreur 403 sur application publiée - [x] Identifier la cause de l'erreur 403 après publication de la version avec bodyContent - [x] Corriger le problème (ajout bodyContent dans routers.ts et db.ts) - [x] Tester l'accès public à l'application ## Amélioration prévisualisation templates d'emails - [x] Modifier la prévisualisation pour afficher le contenu saisi dans "Corps du message" en temps réel ## Amélioration éditeur de templates d'emails - [x] Installer React Quill (éditeur WYSIWYG) - [x] Intégrer l'éditeur dans AdminEmailTemplates - [x] Ajouter des boutons pour insérer des variables dynamiques ({{nomApprenant}}, {{nomFormation}}, {{dateDebut}}, etc.) - [x] Tester l'éditeur et la prévisualisation ## Correction erreur React Quill incompatible avec React 19 - [x] Remplacer React Quill par une solution compatible (TipTap) - [x] Tester le nouvel éditeur ## Remplacement automatique des variables dans les emails - [x] Créer une fonction utilitaire de remplacement des variables - [x] Modifier les fonctions d'envoi d'emails pour utiliser le remplacement - [x] Ajouter un bouton "Aperçu email" dans l'interface de gestion des templates - [x] Créer un modal d'aperçu montrant l'email final avec variables remplacées - [x] Tester l'envoi d'emails avec variables ## Tableau de bord analytique avancé - [x] Créer les requêtes backend pour récupérer les données analytiques - [x] Créer une page dédiée au tableau de bord analytique - [x] Ajouter un graphique d'évolution temporelle des inscriptions - [x] Ajouter un graphique de taux de remplissage par mois - [x] Ajouter des statistiques de participation par établissement - [x] Intégrer la page dans le menu de navigation ## Améliorations tableau de bord analytique - [x] Ajouter des filtres de période (dernier mois, trimestre, année, personnalisé) - [x] Implémenter l'export PDF des rapports analytiques (placeholder) - [x] Implémenter l'export Excel des rapports analytiques - [x] Créer le schéma de base de données pour les alertes - [ ] Créer l'interface de configuration des alertes (fonctionnalité future) - [ ] Implémenter le système de vérification et d'envoi des alertes (fonctionnalité future) ## Correction incohérence statistiques - [x] Identifier la source de l'incohérence entre tableau de bord principal et analytique - [x] Uniformiser les calculs de répartition par fonction - [x] Vérifier la cohérence des données affichées ## Ajout graphique répartition par établissement - [x] Ajouter le graphique de répartition par établissement sur le tableau de bord principal - [x] Placer le graphique à côté du graphique par fonction ## Amélioration affichage gestion des séquences - [x] Afficher le taux de remplissage avec couleur conditionnelle (vert <70%, orange 70-90%, rouge >90%) - [x] Changer la couleur de l'icône corbeille en rouge ## Amélioration visuelle fenêtre des séquences - [x] Changer la couleur de l'icône œil en bleu - [x] Coloriser le texte des formations avec une couleur unique par formation (éviter vert, orange, rouge) ## Correction algorithme de couleur des formations - [x] Corriger la fonction getFormationColor pour que chaque formation ait une couleur unique ## Amélioration visuelle page des apprenants - [x] Afficher l'icône corbeille en rouge - [x] Afficher l'icône œil en bleu - [x] Coloriser la fonction (Directeurs, Chefs de service) comme dans les séquences ## Badges de statut apprenants et vue établissements - [x] Ajouter des badges "Actif" (vert) / "Inactif" (gris) dans la liste des apprenants - [x] Créer les requêtes backend pour récupérer les statistiques par établissement - [x] Créer une page "Établissements" avec liste et statistiques - [x] Ajouter le lien dans le menu de navigation ## Corrections bugs interface - [x] Corriger l'erreur d'affichage au clic sur un événement du calendrier (ajout import useState) - [x] Corriger le problème de menu invisible sur la page Établissements (ajout DashboardLayout) ## Correction erreur React #31 dans le calendrier - [x] Corriger l'erreur d'objet passé comme enfant React dans le modal de détails du calendrier ## Réorganisation du menu du tableau de bord - [x] Réorganiser le menu en 4 zones distinctes avec séparateurs visuels - Zone 1 : Tableau de bord - Zone 2 : Gestion (Formations, Séquences, Calendrier, Apprenants) - Zone 3 : Configuration (Utilisateurs, Rappels, Templates d'emails, Configuration SMTP) - Zone 4 : Analyses (Établissements, Tableau de bord analytique, Rapport public cible) ## Modification couleur titres menu - [x] Changer la couleur des titres des zones du menu en bleu ## Génération documents de déploiement - [ ] Créer le guide de déploiement complet (GUIDE_DEPLOIEMENT.md) - [ ] Générer les scripts de déploiement automatisés (deploy.sh, update.sh) - [ ] Créer la documentation de configuration (CONFIGURATION.md) - [ ] Créer le fichier de notes de version (RELEASE_NOTES.md) ## Bug calendrier - Erreur React #31 au survol des vignettes - [x] Analyser l'erreur React #31 dans le calendrier - [x] Identifier la cause de l'erreur lors du survol des vignettes - [x] Corriger le code pour résoudre l'erreur - [x] Tester le calendrier après correction ## Améliorations du calendrier ### Filtres du calendrier - [x] Ajouter un filtre par formation - [x] Ajouter un filtre par lieu - [x] Ajouter un filtre par public cible - [x] Implémenter la logique de filtrage dans la vue calendrier - [x] Tester les filtres avec différentes combinaisons ### Vues alternatives du calendrier - [x] Créer la vue hebdomadaire - [x] Créer la vue journalière - [x] Ajouter un sélecteur de vue (mois/semaine/jour) - [x] Adapter l'affichage des séquences pour chaque vue - [x] Tester la navigation entre les vues ### Export du calendrier - [x] Implémenter l'export PDF du calendrier mensuel - [x] Implémenter l'export iCal pour partage avec les formateurs - [x] Ajouter les boutons d'export dans l'interface - [x] Tester les exports avec différents mois ## Bug création de séquence avec public cible "Tous" - [x] Reproduire le bug avec le public cible "Tous" - [x] Identifier la cause du problème dans le code - [x] Corriger le bug - [x] Tester la création/modification avec public cible "Tous" ## Problème de démarrage du service sur VPS - [x] Diagnostiquer la cause de l'erreur (code exit 1) - [x] Vérifier les logs du service - [x] Identifier les problèmes de configuration (absence de build) - [x] Fournir les solutions de correction - [x] Créer une documentation de dépannage ## Import Excel - Formations et Séquences - [x] Créer le template Excel avec colonnes définies - [x] Développer la procédure backend pour parser le fichier Excel - [x] Implémenter la validation des données importées - [x] Créer la logique d'insertion en base de données - [x] Développer l'interface frontend d'upload - [x] Ajouter la prévisualisation des données avant import - [x] Gérer les erreurs et retours utilisateur - [x] Créer la documentation utilisateur avec exemple - [x] Tester l'import avec différents fichiers Excel ## Bug import Excel - Erreur lors de la création des formations - [x] Identifier la cause de l'erreur "Cannot read properties of undefined (reading 'nom')" (conflit de nom) - [x] Corriger la logique d'insertion des formations (renommage des imports) - [x] Tester l'import avec le fichier Excel d'exemple - [x] Vérifier que les formations et séquences sont bien créées ## Bug import Excel - Erreur de nom de colonne lienInscription vs lienUnique - [x] Vérifier le schéma de la table formations - [x] Corriger le nom de colonne dans importExcel.ts (lienInscription → lienUnique) - [x] Tester l'import après correction ## Bug import Excel - Formation non trouvée après création - [ ] Analyser le fichier Excel de test fourni - [ ] Identifier pourquoi la formation n'est pas trouvée dans la map - [ ] Corriger la logique d'import - [ ] Tester avec le fichier Excel fourni ## Bug import Excel - Erreur nom de colonne publicCible - [x] Vérifier le schéma de la table formations en base de données (publicCible n'existe pas dans formations) - [x] Corriger le code d'import (retiré publicCible de l'insertion formations) - [x] Tester l'import après correction ## Bug import Excel - Problème persistant "Formation non trouvée" - [x] Analyser les logs serveur pour voir si la formation est réellement créée (ID = NaN) - [x] Vérifier si l'erreur vient de la création ou de la recherche dans la map (problème de récupération ID) - [x] Corriger le problème identifié (utilisation de $returningId() pour formations et séquences, ajout ordre pour dates) - [x] Tester l'import et valider que tout fonctionne ## Bug décalage horaire - Heures de séquences - [x] Identifier où se produit le décalage horaire (+1h) (conversion locale vs UTC) - [x] Vérifier la gestion des fuseaux horaires dans le formulaire - [x] Corriger la conversion des dates/heures (UTC pour affichage et envoi) - [x] Tester la saisie et l'affichage des heures ## Bug décalage horaire dans formulaire d'édition - [x] Identifier pourquoi le formulaire affiche -2h (ex: 9h00 → 7h00) (utilisation de méthodes UTC au lieu de locales) - [x] Corriger la fonction safeFormatDate (utiliser getHours() au lieu de getUTCHours()) - [ ] Tester l'édition de séquences ## Bug page d'import Excel sans menu - [x] Ajouter le DashboardLayout wrapper à la page d'import Excel - [x] Vérifier que le menu de navigation s'affiche correctement ## Déplacement menu Import Excel - [x] Déplacer "Import Excel" du bloc GESTION vers le bloc CONFIGURATION - [x] Vérifier l'affichage dans le menu de navigation ## Scripts de mise à jour VPS - [x] Créer le script de mise à jour automatique (update-app.sh) - [x] Créer le script de sauvegarde avant mise à jour (backup-before-update.sh) - [x] Créer la documentation de mise à jour (GUIDE_MISE_A_JOUR.md) - [x] Créer le package de déploiement complet (formation-manager-update-*.tar.gz) ## Correction nom répertoire dans scripts - [x] Corriger APP_DIR dans backup-before-update.sh - [x] Corriger APP_DIR dans update-app.sh - [x] Corriger SERVICE_NAME dans tous les fichiers - [x] Corriger la documentation (GUIDE_MISE_A_JOUR.md et README.md) - [x] Recréer le package de déploiement (formation-manager-update-20251127_095935.tar.gz) ## Bug drizzle-kit not found - [x] Corriger update-app.sh pour installer toutes les dépendances (pas seulement --prod) - [x] Corriger GUIDE_MISE_A_JOUR.md - [x] Recréer le package de déploiement (formation-manager-update-20251127_114306.tar.gz) ## Envoi emails via SMTP (sans Resend) - [x] Analyser le code d'envoi d'emails actuel - [x] Ajouter les champs SMTP dans le schéma de base de données - [x] Installer nodemailer - [x] Créer une fonction d'envoi SMTP avec nodemailer (smtpSender.ts) - [x] Modifier emailSender.ts pour supporter SMTP - [x] Ajouter l'interface SMTP dans AdminEmailConfig.tsx - [x] Tester l'envoi d'emails via SMTP (interface visible dans Configuration SMTP) ## Bug enregistrement configuration SMTP - [x] Vérifier les procédures tRPC emailConfig - [x] Corriger la mutation upsert pour supporter les champs SMTP - [x] Tester l'enregistrement de la configuration SMTP (champs ajoutés dans l'input tRPC) ## Bug email de test envoyé à la mauvaise adresse - [x] Vérifier la fonction sendEmail dans emailSender.ts - [x] Vérifier la fonction sendEmailViaSMTP dans smtpSender.ts - [x] Vérifier pourquoi le mode production ne peut pas être activé (le switch fonctionne) - [x] Corriger l'affichage du statut pour montrer SMTP au lieu de Resend - [x] Ajouter des alertes spécifiques pour SMTP - [x] Corriger la fonction upsertEmailConfig pour mettre à jour au lieu de créer - [x] Forcer la mise à jour du provider dans la base de données - [x] Vérifier que la configuration SMTP est bien enregistrée (provider=smtp) - [x] Tester l'envoi d'email de test en mode production (correction du cache appliquée) ## Bug email de test SMTP non reçu - [x] Vérifier les logs du serveur pour voir les erreurs SMTP - [x] Vérifier que le mot de passe SMTP est correct - [x] Identifier que le mail de simulation est envoyé au lieu de SMTP - [x] Corriger le problème de cache React Query qui garde provider='resend' - [x] Forcer l'invalidation du cache après enregistrement (utils.emailConfig.get.invalidate()) ## Erreur "Unexpected token '<'" sur /admin/email-config - [x] Vérifier les logs du serveur pour voir l'erreur exacte (erreur temporaire liée au redémarrage) - [x] Tester le chargement de la page (fonctionne correctement) ## Bug envoi email fonctionne en dev mais pas en production - [x] Vérifier si nodemailer est dans les dependencies (OK, ligne 75) - [ ] Vérifier que la configuration SMTP est bien enregistrée en production - [ ] Ajouter une page de diagnostic pour vérifier la config en production - [ ] Corriger le problème ## Bug emails de rappel utilisent mail de test au lieu de SMTP - [x] Trouver où les emails de rappel sont envoyés dans le code (sendGroupEmail) - [x] Vérifier qu'ils utilisent bien sendEmail() (OK, ligne 249 emailService.ts) - [x] Vérifier le filtre des inscriptions (statut='confirmee' ligne 517) - [x] Confirmer qu'il y a des apprenants confirmés avec vraies adresses - [x] Ajouter des logs pour diagnostiquer l'envoi (console.log dans routers.ts) - [x] Ajouter un message de retour avec le nombre d'emails envoyés - [x] Tester l'envoi de rappel et vérifier les logs (fonctionne correctement) ## Bug tag {nom de la formation} non remplacé dans email teaser - [x] Trouver où le template d'email est généré (emailTemplateGenerator.ts) - [x] Vérifier le système de remplacement des tags ({{nomFormation}}) - [x] Corriger le remplacement du tag (ajout des variables dans sendTeaserEmail et sendRappelJ7Email) - [x] Corriger et préparer pour test en production ## Email teaser sans formateur ni lieu - [x] Vérifier les données disponibles dans sendTeaserEmail - [x] Ajouter le formateur et le lieu dans les paramètres de sendTeaserEmail - [x] Récupérer le formateur depuis la base de données dans routers.ts - [x] Modifier le template pour afficher lieu et formateur - [x] Ajouter lieu et formateur dans les variables - [x] Préparer pour test en production ## Personnalisation templates d'emails avec variables - [x] Vérifier que les templates personnalisés utilisent bien les variables (OK, replaceEmailVariables) - [x] Documenter les variables disponibles dans l'interface (OK, boutons d'insertion présents) - [x] Les variables {{lieu}} et {{formateur}} sont déjà disponibles ## Aperçu avant envoi d'emails - [x] Créer une procédure tRPC pour générer un aperçu d'email (emailPreview.ts) - [x] Ajouter un bouton "Aperçu" dans l'interface d'envoi (AdminSequenceInscrits.tsx) - [x] Afficher un modal avec le rendu de l'email (Dialog avec iframe) - [x] Utiliser le premier apprenant confirmé pour l'aperçu ## Email de rappel J-1 - [x] Créer la fonction sendRappelJ1Email dans emailService.ts - [x] Ajouter un bouton "Envoyer rappel J-1" dans l'interface - [x] Créer le template d'email de rappel J-1 - [x] Ajouter le bouton d'aperçu pour rappel J-1 - [x] Modifier la procédure tRPC pour supporter rappel_j1 - [x] Préparer pour test (serveur redémarré) ## Correction template email rappel J-1 - [x] Ajouter le template de rappel J-1 dans la page de gestion des templates d'emails ## Correction template email J-7 - [x] Analyser le template J-7 dans la page des templates d'emails - [x] Analyser l'aperçu J-7 depuis les séquences - [x] Identifier les différences entre les deux - [x] Corriger le template pour qu'il corresponde à l'aperçu des séquences ## Amélioration template J-7 : afficher toutes les dates - [ ] Analyser comment le template précédent affichait toutes les dates - [ ] Modifier le système de génération pour passer toutes les dates au template - [ ] Mettre à jour le template J-7 en base de données ## Amélioration template J-7 - Affichage de toutes les dates - [x] Ajouter la variable datesHTML dans EmailVariables - [x] Générer datesHTML dans emailPreview.ts - [x] Ajouter datesHTML dans sendRappelJ7Email - [x] Ajouter datesHTML dans sendRappelJ1Email - [x] Ajouter datesHTML dans sendTeaserEmail - [x] Mettre à jour le template J-7 en base de données avec {{datesHTML}} - [x] Mettre à jour le template J-1 en base de données avec {{datesHTML}} - [x] Mettre à jour les templates par défaut dans db.ts - [x] Tester l'affichage du template J-7 dans la page des templates ## Configuration finale des emails et rappels - [x] Créer un guide complet pour personnaliser les couleurs et le logo des templates J-7 et J-1 - [x] Créer un guide complet pour tester l'envoi réel d'emails avec aperçu - [x] Créer un guide complet pour configurer les rappels automatiques pour J-7 et J-1 ## Conversion du guide en Word - [x] Convertir le guide de configuration des emails en format Word (.docx) ## Bug SMTP - Mode simulation persistant - [x] Analyser le code d'envoi d'emails pour identifier pourquoi le mode simulation persiste - [x] Corriger le double envoi (email réel + notification simulée) - [ ] Tester l'envoi réel d'emails après correction ## Bug Rappels - Types J-7 et J-1 manquants - [x] Analyser la page des rappels pour identifier pourquoi les types J-7 et J-1 n'apparaissent pas - [x] Ajouter les types J-7 et J-1 dans l'interface de gestion des rappels - [ ] Tester la création de rappels J-7 et J-1 ## Correction template email rappel J-1 - [x] Ajouter le template de rappel J-1 dans la page de gestion des templates d'emails ## Correction template email J-7 - [x] Analyser le template J-7 dans la page des templates d'emails - [x] Analyser l'aperçu J-7 depuis les séquences - [x] Identifier les différences entre les deux - [x] Corriger le template pour qu'il corresponde à l'aperçu des séquences ## Amélioration template J-7 - [x] Modifier le template J-7 pour afficher toutes les dates de la séquence au lieu d'une seule date ## Bug SMTP - Mode simulation - [x] Analyser le code d'envoi d'emails pour identifier pourquoi le mode simulation persiste - [x] Corriger le double envoi (email réel + notification simulée) - [x] Tester l'envoi réel d'emails après correction ## Bug Rappels - Types J-7 et J-1 manquants - [x] Analyser la page des rappels pour identifier pourquoi les types J-7 et J-1 n'apparaissent pas - [x] Ajouter les types J-7 et J-1 dans l'interface de gestion des rappels - [ ] Corriger le bug d'insertion SQL (erreur sur derniereExecution) - [ ] Tester la création de rappels J-7 et J-1 ## Finalisation des rappels automatiques - [x] Corriger le bug d'insertion SQL (champ derniereExecution) - [x] Tester la création de rappels J-7 et J-1 - [x] Créer un job automatique qui vérifie quotidiennement les séquences à venir - [x] Implémenter la logique d'envoi automatique des rappels selon les règles configurées - [x] Tester l'envoi automatique en conditions réelles (scheduler actif, vérification toutes les heures) ## Personnalisation des templates d'emails - [x] Ajouter le logo Itinova dans les templates J-7 et J-1 - [x] Ajuster les couleurs de l'en-tête selon la charte graphique Itinova (Bleu #283581, Bleu clair #0578BE, Orange #E94E1B, Vert #45ac34) - [x] Appliquer un style sobre et professionnelt liens - [x] Tester le rendu des templates personnalisés ## Bug Email Confirmation - Variables non remplacées - [x] Analyser la fonction d'envoi d'email de confirmation d'inscription - [x] Identifier pourquoi {{prenom}} et autres variables ne sont pas remplacées - [x] Corriger le remplacement des variables (ajout d'alias pour compatibilité) - [x] Corriger le code pour supporter les deux formats de variables ({{prenom}} et {{prenomApprenant}}) - [ ] Tester l'envoi d'un email de confirmation en production ## Bug Inscriptions - Inscriptions annulées toujours affichées - [x] Analyser où les inscriptions annulées ne sont pas filtrées (affichage, emails, rappels) - [x] Corriger getInscriptionsBySequence pour exclure les inscriptions annulées - [x] Corriger getInscriptionsByApprenant pour exclure les inscriptions annulées - [x] Vérifier que les rappels ne sont pas envoyés aux inscriptions annulées (déjà filtré) - [ ] Tester l'affichage après annulation d'une inscription ## Bug Inscription - Détection incorrecte d'inscription existante - [x] Analyser la fonction checkExistingInscription - [x] Corriger le filtrage pour ne pas considérer les inscriptions annulées comme existantes - [ ] Tester la réinscription après annulation ## Bug Inscription - Mauvais apprenant associé lors de l'inscription - [x] Analyser le processus d'inscription (page Inscription.tsx et procédure tRPC) - [x] Identifier pourquoi l'inscription de MONROE Marylin crée une inscription pour PIGNOL François - [x] Corriger le code pour associer le bon apprenant lors de l'inscription (création de createPublic) - [ ] Tester l'inscription avec différents apprenants pour vérifier la correction ## Bug Email Confirmation - Variable {{prenomApprenant}} non remplacée - [x] Analyser la fonction sendInscriptionConfirmation dans email.ts - [x] Identifier pourquoi {{prenomApprenant}} n'est pas remplacé (affiche "Cher(e) {{prenomApprenant}} monroe") - [x] Corriger le remplacement des variables dans l'email de confirmation (mise à jour du bodyContent du template) - [ ] Tester l'envoi d'un email de confirmation avec les bonnes variables ## Ajout du bouton {{datesHTML}} dans les templates d'emails - [x] Localiser l'interface AdminEmailTemplates - [x] Ajouter le bouton pour insérer {{datesHTML}} dans la liste des variables disponibles - [x] Ajouter le remplacement de {{datesHTML}} dans la prévisualisation - [ ] Tester l'insertion de la variable dans un template ## Vérification invitations ICS - Une invitation par date de séquence - [ ] Analyser le code de génération des invitations ICS dans sendInscriptionConfirmation - [ ] Vérifier qu'il y a bien une invitation ICS générée pour chaque date de la séquence - [ ] Corriger si nécessaire - [ ] Tester l'envoi d'un email avec plusieurs dates ## Bug Email Confirmation - Variable {{datesHTML}} non remplacée - [x] Analyser pourquoi {{datesHTML}} n'est pas remplacée dans l'email de confirmation - [x] Ajouter la variable datesHTML dans l'objet variables de sendInscriptionConfirmation - [x] Générer le HTML formaté des dates pour cette variable (déjà présent) - [ ] Tester l'envoi d'un email de confirmation avec {{datesHTML}}