# 📧 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] ```