Notifications¶
Ce que fait le module notification¶
Chaque fois qu'un événement mérite d'être signalé à un utilisateur — une demande de congé soumise, une étape de workflow assignée, un paiement confirmé, une licence on-premise émise — Jigi envoie une notification. Ce module centralise l'envoi effectif de ces notifications (email, in-app, temps réel), pour que les autres modules n'aient qu'à déclarer « quoi » notifier sans se soucier du « comment ».
Le principe : tout passe par une file de messages¶
Aucun module métier n'envoie un email de façon synchrone. À la place, il publie un message sur une file RabbitMQ, et un consommateur dédié (EmailNotificationConsumer) traite l'envoi réel de façon asynchrone. Cela évite qu'un problème d'envoi d'email (SMTP lent, indisponible) ne ralentisse ou ne fasse échouer l'action métier de l'utilisateur.
Module métier (ex. congés) → publie un message sur la queue "jigi.email"
↓
EmailNotificationConsumer (RabbitListener)
↓
Résolution du destinataire + choix du template
↓
Envoi SMTP via JavaMailSender
Les trois canaux¶
- Email — via
EmailNotificationConsumer, avec un template Thymeleaf HTML différent selon le type de notification (mail/leave-status-change,mail/workflow-step-assigned,mail/recruitment/interview-invitation,mail/subscription/payment-confirmed, etc.). Certains emails embarquent une pièce jointe (invitation calendrier.icspour un entretien, fichier.licpour une licence on-premise). - In-app — des notifications stockées en base (
InAppNotification) et consultables dans l'interface, gérées parInAppNotificationService/InAppNotificationConsumer. - Temps réel — diffusion via WebSocket (STOMP/SockJS) pour les alertes qui doivent apparaître immédiatement sans rechargement de page.
Trois façons de cibler un destinataire¶
- Un utilisateur précis (
recipientUserId) — le cas le plus courant : la personne assignée à une étape, l'auteur d'une demande. - Un destinataire externe sans compte Jigi (
externalEmail) — utilisé pour les candidats de recrutement (invitation d'entretien, lettre d'offre) qui n'ont pas de compte utilisateur. - Un rôle, au sein d'un tenant (
role+tenantId) — le message est diffusé à tous les utilisateurs détenant ce rôle dans la société concernée (RoleUserResolverrésout la liste des destinataires).
Grandes familles de notifications existantes¶
| Famille | Exemples |
|---|---|
| Congés | Soumission, approbation, rejet d'une demande de congé |
| Workflow générique | Assignation d'une étape, notification pure d'étape |
| Recrutement | Invitation/réponse à un entretien, envoi/acceptation/refus d'une lettre d'offre, vérification d'email candidat |
| Performance | Objectifs, cycles d'évaluation, 1:1, campagnes de feedback 360 |
| Abonnement | Essai gratuit (J-7, J-12, expiration), paiement confirmé/échoué, renouvellement, changement de plan |
| Import en masse | Rapport d'import, notification aux managers/comptables/responsables de ressources concernés |
| Licence on-premise | Émission, suspension, révocation, réactivation d'une licence .lic |
| Inscription | Bienvenue, approbation/rejet d'une demande d'inscription |
Détails techniques
- Package :
app.jigi.notification(controller/,domain/,service/). - Classes clés :
EmailNotificationConsumer(@RabbitListener(queues = RabbitMQConfig.EMAIL_QUEUE)),InAppNotificationConsumer,InAppNotificationService,RoleUserResolver. - Interface de publication utilisée par les autres modules :
app.jigi.common.contract.NotificationDispatcher(méthodessend(userId, type, payload)etsendToRole(role, tenantId, type, payload)). - Enum des types de notification :
app.jigi.common.contract.enums.NotificationType— chaque valeur détermine le template Thymeleaf et le titre d'email utilisés. - Convention d'architecture (voir
backend/CLAUDE.md) : tout email doit passer par la queue RabbitMQjigi.email— un service métier ne doit jamais appelerJavaMailSenderdirectement. - Les templates HTML vivent sous
backend/src/main/resources/templates/mail/. - Le moteur de workflow (voir Moteur de workflow) ne connaît aucun de ces canaux : il se contente de publier des événements que ce module transforme en notifications concrètes.
FAQ¶
Que se passe-t-il si l'envoi d'un email échoue (ex. adresse invalide) ? L'erreur est journalisée côté serveur sans faire échouer l'action métier de l'utilisateur (ex. la demande de congé reste bien soumise même si l'email de confirmation échoue).
Un utilisateur peut-il désactiver certaines notifications email ? Cela dépend du type de notification — les notifications critiques (assignation de tâche d'approbation, sécurité du compte) restent envoyées systématiquement ; se référer à l'écran de profil pour les préférences disponibles.
Pourquoi certains messages RabbitMQ ciblent-ils un rôle plutôt qu'un utilisateur précis ? Cela permet de notifier « tous les comptables du tenant » ou « tous les responsables RH » sans que le module émetteur ait besoin de connaître la liste exacte des utilisateurs concernés — cette résolution est faite au moment de l'envoi, donc toujours à jour.