Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
| eadl:bloc3:dev_av:td4 [2025/11/09 18:09] – [Contexte : User Story] jcheron | eadl:bloc3:dev_av:td4 [2025/11/10 16:28] (Version actuelle) – [Concepts clés à retenir] jcheron | ||
|---|---|---|---|
| Ligne 166: | Ligne 166: | ||
| ==== 1.1 Structure modulaire proposée ==== | ==== 1.1 Structure modulaire proposée ==== | ||
| - | <sxh bash> | + | <sxh bash; |
| src/ | src/ | ||
| ├── order/ | ├── order/ | ||
| Ligne 202: | Ligne 202: | ||
| │ | │ | ||
| │ | │ | ||
| - | ├── product/ | + | ├── product/ |
| │ | │ | ||
| │ | │ | ||
| │ | │ | ||
| │ | │ | ||
| - | └── user/ # Domaine User (existant) | + | └── user/ # Domaine User |
| ├── domain/ | ├── domain/ | ||
| ├── service/ | ├── service/ | ||
| Ligne 383: | Ligne 383: | ||
| ===== Partie 3 : Pattern Strategy pour les canaux de notification (1h) ===== | ===== Partie 3 : Pattern Strategy pour les canaux de notification (1h) ===== | ||
| + | < | ||
| + | <uml> | ||
| + | @startuml | ||
| + | |||
| + | interface NotificationSender << | ||
| + | + send(recipient, | ||
| + | + getSupportedChannel(): | ||
| + | + isAvailable(): | ||
| + | } | ||
| + | class EmailNotificationSender << | ||
| + | - mailSender: JavaMailSender | ||
| + | + send() | ||
| + | + getSupportedChannel(): | ||
| + | } | ||
| + | class ConsoleNotificationSender << | ||
| + | + send() | ||
| + | + getSupportedChannel(): | ||
| + | } | ||
| + | class SmsNotificationSender << | ||
| + | + send() | ||
| + | + getSupportedChannel(): | ||
| + | } | ||
| + | class NotificationService << | ||
| + | - senders: List< | ||
| + | + sendNotification(channel, | ||
| + | } | ||
| + | NotificationSender <|.. EmailNotificationSender | ||
| + | NotificationSender <|.. ConsoleNotificationSender | ||
| + | NotificationSender <|.. SmsNotificationSender | ||
| + | NotificationService o--> " | ||
| + | note right of NotificationService | ||
| + | Le Context choisit dynamiquement | ||
| + | la bonne stratégie selon le canal | ||
| + | Strategy Pattern + Factory Pattern | ||
| + | (injection automatique Spring) | ||
| + | end note | ||
| + | note bottom of NotificationSender | ||
| + | Interface commune pour | ||
| + | tous les algorithmes d' | ||
| + | end note | ||
| + | @enduml | ||
| + | </ | ||
| + | < | ||
| ==== 3.1 Interface NotificationSender ==== | ==== 3.1 Interface NotificationSender ==== | ||
| Ligne 519: | Ligne 562: | ||
| </ | </ | ||
| - | ==== 3.4 NotificationService avec Pattern Factory | + | ==== 3.4 NotificationService avec Injection des senders |
| <sxh kotlin> | <sxh kotlin> | ||
| Ligne 1262: | Ligne 1305: | ||
| </ | </ | ||
| < | < | ||
| + | |||
| + | ===== Partie 7 : Visualiser les emails avec MailPit (Bonus : 10min) ===== | ||
| + | |||
| + | <WRAP round bloc info> | ||
| + | **Mailpit** = Serveur SMTP de test avec interface web moderne | ||
| + | * Capture tous les emails envoyés par l' | ||
| + | * Interface web pour visualiser les emails | ||
| + | * Aucune configuration SMTP complexe | ||
| + | * Parfait pour le développement | ||
| + | </ | ||
| + | |||
| + | ==== 7.1 Ajouter Mailpit au docker-compose.yml ==== | ||
| + | |||
| + | Ajouter ce service dans votre fichier **'' | ||
| + | |||
| + | <sxh yaml> | ||
| + | mailpit: | ||
| + | image: axllent/ | ||
| + | container_name: | ||
| + | ports: | ||
| + | - " | ||
| + | - " | ||
| + | networks: | ||
| + | - ecommerce-network | ||
| + | </ | ||
| + | |||
| + | <sxh bash> | ||
| + | # Démarrer Mailpit | ||
| + | docker-compose up -d mailpit | ||
| + | |||
| + | # Vérifier que Mailpit est démarré | ||
| + | docker ps | grep mailpit | ||
| + | </ | ||
| + | |||
| + | ==== 7.2 Configuration Spring ==== | ||
| + | |||
| + | Modifier le fichier **'' | ||
| + | |||
| + | <sxh properties> | ||
| + | # Mailpit configuration | ||
| + | spring.mail.host=localhost | ||
| + | spring.mail.port=1025 | ||
| + | spring.mail.username= | ||
| + | spring.mail.password= | ||
| + | spring.mail.properties.mail.smtp.auth=false | ||
| + | spring.mail.properties.mail.smtp.starttls.enable=false | ||
| + | |||
| + | # Notification settings | ||
| + | notification.email.enabled=true | ||
| + | notification.email.from=noreply@ecommerce-demo.com | ||
| + | |||
| + | # Logs pour voir les envois | ||
| + | logging.level.org.springframework.mail=DEBUG | ||
| + | </ | ||
| + | |||
| + | Modifier également **'' | ||
| + | |||
| + | <sxh properties> | ||
| + | # Mailpit pour les tests | ||
| + | spring.mail.host=localhost | ||
| + | spring.mail.port=1025 | ||
| + | |||
| + | notification.email.enabled=true | ||
| + | notification.email.from=test@ecommerce-demo.com | ||
| + | </ | ||
| + | |||
| + | ==== 7.3 Améliorer les logs dans EmailNotificationSender ==== | ||
| + | |||
| + | Modifier la méthode **'' | ||
| + | |||
| + | <sxh kotlin> | ||
| + | override fun send(recipient: | ||
| + | try { | ||
| + | val message = mailSender.createMimeMessage() | ||
| + | val helper = MimeMessageHelper(message, | ||
| + | | ||
| + | helper.setFrom(fromEmail) | ||
| + | helper.setTo(recipient) | ||
| + | helper.setSubject(subject) | ||
| + | helper.setText(content, | ||
| + | | ||
| + | mailSender.send(message) | ||
| + | | ||
| + | logger.info(" | ||
| + | logger.info(" | ||
| + | | ||
| + | } catch (e: Exception) { | ||
| + | logger.error(" | ||
| + | throw RuntimeException(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== 7.4 Test manuel ==== | ||
| + | |||
| + | <sxh bash> | ||
| + | # 1. Démarrer Mailpit (si pas déjà fait) | ||
| + | docker-compose up -d mailpit | ||
| + | |||
| + | # 2. Lancer l' | ||
| + | mvn spring-boot: | ||
| + | |||
| + | # 3. Créer une commande pour déclencher l' | ||
| + | curl -X POST http:// | ||
| + | -H " | ||
| + | -d '{ | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | ] | ||
| + | }' | ||
| + | |||
| + | # 7.4 Ouvrir l' | ||
| + | open http:// | ||
| + | # Ou dans votre navigateur : http:// | ||
| + | </ | ||
| + | |||
| + | <WRAP round bloc todo> | ||
| + | **Vérifications à effectuer :** | ||
| + | 1. Ouvrir http:// | ||
| + | 2. Vérifier qu'un email apparaît dans la liste | ||
| + | 3. Cliquer sur l' | ||
| + | 4. Vérifier que le contenu HTML est correct | ||
| + | 5. Vérifier le sujet : "Order Confirmation #XXX" | ||
| + | 6. Vérifier les détails de la commande dans l' | ||
| + | </ | ||
| + | |||
| + | ==== 7.5 Interface Mailpit ==== | ||
| + | |||
| + | L' | ||
| + | * Voir tous les emails envoyés | ||
| + | * Rechercher dans les emails | ||
| + | * Prévisualiser le HTML et le texte brut | ||
| + | * Voir les pièces jointes | ||
| + | * Supprimer les emails | ||
| + | * Tester le responsive design des emails | ||
| + | |||
| + | ==== 7.6 Configuration pour la production ==== | ||
| + | |||
| + | <WRAP round bloc important> | ||
| + | ** Mailpit est uniquement pour le développement !** | ||
| + | |||
| + | En **développement** (Mailpit) : | ||
| + | <sxh properties> | ||
| + | spring.mail.host=localhost | ||
| + | spring.mail.port=1025 | ||
| + | notification.email.enabled=true | ||
| + | </ | ||
| + | |||
| + | En **production** (SMTP réel - exemple avec Gmail) : | ||
| + | <sxh properties> | ||
| + | spring.mail.host=smtp.gmail.com | ||
| + | spring.mail.port=587 | ||
| + | spring.mail.username=${SMTP_USERNAME} | ||
| + | spring.mail.password=${SMTP_PASSWORD} | ||
| + | spring.mail.properties.mail.smtp.auth=true | ||
| + | spring.mail.properties.mail.smtp.starttls.enable=true | ||
| + | |||
| + | notification.email.enabled=true | ||
| + | notification.email.from=${EMAIL_FROM} | ||
| + | </ | ||
| + | |||
| + | ** Bonnes pratiques :** | ||
| + | * Ne **jamais** commiter les credentials SMTP dans le code | ||
| + | * Utiliser des **variables d' | ||
| + | * Activer **TLS/SSL** en production | ||
| + | * Utiliser des **app passwords** (Gmail, Outlook, etc.) | ||
| + | </ | ||
| + | |||
| + | ==== 7.7 Commandes utiles ==== | ||
| + | |||
| + | <sxh bash> | ||
| + | # Démarrer uniquement Mailpit | ||
| + | docker-compose up -d mailpit | ||
| + | |||
| + | # Voir les logs de Mailpit | ||
| + | docker logs -f ecommerce-mailpit | ||
| + | |||
| + | # Redémarrer Mailpit | ||
| + | docker-compose restart mailpit | ||
| + | |||
| + | # Arrêter Mailpit | ||
| + | docker-compose stop mailpit | ||
| + | |||
| + | # Supprimer le conteneur Mailpit | ||
| + | docker-compose down mailpit | ||
| + | </ | ||
| + | |||
| + | ==== 7.8 Dépannage ==== | ||
| + | |||
| + | **Problème : Les emails n' | ||
| + | |||
| + | <sxh bash> | ||
| + | # 1. Vérifier que Mailpit est démarré | ||
| + | docker ps | grep mailpit | ||
| + | |||
| + | # 2. Vérifier les logs de l' | ||
| + | # Rechercher : "Email sent to:" ou " | ||
| + | |||
| + | # 3. Vérifier que le profil dev est actif | ||
| + | # Dans les logs au démarrage : "The following profiles are active: dev" | ||
| + | |||
| + | # 4. Tester la connexion SMTP | ||
| + | telnet localhost 1025 | ||
| + | </ | ||
| + | |||
| + | **Problème : " | ||
| + | |||
| + | < | ||
| + | # Vérifier que le port 1025 n'est pas déjà utilisé | ||
| + | lsof -i :1025 | ||
| + | |||
| + | # Si occupé, changer le port dans docker-compose.yml et application-dev.properties | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| ===== Livrables attendus ===== | ===== Livrables attendus ===== | ||
| Ligne 1297: | Ligne 1564: | ||
| * Ajout du canal SMS | * Ajout du canal SMS | ||
| - | * Template d' | + | * Template d' |
| * Retry automatique en cas d' | * Retry automatique en cas d' | ||
| * Dashboard des notifications dans H2 console | * Dashboard des notifications dans H2 console | ||
| Ligne 1310: | Ligne 1577: | ||
| * **Observer** : Spring Events pour la communication inter-domaines | * **Observer** : Spring Events pour la communication inter-domaines | ||
| * **Strategy** : '' | * **Strategy** : '' | ||
| - | * **Factory** : Injection automatique de tous les senders | + | * **Factory** : Injection automatique de tous les senders |
| * **Dependency Inversion** : '' | * **Dependency Inversion** : '' | ||