Feature #1142
openFeature #1133: Implémenter une page de profil utilisateur avec gestion des crédits et des tiers d'abonnement
Backend — Notifications email (mot de passe, tier, crédits bas <20 %)
0%
issue:1133 — spec in epic + ticket description
Description
## Objectif
Envoyer des emails automatiques en réaction aux événements de domaine émis par le modèle crédits/tiers (#1141). Couvre : changement de mot de passe, changement de tier, et crédits bas (<20 % du quota du tier).
## Dépendances
Dépend du backend modèle crédits/tiers/historique (#1141) qui émet les événements de domaine.
## Portée
- Souscripteurs/handlers consommant les événements de domaine (tier changé, crédits ajustés/bas, mot de passe changé) côté `api/` (application/infrastructure).
- Gabarits d'email (FR) pour : confirmation de changement de mot de passe, notification de changement de tier (ancien→nouveau), alerte crédits bas (<20 %).
- Service d'envoi via la configuration SMTP existante; envoi non bloquant (n'échoue pas la requête métier si l'email échoue — log + retry/best-effort).
- Anti-spam pour l'alerte crédits bas : ne pas renvoyer tant que le seuil n'est pas re-franchi (un seul email par passage sous 20 %).
## Acceptance criteria
- [ ] Un email de confirmation est envoyé lors d'un changement de mot de passe.
- [ ] Un email est envoyé au client lors d'un changement de tier (mentionnant ancien et nouveau tier).
- [ ] Une alerte email est envoyée quand les crédits passent sous 20 % du quota, une seule fois par franchissement.
- [ ] Les emails sont en français et utilisent la configuration SMTP du projet.
- [ ] L'échec d'envoi d'email ne fait pas échouer l'opération métier (loggé, best-effort).
- [ ] Tests pytest verts (handlers déclenchés sur événements, mock SMTP), `ruff check .` et `mypy src` propres.
RA Updated by Redmine Admin about 2 months ago
- Status changed from Submitted to Spec
- spec_ref updated (diff)
RA Updated by Redmine Admin about 2 months ago
- Status changed from Spec to In development
RA Updated by Redmine Admin about 2 months ago
- Status changed from In development to QA
- branch set to feat/1142-email-notifications
- pr_url set to https://github.com/omdev-tech/PipeLiner-Client/pull/68
PR ouverte vers `dev` : https://github.com/omdev-tech/PipeLiner-Client/pull/68
Implémentation backend des notifications email (architecture hexagonale, TDD) :
- Souscription aux événements de domaine #1141 (post-commit) : `TierChanged`, `CreditsAdjusted`, `LowCredits` via un `NotificationDispatcher` branché sur le seam `DomainEventPublisher`.
- Gabarits FR : changement de tier (ancien→nouveau), ajustement de crédits, alerte crédits bas (<20 %), + un gabarit de confirmation de mot de passe en stub (l'événement déclencheur appartient à #1144 — il n'y aura qu'à brancher le handler).
- Envoi d'email : port `EmailSender` avec implémentation no-op/logging par défaut (`LoggingEmailSender`) — n'envoie jamais, journalise destinataire + sujet + corps. Le client Resend se branchera ici (`TODO(#resend)` dans `infrastructure/notifications/email_sender.py`, via la dépendance `get_email_sender`), sans autre changement de couche.
- Best-effort / non bloquant : tout échec (contact manquant, rendu, annuaire, envoi) est journalisé et avalé ; `publish` ne lève jamais → ne fait jamais échouer/500 la mutation métier déjà committée.
- Anti-spam crédits bas : repose sur la sémantique « un événement par franchissement descendant » ; un test d'intégration vérifie un seul email par franchissement (et aucun tant qu'on reste <20 %).
Aucun changement de schéma, aucun changement du contrat / des payloads de #1141.
Gates verts (api/.venv) : `pytest -q` 566 passed / 2 skipped (lancé 2× sur la même base, idempotent), `ruff check .` propre, `mypy src` propre.
Passage du ticket en QA.