Envoi mail salarié esign en interne depuis AWS Lambda
This commit is contained in:
parent
44c1238730
commit
2b945dec70
8 changed files with 1231 additions and 0 deletions
|
|
@ -37,3 +37,8 @@ DOCUSEAL_PROXY_BASE=https://your-api-gateway.amazonaws.com/default/docuseal
|
|||
# Development only
|
||||
AUTH_BYPASS=0
|
||||
DEBUG_UPSTREAM=0
|
||||
|
||||
# Lambda API Authentication
|
||||
# Used by AWS Lambda to authenticate API calls to Espace Paie
|
||||
# Generate with: openssl rand -hex 32
|
||||
LAMBDA_API_KEY=your-lambda-api-key-64-chars-hex
|
||||
|
|
|
|||
229
ACTIONS_A_FAIRE.md
Normal file
229
ACTIONS_A_FAIRE.md
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
# 🎯 Actions à effectuer - Migration Email Signature Salarié
|
||||
|
||||
## ✅ Ce qui est DÉJÀ fait dans le code
|
||||
|
||||
- ✅ Route API créée : `app/api/emails/signature-salarie/route.ts`
|
||||
- ✅ Type d'email ajouté au système universel v2
|
||||
- ✅ Configuration du template email
|
||||
- ✅ Code Lambda modifié (fichier fourni)
|
||||
- ✅ Documentation complète
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Ce que VOUS devez faire
|
||||
|
||||
### 1️⃣ Générer une API Key sécurisée
|
||||
|
||||
```bash
|
||||
# Exécuter cette commande pour générer une clé aléatoire
|
||||
openssl rand -hex 32
|
||||
```
|
||||
|
||||
**Exemple de résultat :**
|
||||
```
|
||||
a7f3d8c2b1e9f4a6d8c3b2e1f5a9d7c4b8e2f6a3d9c5b7e4f1a8d6c3b9e5f2a7
|
||||
```
|
||||
|
||||
⚠️ **Sauvegardez cette clé dans un endroit sûr** (vous en aurez besoin 2 fois)
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ Ajouter la clé dans l'Espace Paie (Local)
|
||||
|
||||
```bash
|
||||
# Dans le terminal, depuis le dossier du projet
|
||||
echo "LAMBDA_API_KEY=<collez_votre_clé_ici>" >> .env.local
|
||||
```
|
||||
|
||||
**Exemple :**
|
||||
```bash
|
||||
echo "LAMBDA_API_KEY=a7f3d8c2b1e9f4a6d8c3b2e1f5a9d7c4b8e2f6a3d9c5b7e4f1a8d6c3b9e5f2a7" >> .env.local
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ Ajouter la clé sur Vercel (Production)
|
||||
|
||||
#### Option A : Via interface Vercel
|
||||
|
||||
1. Aller sur https://vercel.com/votre-projet
|
||||
2. Settings → Environment Variables
|
||||
3. Ajouter une nouvelle variable :
|
||||
- **Name** : `LAMBDA_API_KEY`
|
||||
- **Value** : `<collez_votre_clé>`
|
||||
- **Environments** : Cocher Production, Preview, Development
|
||||
4. Cliquer sur "Save"
|
||||
|
||||
#### Option B : Via CLI Vercel
|
||||
|
||||
```bash
|
||||
# Installer Vercel CLI si nécessaire
|
||||
npm i -g vercel
|
||||
|
||||
# Se connecter
|
||||
vercel login
|
||||
|
||||
# Ajouter la variable
|
||||
vercel env add LAMBDA_API_KEY
|
||||
|
||||
# Coller la clé quand demandé
|
||||
# Sélectionner : Production, Preview, Development
|
||||
```
|
||||
|
||||
#### Redéployer
|
||||
|
||||
```bash
|
||||
vercel --prod
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4️⃣ Configurer AWS Lambda
|
||||
|
||||
#### Via AWS Console
|
||||
|
||||
1. Aller sur https://console.aws.amazon.com/lambda/
|
||||
2. Région : **eu-west-3** (Paris)
|
||||
3. Trouver la fonction : **postDocuSealSalarie**
|
||||
4. Onglet **Configuration** → **Environment variables**
|
||||
5. Cliquer sur **Edit**
|
||||
|
||||
#### Ajouter ces 2 variables :
|
||||
|
||||
| Key | Value | Description |
|
||||
|-----|-------|-------------|
|
||||
| `ESPACE_PAIE_URL` | `https://staging.paie.odentas.fr` | URL de l'Espace Paie (staging ou prod) |
|
||||
| `ESPACE_PAIE_API_KEY` | `<votre_clé_générée>` | **La même clé qu'à l'étape 1** |
|
||||
|
||||
6. Cliquer sur **Save**
|
||||
|
||||
#### (Optionnel) Supprimer les anciennes variables
|
||||
|
||||
Ces variables ne sont plus utilisées, vous pouvez les supprimer :
|
||||
- `AWS_SES_FROM`
|
||||
- `S3_BUCKET_NAME_EMAILS`
|
||||
- `AIRTABLE_API_KEY`
|
||||
|
||||
---
|
||||
|
||||
### 5️⃣ Mettre à jour le code de la Lambda
|
||||
|
||||
1. Toujours dans AWS Lambda → **postDocuSealSalarie**
|
||||
2. Onglet **Code**
|
||||
3. Ouvrir le fichier `index.js`
|
||||
4. **Remplacer tout le contenu** par le code du fichier `LAMBDA_SIGNATURE_SALARIE_UPDATED.js` (fourni dans ce projet)
|
||||
5. Cliquer sur **Deploy**
|
||||
|
||||
---
|
||||
|
||||
### 6️⃣ Tester
|
||||
|
||||
#### Test 1 : Vérifier que l'API répond
|
||||
|
||||
```bash
|
||||
# Depuis votre terminal local
|
||||
curl -X POST https://paie.odentas.fr/api/emails/signature-salarie \
|
||||
-H "X-API-Key: <votre_clé>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"employeeEmail": "votre-email@example.com",
|
||||
"signatureLink": "https://test.com",
|
||||
"reference": "TEST-001",
|
||||
"organizationName": "Test",
|
||||
"firstName": "Test",
|
||||
"matricule": "TEST001"
|
||||
}'
|
||||
```
|
||||
|
||||
**Réponse attendue :**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"messageId": "01000192abc...",
|
||||
"recipient": "votre-email@example.com",
|
||||
"reference": "TEST-001"
|
||||
}
|
||||
```
|
||||
|
||||
**Si erreur 401** : Vérifiez que la clé API est correcte
|
||||
|
||||
#### Test 2 : Déclencher un vrai webhook
|
||||
|
||||
1. Faire signer un contrat par l'employeur dans DocuSeal
|
||||
2. Observer les logs Lambda dans CloudWatch
|
||||
3. Vérifier l'email reçu par le salarié
|
||||
4. Vérifier dans l'interface : `/staff/email-logs`
|
||||
|
||||
---
|
||||
|
||||
### 7️⃣ Vérifier les logs
|
||||
|
||||
#### Dans AWS CloudWatch
|
||||
|
||||
1. AWS Console → CloudWatch → Log groups
|
||||
2. Chercher : `/aws/lambda/postDocuSealSalarie`
|
||||
3. Logs à chercher :
|
||||
```
|
||||
📤 Appel de l'API Espace Paie pour envoi email...
|
||||
✅ E-mail envoyé via l'API Espace Paie
|
||||
```
|
||||
|
||||
#### Dans l'Espace Paie
|
||||
|
||||
1. Aller sur : `https://staging.paie.odentas.fr/staff/email-logs`
|
||||
2. Filtrer par type : **signature-request-salarie**
|
||||
3. Vérifier le statut : **sent**
|
||||
4. Cliquer sur une ligne pour voir le contenu HTML
|
||||
|
||||
---
|
||||
|
||||
## 🎉 C'est terminé !
|
||||
|
||||
Si tout est OK :
|
||||
- ✅ Les emails de signature sont envoyés via le système universel v2
|
||||
- ✅ Tous les emails sont loggés dans la base de données
|
||||
- ✅ Vous pouvez voir les logs dans l'interface Staff
|
||||
- ✅ Le template est cohérent avec les autres emails
|
||||
|
||||
---
|
||||
|
||||
## 🆘 En cas de problème
|
||||
|
||||
### Erreur 401 "Unauthorized"
|
||||
|
||||
➡️ **Solution** : Vérifiez que `LAMBDA_API_KEY` (Espace Paie) et `ESPACE_PAIE_API_KEY` (Lambda) ont exactement la même valeur.
|
||||
|
||||
### Erreur 500 "Configuration Error"
|
||||
|
||||
➡️ **Solution** : La variable `LAMBDA_API_KEY` n'est pas définie sur Vercel. Vérifiez l'étape 3.
|
||||
|
||||
### Lambda : Erreur "ESPACE_PAIE_URL is not defined"
|
||||
|
||||
➡️ **Solution** : Les variables d'environnement ne sont pas configurées dans Lambda. Vérifiez l'étape 4.
|
||||
|
||||
### Email non reçu
|
||||
|
||||
➡️ **Solutions** :
|
||||
1. Vérifier CloudWatch logs pour voir si l'API a été appelée
|
||||
2. Vérifier dans `/staff/email-logs` si l'email apparaît
|
||||
3. Vérifier les credentials AWS SES (normalement OK si les autres emails fonctionnent)
|
||||
4. Vérifier que l'email du salarié est valide
|
||||
|
||||
### L'API ne répond pas
|
||||
|
||||
➡️ **Solutions** :
|
||||
1. Vérifier que l'Espace Paie est déployé sur Vercel
|
||||
2. Vérifier que la route existe : `app/api/emails/signature-salarie/route.ts`
|
||||
3. Regarder les logs Vercel
|
||||
|
||||
---
|
||||
|
||||
## 📞 Support
|
||||
|
||||
- **Documentation complète** : `LAMBDA_EMAIL_SIGNATURE_SALARIE_GUIDE.md`
|
||||
- **Résumé des changements** : `LAMBDA_EMAIL_SIGNATURE_SALARIE_SUMMARY.md`
|
||||
- **Code Lambda mis à jour** : `LAMBDA_SIGNATURE_SALARIE_UPDATED.js`
|
||||
|
||||
---
|
||||
|
||||
*Bonne chance ! 🚀*
|
||||
357
LAMBDA_EMAIL_SIGNATURE_SALARIE_GUIDE.md
Normal file
357
LAMBDA_EMAIL_SIGNATURE_SALARIE_GUIDE.md
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
# Configuration Lambda → Espace Paie : Email Signature Salarié
|
||||
|
||||
## 📋 Vue d'ensemble
|
||||
|
||||
Cette documentation détaille la configuration nécessaire pour faire communiquer la Lambda AWS `postDocuSealSalarie` avec l'Espace Paie pour l'envoi d'emails de signature aux salariés.
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
DocuSeal Webhook → Lambda postDocuSealSalarie → API Espace Paie → Système Email Universel v2 → AWS SES
|
||||
↓
|
||||
Logs emails (Supabase)
|
||||
```
|
||||
|
||||
### Avantages de cette architecture
|
||||
|
||||
✅ **Centralisation** : Tous les emails passent par le système universel v2
|
||||
✅ **Logs automatiques** : Tous les envois sont enregistrés dans `email_logs`
|
||||
✅ **Cohérence** : Même template et même système que les autres emails
|
||||
✅ **Maintenance simplifiée** : Un seul endroit pour gérer les emails
|
||||
✅ **Debugging facilité** : Logs accessibles dans l'interface Staff
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Configuration AWS Lambda
|
||||
|
||||
### Variables d'environnement à ajouter/modifier
|
||||
|
||||
Dans la configuration de la Lambda `postDocuSealSalarie` :
|
||||
|
||||
```env
|
||||
# Existantes (à conserver)
|
||||
DOCUSEAL_API_TOKEN=xxxxx
|
||||
SUPABASE_URL=https://xxxxx.supabase.co
|
||||
SUPABASE_SERVICE_ROLE=xxxxx
|
||||
ZAPIER_WEBHOOK_URL=https://hooks.zapier.com/xxxxx
|
||||
|
||||
# NOUVELLES variables à ajouter
|
||||
ESPACE_PAIE_URL=https://staging.paie.odentas.fr
|
||||
ESPACE_PAIE_API_KEY=<générer une clé secrète forte>
|
||||
```
|
||||
|
||||
### ⚠️ Variables à SUPPRIMER
|
||||
|
||||
Les variables suivantes ne sont plus nécessaires car l'envoi d'email est géré par l'Espace Paie :
|
||||
|
||||
```env
|
||||
# À SUPPRIMER
|
||||
AWS_SES_FROM=paie@odentas.fr
|
||||
S3_BUCKET_NAME_EMAILS=odentas-emails
|
||||
AIRTABLE_API_KEY=xxxxx
|
||||
```
|
||||
|
||||
### Génération de l'API Key
|
||||
|
||||
Pour générer une API Key sécurisée :
|
||||
|
||||
```bash
|
||||
# Méthode 1 : OpenSSL
|
||||
openssl rand -hex 32
|
||||
|
||||
# Méthode 2 : Node.js
|
||||
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
||||
|
||||
# Méthode 3 : Python
|
||||
python3 -c "import secrets; print(secrets.token_hex(32))"
|
||||
```
|
||||
|
||||
**Important** : Utilisez la même clé dans AWS Lambda et dans l'Espace Paie.
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Configuration Espace Paie
|
||||
|
||||
### Variables d'environnement à ajouter
|
||||
|
||||
Dans `.env.local` (dev) et dans Vercel (production) :
|
||||
|
||||
```env
|
||||
# API Key pour authentifier les appels depuis la Lambda
|
||||
LAMBDA_API_KEY=<même clé que ESPACE_PAIE_API_KEY de la Lambda>
|
||||
```
|
||||
|
||||
### Déploiement de la variable sur Vercel
|
||||
|
||||
```bash
|
||||
# Ajouter la variable d'environnement sur Vercel
|
||||
vercel env add LAMBDA_API_KEY
|
||||
|
||||
# Saisir la valeur : <la même que dans AWS Lambda>
|
||||
# Environnements : Production, Preview, Development
|
||||
|
||||
# Redéployer pour prendre en compte la nouvelle variable
|
||||
vercel --prod
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Fichiers modifiés/créés
|
||||
|
||||
### 1. Espace Paie (Next.js)
|
||||
|
||||
#### ✨ Nouveau fichier créé
|
||||
- **`app/api/emails/signature-salarie/route.ts`**
|
||||
- Route API POST pour recevoir les demandes d'envoi d'email
|
||||
- Authentification par API Key
|
||||
- Utilise `sendUniversalEmailV2()`
|
||||
- Logs automatiques dans `email_logs`
|
||||
|
||||
#### 📝 Fichiers modifiés
|
||||
- **`lib/emailTemplateService.ts`**
|
||||
- Ajout du type `'signature-request-salarie'` dans `EmailTypeV2`
|
||||
- Ajout des champs `matricule` et `typecontrat` dans `EmailDataV2`
|
||||
- Configuration du template email avec cartes info et détails
|
||||
|
||||
- **`lib/cleanEnv.ts`**
|
||||
- Ajout de `LAMBDA_API_KEY` dans l'objet `ENV`
|
||||
|
||||
### 2. Lambda AWS
|
||||
|
||||
#### 📝 Fichier modifié
|
||||
- **`index.js`** (version mise à jour fournie : `LAMBDA_SIGNATURE_SALARIE_UPDATED.js`)
|
||||
- ❌ Suppression de `sendSignatureEmail()` (envoi direct SES)
|
||||
- ❌ Suppression de `uploadEmailToS3()` (stockage S3)
|
||||
- ❌ Suppression de `logToAirtable()` (logging Airtable)
|
||||
- ❌ Suppression de `generateEmailHtml()` (template HTML)
|
||||
- ✅ Ajout de l'appel API vers l'Espace Paie
|
||||
- ✅ Headers d'authentification avec API Key
|
||||
- ✅ Gestion d'erreurs améliorée
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Déploiement
|
||||
|
||||
### Étape 1 : Déployer l'Espace Paie
|
||||
|
||||
```bash
|
||||
# En local, vérifier que la variable existe
|
||||
grep LAMBDA_API_KEY .env.local
|
||||
|
||||
# Si absente, l'ajouter
|
||||
echo "LAMBDA_API_KEY=votre_cle_secrete_ici" >> .env.local
|
||||
|
||||
# Sur Vercel (production)
|
||||
vercel env add LAMBDA_API_KEY
|
||||
# Puis redéployer
|
||||
vercel --prod
|
||||
```
|
||||
|
||||
### Étape 2 : Mettre à jour la Lambda AWS
|
||||
|
||||
1. **Via AWS Console** :
|
||||
- Aller dans AWS Lambda → `postDocuSealSalarie`
|
||||
- Onglet "Configuration" → "Environment variables"
|
||||
- Ajouter :
|
||||
- `ESPACE_PAIE_URL` = `https://staging.paie.odentas.fr` (ou prod)
|
||||
- `ESPACE_PAIE_API_KEY` = `<votre clé générée>`
|
||||
- Supprimer les anciennes variables (optionnel mais recommandé)
|
||||
|
||||
2. **Mettre à jour le code** :
|
||||
- Remplacer le contenu de `index.js` par celui de `LAMBDA_SIGNATURE_SALARIE_UPDATED.js`
|
||||
- Cliquer sur "Deploy"
|
||||
|
||||
### Étape 3 : Tester
|
||||
|
||||
```bash
|
||||
# Test depuis la Lambda (déclencher un webhook DocuSeal)
|
||||
# Vérifier les logs CloudWatch pour :
|
||||
# - "📤 Appel de l'API Espace Paie pour envoi email..."
|
||||
# - "✅ E-mail envoyé via l'API Espace Paie"
|
||||
|
||||
# Vérifier dans l'Espace Paie
|
||||
# - Aller sur /staff/email-logs
|
||||
# - Chercher le type "signature-request-salarie"
|
||||
# - Vérifier le statut "sent"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Debug & Monitoring
|
||||
|
||||
### Logs Lambda (CloudWatch)
|
||||
|
||||
```
|
||||
📤 Appel de l'API Espace Paie pour envoi email...
|
||||
✅ E-mail envoyé via l'API Espace Paie: { success: true, messageId: '...' }
|
||||
```
|
||||
|
||||
### Logs Espace Paie (Console serveur)
|
||||
|
||||
```
|
||||
=== API Email Signature Salarié ===
|
||||
✅ Authentication successful
|
||||
📦 Données reçues: { employeeEmail: '...', reference: '...', ... }
|
||||
📧 Préparation de l'envoi de l'email: { to: '...', type: 'signature-request-salarie' }
|
||||
✅ Email envoyé avec succès: { messageId: '...', recipient: '...', reference: '...' }
|
||||
```
|
||||
|
||||
### Vérification dans l'interface
|
||||
|
||||
1. **Interface Staff** : `/staff/email-logs`
|
||||
- Filtrer par type : `signature-request-salarie`
|
||||
- Vérifier le statut et le contenu HTML
|
||||
|
||||
2. **Base de données** : Table `email_logs`
|
||||
```sql
|
||||
SELECT * FROM email_logs
|
||||
WHERE email_type = 'signature-request-salarie'
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 10;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Sécurité
|
||||
|
||||
### API Key
|
||||
|
||||
- ✅ Utilisez une clé de minimum 32 caractères hexadécimaux (256 bits)
|
||||
- ✅ Ne commitez JAMAIS la clé dans le code
|
||||
- ✅ Utilisez des variables d'environnement différentes par environnement
|
||||
- ✅ Renouvelez la clé périodiquement (tous les 6 mois)
|
||||
|
||||
### HTTPS
|
||||
|
||||
- ✅ L'API Espace Paie doit être en HTTPS uniquement
|
||||
- ✅ Vérifiez le certificat SSL (fait automatiquement par axios)
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
À considérer pour le futur :
|
||||
- Limiter le nombre de requêtes par minute depuis une IP
|
||||
- Implémenter un système de throttling
|
||||
|
||||
---
|
||||
|
||||
## 📊 Données envoyées
|
||||
|
||||
### Payload de la Lambda vers l'API
|
||||
|
||||
```json
|
||||
{
|
||||
"employeeEmail": "salarie@example.com",
|
||||
"signatureLink": "https://staging.paie.odentas.fr/odentas-sign?docuseal_id=abc123",
|
||||
"reference": "CDDU-2025-001",
|
||||
"firstName": "Jean",
|
||||
"organizationName": "Théâtre National",
|
||||
"matricule": "SAL001",
|
||||
"typecontrat": "CDDU",
|
||||
"startDate": "15/01/2025",
|
||||
"profession": "Comédien",
|
||||
"productionName": "Le Mariage de Figaro",
|
||||
"organizationId": "uuid-org",
|
||||
"contractId": "uuid-contract"
|
||||
}
|
||||
```
|
||||
|
||||
### Réponse de l'API
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"messageId": "01000192...",
|
||||
"recipient": "salarie@example.com",
|
||||
"reference": "CDDU-2025-001"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ❌ Gestion des erreurs
|
||||
|
||||
### Erreurs possibles
|
||||
|
||||
| Code | Erreur | Cause | Solution |
|
||||
|------|--------|-------|----------|
|
||||
| 401 | Unauthorized | API Key invalide ou manquante | Vérifier `LAMBDA_API_KEY` et `ESPACE_PAIE_API_KEY` |
|
||||
| 400 | Bad Request | Champs requis manquants | Vérifier le payload envoyé |
|
||||
| 500 | Server Error | Erreur lors de l'envoi SES | Vérifier les credentials AWS SES |
|
||||
| 500 | Configuration Error | `LAMBDA_API_KEY` non définie | Ajouter la variable dans Vercel |
|
||||
|
||||
### En cas d'échec
|
||||
|
||||
La Lambda retourne une erreur 500 mais **ne bloque pas** :
|
||||
- Le contrat reste signé par l'employeur dans Supabase
|
||||
- Le webhook Zapier est appelé quand même
|
||||
- L'erreur est loggée dans CloudWatch
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Rollback
|
||||
|
||||
Si vous devez revenir en arrière :
|
||||
|
||||
1. **Restaurer l'ancien code Lambda**
|
||||
- Utiliser le fichier `/tmp/aws-toolkit-vscode/lambda/eu-west-3/postDocuSealSalarie/index.js`
|
||||
|
||||
2. **Rétablir les variables d'environnement**
|
||||
- Réajouter `AWS_SES_FROM`, `S3_BUCKET_NAME_EMAILS`, `AIRTABLE_API_KEY`
|
||||
- Supprimer `ESPACE_PAIE_URL` et `ESPACE_PAIE_API_KEY`
|
||||
|
||||
3. **L'Espace Paie reste compatible**
|
||||
- La route API peut rester en place (elle ne sera simplement pas appelée)
|
||||
- Le nouveau type d'email `signature-request-salarie` ne causera pas d'erreur
|
||||
|
||||
---
|
||||
|
||||
## 📚 Ressources
|
||||
|
||||
- [Système Email Universel v2](./EMAIL_TEMPLATE_SYSTEM.md)
|
||||
- [Logs Emails](./DEBUG_EMAIL_LOGS.md)
|
||||
- [DocuSeal API](https://docs.docuseal.co/)
|
||||
- [AWS Lambda Configuration](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist de déploiement
|
||||
|
||||
### Avant déploiement
|
||||
|
||||
- [ ] Générer une API Key sécurisée (32 caractères hex minimum)
|
||||
- [ ] Tester localement la route API avec un faux payload
|
||||
- [ ] Vérifier que le template email s'affiche correctement
|
||||
|
||||
### Espace Paie
|
||||
|
||||
- [ ] Ajouter `LAMBDA_API_KEY` dans `.env.local`
|
||||
- [ ] Ajouter `LAMBDA_API_KEY` sur Vercel (tous les environnements)
|
||||
- [ ] Déployer sur Vercel
|
||||
- [ ] Vérifier que la route `/api/emails/signature-salarie` répond
|
||||
|
||||
### Lambda AWS
|
||||
|
||||
- [ ] Ajouter `ESPACE_PAIE_URL` dans les variables d'env
|
||||
- [ ] Ajouter `ESPACE_PAIE_API_KEY` dans les variables d'env (même valeur que `LAMBDA_API_KEY`)
|
||||
- [ ] Mettre à jour le code de la Lambda
|
||||
- [ ] Déployer
|
||||
|
||||
### Tests
|
||||
|
||||
- [ ] Déclencher un webhook DocuSeal (signature employeur)
|
||||
- [ ] Vérifier les logs CloudWatch de la Lambda
|
||||
- [ ] Vérifier les logs de l'API Espace Paie
|
||||
- [ ] Vérifier que l'email a été reçu par le salarié
|
||||
- [ ] Vérifier l'entrée dans `/staff/email-logs`
|
||||
- [ ] Vérifier le contenu HTML de l'email
|
||||
|
||||
### Post-déploiement
|
||||
|
||||
- [ ] Monitorer les logs pendant 24h
|
||||
- [ ] Vérifier le taux de succès des emails
|
||||
- [ ] Documenter tout problème rencontré
|
||||
- [ ] Célébrer ! 🎉
|
||||
|
||||
---
|
||||
|
||||
*Dernière mise à jour : 15 octobre 2025*
|
||||
253
LAMBDA_EMAIL_SIGNATURE_SALARIE_SUMMARY.md
Normal file
253
LAMBDA_EMAIL_SIGNATURE_SALARIE_SUMMARY.md
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
# 📧 Résumé : Migration Email Signature Salarié vers Système Universel v2
|
||||
|
||||
## 🎯 Objectif atteint
|
||||
|
||||
Au lieu que la Lambda `postDocuSealSalarie` envoie directement les emails via AWS SES, elle appelle maintenant une API de l'Espace Paie qui utilise le système universel v2. Tous les emails sont maintenant loggés dans la base de données.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Ce qui a été fait
|
||||
|
||||
### 1. **Espace Paie - Système Email**
|
||||
|
||||
#### Fichier : `lib/emailTemplateService.ts`
|
||||
- ✅ Ajout du type `'signature-request-salarie'` dans `EmailTypeV2`
|
||||
- ✅ Ajout des champs `matricule` et `typecontrat` dans `EmailDataV2`
|
||||
- ✅ Configuration complète du template avec :
|
||||
- Subject : `"Signez votre contrat {{organizationName}}"`
|
||||
- Carte info : employeur + matricule
|
||||
- Carte détails : référence, type contrat, dates, poste, production
|
||||
- Bouton CTA : "Signer le contrat"
|
||||
- Footer personnalisé pour les salariés
|
||||
|
||||
#### Fichier : `lib/cleanEnv.ts`
|
||||
- ✅ Ajout de `LAMBDA_API_KEY` dans l'objet `ENV`
|
||||
|
||||
#### Fichier : `app/api/emails/signature-salarie/route.ts` ⭐ NOUVEAU
|
||||
- ✅ Route POST protégée par API Key
|
||||
- ✅ Validation des données entrantes
|
||||
- ✅ Appel à `sendUniversalEmailV2()` avec le type `signature-request-salarie`
|
||||
- ✅ Retour du messageId SES
|
||||
- ✅ Logs automatiques dans `email_logs` (via le système universel)
|
||||
|
||||
### 2. **Lambda AWS**
|
||||
|
||||
#### Fichier : `LAMBDA_SIGNATURE_SALARIE_UPDATED.js` ⭐ CODE MIS À JOUR
|
||||
Changements par rapport à l'ancien code :
|
||||
|
||||
**❌ Supprimé :**
|
||||
- `sendSignatureEmail()` - Envoi direct via SES
|
||||
- `uploadEmailToS3()` - Upload du HTML sur S3
|
||||
- `logToAirtable()` - Journalisation Airtable
|
||||
- `generateEmailHtml()` - Template HTML hardcodé
|
||||
- Import de `ses` d'AWS SDK
|
||||
|
||||
**✅ Ajouté :**
|
||||
- Appel POST vers `${ESPACE_PAIE_URL}/api/emails/signature-salarie`
|
||||
- Header `X-API-Key` pour l'authentification
|
||||
- Payload structuré avec tous les champs nécessaires
|
||||
- Gestion d'erreur améliorée avec timeout
|
||||
|
||||
**📝 Variables d'environnement :**
|
||||
- **Nouvelles** : `ESPACE_PAIE_URL`, `ESPACE_PAIE_API_KEY`
|
||||
- **À supprimer** : `AWS_SES_FROM`, `S3_BUCKET_NAME_EMAILS`, `AIRTABLE_API_KEY`
|
||||
|
||||
### 3. **Documentation**
|
||||
|
||||
#### Fichier : `LAMBDA_EMAIL_SIGNATURE_SALARIE_GUIDE.md` ⭐ NOUVEAU
|
||||
Guide complet avec :
|
||||
- Architecture du système
|
||||
- Configuration AWS Lambda
|
||||
- Configuration Espace Paie
|
||||
- Déploiement pas à pas
|
||||
- Debug & monitoring
|
||||
- Sécurité
|
||||
- Gestion des erreurs
|
||||
- Checklist de déploiement
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Configuration requise
|
||||
|
||||
### Variables d'environnement Espace Paie
|
||||
|
||||
```env
|
||||
# .env.local (développement)
|
||||
LAMBDA_API_KEY=<générer une clé de 64 caractères hex>
|
||||
|
||||
# Vercel (production)
|
||||
# Ajouter via : vercel env add LAMBDA_API_KEY
|
||||
```
|
||||
|
||||
### Variables d'environnement Lambda AWS
|
||||
|
||||
```env
|
||||
# À AJOUTER
|
||||
ESPACE_PAIE_URL=https://staging.paie.odentas.fr # ou production
|
||||
ESPACE_PAIE_API_KEY=<même clé que LAMBDA_API_KEY>
|
||||
|
||||
# À CONSERVER (pour Supabase, DocuSeal, Zapier)
|
||||
DOCUSEAL_API_TOKEN=xxxxx
|
||||
SUPABASE_URL=xxxxx
|
||||
SUPABASE_SERVICE_ROLE=xxxxx
|
||||
ZAPIER_WEBHOOK_URL=xxxxx
|
||||
|
||||
# À SUPPRIMER (optionnel mais recommandé)
|
||||
AWS_SES_FROM=paie@odentas.fr
|
||||
S3_BUCKET_NAME_EMAILS=odentas-emails
|
||||
AIRTABLE_API_KEY=xxxxx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Flux de données
|
||||
|
||||
### Avant (ancien système)
|
||||
|
||||
```
|
||||
DocuSeal → Lambda → AWS SES → Salarié
|
||||
↓
|
||||
S3 (HTML)
|
||||
↓
|
||||
Airtable (logs)
|
||||
```
|
||||
|
||||
### Après (nouveau système) ⭐
|
||||
|
||||
```
|
||||
DocuSeal → Lambda → API Espace Paie → Système Email v2 → AWS SES → Salarié
|
||||
↓
|
||||
Supabase email_logs
|
||||
↓
|
||||
Interface /staff/email-logs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎁 Avantages
|
||||
|
||||
| Aspect | Avant | Après |
|
||||
|--------|-------|-------|
|
||||
| **Templates** | HTML hardcodé dans Lambda | Template universel v2 centralisé |
|
||||
| **Logs** | Airtable (externe) | Supabase `email_logs` (intégré) |
|
||||
| **Debugging** | CloudWatch uniquement | CloudWatch + Interface Staff + DB |
|
||||
| **Cohérence** | Email différent des autres | Même style que tous les emails |
|
||||
| **Maintenance** | 4 fichiers à maintenir | 1 configuration template |
|
||||
| **HTML Storage** | S3 manuel | Automatique dans logs |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Pour déployer
|
||||
|
||||
### 1. Générer l'API Key
|
||||
|
||||
```bash
|
||||
openssl rand -hex 32
|
||||
# Copier la clé générée
|
||||
```
|
||||
|
||||
### 2. Espace Paie
|
||||
|
||||
```bash
|
||||
# Local
|
||||
echo "LAMBDA_API_KEY=<clé_générée>" >> .env.local
|
||||
|
||||
# Vercel
|
||||
vercel env add LAMBDA_API_KEY
|
||||
# Coller la clé
|
||||
# Puis redéployer
|
||||
vercel --prod
|
||||
```
|
||||
|
||||
### 3. Lambda AWS
|
||||
|
||||
1. Aller dans AWS Console → Lambda → `postDocuSealSalarie`
|
||||
2. Configuration → Environment variables
|
||||
3. Ajouter :
|
||||
- `ESPACE_PAIE_URL` = `https://staging.paie.odentas.fr`
|
||||
- `ESPACE_PAIE_API_KEY` = `<clé_générée>` (la même)
|
||||
4. Code → Remplacer par `LAMBDA_SIGNATURE_SALARIE_UPDATED.js`
|
||||
5. Deploy
|
||||
|
||||
### 4. Tester
|
||||
|
||||
1. Déclencher un webhook DocuSeal
|
||||
2. Vérifier CloudWatch logs
|
||||
3. Vérifier `/staff/email-logs`
|
||||
4. Vérifier la réception de l'email
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Vérifications
|
||||
|
||||
### ✅ L'API fonctionne
|
||||
|
||||
```bash
|
||||
curl -X POST https://staging.paie.odentas.fr/api/emails/signature-salarie \
|
||||
-H "X-API-Key: votre_cle" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"employeeEmail": "test@example.com",
|
||||
"signatureLink": "https://test.com",
|
||||
"reference": "TEST-001",
|
||||
"organizationName": "Test Org"
|
||||
}'
|
||||
```
|
||||
|
||||
Réponse attendue :
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"messageId": "01000192...",
|
||||
"recipient": "test@example.com",
|
||||
"reference": "TEST-001"
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Les logs apparaissent
|
||||
|
||||
1. Interface : `/staff/email-logs`
|
||||
2. Filtrer par type : `signature-request-salarie`
|
||||
3. Vérifier le statut `sent`
|
||||
4. Cliquer pour voir le HTML
|
||||
|
||||
---
|
||||
|
||||
## 📁 Fichiers du projet
|
||||
|
||||
```
|
||||
Espace Paie/
|
||||
├── app/api/emails/signature-salarie/
|
||||
│ └── route.ts ⭐ NOUVEAU
|
||||
├── lib/
|
||||
│ ├── emailTemplateService.ts ✏️ MODIFIÉ
|
||||
│ └── cleanEnv.ts ✏️ MODIFIÉ
|
||||
├── LAMBDA_SIGNATURE_SALARIE_UPDATED.js ⭐ NOUVEAU (à copier dans Lambda)
|
||||
├── LAMBDA_EMAIL_SIGNATURE_SALARIE_GUIDE.md ⭐ NOUVEAU
|
||||
└── LAMBDA_EMAIL_SIGNATURE_SALARIE_SUMMARY.md ⭐ CE FICHIER
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🆘 Support
|
||||
|
||||
En cas de problème :
|
||||
|
||||
1. **Logs Lambda** : CloudWatch Logs
|
||||
2. **Logs API** : Console serveur Next.js (Vercel logs)
|
||||
3. **Logs email** : `/staff/email-logs` dans l'interface
|
||||
4. **Documentation** : `LAMBDA_EMAIL_SIGNATURE_SALARIE_GUIDE.md`
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- ✅ Compatible avec l'ancien système (possibilité de rollback)
|
||||
- ✅ Pas d'impact sur les autres emails
|
||||
- ✅ Le template peut être modifié dans `emailTemplateService.ts`
|
||||
- ✅ L'API peut être réutilisée pour d'autres webhooks Lambda
|
||||
|
||||
---
|
||||
|
||||
*Implémentation réalisée le 15 octobre 2025*
|
||||
*Système Email Universel v2 - Odentas Espace Paie*
|
||||
214
LAMBDA_SIGNATURE_SALARIE_UPDATED.js
Normal file
214
LAMBDA_SIGNATURE_SALARIE_UPDATED.js
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
const AWS = require('aws-sdk');
|
||||
const axios = require('axios');
|
||||
const dynamoDB = new AWS.DynamoDB.DocumentClient();
|
||||
|
||||
// Supabase (option 1 - REST avec service role)
|
||||
const SUPABASE_URL = process.env.SUPABASE_URL; // ex: https://xxxxx.supabase.co
|
||||
const SUPABASE_SERVICE_ROLE = process.env.SUPABASE_SERVICE_ROLE; // secret service role JWT
|
||||
|
||||
// Fonction principale de gestion du webhook
|
||||
exports.handler = async (event) => {
|
||||
console.log("Webhook reçu :", JSON.stringify(event, null, 2));
|
||||
|
||||
try {
|
||||
const body = JSON.parse(event.body);
|
||||
const submissionId = body.data.submission_id;
|
||||
const documentName = body.data.documents[0].name;
|
||||
|
||||
// Récupération des détails de la soumission depuis DocuSeal
|
||||
const docusealResponse = await axios.get(`https://api.docuseal.eu/submissions/${submissionId}`, {
|
||||
headers: {
|
||||
'X-Auth-Token': process.env.DOCUSEAL_API_TOKEN
|
||||
}
|
||||
});
|
||||
|
||||
console.log("Réponse de l'API DocuSeal :", JSON.stringify(docusealResponse.data, null, 2));
|
||||
|
||||
// Récupération du slug du salarié
|
||||
const employeeSlug = extractEmployeeSlug(docusealResponse.data);
|
||||
if (!employeeSlug) throw new Error("Slug pour le salarié introuvable dans la réponse de DocuSeal");
|
||||
|
||||
// Récupération des données du document dans DynamoDB
|
||||
const dynamoData = await retrieveDynamoData(documentName);
|
||||
if (!dynamoData) {
|
||||
console.log("Aucune donnée trouvée dans DynamoDB pour la clé :", documentName);
|
||||
return {
|
||||
statusCode: 404,
|
||||
body: JSON.stringify({ message: "Aucune donnée trouvée" })
|
||||
};
|
||||
}
|
||||
|
||||
// Extraire les champs utiles (dont la référence) depuis DynamoDB
|
||||
const {
|
||||
employeeEmail,
|
||||
reference,
|
||||
salarie,
|
||||
date,
|
||||
poste,
|
||||
analytique,
|
||||
structure,
|
||||
prenom_salarie,
|
||||
prenom_signataire,
|
||||
code_employeur,
|
||||
matricule,
|
||||
typecontrat,
|
||||
organization_id,
|
||||
contract_id
|
||||
} = dynamoData;
|
||||
|
||||
// Met à jour Supabase: contrat signé par employeur = "Oui" pour le contract_number = reference
|
||||
try {
|
||||
await updateSupabaseEmployerSigned(reference);
|
||||
} catch (err) {
|
||||
// Ne pas bloquer complètement le flux d'envoi d'email, mais journaliser clairement l'erreur
|
||||
console.error("Echec de mise à jour Supabase (contrat_signe_par_employeur):", err.message);
|
||||
}
|
||||
|
||||
// Formater la date au format JJ/MM/AAAA
|
||||
let formattedDate;
|
||||
if (dynamoData.date) {
|
||||
const parsedDate = new Date(dynamoData.date);
|
||||
if (!isNaN(parsedDate)) {
|
||||
formattedDate = parsedDate.toLocaleDateString('fr-FR'); // Résultat au format JJ/MM/AAAA
|
||||
} else {
|
||||
console.warn("La date fournie n'est pas valide. Utilisation de la valeur brute.");
|
||||
formattedDate = dynamoData.date; // Utiliser la valeur brute si la date est invalide
|
||||
}
|
||||
} else {
|
||||
formattedDate = ''; // Valeur par défaut si la date n'est pas définie
|
||||
}
|
||||
|
||||
// Génération du lien de signature
|
||||
const signatureLink = `https://staging.paie.odentas.fr/odentas-sign?docuseal_id=${employeeSlug}`;
|
||||
|
||||
// ============================================
|
||||
// NOUVEAU : Appel API Espace Paie au lieu d'envoi direct SES
|
||||
// ============================================
|
||||
console.log("📤 Appel de l'API Espace Paie pour envoi email...");
|
||||
|
||||
const emailPayload = {
|
||||
employeeEmail: employeeEmail,
|
||||
signatureLink: signatureLink,
|
||||
reference: reference,
|
||||
firstName: prenom_salarie,
|
||||
organizationName: structure,
|
||||
matricule: matricule,
|
||||
typecontrat: typecontrat,
|
||||
startDate: formattedDate,
|
||||
profession: poste,
|
||||
productionName: analytique,
|
||||
organizationId: organization_id,
|
||||
contractId: contract_id
|
||||
};
|
||||
|
||||
// Appel de l'API Espace Paie et du webhook Zapier en parallèle
|
||||
const apiPromise = axios.post(
|
||||
`${process.env.ESPACE_PAIE_URL}/api/emails/signature-salarie`,
|
||||
emailPayload,
|
||||
{
|
||||
headers: {
|
||||
'X-API-Key': process.env.ESPACE_PAIE_API_KEY,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000
|
||||
}
|
||||
);
|
||||
|
||||
const zapierPromise = axios.post(process.env.ZAPIER_WEBHOOK_URL, {
|
||||
Contrat: reference,
|
||||
Type: "autosignature"
|
||||
}).catch(error => {
|
||||
console.error("Erreur lors de l'appel au webhook Zapier :", error);
|
||||
});
|
||||
|
||||
const [espacePaieResponse, _] = await Promise.all([apiPromise, zapierPromise]);
|
||||
|
||||
console.log("✅ E-mail envoyé via l'API Espace Paie:", espacePaieResponse.data);
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify({
|
||||
message: "Traitement du webhook terminé.",
|
||||
emailSent: true,
|
||||
messageId: espacePaieResponse.data.messageId
|
||||
})
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Erreur lors du traitement du webhook :", error);
|
||||
return {
|
||||
statusCode: 500,
|
||||
body: JSON.stringify({
|
||||
message: "Erreur lors du traitement du webhook",
|
||||
error: error.toString()
|
||||
})
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Fonction pour extraire le slug du salarié
|
||||
function extractEmployeeSlug(data) {
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
const employeeData = data.find(sub => sub.role === "Salarié");
|
||||
return employeeData ? employeeData.slug : null;
|
||||
} else if (data.submitters && Array.isArray(data.submitters)) {
|
||||
const employeeData = data.submitters.find(sub => sub.role === "Salarié");
|
||||
return employeeData ? employeeData.slug : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Fonction pour récupérer les données dans DynamoDB
|
||||
async function retrieveDynamoData(documentName) {
|
||||
const params = {
|
||||
TableName: 'DocuSealNotification',
|
||||
Key: { submission_id: documentName }
|
||||
};
|
||||
|
||||
try {
|
||||
const result = await dynamoDB.get(params).promise();
|
||||
return result.Item;
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération des données de DynamoDB :", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Mise à jour Supabase: cddu_contracts (contrat_signe_par_employeur = "Oui") en filtrant par contract_number = reference
|
||||
async function updateSupabaseEmployerSigned(reference) {
|
||||
if (!SUPABASE_URL || !SUPABASE_SERVICE_ROLE) {
|
||||
console.error("SUPABASE_URL ou SUPABASE_SERVICE_ROLE manquant(s) dans les variables d'environnement.");
|
||||
throw new Error("Configuration Supabase incomplète.");
|
||||
}
|
||||
if (!reference) {
|
||||
console.error("Référence vide ou invalide pour la mise à jour Supabase.");
|
||||
throw new Error("Reference manquante pour update Supabase.");
|
||||
}
|
||||
|
||||
const endpoint =
|
||||
`${SUPABASE_URL}/rest/v1/cddu_contracts?contract_number=eq.${encodeURIComponent(reference)}&contrat_signe_par_employeur=neq.Oui`;
|
||||
|
||||
try {
|
||||
const { data, status } = await axios.patch(
|
||||
endpoint,
|
||||
{ contrat_signe_par_employeur: "Oui" },
|
||||
{
|
||||
headers: {
|
||||
apikey: SUPABASE_SERVICE_ROLE,
|
||||
Authorization: `Bearer ${SUPABASE_SERVICE_ROLE}`,
|
||||
'Content-Type': 'application/json',
|
||||
Prefer: 'return=representation'
|
||||
},
|
||||
timeout: 8000
|
||||
}
|
||||
);
|
||||
|
||||
console.log("Mise à jour Supabase (employeur signé) statut:", status, "data:", JSON.stringify(data));
|
||||
return data;
|
||||
} catch (err) {
|
||||
// Log étendu mais sans secrets
|
||||
const status = err.response?.status;
|
||||
const respData = err.response?.data;
|
||||
console.error("Erreur update Supabase:", status, respData || err.message);
|
||||
throw new Error(`Echec update Supabase: ${status || ''} ${respData ? JSON.stringify(respData) : err.message}`);
|
||||
}
|
||||
}
|
||||
130
app/api/emails/signature-salarie/route.ts
Normal file
130
app/api/emails/signature-salarie/route.ts
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { sendUniversalEmailV2, EmailDataV2 } from '@/lib/emailTemplateService';
|
||||
import { ENV } from '@/lib/cleanEnv';
|
||||
|
||||
/**
|
||||
* POST /api/emails/signature-salarie
|
||||
*
|
||||
* Route API appelée par la Lambda postDocuSealSalarie pour envoyer l'email de signature au salarié
|
||||
* Utilise le système universel d'emails v2 avec logging automatique
|
||||
*
|
||||
* Authentification : API Key dans le header X-API-Key
|
||||
*/
|
||||
export async function POST(request: NextRequest) {
|
||||
console.log('=== API Email Signature Salarié ===');
|
||||
|
||||
try {
|
||||
// 1. Vérification de l'authentification via API Key
|
||||
const apiKey = request.headers.get('X-API-Key');
|
||||
const validApiKey = ENV.LAMBDA_API_KEY;
|
||||
|
||||
if (!validApiKey) {
|
||||
console.error('❌ Configuration error: LAMBDA_API_KEY not configured');
|
||||
return NextResponse.json(
|
||||
{ error: 'Server configuration error' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
if (!apiKey || apiKey !== validApiKey) {
|
||||
console.error('❌ Unauthorized: Invalid or missing API key');
|
||||
return NextResponse.json(
|
||||
{ error: 'Unauthorized' },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
console.log('✅ Authentication successful');
|
||||
|
||||
// 2. Récupération et validation des données
|
||||
const data = await request.json();
|
||||
console.log('📦 Données reçues:', {
|
||||
employeeEmail: data.employeeEmail,
|
||||
reference: data.reference,
|
||||
structure: data.structure,
|
||||
firstName: data.firstName,
|
||||
matricule: data.matricule
|
||||
});
|
||||
|
||||
const {
|
||||
employeeEmail,
|
||||
signatureLink,
|
||||
reference,
|
||||
firstName,
|
||||
organizationName,
|
||||
matricule,
|
||||
typecontrat,
|
||||
startDate,
|
||||
profession,
|
||||
productionName,
|
||||
organizationId,
|
||||
contractId
|
||||
} = data;
|
||||
|
||||
// Validation des champs requis
|
||||
if (!employeeEmail || !signatureLink || !reference || !organizationName) {
|
||||
console.error('❌ Champs requis manquants');
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Champs manquants',
|
||||
required: ['employeeEmail', 'signatureLink', 'reference', 'organizationName']
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Préparation des données de l'email
|
||||
const emailData: EmailDataV2 = {
|
||||
firstName: firstName || 'Salarié',
|
||||
organizationName: organizationName,
|
||||
matricule: matricule || 'N/A',
|
||||
contractReference: reference,
|
||||
typecontrat: typecontrat || 'CDDU',
|
||||
startDate: startDate || '',
|
||||
profession: profession || '',
|
||||
productionName: productionName || '',
|
||||
ctaUrl: signatureLink,
|
||||
// Ajout des IDs pour le logging (si disponibles)
|
||||
organizationId: organizationId,
|
||||
contractId: contractId
|
||||
};
|
||||
|
||||
console.log('📧 Préparation de l\'envoi de l\'email:', {
|
||||
to: employeeEmail,
|
||||
type: 'signature-request-salarie',
|
||||
subject: `Signez votre contrat ${organizationName}`
|
||||
});
|
||||
|
||||
// 4. Envoi de l'email via le système universel v2
|
||||
const messageId = await sendUniversalEmailV2({
|
||||
type: 'signature-request-salarie',
|
||||
toEmail: employeeEmail,
|
||||
data: emailData,
|
||||
});
|
||||
|
||||
console.log('✅ Email envoyé avec succès:', {
|
||||
messageId,
|
||||
recipient: employeeEmail,
|
||||
reference
|
||||
});
|
||||
|
||||
// 5. Retour du succès avec le messageId SES
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
messageId,
|
||||
recipient: employeeEmail,
|
||||
reference
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Erreur lors de l\'envoi de l\'email de signature salarié:', error);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Échec de l\'envoi de l\'email',
|
||||
message: error instanceof Error ? error.message : 'Unknown error'
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -47,6 +47,9 @@ export const ENV = {
|
|||
// APIs
|
||||
UPSTREAM_API_BASE: cleanEnv('UPSTREAM_API_BASE'),
|
||||
|
||||
// Sécurité
|
||||
LAMBDA_API_KEY: cleanEnv('LAMBDA_API_KEY'),
|
||||
|
||||
// Autres
|
||||
NODE_ENV: process.env.NODE_ENV
|
||||
};
|
||||
|
|
@ -34,6 +34,7 @@ export type EmailTypeV2 =
|
|||
| 'signature-request'
|
||||
| 'signature-request-employer'
|
||||
| 'signature-request-employee'
|
||||
| 'signature-request-salarie' // Nouveau type pour demande signature salarié (depuis Lambda DocuSeal)
|
||||
| 'bulk-signature-notification' // Nouveau type pour notification de signatures en masse
|
||||
| 'salary-transfer-notification' // Nouveau type pour notification d'appel à virement
|
||||
| 'contribution-notification' // Nouveau type pour notification de cotisations
|
||||
|
|
@ -95,6 +96,9 @@ export interface EmailDataV2 {
|
|||
ticketStatus?: string;
|
||||
userEmail?: string;
|
||||
userMessage?: string;
|
||||
// Ajout des champs pour la signature salarié (depuis Lambda DocuSeal)
|
||||
matricule?: string;
|
||||
typecontrat?: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
|
|
@ -694,6 +698,42 @@ const EMAIL_TEMPLATES_V2: Record<EmailTypeV2, EmailTemplateV2> = {
|
|||
}
|
||||
},
|
||||
|
||||
'signature-request-salarie': {
|
||||
subject: 'Signez votre contrat {{organizationName}}',
|
||||
title: 'Demande de signature électronique',
|
||||
greeting: '{{#if firstName}}Bonjour {{firstName}},{{/if}}',
|
||||
mainMessage: 'Nous vous invitons à signer votre contrat de travail ci-dessous.<br><br>Cliquez sur « Signer le contrat » pour accéder à Odentas Sign. Vous pourrez télécharger votre contrat dès validation de votre signature.',
|
||||
ctaText: 'Signer le contrat',
|
||||
closingMessage: 'Pour toute question, contactez-nous à <a href="mailto:paie@odentas.fr" style="color:#0B5FFF; text-decoration:none;">paie@odentas.fr</a>.',
|
||||
footerText: 'Vous recevez cet e-mail car votre employeur ou futur employeur ({{organizationName}}) est client d\'Odentas Media SAS, pour vous notifier d\'une action sur votre contrat de travail avec cet employeur. Si vous pensez avoir reçu cet e-mail par erreur, merci de contacter notre équipe à l\'adresse paie@odentas.fr.',
|
||||
preheaderText: 'Signature électronique · {{organizationName}} · Signez votre contrat',
|
||||
colors: {
|
||||
headerColor: STANDARD_COLORS.HEADER,
|
||||
titleColor: '#0F172A',
|
||||
buttonColor: STANDARD_COLORS.BUTTON,
|
||||
buttonTextColor: STANDARD_COLORS.BUTTON_TEXT,
|
||||
cardBackgroundColor: '#FFFFFF',
|
||||
cardBorder: '#E5E7EB',
|
||||
cardTitleColor: '#0F172A',
|
||||
alertIndicatorColor: '#22C55E',
|
||||
},
|
||||
infoCard: [
|
||||
{ label: 'Votre employeur', key: 'organizationName' },
|
||||
{ label: 'Votre matricule', key: 'matricule' },
|
||||
],
|
||||
detailsCard: {
|
||||
title: 'Détails du contrat',
|
||||
rows: [
|
||||
{ label: 'Référence', key: 'contractReference' },
|
||||
{ label: 'Type de contrat', key: 'typecontrat' },
|
||||
{ label: 'Employeur', key: 'organizationName' },
|
||||
{ label: 'Début contrat', key: 'startDate' },
|
||||
{ label: 'Poste', key: 'profession' },
|
||||
{ label: 'Production', key: 'productionName' },
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
'bulk-signature-notification': {
|
||||
subject: 'Contrats à signer – {{contractCount}} signature{{#if (gt contractCount 1)}}s{{/if}} en attente',
|
||||
title: 'Contrats en attente de signature',
|
||||
|
|
|
|||
Loading…
Reference in a new issue