espace-paie-odentas/SUPPORT_TICKET_NOTIFICATIONS.md

214 lines
9.9 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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