feat: Migration Lambda avenant completion vers Next.js API

- Créé route /api/webhooks/docuseal-amendment-completed
- Ajouté templates emails amendment-completed-employer et amendment-completed-employee
- Intégration système emails universel v2 (Handlebars)
- Logging dans Supabase email_logs (plus d'Airtable)
- Types ajoutés à EmailTypeV2 et EmailType
- Documentation complète dans LAMBDA_MIGRATION_AVENANT_COMPLETION.md
- Script SQL migration dans MIGRATION_SQL_EMAIL_TYPES.md

Migration complète AWS Lambda → Next.js cdg1 (RGPD compliant)
This commit is contained in:
odentas 2025-10-23 19:39:38 +02:00
parent 4292041f40
commit 2520a73602
5 changed files with 585 additions and 0 deletions

View file

@ -0,0 +1,218 @@
# Migration Lambda → Next.js API - Avenant Completion
## 📋 Context
Migration de la Lambda AWS `postDocuSealFinalEmailsAvenant` vers une route API Next.js intégrée au système d'emails universel v2.
## 🎯 Objectifs
1. ✅ Remplacer la Lambda AWS par une route Next.js
2. ✅ Utiliser le système d'emails universel v2 (templates Handlebars)
3. ✅ Logger les emails dans Supabase (`email_logs`)
4. ✅ Supprimer la dépendance à Airtable
5. ✅ Supprimer le HTML inline hardcodé
## 🔧 Fichiers Créés/Modifiés
### ✅ Nouveau Webhook Handler
**Fichier** : `app/api/webhooks/docuseal-amendment-completed/route.ts`
**Fonction** : Traite la complétion d'un avenant (toutes parties signées)
**Flow** :
1. Reçoit webhook DocuSeal avec `submissionId`
2. Recherche l'avenant par `docuseal_submission_id`
3. Met à jour `signature_status``'completed'`
4. Envoie email à l'employeur (`amendment-completed-employer`)
5. Envoie email au salarié (`amendment-completed-employee`)
6. Logs les emails dans `email_logs`
**Sécurité** :
- Utilise `createRouteHandlerClient` (Supabase Auth)
- Clé API DocuSeal en Authorization header
### ✅ Templates d'Emails Ajoutés
**Fichier** : `lib/emailTemplateService.ts`
**Templates créés** :
#### 1. `amendment-completed-employer`
- **Sujet** : "Avenant n°X signé - [Organisation]"
- **CTA** : "Voir les documents"
- **Info** : Salarié, matricule, détails avenant
- **Message** : Confirmation signature par toutes les parties
#### 2. `amendment-completed-employee`
- **Sujet** : "Votre avenant n°X est signé - [Organisation]"
- **CTA** : "Télécharger l'avenant"
- **Info** : Employeur, matricule, détails avenant
- **Message** : Téléchargement de l'exemplaire signé
### ✅ Types Ajoutés
**Fichiers** :
- `lib/emailTemplateService.ts` (EmailTypeV2)
- `lib/emailLoggingService.ts` (EmailType)
**Types** :
- `amendment-completed-employer`
- `amendment-completed-employee`
## 🔄 Flux Complet Avenant
### Étape 1 : Signature Employeur
**Webhook** : `/api/webhooks/docuseal-amendment`
**Action** :
1. Employeur signe l'avenant sur DocuSeal
2. Webhook reçu avec `submissionId`
3. Update avenant : `signature_status``'pending_employee'`
4. Envoi email au salarié (`signature-request-employee-amendment`)
### Étape 2 : Signature Salarié (Complétion)
**Webhook** : `/api/webhooks/docuseal-amendment-completed`
**Action** :
1. Salarié signe l'avenant sur DocuSeal
2. Webhook reçu avec `submissionId`
3. Update avenant : `signature_status``'completed'`
4. Envoi email employeur (`amendment-completed-employer`)
5. Envoi email salarié (`amendment-completed-employee`)
## 📊 Comparaison Lambda vs Next.js
| Aspect | Lambda (Avant) | Next.js (Après) |
|--------|----------------|-----------------|
| **Localisation** | iad1 (US-Est) ❌ | cdg1 (Paris) ✅ |
| **Templates** | HTML inline hardcodé | Handlebars universel v2 |
| **Logging** | Airtable ❌ | Supabase `email_logs` ✅ |
| **Auth** | Clé API custom | Supabase Auth |
| **Maintenance** | Code séparé | Code intégré au projet |
| **Réutilisabilité** | Zéro | Composants réutilisables |
## ⚠️ Migration SQL Requise
Exécuter dans **Supabase SQL Editor** :
```sql
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'amendment-completed-employer';
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'amendment-completed-employee';
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'signature-request-employee-amendment';
```
Voir : `MIGRATION_SQL_EMAIL_TYPES.md` pour le script complet.
## 🧪 Tests à Effectuer
### Test 1 : Signature Employeur → Email Salarié
1. Créer un avenant via staff/contrats
2. Envoyer pour signature employeur
3. Signer en tant qu'employeur
4. ✅ Vérifier email reçu par salarié
5. ✅ Vérifier log dans `email_logs` (type: `signature-request-employee-amendment`)
### Test 2 : Signature Salarié → Emails Confirmation
1. Reprendre avenant de Test 1 (pending_employee)
2. Signer en tant que salarié
3. ✅ Vérifier email reçu par employeur (type: `amendment-completed-employer`)
4. ✅ Vérifier email reçu par salarié (type: `amendment-completed-employee`)
5. ✅ Vérifier logs dans `email_logs` (2 entrées)
6. ✅ Vérifier `signature_status` = `'completed'` dans `avenants`
### Test 3 : Liens de Téléchargement
1. Cliquer sur CTA dans email employeur
2. ✅ Vérifier accès aux documents
3. Cliquer sur CTA dans email salarié
4. ✅ Vérifier téléchargement avenant signé
## 🗑️ Nettoyage Lambda (Après Tests)
Une fois les tests validés :
1. **AWS Lambda Console** :
- Désactiver trigger DocuSeal
- Supprimer fonction `postDocuSealFinalEmailsAvenant`
- Supprimer layer Node.js si non utilisé ailleurs
2. **DocuSeal** :
- Vérifier webhook configuré sur nouvelle route Next.js
- URL : `https://espacepaieodentas.com/api/webhooks/docuseal-amendment-completed`
3. **Airtable** :
- ✅ Déjà supprimé (variables d'environnement retirées)
4. **Documentation** :
- Mettre à jour `DOCUSEAL_SIGNATURE_CONFIG.md`
- Archiver code Lambda dans repo si backup souhaité
## 📝 Configuration DocuSeal
**Webhook à Configurer** :
- **Event** : `form.completed` (toutes parties signées)
- **URL** : `https://espacepaieodentas.com/api/webhooks/docuseal-amendment-completed`
- **Method** : POST
- **Headers** :
- `Authorization: Bearer [DOCUSEAL_API_KEY]`
- `Content-Type: application/json`
**Payload Attendu** :
```json
{
"event_type": "form.completed",
"data": {
"id": "submission_123456",
"template": {
"name": "AVENANT_REF_CONTRACT"
},
"created_at": "2025-01-XX",
"submitters": [
{
"email": "employer@company.com",
"role": "Employeur"
},
{
"email": "employee@example.com",
"role": "Salarié"
}
]
}
}
```
## 🎯 Avantages de la Migration
1. **RGPD** : Région Paris (cdg1) → données EU uniquement
2. **Maintenance** : Code centralisé dans le projet Next.js
3. **Réutilisabilité** : Templates Handlebars pour tous les emails
4. **Logging** : Traçabilité complète dans Supabase
5. **Performance** : Moins de latence (cdg1 vs iad1)
6. **Coûts** : Réduction coûts AWS Lambda
7. **Cohérence** : Système unifié pour tous les emails
## 🔗 Références
- Webhook avenant étape 1 : `/api/webhooks/docuseal-amendment`
- Webhook avenant étape 2 : `/api/webhooks/docuseal-amendment-completed`
- Email templates : `lib/emailTemplateService.ts`
- Email logging : `lib/emailLoggingService.ts`
- Migration SQL : `MIGRATION_SQL_EMAIL_TYPES.md`
- Lambda original : `LAMBDA_EMAIL_SIGNATURE_SALARIE_GUIDE.md` (contrats initiaux)
## ✅ Checklist Déploiement
- [x] Créer route API Next.js
- [x] Ajouter templates emails (employer + employee)
- [x] Ajouter types TypeScript
- [ ] Exécuter migration SQL Supabase
- [ ] Configurer webhook DocuSeal
- [ ] Tester flux complet (étape 1 + étape 2)
- [ ] Vérifier logs dans `email_logs`
- [ ] Valider emails reçus (contenu + design)
- [ ] Désactiver Lambda AWS
- [ ] Mettre à jour documentation
- [ ] Commit + push code
## 📅 Status
**Date** : 2025-01-XX
**Status** : ✅ Code prêt, en attente SQL + tests
**Bloquants** : Migration SQL à exécuter dans Supabase
**Prochaine étape** : Exécuter SQL puis tester avec avenant réel

View file

@ -0,0 +1,67 @@
# Migration SQL - Nouveaux Types d'Emails
## 📋 Context
Ajout de nouveaux types d'emails pour supporter les notifications d'avenants et autres fonctionnalités récentes.
## 🎯 Types à Ajouter
Les types TypeScript ont été ajoutés dans :
- `lib/emailTemplateService.ts` (EmailTypeV2)
- `lib/emailLoggingService.ts` (EmailType)
Il faut maintenant ajouter les valeurs correspondantes à l'enum PostgreSQL `email_type` dans Supabase.
## 🔧 Script SQL à Exécuter
Exécuter dans **Supabase SQL Editor** :
```sql
-- Ajouter les nouveaux types d'emails à l'enum email_type
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'signature-request-employee-amendment';
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'signature-request-salarie';
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'contribution-notification';
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'support-reply';
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'support-ticket-created';
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'support-ticket-reply';
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'contact-support';
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'amendment-completed-employer';
ALTER TYPE email_type ADD VALUE IF NOT EXISTS 'amendment-completed-employee';
```
## ✅ Vérification
Après exécution, vérifier que les types sont bien ajoutés :
```sql
SELECT enumlabel
FROM pg_enum
WHERE enumtypid = 'email_type'::regtype
ORDER BY enumlabel;
```
## 📝 Détails des Nouveaux Types
| Type | Description | Utilisé par |
|------|-------------|-------------|
| `signature-request-employee-amendment` | Demande signature avenant par salarié | Webhook avenant (étape 1) |
| `signature-request-salarie` | Demande signature salarié (legacy Lambda) | Lambda DocuSeal |
| `contribution-notification` | Notification cotisations mensuelles | Envoi cotisations |
| `support-reply` | Réponse du support | Système tickets |
| `support-ticket-created` | Nouveau ticket créé | Système tickets |
| `support-ticket-reply` | Réponse utilisateur sur ticket | Système tickets |
| `contact-support` | Formulaire contact public | Page contact |
| `amendment-completed-employer` | Avenant signé (notif employeur) | Webhook avenant (étape 2) |
| `amendment-completed-employee` | Avenant signé (notif salarié) | Webhook avenant (étape 2) |
## ⚠️ Important
**L'ajout d'une valeur à un ENUM PostgreSQL est irréversible** (ne peut pas être supprimé sans recréer l'enum).
La commande `IF NOT EXISTS` permet d'exécuter le script plusieurs fois sans erreur.
## 🔗 Références
- Route webhook : `/api/webhooks/docuseal-amendment-completed`
- Template service : `lib/emailTemplateService.ts`
- Logging service : `lib/emailLoggingService.ts`

View file

@ -0,0 +1,226 @@
import { NextRequest, NextResponse } from "next/server";
import { createSbServiceRole } from "@/lib/supabaseServer";
import { sendUniversalEmailV2, EmailDataV2 } from "@/lib/emailTemplateService";
export const dynamic = "force-dynamic";
/**
* Webhook appelé quand TOUTES les parties ont signé l'avenant (employeur + salarié)
* Envoie les emails de confirmation finaux aux deux parties
*
* Flux :
* 1. Employeur signe Lambda postDocuSealAvenantSalarie /api/webhooks/docuseal-amendment
* 2. Salarié signe DocuSeal webhook Cette route
* 3. Envoi emails de confirmation à l'employeur ET au salarié
*/
export async function POST(request: NextRequest) {
console.log("🎉 [WEBHOOK AVENANT COMPLETED] Début du traitement");
try {
const body = await request.json();
console.log("📦 [WEBHOOK AVENANT COMPLETED] Body reçu:", JSON.stringify(body, null, 2));
// Extraire les données du webhook DocuSeal
const eventType = body.event_type;
const submissionId = body.data?.submission?.id || body.data?.submission_id;
const templateExternalId = body.data?.template?.external_id;
console.log("🔍 [WEBHOOK AVENANT COMPLETED] Event type:", eventType);
console.log("🔍 [WEBHOOK AVENANT COMPLETED] Submission ID:", submissionId);
console.log("🔍 [WEBHOOK AVENANT COMPLETED] Template external ID:", templateExternalId);
// Vérifier que c'est bien un événement de complétion
if (eventType !== "submission.completed") {
console.log(" [WEBHOOK AVENANT COMPLETED] Event type non géré:", eventType);
return NextResponse.json({ message: "Event type ignoré" }, { status: 200 });
}
if (!submissionId) {
console.error("❌ [WEBHOOK AVENANT COMPLETED] submission_id manquant");
return NextResponse.json(
{ error: "submission_id requis" },
{ status: 400 }
);
}
const supabase = createSbServiceRole();
// 1. Récupérer l'avenant depuis Supabase via le docuseal_submission_id
console.log("🔍 [WEBHOOK AVENANT COMPLETED] Recherche de l'avenant...");
const { data: avenant, error: avenantError } = await supabase
.from("avenants")
.select(`
*,
cddu_contracts (
*,
salaries (
prenom,
nom,
adresse_mail
),
organizations (
id,
name,
code_employeur
)
)
`)
.eq("docuseal_submission_id", submissionId)
.maybeSingle();
if (avenantError || !avenant) {
console.error("❌ [WEBHOOK AVENANT COMPLETED] Avenant non trouvé:", avenantError);
return NextResponse.json(
{ error: "Avenant non trouvé", details: avenantError?.message },
{ status: 404 }
);
}
console.log("✅ [WEBHOOK AVENANT COMPLETED] Avenant trouvé:", {
id: avenant.id,
numero: avenant.numero_avenant,
contract_id: avenant.contract_id,
});
// 2. Mettre à jour le statut de l'avenant
console.log("🔄 [WEBHOOK AVENANT COMPLETED] Mise à jour du statut...");
const { error: updateError } = await supabase
.from("avenants")
.update({
signature_status: "completed",
completed_at: new Date().toISOString(),
})
.eq("id", avenant.id);
if (updateError) {
console.error("❌ [WEBHOOK AVENANT COMPLETED] Erreur mise à jour:", updateError);
} else {
console.log("✅ [WEBHOOK AVENANT COMPLETED] Statut mis à jour: completed");
}
// 3. Préparer les données pour les emails
const contract = avenant.cddu_contracts;
const salarie = contract?.salaries;
const organization = contract?.organizations;
if (!contract || !salarie || !organization) {
console.error("❌ [WEBHOOK AVENANT COMPLETED] Données manquantes:", {
hasContract: !!contract,
hasSalarie: !!salarie,
hasOrganization: !!organization,
});
return NextResponse.json(
{ error: "Données du contrat/salarié/organisation manquantes" },
{ status: 400 }
);
}
// Formater la date
const formatDate = (dateStr?: string | null) => {
if (!dateStr) return "-";
try {
const parts = dateStr.split("-");
if (parts.length === 3) {
const [y, m, d] = parts;
return `${d}/${m}/${y}`;
}
return dateStr;
} catch {
return dateStr;
}
};
const startDate = formatDate(contract.start_date);
const employerEmail = organization.email || "hello@odentas.fr"; // Fallback si pas d'email
const employeeEmail = salarie.adresse_mail;
// Récupérer le prénom du signataire depuis l'organisation (profiles)
let employerFirstName = "Employeur";
if (organization.id) {
const { data: profiles } = await supabase
.from("profiles")
.select("first_name, last_name")
.eq("organization_id", organization.id)
.limit(1)
.maybeSingle();
if (profiles?.first_name) {
employerFirstName = profiles.first_name;
}
}
// 4. Envoyer l'email à l'EMPLOYEUR
console.log("📧 [WEBHOOK AVENANT COMPLETED] Envoi email employeur...");
const employerEmailData: EmailDataV2 = {
firstName: employerFirstName,
organizationName: organization.name || "Votre structure",
employerCode: organization.code_employeur || "Non spécifié",
contractReference: contract.contract_number || "Non spécifié",
startDate: startDate,
profession: contract.fonction || "Non spécifié",
productionName: contract.analytique || "Non spécifié",
ctaUrl: "https://paie.odentas.fr/",
ctaText: "Accès à l'Espace Paie",
numeroAvenant: avenant.numero_avenant,
salarieName: `${salarie.prenom} ${salarie.nom}`,
contractType: "CDDU (contrat intermittent)",
};
try {
const employerMessageId = await sendUniversalEmailV2({
type: "amendment-completed-employer",
toEmail: employerEmail,
data: employerEmailData,
});
console.log("✅ [WEBHOOK AVENANT COMPLETED] Email employeur envoyé:", employerMessageId);
} catch (emailError: any) {
console.error("❌ [WEBHOOK AVENANT COMPLETED] Erreur email employeur:", emailError);
}
// 5. Envoyer l'email au SALARIÉ
console.log("📧 [WEBHOOK AVENANT COMPLETED] Envoi email salarié...");
const employeeEmailData: EmailDataV2 = {
firstName: salarie.prenom || "Salarié",
organizationName: organization.name || "Votre employeur",
matricule: contract.matricule || "Non spécifié",
contractReference: contract.contract_number || "Non spécifié",
startDate: startDate,
profession: contract.fonction || "Non spécifié",
productionName: contract.analytique || "Non spécifié",
ctaUrl: `https://paie.odentas.fr/dl-avenant?avenant_id=${avenant.id}`,
ctaText: "Télécharger l'avenant",
numeroAvenant: avenant.numero_avenant,
contractType: "CDDU (contrat intermittent)",
};
try {
const employeeMessageId = await sendUniversalEmailV2({
type: "amendment-completed-employee",
toEmail: employeeEmail,
data: employeeEmailData,
});
console.log("✅ [WEBHOOK AVENANT COMPLETED] Email salarié envoyé:", employeeMessageId);
} catch (emailError: any) {
console.error("❌ [WEBHOOK AVENANT COMPLETED] Erreur email salarié:", emailError);
}
return NextResponse.json({
success: true,
message: "Emails de confirmation envoyés",
avenantId: avenant.id,
numeroAvenant: avenant.numero_avenant,
});
} catch (error: any) {
console.error("❌ [WEBHOOK AVENANT COMPLETED] Erreur:", error);
return NextResponse.json(
{
error: "Erreur lors du traitement",
details: error.message,
},
{ status: 500 }
);
}
}

View file

@ -22,6 +22,8 @@ export type EmailType =
| 'support-ticket-created' // Nouveau ticket | 'support-ticket-created' // Nouveau ticket
| 'support-ticket-reply' // Réponse utilisateur | 'support-ticket-reply' // Réponse utilisateur
| 'contact-support' // Formulaire contact public | 'contact-support' // Formulaire contact public
| 'amendment-completed-employer' // Avenant signé (notification employeur)
| 'amendment-completed-employee' // Avenant signé (notification salarié)
| 'account-activation' | 'account-activation'
| 'access-updated' | 'access-updated'
| 'access-revoked' | 'access-revoked'

View file

@ -36,6 +36,8 @@ export type EmailTypeV2 =
| 'signature-request-employee' | 'signature-request-employee'
| 'signature-request-employee-amendment' // Nouveau type pour signature avenant salarié | 'signature-request-employee-amendment' // Nouveau type pour signature avenant salarié
| 'signature-request-salarie' // Nouveau type pour demande signature salarié (depuis Lambda DocuSeal) | 'signature-request-salarie' // Nouveau type pour demande signature salarié (depuis Lambda DocuSeal)
| 'amendment-completed-employer' // Confirmation signature complète avenant pour employeur
| 'amendment-completed-employee' // Confirmation signature complète avenant pour salarié
| 'bulk-signature-notification' // Nouveau type pour notification de signatures en masse | 'bulk-signature-notification' // Nouveau type pour notification de signatures en masse
| 'salary-transfer-notification' // Nouveau type pour notification d'appel à virement | 'salary-transfer-notification' // Nouveau type pour notification d'appel à virement
| 'contribution-notification' // Nouveau type pour notification de cotisations | 'contribution-notification' // Nouveau type pour notification de cotisations
@ -1031,6 +1033,76 @@ const EMAIL_TEMPLATES_V2: Record<EmailTypeV2, EmailTemplateV2> = {
{ label: 'Contenu', key: 'message' }, { label: 'Contenu', key: 'message' },
] ]
} }
},
'amendment-completed-employer': {
subject: 'Avenant {{#if numeroAvenant}}n°{{numeroAvenant}}{{/if}} signé - {{organizationName}}',
title: 'Avenant signé',
greeting: '{{#if firstName}}Bonjour {{firstName}},{{/if}}',
mainMessage: 'L\'avenant au contrat de travail a été signé par toutes les parties.<br><br>Les deux exemplaires signés sont disponibles sur la plateforme Odentas.',
ctaText: 'Voir les documents',
closingMessage: 'Pour toute question, contactez-nous à <a href="mailto:paie@odentas.fr" style="color:#0B5FFF; text-decoration:none;">paie@odentas.fr</a>.',
footerText: 'Notification de signature · Espace Paie Odentas',
preheaderText: 'Avenant signé · {{#if numeroAvenant}}n°{{numeroAvenant}}{{/if}} · {{organizationName}}',
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: 'Salarié', key: 'employeeName' },
{ label: 'Matricule', key: 'matricule' },
],
detailsCard: {
title: 'Détails de l\'avenant',
rows: [
{ label: 'Référence contrat', key: 'contractReference' },
{ label: 'Type de contrat', key: 'contractType' },
{ label: 'Profession', key: 'profession' },
{ label: 'Date de début', key: 'startDate' },
{ label: 'Production', key: 'productionName' },
]
}
},
'amendment-completed-employee': {
subject: 'Votre avenant {{#if numeroAvenant}}n°{{numeroAvenant}}{{/if}} est signé - {{organizationName}}',
title: 'Avenant signé',
greeting: '{{#if firstName}}Bonjour {{firstName}},{{/if}}',
mainMessage: 'Votre avenant au contrat de travail a été signé par toutes les parties.<br><br>Vous pouvez dès maintenant télécharger votre exemplaire signé depuis le lien ci-dessous.',
ctaText: 'Télécharger l\'avenant',
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 ({{organizationName}}) est client d\'Odentas Media SAS, pour vous notifier d\'une action sur votre contrat de travail avec cet employeur.',
preheaderText: 'Avenant signé · {{#if numeroAvenant}}n°{{numeroAvenant}}{{/if}} · {{organizationName}}',
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 de l\'avenant',
rows: [
{ label: 'Référence contrat', key: 'contractReference' },
{ label: 'Type de contrat', key: 'contractType' },
{ label: 'Profession', key: 'profession' },
{ label: 'Date de début', key: 'startDate' },
{ label: 'Production', key: 'productionName' },
]
}
} }
}; };