Ajout du workflow tar.gz (méthode habituelle du client) :
1. DEPLOIEMENT-TARGZ.md :
- Guide complet pour créer l'archive .tar.gz
- Instructions de transfert via SFTP/SCP
- Procédure de mise à jour simplifiée
2. deploy-update-targz.sh :
- Script automatique pour mise à jour via archive
- Sauvegarde automatique de la BDD
- Extraction et copie des fichiers
- Installation dépendances + migrations + build
- Redémarrage automatique du serveur
- Usage: ./deploy-update-targz.sh /tmp/archive.tar.gz
Le client peut maintenant utiliser son workflow habituel :
- Télécharger depuis Manus
- Créer archive .tar.gz
- Transférer sur VPS
- Lancer le script de mise à jour
Toutes les corrections de bugs précédentes sont incluses.
Contenu de cette version :
1. Corrections de bugs (versions précédentes) :
- Bug d'inscription (procédure publique createPublic)
- Bug email de confirmation (variables {{prenomApprenant}} et {{datesHTML}})
- Amélioration interface templates d'emails
2. Scripts de déploiement VPS avec Git :
- deploy-update.sh : Script automatique avec git pull
- update-database.sql : Script SQL de mise à jour
- INSTRUCTIONS-DEPLOIEMENT.md : Documentation complète
- GUIDE-GIT.md : Guide Git pour débutants
3. Déploiement manuel SANS Git (NOUVEAU) :
- DEPLOIEMENT-MANUEL.md : Guide complet déploiement manuel
- deploy-update-manual.sh : Script de mise à jour sans git pull
- Transfert via SFTP (FileZilla/WinSCP)
- Procédure simplifiée étape par étape
Le client peut maintenant choisir :
- Option A : Déploiement avec Git (automatisé)
- Option B : Déploiement manuel via SFTP (plus simple)
Prêt pour le déploiement en production.
Contenu de cette version :
1. Corrections de bugs (version précédente) :
- Bug d'inscription (procédure publique createPublic)
- Bug email de confirmation (variables {{prenomApprenant}} et {{datesHTML}})
- Amélioration interface templates d'emails
2. Scripts de déploiement VPS :
- deploy-update.sh : Script automatique de mise à jour
- update-database.sql : Script SQL de mise à jour
- INSTRUCTIONS-DEPLOIEMENT.md : Documentation de déploiement
3. Guide Git complet (NOUVEAU) :
- GUIDE-GIT.md : Guide pas à pas pour débutants
- Configuration GitHub
- Création du dépôt
- Premier push
- Configuration du serveur VPS
- Workflow de mise à jour
4. Configuration Git :
- .gitignore mis à jour (exclusion backups)
- README.md existant (complet)
Tout est prêt pour le premier déploiement Git + VPS.
Contenu de cette version :
1. Corrections de bugs :
- Bug d'inscription (procédure publique createPublic)
- Bug email de confirmation (variables {{prenomApprenant}} et {{datesHTML}})
- Amélioration interface templates d'emails
2. Scripts de déploiement VPS :
- deploy-update.sh : Script automatique de mise à jour
- update-database.sql : Script SQL de mise à jour de la base
- INSTRUCTIONS-DEPLOIEMENT.md : Documentation complète
Le script deploy-update.sh gère automatiquement :
- Sauvegarde de la base de données
- Arrêt/redémarrage du serveur
- Récupération du code
- Installation des dépendances
- Migrations de base de données
- Compilation du projet
Prêt pour le déploiement en production.
Problème identifié :
- La variable datesHTML était générée dans le code (lignes 60-80) pour créer le HTML formaté des dates
- Mais elle n'était pas ajoutée dans l'objet variables passé au template personnalisé
- Résultat : {{datesHTML}} n'était pas remplacée dans le template
Solution appliquée :
- Ajout de datesHTML dans l'objet variables (ligne 134)
- La variable contient le HTML formaté de toutes les dates de la séquence
- Format : <div class="date-item"><strong>Date X :</strong><br/>Du ... au ...</div>
La variable {{datesHTML}} est maintenant correctement remplacée dans les templates d'emails personnalisés.
Modifications apportées :
- Ajout d'un nouveau bouton "Dates (HTML)" dans l'interface AdminEmailTemplates
- Le bouton permet d'insérer la variable {{datesHTML}} dans le corps du message
- Ajout du remplacement de {{datesHTML}} dans la fonction de prévisualisation avec un exemple formaté
- Mise à jour de la description de la prévisualisation pour mentionner la nouvelle variable
La variable {{datesHTML}} permet d'afficher toutes les dates d'une séquence de formation de manière formatée dans les emails (rappels, teasers, confirmations).
1. Bug d'inscription - Mauvais apprenant associé :
- Problème : La procédure apprenants.create était une procédure admin, empêchant la création d'apprenants depuis la page publique
- Solution : Création d'une nouvelle procédure publique apprenants.createPublic
- Résultat : Les inscriptions sont maintenant correctement associées au bon apprenant
2. Bug email de confirmation - Variable {{prenomApprenant}} non remplacée :
- Problème : Le template d'inscription contenait {{prenomApprenant}} qui n'était pas remplacé
- Solution : Mise à jour du bodyContent du template d'inscription dans la base de données avec les bonnes variables
- Résultat : Les emails de confirmation affichent maintenant correctement le prénom et le nom de l'apprenant
Les deux bugs sont corrigés et prêts pour la publication.
Problème identifié :
- La procédure apprenants.create était une procédure admin (adminProcedure)
- La page d'inscription publique n'est pas authentifiée
- Lors de la création d'un apprenant, la mutation échouait silencieusement
- Le code récupérait ensuite un mauvais apprenant par email
Solution appliquée :
- Création d'une nouvelle procédure publique apprenants.createPublic
- Modification de Inscription.tsx pour utiliser createPublic au lieu de create
- Les nouveaux apprenants peuvent maintenant être créés depuis la page publique
- L'inscription associe maintenant le bon apprenant à la séquence
- Modification de checkExistingInscription pour exclure les inscriptions avec statut "annulee"
- Permet maintenant de réinscrire un apprenant à une séquence après annulation de son inscription précédente
- Les inscriptions annulées ne sont plus considérées comme des inscriptions actives lors de la vérification de doublon
- Modification de getInscriptionsBySequence pour exclure les inscriptions avec statut "annulee"
- Modification de getInscriptionsByApprenant pour exclure les inscriptions avec statut "annulee"
- Ajout de l'import de la fonction ne depuis drizzle-orm
- Vérification que le scheduler de rappels filtre déjà correctement (envoie uniquement aux inscriptions confirmées)
- Ajout d'alias de variables pour supporter les deux formats : {{prenom}} et {{prenomApprenant}}
- Les templates peuvent maintenant utiliser indifféremment les noms courts (prenom, nom, formation, sequence) ou les noms longs (prenomApprenant, nomApprenant, nomFormation, nomSequence)
- Correction appliquée dans sendInscriptionConfirmation
- Correction du bug d'insertion SQL des rappels (champ derniereExecution)
- Création de la table rappels et des fonctions CRUD
- Implémentation du scheduler automatique (vérification toutes les heures)
- Personnalisation des templates J-7 et J-1 avec logo et couleurs Itinova (Bleu #283581, Bleu clair #0578BE, Orange #E94E1B, Vert #45ac34)
- Style sobre et professionnel appliqué
- Variable {{datesHTML}} pour afficher toutes les dates de chaque séquence
1. Personnalisation des templates d'emails avec variables {{lieu}} et {{formateur}} (déjà disponible)
2. Aperçu avant envoi avec données réelles d'un apprenant (modal avec iframe)
3. Email de rappel J-1 avec bouton d'envoi et d'aperçu
Les templates personnalisés supportent maintenant toutes les variables disponibles.
L'aperçu permet de vérifier le rendu final avant l'envoi groupé.
Le rappel J-1 complète le système de communication avec les apprenants.
Modifications apportées :
- Ajout des paramètres `lieu` et `formateur` à la fonction sendTeaserEmail
- Récupération du formateur depuis la base de données dans routers.ts via getFormateurById
- Affichage du lieu et du formateur dans le contenu HTML de l'email teaser
- Ajout de `lieu` et `formateur` dans les variables disponibles pour les templates personnalisés
Variables disponibles dans les templates d'emails :
- {{nomApprenant}} - Nom de l'apprenant
- {{prenomApprenant}} - Prénom de l'apprenant
- {{nomFormation}} - Nom de la formation
- {{nomSequence}} - Nom de la séquence
- {{dateDebut}} - Date de début formatée
- {{dateFin}} - Date de fin formatée
- {{lieu}} - Lieu de la formation
- {{formateur}} - Nom du formateur
L'email de teaser affiche maintenant toutes les informations importantes pour les apprenants.
Problème corrigé :
- Les tags {{nomFormation}}, {{nomSequence}}, etc. n'étaient pas remplacés dans les emails de teaser et rappel
- Les fonctions sendTeaserEmail et sendRappelJ7Email ne passaient pas les variables au générateur de template
Solution appliquée :
- Ajout de l'objet variables dans sendTeaserEmail avec : nomApprenant, prenomApprenant, nomFormation, nomSequence, dateDebut, dateFin
- Ajout de l'objet variables dans sendRappelJ7Email avec les mêmes variables plus le lieu
- Les variables sont maintenant correctement transmises à getEmailTemplate() pour le remplacement
Variables disponibles dans les templates :
- {{nomApprenant}} - Nom de l'apprenant
- {{prenomApprenant}} - Prénom de l'apprenant
- {{nomFormation}} - Nom de la formation
- {{nomSequence}} - Nom de la séquence
- {{dateDebut}} - Date de début formatée
- {{dateFin}} - Date de fin formatée
- {{lieu}} - Lieu de la formation (rappel uniquement)
Fonctionnalités ajoutées :
- Logs serveur détaillés pour l'envoi d'emails groupés (nombre de destinataires, adresses)
- Message de retour avec le nombre d'emails envoyés avec succès et échoués
- Avertissement si aucun email n'est envoyé (aucun apprenant confirmé)
Corrections apportées :
- Les emails de teaser et rappel utilisent maintenant correctement la configuration SMTP
- Affichage d'un message de succès clair après l'envoi d'emails groupés
Note technique :
- Le code utilise bien sendEmail() qui respecte la configuration SMTP
- Les emails ne sont envoyés qu'aux apprenants avec statut "confirmee"
- La configuration SMTP doit être faite séparément en production (base de données différente)
Fonctionnalités ajoutées :
- Support SMTP Direct pour l'envoi d'emails (Gmail, Outlook, serveurs personnalisés)
- Interface de configuration SMTP dans l'administration
- Basculement automatique entre Resend API et SMTP Direct
- Affichage du statut de configuration (Resend/SMTP, Simulation/Production)
Corrections apportées :
- Correction du bug de décalage horaire dans le formulaire d'édition des séquences
- Ajout du menu de navigation sur la page Import Excel
- Déplacement du menu Import Excel vers le bloc Configuration
- Correction de la fonction upsertEmailConfig pour mettre à jour au lieu de créer des doublons
- Correction du bug d'enregistrement des champs SMTP dans la base de données
- Correction du problème de cache React Query qui gardait l'ancienne configuration
- Invalidation automatique du cache après enregistrement de la configuration
Scripts de déploiement :
- Scripts de mise à jour VPS avec sauvegarde automatique
- Package de déploiement prêt pour le serveur de production
- Ajout du support SMTP pour l'envoi d'emails (sans dépendre de Resend)
- Correction de l'affichage du statut pour montrer "SMTP Direct" au lieu de "Resend"
- Ajout d'alertes spécifiques pour la configuration SMTP
- Correction de la fonction upsertEmailConfig pour mettre à jour au lieu de créer une nouvelle configuration
- Correction du bug d'enregistrement des champs SMTP dans la base de données
- Mise à jour forcée du provider à "smtp" dans la base de données
**Problème identifié** :
La mutation tRPC `emailConfig.upsert` n'acceptait pas les champs SMTP (smtpHost, smtpPort, smtpSecure, smtpUser, smtpPassword) dans son schéma de validation Zod, ce qui empêchait l'enregistrement de la configuration SMTP.
**Solution appliquée** :
- Ajout des 5 champs SMTP dans le schéma d'input de la mutation `upsert` dans `server/routers.ts`
- Tous les champs SMTP sont définis comme nullable et optional pour permettre la flexibilité
- Types corrects : smtpPort (number), smtpSecure (enum), autres (string)
**Résultat** :
La configuration SMTP peut maintenant être enregistrée correctement dans la base de données. Les champs sont transmis du frontend au backend et stockés via la fonction `upsertEmailConfig`.
**Modifications de la base de données** :
- Ajout des champs SMTP dans la table `emailConfig` : smtpHost, smtpPort, smtpSecure, smtpUser, smtpPassword
**Backend** :
- Installation de `nodemailer` pour l'envoi SMTP
- Création de `server/_core/smtpSender.ts` avec les fonctions d'envoi SMTP et de test de connexion
- Modification de `server/_core/emailSender.ts` pour supporter les deux méthodes (Resend et SMTP)
- Priorité donnée à SMTP si configuré, sinon fallback sur Resend
**Frontend** :
- Mise à jour de `AdminEmailConfig.tsx` pour permettre le choix entre Resend et SMTP
- Ajout d'un sélecteur de méthode d'envoi (Resend API / SMTP Direct)
- Formulaire de configuration SMTP avec :
* Hôte SMTP (ex: smtp.gmail.com)
* Port (587, 465, 25)
* Sécurité (TLS, SSL, None)
* Identifiants (utilisateur/mot de passe)
* Email expéditeur
**Compatibilité** :
- Support des principaux fournisseurs SMTP (Gmail, Outlook, serveurs SMTP personnalisés)
- Instructions pour les mots de passe d'application Gmail
- Mode simulation toujours disponible pour les tests
**Problème identifié** :
Le script `update-app.sh` utilisait `pnpm install --prod` qui n'installe que les dépendances de production, excluant les devDependencies comme `drizzle-kit` nécessaire pour les migrations.
**Solution appliquée** :
1. **update-app.sh** : Changé `pnpm install --prod` en `pnpm install` pour installer toutes les dépendances (production + développement)
2. **GUIDE_MISE_A_JOUR.md** : Mise à jour de la documentation pour refléter ce changement
**Justification** :
`drizzle-kit` est nécessaire pour exécuter `pnpm db:push` qui applique les migrations de base de données. Sans les devDependencies, la commande échoue.
**Nouveau package créé** :
- formation-manager-update-20251127_114306.tar.gz (2.6M)
- Prêt pour déploiement avec la correction
**Modifications apportées** :
1. **backup-before-update.sh** :
- APP_DIR: /var/www/formation-manager-itinova
- BACKUP_DIR: /var/backups/formation-manager-itinova
2. **update-app.sh** :
- APP_DIR: /var/www/formation-manager-itinova
- SERVICE_NAME: formation-manager-itinova
3. **GUIDE_MISE_A_JOUR.md** :
- Tous les chemins mis à jour vers formation-manager-itinova
- Tous les noms de service corrigés
4. **README.md** :
- Documentation mise à jour avec les bons chemins
- Exemples corrigés
5. **Nouveau package créé** :
- formation-manager-update-20251127_095935.tar.gz (2.6M)
- Prêt pour déploiement sur le serveur VPS
1. **backup-before-update.sh** : Script de sauvegarde automatique
- Sauvegarde complète des fichiers de l'application
- Export de la base de données MySQL
- Sauvegarde du fichier .env
- Conservation des 10 dernières sauvegardes
2. **update-app.sh** : Script de mise à jour automatique
- Création d'une sauvegarde de sécurité
- Arrêt/redémarrage du service
- Copie des nouveaux fichiers
- Installation des dépendances
- Application des migrations de base de données
- Vérification du bon fonctionnement
3. **create-deployment-package.sh** : Script de création de package
- Crée une archive .tar.gz prête à transférer
- Inclut tous les fichiers nécessaires
- Exclut node_modules, .git, .env
4. **Documentation complète** :
- GUIDE_MISE_A_JOUR.md : Guide détaillé avec procédures de mise à jour et rollback
- README.md : Documentation des scripts avec exemples d'utilisation
5. **Package de déploiement créé** :
- formation-manager-update-20251127_074417.tar.gz (2.6M)
- Prêt à être transféré sur le serveur VPS
1. Bug décalage horaire dans le formulaire d'édition des séquences
- Correction de la fonction safeFormatDate pour utiliser les méthodes locales (getHours, getMinutes) au lieu des méthodes UTC
- Les heures saisies (ex: 9h00) s'affichent maintenant correctement dans le formulaire d'édition
2. Ajout du menu de navigation sur la page Import Excel
- Intégration du DashboardLayout wrapper dans AdminImportExcel.tsx
- Le menu latéral s'affiche maintenant correctement sur cette page
3. Déplacement du menu "Import Excel"
- Déplacé du bloc GESTION vers le bloc CONFIGURATION dans le menu de navigation
- Positionné après "Utilisateurs" et avant "Rappels" pour une meilleure organisation
- Ajout de la valeur "tous" dans l'enum publicCible du schéma drizzle/schema.ts
- Mise à jour des validations Zod dans server/routers.ts
- Modification directe de la colonne publicCible en base de données via SQL
- Test réussi : création d'une séquence avec public cible "Tous" fonctionne parfaitement
Corrections apportées:
- Utilisation de clés stables (format yyyy-MM-dd) au lieu de day.toISOString() pour éviter l'erreur React #31
- Gestion correcte des objets Date vs strings pour dateBloquage dans le modal
- Gestion correcte du champ formateur qui peut être un objet ou une string
- Ajout de clés uniques pour les dates de formation dans le modal
Le calendrier fonctionne maintenant sans erreur lors du survol et de l'ouverture des modals de détails.