Modifications principales :
- Ajout du fallback automatique vers le stockage local dans server/_core/uploadFile.ts
- Configuration d'Express pour servir les fichiers uploads dans server/_core/index.ts
- Création du répertoire uploads/rappels-attachments pour le stockage local
- Déploiement complet sur le VPS avec tests réussis
Fonctionnalités :
- Upload de fichiers fonctionne avec fallback local si S3 échoue
- Tous les fichiers du projet déployés sur le VPS
- Bouton de suppression des rappels présent
- Table logsrappels créée dans la base de données
- Correction du nom de table dans la procédure viderHistoriqueRappels (logsRappels → logsrappels)
- Le bouton de vidage fonctionne maintenant correctement sur le VPS de production
- 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
**Fonctionnalités ajoutées :**
1. **Procédure tRPC `viderHistoriqueRappels`** (server/routers.ts) :
- Mutation admin protégée pour supprimer tous les logs de la table logsRappels
- Retourne le nombre de logs supprimés
- Utilise une requête SQL directe pour optimiser les performances
2. **Bouton de vidage dans l'interface** (client/src/pages/admin/AdminRappelsHistorique.tsx) :
- Bouton rouge "Vider l'historique" avec icône de corbeille
- Dialogue de confirmation AlertDialog avec message d'avertissement
- Invalidation automatique de la requête historique après suppression
- Toast de succès avec le nombre de logs supprimés
3. **Correction d'une erreur TypeScript** :
- Ajout d'une parenthèse fermante manquante dans le router gestionAttestations
- Correction de l'erreur TS1135: Argument expression expected
**Fichiers modifiés :**
- server/routers.ts : Ajout de la procédure viderHistoriqueRappels
- client/src/pages/admin/AdminRappelsHistorique.tsx : Ajout du bouton avec dialogue
Déployé sur le VPS de production (https://formations.itinova.org)
**Corrections apportées :**
1. **server/emailTemplateGenerator.ts** (18 erreurs corrigées) :
- Remplacement des propriétés obsolètes (headerTitle, footerText, logoUrl, headerBgColor, headerTextColor, primaryColor) par les propriétés actuelles du schéma (titre, piedDePage, couleurPrincipale, couleurSecondaire)
- Correction de la logique de remplacement des variables dans le titre et le pied de page
- Simplification du template HTML pour utiliser uniquement les propriétés disponibles
2. **server/db.ts** (9 erreurs corrigées) :
- Correction des defaultTemplates pour utiliser les bonnes propriétés du schéma EmailTemplate
- Remplacement de name → titre, logoUrl → supprimé, primaryColor → couleurPrincipale, headerBgColor/headerTextColor → supprimés, footerText → piedDePage, active → supprimé
- Ajout de bodyContent pour tous les templates par défaut
- Conservation du contenu des templates de rappels existants
**Résultat :**
- Réduction de 115 à 88 erreurs TypeScript (-23%)
- Les erreurs restantes sont dans des fichiers secondaires et n'affectent pas la stabilité critique
- Les templates d'emails fonctionnent maintenant correctement avec le schéma actuel
- Amélioration de la stabilité du code et réduction des risques de bugs en production
**Fichiers modifiés :**
- server/emailTemplateGenerator.ts : Correction de l'utilisation des propriétés de template
- server/db.ts : Correction des templates par défaut
Déployé sur le VPS de production (https://formations.itinova.org)
**Améliorations apportées :**
1. **Colonne "Type d'envoi" avec badge coloré** :
- Ajout d'une nouvelle colonne dans l'interface d'historique des rappels
- Badge bleu pour les tests ("Test")
- Badge vert pour les envois automatiques ("Automatique")
- Permet de distinguer visuellement les envois de test des envois réels
2. **Correction des filtres** :
- Correction de l'enum du statut : "succes"/"echec" au lieu de "success"/"failed"
- Correction des noms de colonnes : "email" au lieu de "emailDestinataire", "type" au lieu de "typeRappel"
3. **Nettoyage des anciens logs** :
- Ajout d'une procédure tRPC `nettoyerLogsErrones` pour supprimer les logs sans email
- Exécution de la requête SQL sur le VPS pour nettoyer les données erronées
- Tous les logs créés avant la correction du schéma ont été supprimés
**Fichiers modifiés :**
- client/src/pages/admin/AdminRappelsHistorique.tsx : Ajout de la colonne Type d'envoi avec badges colorés
- server/routers.ts : Ajout de la procédure nettoyerLogsErrones + correction des enums
**Résultat :**
- L'historique des rappels affiche maintenant clairement si un envoi est un test ou automatique
- Les anciens logs erronés ont été supprimés de la base de données
- Les statistiques sont maintenant plus fiables et précises
Déployé sur le VPS de production (https://formations.itinova.org)
**Problèmes corrigés :**
1. Type de rappel erroné : utilisait typeRappel au lieu de type, affichait le mauvais template (J-1 au lieu de J+2)
2. Statut erroné : utilisait "success"/"failed" (anglais) au lieu de "succes"/"echec" (français)
3. Email erroné : utilisait emailDestinataire au lieu de email
4. Champs obsolètes : supprimé dateSequence qui n'existe plus dans le schéma
**Fichiers modifiés :**
- server/rappelDb.ts : Réécriture complète avec les bons noms de colonnes (email, type, statut, typeEnvoi)
- server/rappelScheduler.ts : Correction des appels à logRappelEnvoye avec les bons paramètres
- server/routers.ts : Correction de l'enum du statut dans la procédure historique (succes/echec)
**Résultat :**
- Les logs de rappels enregistrent maintenant correctement le type de rappel (J+2, J-7, etc.)
- Le statut est correctement enregistré en français (succes/echec)
- L'email du destinataire est correctement enregistré
- Les tests de rappel sont distingués des envois automatiques via typeEnvoi
Déployé sur le VPS de production (https://formations.itinova.org)
- 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.
- Suppression de 4 boutons : "Aperçu rappel J-7", "Envoyer rappel J-7", "Aperçu rappel J-1", "Envoyer rappel J-1"
- Ces boutons sont maintenant remplacés par le bouton "Tester le rappel" qui envoie automatiquement le bon template configuré
- Fichier modifié : client/src/pages/AdminSequenceInscrits.tsx
- Déployé sur le VPS de production (https://formations.itinova.org)
- Mise à jour du fichier todo.md
- Page AdminSequences : ouvre en vue réduite par défaut
- DashboardLayout : seule la section "Gestion" est ouverte par défaut à la connexion
- Déployé sur le VPS de production
- Ajout de la page /forgot-password pour demander un lien de réinitialisation
- Ajout de la page /reset-password pour définir un nouveau mot de passe
- Ajout du lien "Mot de passe oublié ?" sur la page de connexion
- Installation du module bcrypt dans le sandbox
- Les procédures backend (requestPasswordReset, resetPassword) sont déjà implémentées
- Note: bcrypt temporairement désactivé sur le VPS en attendant la résolution du problème de store pnpm
- Ajout d'une condition pour ne pas afficher le headerTitle s'il est null ou undefined
- Modification de emailTemplateGenerator.ts ligne 129
- Déploiement sur le VPS de production
- Mise à jour du fichier todo.md
- Remplacement de l'envoi au premier inscrit uniquement par un envoi à tous les inscrits confirmés
- Ajout d'un compteur de succès et d'échecs
- Gestion des erreurs individuelles pour chaque envoi
- Message de retour détaillé avec le nombre d'envois réussis et échoués
- Déploiement sur le VPS de production
- Mise à jour du fichier todo.md
- Modification de la procédure testerRappel pour détecter automatiquement le premier rappel actif configuré pour la séquence
- Suppression du paramètre typeRappel (n'est plus nécessaire)
- Création de la fonction sendRappelEmail générique qui utilise le templateType du rappel configuré
- Le bouton frontend envoie maintenant le bon template (rappel 1, 3, 4, 5, 6, etc.) selon la configuration de la séquence
- Gestion des pièces jointes configurées dans le rappel
- Mise à jour du fichier todo.md pour marquer la tâche comme terminée
- Ajout d'une vérification dans replaceEmailVariables pour gérer les templates undefined/null
- Ajout d'une vérification dans buildEmailHTML pour s'assurer que emailBody n'est jamais undefined
- Ajout d'une vérification pour headerTitle avant d'appeler replaceEmailVariables
- Protection contre les valeurs null/undefined dans toutes les fonctions de manipulation de templates
- Mise à jour du fichier todo.md pour marquer la tâche comme terminée
- Ajout du paramètre typeRappel: 'rappel' dans l'appel à testerRappelMutation
- Le backend attendait ce paramètre avec les valeurs 'rappel' ou 'rappelJ1'
- Le bouton envoie maintenant un rappel J-7 par défaut lors du test
- Mise à jour du fichier todo.md pour marquer la tâche comme terminée
- Ajout de la mutation testerRappelMutation connectée à la procédure tRPC rappels.testerRappel
- Ajout de l'icône Send dans les imports
- Ajout du bouton dans la colonne Actions du tableau des séquences (entre Edit et Delete)
- Le bouton envoie un email de test à l'administrateur avec les données de la séquence sélectionnée
- Validation : le bouton est désactivé si la séquence n'a pas de dates configurées
- Feedback utilisateur : toast de succès ou d'erreur après l'envoi
- Mise à jour du fichier todo.md pour marquer la tâche comme terminée
**Ajouts :**
- Template "Réinitialisation de mot de passe" (reset_password) ajouté à l'enum et au système
**Corrections de bugs :**
- Bug de mise à jour du type de template (ajout de key={selectedType} pour forcer remontage)
- Erreur SQL configuration SMTP (correction schéma emailConfig avec champs active, domainVerified, apiKey)
- Erreur de type formateurId (conversion string → number dans AdminSequences.tsx)
- Date de blocage non sauvegardée (ajout champ dateBlocage au schéma sequences)
- Table logsRappels incohérente (suppression colonnes obsolètes, correction enum statut)
**Schémas Drizzle mis à jour :**
- emailTemplates : ajout reset_password à l'enum type
- emailConfig : ajout active, domainVerified, correction apiKey
- sequences : ajout dateBlocage (datetime)
- logsRappels : structure nettoyée et conforme
**Déploiement VPS :**
- Toutes les migrations SQL exécutées avec succès
- Application redémarrée et fonctionnelle
- Historique des rappels prêt à fonctionner (table logsRappels corrigée)
- Ajout de "reset_password" à l'enum du schéma Drizzle (table emailTemplates)
- Migration SQL pour modifier l'enum dans la base de données
- Création du template dans la base de données avec un contenu par défaut approprié
- Mise à jour de la procédure tRPC emailTemplates.upsert pour utiliser les noms de colonnes français (titre, couleurPrincipale, couleurSecondaire, piedDePage)
- Mise à jour de la fonction upsertEmailTemplate dans server/db.ts pour utiliser les noms de colonnes français
- Réécriture complète de AdminEmailTemplates.tsx pour utiliser les noms de colonnes français
- Test complet de l'interface : le template s'affiche correctement, peut être modifié et prévisualisé
- Le template contient les variables {{prenom}}, {{nom}}, {{lienReinitialisation}} pour la réinitialisation de mot de passe
- Total de 9 templates d'emails maintenant disponibles (inscription, teaser, rappel, rappelJ1, rappel3-6, reset_password)
- Renommage questionnaire.nom → questionnaire.titre dans QuestionnaireReponse.tsx, AdminQuestionnaireEdit.tsx, questionnaireScheduler.ts, questionnaireExport.ts
- Correction des requêtes SQL dans questionnaireDb.ts (suppression de la condition complete inexistante)
- Ajout des colonnes valeurMin et valeurMax dans la table questions
- Renommage de la colonne nom en titre dans la table questionnaires
- Correction des 170 erreurs TypeScript liées aux types templateType dans les procédures rappels.create et rappels.update (passage de z.string() à z.enum() avec les valeurs correctes)
- Nettoyage complet des fichiers de migration Drizzle (suppression des 32 anciens fichiers et génération d'une nouvelle migration propre 0000_clean_justice.sql)
- Création du guide utilisateur GUIDE_CONFIGURATION_ATTESTATIONS.md expliquant en détail le nouveau workflow de configuration des attestations (modes de génération et d'envoi, workflows recommandés, bonnes pratiques, dépannage)
- Vérification que tous les paramètres liés aux attestations sont bien accessibles dans la page de gestion des attestations (mode de génération et mode d'envoi)
- Retrait du champ envoiAutomatiqueAttestations du schéma Drizzle
- Suppression de la colonne envoiAutomatiqueAttestations de la table parametres dans la base de données
- Mise à jour de la procédure tRPC parametres.update pour retirer ce champ
- Test complet du workflow : le serveur fonctionne correctement et le tableau de bord s'affiche sans erreur
- Changement du champ 'nom' en 'titre' pour les questionnaires (backend et frontend)
- Suppression de la propriété 'complete' inexistante dans reponsesQuestionnaires
- Correction du type 'provider' dans la configuration email
- Gestion des valeurs null pour le champ 'fonction' des apprenants
- Résolution de l'erreur logsRappels.email après redémarrage du serveur
Fonctionnalités :
- Configuration par formation (génération auto/manuel, envoi auto/manuel)
- Affichage de la liste des apprenants inscrits
- Upload de documents PDF par apprenant (mode manuel)
- Boutons de prévisualisation et d'envoi manuel
- Gestion complète des attestations
Corrections :
- Ajout des colonnes modeAttestation et modeEnvoi dans la table formations
- Ajout des colonnes documentUrl, documentS3Key, uploadedBy, uploadedAt, emailEnvoye, dateEnvoiEmail dans la table attestations
- Correction de l'erreur SQL en retirant la colonne urlPdf inexistante de la requête
Nouvelle fonctionnalité complète pour gérer les attestations :
- Schéma de base de données : colonnes modeAttestation et modeEnvoi dans formations, colonnes documentUrl, documentS3Key, uploadedBy, uploadedAt dans attestations
- Backend : fichier gestionAttestationsDb.ts, procédures tRPC, fonction sendAttestationEmail
- Interface : page AdminGestionAttestations avec sélection de formation, configuration des modes, tableau des apprenants, boutons upload/prévisualisation/envoi/suppression
- Navigation : lien dans menu Gestion, route /admin/gestion-attestations
- Ajout du paramètre d'envoi automatique des attestations dans la page Paramètres
- Ajout de la prévisualisation du modèle d'attestation avec génération PDF
- Création de la page Historique des attestations dans la section Traçabilité
- Création de la table historiqueAttestations pour tracer les envois
- Ajout des procédures tRPC pour l'historique et la prévisualisation
- Modification du schéma rappels : remplacement de nbJours par joursAvant pour correspondre à la structure réelle de la base de données
- Correction des noms de colonnes pour utiliser exactement la même casse que la base de données (templateType, heureEnvoi, nomFichier, urlFichier, s3Key, typeFichier, tailleFichier, derniereExecution)
- La page Rappels fonctionne maintenant correctement et affiche tous les rappels configurés sans erreurs SQL
- Modification du schéma apprenants : codeEtablissement et fonction en VARCHAR nullable (au lieu de NOT NULL et ENUM)
- Suppression de la colonne isActive qui n'existe pas dans la base de données
- Modification du schéma sequences : ajout des statuts "bloquee" et "terminee" dans l'ENUM
- Suppression de la colonne dateBloquage qui n'existe pas dans la base de données
- Le dashboard admin fonctionne maintenant correctement sans erreurs de requêtes SQL
- Ajout du composant DashboardLayout à la page FormateurDashboard
- Le menu de navigation latéral s'affiche maintenant correctement pour les utilisateurs avec le rôle formateur
- Navigation cohérente entre toutes les pages de l'espace formateur (Dashboard et Émargement)
- Ajout de 3 nouveaux paramètres globaux : délai d'expiration QR codes (minutes), durée de validité tokens (heures), notifications actives (boolean)
- Création de la table historiqueParametres pour tracer toutes les modifications avec userId, userName, champModifié, ancienneValeur, nouvelleValeur et dateModification
- Ajout d'un bouton "Tester l'URL" avec indicateur visuel de statut (vert si accessible, rouge si erreur)
- Affichage de l'historique des modifications dans un tableau avec toutes les informations de traçabilité
- Mise à jour automatique de l'historique lors de chaque modification de paramètre
Modifications :
- Ajout de DashboardLayout dans client/src/pages/AdminParametres.tsx
- Ajout de DashboardLayout dans client/src/pages/FormateurEmargement.tsx
Le menu de navigation s'affiche maintenant correctement dans toutes les pages de l'application.
Modifications apportées :
- Création de la table parametres dans la base de données
- Création du fichier server/parametresDb.ts avec les fonctions getParametres et updateUrlPublique
- Ajout du router parametres dans server/routers.ts avec les procédures get et updateUrlPublique
- Création de la page client/src/pages/AdminParametres.tsx avec formulaire de modification
- Ajout de la route /admin/parametres dans App.tsx
- Ajout du lien "Paramètres" dans le menu après "Configuration SMTP" dans DashboardLayout
- Modification de server/qrCodeGenerator.ts pour utiliser l'URL de la BDD au lieu de getAppBaseUrl
- URL par défaut définie : https://formations.itinova.org
Fonctionnalités :
- Interface graphique pour modifier l'URL publique de l'application
- Les QR codes d'émargement utilisent maintenant l'URL configurée dans la base de données
- Validation de l'URL avant enregistrement
- Message d'information sur l'impact des modifications
Modifications apportées :
- Création de server/_core/appUrl.ts : fonction getAppBaseUrl() pour gérer l'URL de base
- Modification de server/qrCodeGenerator.ts : utilise getAppBaseUrl() au lieu de localhost
- Support de plusieurs variables d'environnement (APP_PUBLIC_URL, DOMAIN_NAME, SERVER_URL)
- Création du guide CONFIGURATION_URL_PUBLIQUE.md avec instructions détaillées
- Création du script configure-public-url.sh pour faciliter la configuration
Configuration requise sur le serveur VPS :
Ajouter dans le fichier .env : APP_PUBLIC_URL=https://formations.itinova.org
Puis redémarrer l'application avec PM2 ou systemd.
Les QR codes générés utiliseront maintenant l'URL publique configurée au lieu de localhost.
Corrections apportées :
- Correction des références à heureDebut/heureFin dans AdminRappels.tsx (utilisation de dateDebut/dateFin)
- Correction de l'accès à la propriété dates dans EmargementScan.tsx (cast de type)
- Ajout de l'import manquant de QrCode dans DashboardLayout.tsx
- Correction des erreurs TypeScript dans DashboardLayout.tsx (gestion de subItems)
- Ajout de downlevelIteration dans tsconfig.json
- Correction de l'utilisation de Set dans DateFormationMultiSelect.tsx (Array.from)
- Correction de l'appel à createAttestation (utilisation de enregistrerAttestation)
L'application fonctionne maintenant correctement sans erreurs TypeScript.
## Base de données
- ✅ Table `presences` créée (inscriptionId, dateFormationId, heurePresence, modeValidation, validateurId)
- ✅ Colonne `qrCodeToken` ajoutée à la table `sequences`
## Backend
- ✅ Génération de QR code unique par séquence (qrCodeGenerator.ts)
- ✅ Procédures tRPC pour l'émargement (presences.generateQRCode, presences.valider, presences.listBySequence)
- ✅ Fonctions de base de données (presenceDb.ts) pour gérer les présences
- ✅ Génération automatique d'attestation après validation de toutes les présences
- ✅ Intégration avec le service d'attestations existant
## Interface formateur (/formateur/emargement)
- ✅ Sélection de la séquence
- ✅ Génération et affichage du QR code en modal
- ✅ Liste des inscrits avec statut de présence par date
- ✅ Validation manuelle de présence possible
- ✅ Actualisation en temps réel des présences
- ✅ Entrée de menu "Émargement" dans DashboardLayout
## Interface publique (/emargement/:token)
- ✅ Page de scan QR code accessible sans authentification
- ✅ Recherche de l'apprenant par email
- ✅ Sélection de la formation et de la date
- ✅ Validation automatique de la présence via QR code
- ✅ Écrans de confirmation (succès/erreur)
- ✅ Gestion des erreurs (QR invalide, déjà émargé, etc.)
## Génération automatique d'attestations
- ✅ Vérification automatique après chaque validation de présence
- ✅ Génération du PDF d'attestation si toutes les présences sont validées
- ✅ Enregistrement en base de données
- ✅ Upload automatique sur S3
## Dépendances installées
- qrcode (génération de QR codes)
- @types/qrcode (types TypeScript)
Le système est entièrement fonctionnel et prêt à être utilisé par les formateurs et apprenants.
- Ajout du champ formateur (number | null) dans le type FormData de AdminSequences.tsx
- Ajout du type "tous" dans publicCible pour supporter toutes les valeurs possibles
- Correction de FormateurCombobox pour accepter number | null au lieu de string
- Correction des erreurs null dans QuestionnaireReponse.tsx avec optional chaining
- Correction du type previewType dans AdminSequenceInscrits.tsx pour inclure "rappel_j1"
- Build de production testé et fonctionnel (✓ built in 14.69s)
Les quelques avertissements TypeScript restants (11) ne bloquent pas le build de production. L'application peut maintenant être publiée.