214 lines
9.9 KiB
Markdown
214 lines
9.9 KiB
Markdown
# Système de notifications pour les tickets support
|
||
|
||
## ✨ Résumé des fonctionnalités
|
||
|
||
### Modal de confirmation avant envoi
|
||
- **Apparence moderne** : Modal inspiré du système de signatures électroniques groupées
|
||
- **Informations affichées** :
|
||
- Adresse email personnelle du destinataire
|
||
- Nom complet de l'utilisateur
|
||
- Prévisualisation complète du message
|
||
- Note explicative sur l'envoi à l'adresse personnelle
|
||
- **Actions** : Boutons d'annulation et de confirmation avec états de chargement
|
||
- **Comportement intelligent** : Notes internes envoyées directement sans modal
|
||
|
||
### Envoi à l'adresse personnelle
|
||
⚠️ **Particularité importante** : L'email de notification est envoyé à l'adresse email personnelle de l'utilisateur qui a créé le ticket (récupérée via `auth.users`), et **non** à l'adresse générale de l'organisation. Cela garantit que la bonne personne reçoit la notification.
|
||
|
||
## 📧 Notifications par email
|
||
|
||
### Fonctionnalité
|
||
Lorsqu'un membre du staff répond à un ticket support, le client reçoit automatiquement un email de notification avec :
|
||
- Le nom du membre du staff qui a répondu
|
||
- Le message de réponse
|
||
- Un lien direct vers le ticket pour continuer la conversation
|
||
|
||
### Aperçu de l'email
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────┐
|
||
│ ODENTAS PAIE │
|
||
├──────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Réponse à votre ticket │
|
||
│ ════════════════════ │
|
||
│ │
|
||
│ Bonjour [Prénom], │
|
||
│ │
|
||
│ Vous avez reçu une réponse à votre ticket support. │
|
||
│ │
|
||
│ ┌─────────────────────────────────────────────┐ │
|
||
│ │ ℹ️ Informations │ │
|
||
│ │ │ │
|
||
│ │ Répondu par: [Nom du staff] │ │
|
||
│ │ Sujet du ticket: [Sujet] │ │
|
||
│ └─────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─────────────────────────────────────────────┐ │
|
||
│ │ 💬 Message │ │
|
||
│ │ │ │
|
||
│ │ Réponse: [Message du staff] │ │
|
||
│ └─────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌──────────────────────┐ │
|
||
│ │ Voir le ticket │ │
|
||
│ └──────────────────────┘ │
|
||
│ │
|
||
│ Vous recevez cet e-mail suite à une réponse de │
|
||
│ notre équipe support. │
|
||
└──────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Template email utilisé
|
||
Type: `support-reply` (système universel V2)
|
||
|
||
**Caractéristiques :**
|
||
- Design moderne avec card pour le message
|
||
- Affichage du nom du staff et du sujet du ticket
|
||
- Bouton CTA "Voir le ticket" qui redirige vers `/support/{ticketId}`
|
||
- Couleurs standardisées de la marque Odentas
|
||
|
||
### Données du template
|
||
|
||
```typescript
|
||
{
|
||
firstName?: string; // Prénom du client
|
||
ticketId: string; // ID du ticket
|
||
ticketSubject: string; // Sujet du ticket
|
||
staffName: string; // Nom du staff qui répond
|
||
staffMessage: string; // Message de réponse
|
||
ctaUrl: string; // URL vers le ticket
|
||
}
|
||
```
|
||
|
||
## 🔔 Quand les notifications sont envoyées
|
||
|
||
### ✅ Notifications envoyées dans ces cas :
|
||
- Un membre du staff répond à un ticket
|
||
- Le message n'est **PAS** marqué comme "interne"
|
||
|
||
### ❌ Notifications NON envoyées dans ces cas :
|
||
- Le message est marqué comme "Note interne" (checkbox cochée)
|
||
- Un client répond à son propre ticket
|
||
- Erreur lors de la récupération des informations
|
||
|
||
## 🎯 Affichage enrichi de la page staff
|
||
|
||
### Page `/staff/tickets/[id]`
|
||
|
||
La page affiche maintenant en haut du ticket :
|
||
- **Organisation** : Le nom de l'organisation concernée
|
||
- **Ouvert par** : Le nom complet de l'utilisateur qui a ouvert le ticket
|
||
|
||
**Logique de résolution du nom :**
|
||
1. Recherche dans `organization_members` pour récupérer `first_name` et `last_name`
|
||
2. Si trouvé : affiche "Prénom Nom" ou juste "Prénom"
|
||
3. Sinon : affiche l'email de l'utilisateur
|
||
4. En dernier recours : "Utilisateur inconnu"
|
||
|
||
## 📝 Implémentation technique
|
||
|
||
### Fichiers modifiés
|
||
|
||
#### 1. `/lib/emailTemplateService.ts`
|
||
- Ajout du type `'support-reply'` dans `EmailTypeV2`
|
||
- Ajout des champs dans `EmailDataV2` :
|
||
- `ticketId`
|
||
- `ticketSubject`
|
||
- `staffName`
|
||
- `staffMessage`
|
||
- Création du template email avec design de card moderne
|
||
|
||
#### 2. `/app/api/tickets/[id]/messages/route.ts`
|
||
- Import de `sendUniversalEmailV2`
|
||
- Logique d'envoi d'email après insertion du message
|
||
- Récupération des informations du ticket et de l'utilisateur créateur
|
||
- Gestion d'erreur non-bloquante (l'email échoue sans faire échouer la création du message)
|
||
|
||
#### 3. `/app/(app)/staff/tickets/[id]/page.tsx`
|
||
- Récupération du nom de l'organisation depuis `organizations`
|
||
- Récupération du nom de l'utilisateur depuis `auth.users` et `organization_members`
|
||
- Affichage d'une card d'information avec l'organisation et le créateur
|
||
|
||
#### 4. `/components/staff/StaffTicketActions.tsx`
|
||
- Import et utilisation de `TicketReplyConfirmationModal`
|
||
- Récupération des informations du destinataire via `/api/tickets/[id]/recipient-info`
|
||
- Gestion de l'état du modal (affichage/masquage)
|
||
- Envoi différencié : notes internes sans confirmation, réponses publiques avec modal
|
||
- Affichage du modal avant envoi avec email, nom et message
|
||
|
||
#### 5. `/components/staff/TicketReplyConfirmationModal.tsx`
|
||
- Composant modal de confirmation d'envoi
|
||
- Affichage de l'email et du nom du destinataire
|
||
- Prévisualisation du message
|
||
- Note explicative sur l'envoi à l'adresse personnelle
|
||
- Boutons d'annulation et de confirmation
|
||
|
||
#### 6. `/app/api/tickets/[id]/recipient-info/route.ts`
|
||
- Route API pour récupérer les informations du destinataire
|
||
- Retourne l'email et le nom de l'utilisateur qui a créé le ticket
|
||
- Accessible uniquement au staff
|
||
- Gestion sécurisée via `auth.admin.getUserById()`
|
||
|
||
## 🚀 Utilisation
|
||
|
||
### Pour le staff
|
||
1. Aller sur un ticket : `/staff/tickets/{id}`
|
||
2. Voir l'organisation et le créateur du ticket en haut
|
||
3. Écrire une réponse dans le formulaire en bas
|
||
4. **Si vous cochez "Note interne"** : Le message sera envoyé directement sans notification email
|
||
5. **Si vous NE cochez PAS "Note interne"** : Un modal de confirmation s'affiche avec :
|
||
- L'adresse email personnelle du destinataire
|
||
- Le nom de l'utilisateur
|
||
- Votre message de réponse
|
||
- Un bouton pour confirmer ou annuler l'envoi
|
||
6. Confirmer l'envoi → Le client reçoit automatiquement un email à son adresse personnelle
|
||
|
||
### Spécificité importante
|
||
⚠️ **L'email est envoyé à l'adresse personnelle de l'utilisateur qui a créé le ticket**, et non à l'adresse générale de l'organisation. Cela garantit que la bonne personne reçoit la notification.
|
||
|
||
### Pour le client
|
||
1. Recevoir l'email de notification
|
||
2. Cliquer sur "Voir le ticket"
|
||
3. Être redirigé vers `/support/{id}`
|
||
4. Voir la réponse et pouvoir continuer la conversation
|
||
|
||
## 🔍 Variables d'environnement requises
|
||
|
||
```env
|
||
NEXT_PUBLIC_BASE_URL=https://paie.odentas.fr
|
||
AWS_SES_FROM=paie@odentas.fr
|
||
AWS_REGION=eu-west-3
|
||
```
|
||
|
||
## 🐛 Débogage
|
||
|
||
### Logs à surveiller
|
||
```
|
||
✅ Notification email envoyée à {email} pour le ticket {id}
|
||
```
|
||
|
||
### Erreurs possibles
|
||
- "Erreur lors de l'envoi de la notification email" : L'email n'a pas pu être envoyé mais le message est quand même créé
|
||
- Vérifier la console pour les détails de l'erreur SES
|
||
|
||
## 💡 Améliorations futures possibles
|
||
|
||
1. **Notifications en temps réel** : Utiliser des WebSockets ou Server-Sent Events
|
||
2. **Préférences de notification** : Permettre aux utilisateurs de désactiver les emails
|
||
3. **Notifications push** : Ajouter des notifications push navigateur
|
||
4. **Résumé quotidien** : Envoyer un email quotidien avec tous les tickets mis à jour
|
||
5. **Cache des noms** : Mettre en cache les noms d'utilisateurs pour améliorer les performances
|
||
|
||
## 📊 Performance
|
||
|
||
- L'envoi d'email est **non-bloquant** : si l'email échoue, le message est quand même créé
|
||
- La résolution du nom utilise `maybeSingle()` pour éviter les erreurs si aucun résultat
|
||
- Les requêtes auth.admin sont nécessaires pour accéder aux emails (RLS)
|
||
|
||
## 🔒 Sécurité
|
||
|
||
- Vérification que l'utilisateur est bien staff avant d'envoyer
|
||
- Messages internes jamais envoyés par email (confidentialité)
|
||
- Utilisation de `auth.admin` uniquement côté serveur
|
||
- RLS respectée pour toutes les requêtes
|