Notifications
Notifications
Périmètre : notifications in-app, email transactionnel, SMS transactionnel, templates configurables par organisation, préférences utilisateur, queues persistantes avec retry exponentiel, webhooks providers (Brevo, OVH SMS…).
/account/notifications, /account/preferences/notifications
et /workspace/admin/settings/notifications. Les routes API se trouvent sous /api/notifications
et /api/account/preferences/notifications. Source de cette page : docs/15-domain-notifications.md.EMAIL_PROVIDER configuré.
La valeur par défaut est console : les emails sont simplement loggés en stdout, ce
qui est sûr en développement et évite tout envoi accidentel.Vocabulaire & entités
| Terme | Entité / Code | Définition |
|---|---|---|
| Notification | Notification | Message à destination d'un utilisateur (in-app + canal externe optionnel). |
| Canal | NotificationChannel | IN_APP, EMAIL, SMS, PUSH (futur). |
| Type | type: string | Code stable identifiant le déclencheur (ex : lease.contract.signed). |
| Template | EmailTemplate / SmsTemplate | Modèle de contenu paramétrable par organisation, référencé par code. |
| Queue | EmailQueue / SmsQueue | Table persistante gérée par jobs cron — statuts PENDING, SENDING, SENT, FAILED. |
| Préférence | NotificationPreference | Choix utilisateur des canaux actifs pour un type donné. |
| Catalogue | shared/notifications/catalog.ts | Source de vérité de tous les types de notifications, leurs templates et audiences par défaut. |
Le modèle complet est dans
docs/04-data-model.md§12.
Catalogue des types
Chaque type a un code stable et définit : title template, body template, code template email/SMS,
canaux par défaut, niveau d'importance (info / warning / critical) et audience cible
(owner / manager / accountant…).
auth.* # invitation, reset mot de passe, MFA
identity.user.*
crm.opportunity.*
crm.action.*
sales.quote.*
sales.invoice.*
sales.payment.*
purchases.invoice.*
lease.affair.*
lease.contract.*
lease.lender_request.*
lease.cession.*
asset.maintenance.*
asset.location.*
admin.system.*
ai.workflow.*
Écrans & préférences
| Écran | Route | Contenu |
|---|---|---|
| Centre de notifications | /account/notifications | Liste paginée (50 les plus récentes), filtres type / période / lu, marquer tout lu. Tap → marque lu + redirige vers linkUrl. |
| Icône topbar | (topbar bell icon) | Badge compteur non lus, preview liste rapide. |
| Préférences | /account/preferences/notifications | Tableau par domaine : choix canaux in-app / email / SMS par type. Toggle global "Pause X heures". |
| Templates admin | /workspace/admin/settings/notifications | Liste templates système + custom org, édition WYSIWYG markdown/HTML, preview données dummy, reset système. |
Modèle de données (points clés)
Notification: toujours créée en canalIN_APP(canal incompressible) ; les autres canaux dépendent des préférences.EmailQueue: colonnesstatus,attempts,scheduledAt,providerMessageId. Index composite(status, scheduledAt)pour le job de traitement.NotificationPreference: clé(userId, type, channel), valeur booléenne activé/désactivé.- Index
(userId, status, createdAt)surNotificationpour la liste du centre.
API
Toutes les routes /api/notifications n'exigent qu'une session authentifiée (pas de permission
crm.* ou autre — chaque utilisateur ne voit que ses propres notifications). Les routes
/api/workspace/admin/notifications/templates exigent admin.settings:read/update.
| Méthode | Route | Permission |
|---|---|---|
GET | /api/notifications | authentifié |
POST | /api/notifications/[id]/read | authentifié |
POST | /api/notifications/mark-all-read | authentifié |
GET | /api/notifications/unread-count | authentifié |
GET | /api/account/preferences/notifications | authentifié |
PATCH | /api/account/preferences/notifications | authentifié |
GET | /api/workspace/admin/notifications/templates | admin.settings:read |
POST | /api/workspace/admin/notifications/templates | admin.settings:update |
POST | /api/webhooks/brevo | HMAC |
POST | /api/webhooks/sms | HMAC |
/api/account/preferences/notificationsAuth Met à jour les préférences de notification de l'utilisateur courant pour un ou plusieurs types de notification.
Corps (JSON)
type (code catalogue)
et channel (EMAIL, SMS, IN_APP).Requête
curl -s -X PATCH "$API/api/account/preferences/notifications" \
-H "Content-Type: application/json" -H "Cookie: $SESSION" \
-d '{"preferences":[{"type":"lease.contract.signed","channel":"SMS","enabled":false}]}'
Réponse
{ "updated": 1 }
Workflows
Émission d'une notification
Le service notifications.service.ts expose une fonction notify(opts) appelée
par tous les autres services lors de mutations sensibles.
await notify({
organizationId,
userIds: ['usr_...'], // ou résolution par rôle : { role: 'ACCOUNTANT' }
type: 'lease.contract.signed',
payload: { contractNumber: 'LLD-2026-000123', customerName: 'Lidl France' },
linkUrl: `/workspace/lease/contracts/${contractId}`,
})
Flux interne :
- Résolution des utilisateurs cibles (
userIdsexplicites ou lookup par rôle dans l'org). - Pour chaque utilisateur :
- Charge
NotificationPreferencepour ce type. - Crée
NotificationcanalIN_APP(PENDING). - Canal
EMAILactivé → enqueueEmailQueueavec template rendu. - Canal
SMSactivé → enqueueSmsQueue.
- Charge
Job d'envoi email (send-pending-emails)
Cadence : toutes les 1 minute — traite 50 EmailQueue PENDING dont scheduledAt <= now.
Pour chaque entrée :
1. Marque SENDING
2. Appelle provider (Brevo POST /smtp/email)
3. Succès → SENT + stocke providerMessageId
4. Échec + attempts < maxAttempts → reschedule (backoff : 1 min / 5 min / 15 min / 1h / 6h)
5. Échec + attempts >= maxAttempts → FAILED + alerte admin
Même logique pour le job SMS.
Providers email
Brevo (défaut)
BREVO_API_KEY — https://api.brevo.com/v3/smtp/email. Webhooks delivery / open / click
via POST /api/webhooks/brevo (signature HMAC).
Scaleway TEM (alternative)
Email transactionnel via SMTP Scaleway. Détails dans docs/18-integrations.md.
console (dev)
Valeur par défaut de EMAIL_PROVIDER. Logs en stdout uniquement — aucun envoi réel.
Obligatoire en dev pour éviter tout trafic accidentel.
Providers SMS
OVH SMS, Scaleway SMS ou Twilio selon variable d'environnement. Webhooks entrants
sur POST /api/webhooks/sms (HMAC) pour les événements delivered / failed.
Tracking livraison (webhooks entrants)
POST /api/webhooks/brevo: événementsdelivered,opened,clicked,bounce,spam→ mise à jourNotification.status.POST /api/webhooks/sms: événementsdelivered,failed.- Signature HMAC vérifiée ; requête invalide → 401.
Règles métier
- IN_APP toujours envoyée (sauf préférence explicite
OFFpar l'utilisateur). - EMAIL et SMS soumis aux préférences utilisateur par type.
- Hard bounce : désactive le canal
EMAILpour ce user définitivement + notifie l'admin. - Spam complaint : désactive le canal
EMAILdéfinitivement. - Throttling SMS : max 1 SMS / 5 min par destinataire / type (le 2ᵉ envoi rapide est reschedulé).
- RGPD : opt-out clair en footer pour les emails non strictement transactionnels.
- Templates système : non éditables directement — surchargables par organisation, mais le template système lui-même est immuable.
- Audit log sur toute modification de template (
admin.settings:update). - Performance : queue traite jusqu'à 50 emails / minute (configurable) ; batch Brevo jusqu'à 1 000 destinataires pour un même payload lors de pics.
Collaboration
Référence technique du domaine Collaboration — commentaires, threads, mentions, notes internes, réactions, inbox et notifications.
Administration
Référence technique du domaine Administration — console super-admin, paramètres applicatifs, gestion des organisations, webhooks sortants, audit log et supervision.