espace-paie-odentas/SIGNATURE_SALARIE_PRENOM_FEATURE.md

397 lines
9.6 KiB
Markdown

# 📧 Personnalisation Email Signature Salarié avec Prénom
**Date**: 16 octobre 2025
## 🎯 Objectif
Personnaliser l'email de signature électronique envoyé aux salariés en utilisant leur prénom dans la salutation "Bonjour [Prénom]". Le prénom est récupéré depuis la colonne `prenom` de la table `salaries` dans Supabase.
---
## ✨ Fonctionnalité
### Comportement
Lorsqu'un email de signature électronique est envoyé à un salarié :
1. **Si la Lambda fournit le prénom** → Utilisé directement
2. **Si le prénom n'est pas fourni** → Recherche dans la table `salaries` de Supabase
- Recherche par `matricule` (priorité) ou `adresse_mail`
- Filtre par `employer_id` si disponible
3. **Si aucun prénom trouvé** → Fallback sur "Salarié"
### Email généré
```
Bonjour Jean,
Nous vous invitons à signer votre contrat de travail ci-dessous...
```
---
## 🔧 Implémentation
### Fichier modifié
**`/app/api/emails/signature-salarie/route.ts`**
#### Étape 1 : Renommer le paramètre firstName
```typescript
const {
employeeEmail,
signatureLink,
reference,
firstName: providedFirstName, // ← Renommé pour clarté
organizationName,
matricule,
// ...
} = data;
```
#### Étape 2 : Récupération depuis Supabase
```typescript
// 3. Récupération du prénom depuis Supabase si non fourni
let firstName = providedFirstName;
if (!firstName && (matricule || employeeEmail)) {
console.log('🔍 Récupération du prénom depuis la table salaries...');
try {
const supabase = createSbServiceRole();
// Recherche par matricule ou email
let query = supabase
.from('salaries')
.select('prenom')
.limit(1);
if (organizationId) {
query = query.eq('employer_id', organizationId);
}
// Priorité au matricule
if (matricule) {
query = query.or(`code_salarie.eq.${matricule},num_salarie.eq.${matricule}`);
} else if (employeeEmail) {
query = query.eq('adresse_mail', employeeEmail);
}
const { data: salaryData, error: salaryError } = await query;
if (!salaryError && salaryData && salaryData[0]?.prenom) {
firstName = salaryData[0].prenom;
console.log('✅ Prénom trouvé dans Supabase:', firstName);
} else {
console.warn('⚠️ Prénom non trouvé dans Supabase');
}
} catch (err) {
console.error('⚠️ Erreur lors de la récupération du prénom:', err);
}
}
```
#### Étape 3 : Utilisation du prénom
```typescript
// 4. Préparation des données de l'email
const emailData: EmailDataV2 = {
firstName: firstName || 'Salarié', // ← Fallback si toujours vide
organizationName: organizationName,
// ...
};
```
#### Étape 4 : Logging amélioré
```typescript
console.log('📧 Préparation de l\'envoi de l\'email:', {
to: employeeEmail,
type: 'signature-request-salarie',
subject: `Signez votre contrat ${organizationName}`,
firstName: emailData.firstName // ← Affiche le prénom utilisé
});
```
---
## 🔄 Flux de données
### Cas 1 : Lambda fournit le prénom (DynamoDB)
```
Lambda AWS (DynamoDB)
↓ firstName: "Jean"
API /api/emails/signature-salarie
↓ Utilise "Jean"
Email envoyé avec "Bonjour Jean,"
```
### Cas 2 : Lambda ne fournit pas le prénom
```
Lambda AWS (DynamoDB)
↓ firstName: null/undefined
API /api/emails/signature-salarie
↓ Recherche dans Supabase
Supabase table salaries
↓ prenom: "Marie"
API utilise "Marie"
Email envoyé avec "Bonjour Marie,"
```
### Cas 3 : Aucun prénom disponible
```
Lambda AWS (DynamoDB)
↓ firstName: null
API /api/emails/signature-salarie
↓ Recherche dans Supabase
Supabase table salaries
↓ Aucun résultat
API utilise fallback "Salarié"
Email envoyé avec "Bonjour Salarié,"
```
---
## 📊 Table Supabase utilisée
**Table**: `salaries`
### Colonnes consultées
| Colonne | Type | Description | Utilisation |
|---------|------|-------------|-------------|
| `prenom` | `text` | Prénom du salarié | ✅ Récupéré pour personnalisation |
| `code_salarie` | `text` | Code matricule | 🔍 Critère de recherche |
| `num_salarie` | `text` | Numéro salarié | 🔍 Critère de recherche (alternative) |
| `adresse_mail` | `text` | Email du salarié | 🔍 Critère de recherche (fallback) |
| `employer_id` | `uuid` | ID de l'employeur | 🔍 Filtre (si disponible) |
### Requête SQL équivalente
```sql
SELECT prenom
FROM salaries
WHERE employer_id = 'uuid-org-id'
AND (code_salarie = 'MAT123' OR num_salarie = 'MAT123')
LIMIT 1;
```
---
## 🧪 Tests
### Test 1 : Prénom fourni par Lambda
**Payload envoyé à l'API :**
```json
{
"employeeEmail": "jean.dupont@example.com",
"signatureLink": "https://...",
"reference": "CDDU-2025-001",
"firstName": "Jean",
"organizationName": "Théâtre National",
"matricule": "SAL001"
}
```
**Résultat attendu :**
- ✅ Email envoyé avec "Bonjour Jean,"
- 📝 Log : `firstName: emailData.firstName` → "Jean"
---
### Test 2 : Prénom non fourni, recherche réussie
**Payload envoyé à l'API :**
```json
{
"employeeEmail": "marie.martin@example.com",
"signatureLink": "https://...",
"reference": "CDDU-2025-002",
"firstName": null,
"organizationName": "Opéra de Paris",
"matricule": "SAL002",
"organizationId": "uuid-org"
}
```
**Logs attendus :**
```
🔍 Récupération du prénom depuis la table salaries...
✅ Prénom trouvé dans Supabase: Marie
📧 Préparation de l'envoi de l'email: { firstName: "Marie", ... }
```
**Résultat attendu :**
- ✅ Email envoyé avec "Bonjour Marie,"
---
### Test 3 : Aucun prénom disponible
**Payload envoyé à l'API :**
```json
{
"employeeEmail": "nouveau@example.com",
"signatureLink": "https://...",
"reference": "CDDU-2025-003",
"firstName": null,
"organizationName": "Comédie Française",
"matricule": "UNKNOWN"
}
```
**Logs attendus :**
```
🔍 Récupération du prénom depuis la table salaries...
⚠️ Prénom non trouvé dans Supabase
📧 Préparation de l'envoi de l'email: { firstName: "Salarié", ... }
```
**Résultat attendu :**
- ✅ Email envoyé avec "Bonjour Salarié,"
- ⚠️ Message générique mais email toujours envoyé
---
## 📝 Template Email
Le template utilise Handlebars pour la personnalisation :
**`lib/emailTemplateService.ts`**
```typescript
'signature-request-salarie': {
subject: 'Signez votre contrat {{organizationName}}',
title: 'Demande de signature électronique',
greeting: '{{#if firstName}}Bonjour {{firstName}},{{/if}}', // ← Utilise firstName
mainMessage: 'Nous vous invitons à signer votre contrat de travail ci-dessous...',
// ...
}
```
---
## 🔒 Sécurité
### Authentification
L'API `/api/emails/signature-salarie` est protégée par API Key :
```typescript
const apiKey = request.headers.get('X-API-Key');
const validApiKey = ENV.LAMBDA_API_KEY;
if (!apiKey || apiKey !== validApiKey) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
```
### Permissions Supabase
Utilise `createSbServiceRole()` pour accéder à la table `salaries` avec des permissions élevées :
```typescript
const supabase = createSbServiceRole();
```
---
## 📋 Checklist de déploiement
- [x] Modification de `/app/api/emails/signature-salarie/route.ts`
- [x] Ajout de la récupération du prénom depuis Supabase
- [x] Gestion du fallback "Salarié"
- [x] Logging amélioré avec `firstName` affiché
- [x] Aucune modification nécessaire dans la Lambda (rétrocompatible)
- [x] Aucune modification nécessaire dans le template email (déjà configuré)
---
## ✅ Avantages
1. **Rétrocompatible** : Si la Lambda envoie déjà le prénom, il est utilisé directement
2. **Fallback automatique** : Recherche dans Supabase si le prénom n'est pas fourni
3. **Robuste** : Gestion des erreurs sans bloquer l'envoi d'email
4. **Logging détaillé** : Suivi clair du prénom utilisé dans les logs
5. **Personnalisation améliorée** : Meilleure expérience utilisateur pour les salariés
---
## 🐛 Dépannage
### Le prénom n'apparaît pas dans l'email
**Vérifier :**
1. **Les logs de l'API** :
```
📦 Données reçues: { firstName: null, matricule: "SAL001", ... }
🔍 Récupération du prénom depuis la table salaries...
✅ Prénom trouvé dans Supabase: Jean
```
2. **La table `salaries`** dans Supabase :
- Le salarié existe avec ce matricule ?
- La colonne `prenom` est bien remplie ?
- L'`employer_id` correspond ?
3. **Le template email** :
```typescript
greeting: '{{#if firstName}}Bonjour {{firstName}},{{/if}}'
```
### Erreur de requête Supabase
```
⚠️ Erreur lors de la récupération du prénom: [Error details]
```
**Actions :**
- Vérifier que `SUPABASE_SERVICE_ROLE_KEY` est bien configuré
- Vérifier les permissions RLS sur la table `salaries`
- Vérifier que `createSbServiceRole()` utilise bien le service role
---
## 📚 Fichiers liés
| Fichier | Rôle |
|---------|------|
| `/app/api/emails/signature-salarie/route.ts` | API recevant la demande d'envoi email |
| `/lib/emailTemplateService.ts` | Configuration du template avec `greeting` |
| `/templates-mails/signature-electronique-salarie.html` | Template HTML (utilise Handlebars) |
| `/LAMBDA_SIGNATURE_SALARIE_UPDATED.js` | Code de la Lambda AWS |
| Table `salaries` (Supabase) | Source de données pour le prénom |
---
## 🎉 Résultat
Les emails de signature électronique sont maintenant personnalisés avec le prénom du salarié :
```
Objet : Signez votre contrat Théâtre National
Bonjour Jean,
Nous vous invitons à signer votre contrat de travail ci-dessous.
[Signer le contrat]
```
Au lieu de :
```
Objet : Signez votre contrat Théâtre National
Un document nécessite votre signature électronique.
[Signer le contrat]
```