# Signatures Multiples avec /Name et /Reason - Odentas Sign

## 📋 Concept

Quand plusieurs personnes signent un document via Odentas Sign (employeur puis salarié), **chaque signature est techniquement signée par Odentas** (avec le certificat KMS), mais avec des métadonnées personnalisées indiquant **pour qui** la signature a été faite.

C'est exactement ce que fait DocuSeal : quand vous ouvrez un PDF dans Adobe, vous voyez "DocuSeal" comme signataire technique, mais les champs `/Name` et `/Reason` indiquent le vrai signataire.

## 🔑 Architecture

### Tables Supabase utilisées

**Pas besoin de nouvelles tables !** Votre système existant est parfait :

1. **`sign_requests`** : La demande de signature
2. **`signers`** : Les signataires (Employeur + Salarié)
   - **NOUVELLES colonnes** :
     - `signature_name` : Nom affiché dans la signature (`/Name`)
     - `signature_reason` : Raison de la signature (`/Reason`)
     - `signature_location` : Lieu (`/Location`)
     - `signature_contact_info` : Contact (`/ContactInfo`)
3. **`sign_positions`** : Où placer les signatures
4. **`sign_events`** : Audit trail
5. **`sign_assets`** : Document final scellé

### Workflow de signature

```
1. Création de la demande
   ├─ sign_requests (status: pending)
   ├─ signers[0] (Employeur, signature_name: "Entreprise SARL", signature_reason: "Signature employeur")
   └─ signers[1] (Salarié, signature_name: "Jean Dupont", signature_reason: "Signature salarié")

2. Employeur signe (interface graphique)
   ├─ signers[0].signed_at = now()
   └─ signers[0].signature_image_s3 = "signatures/req-123/employeur.png"

3. Salarié signe (interface graphique)
   ├─ signers[1].signed_at = now()
   └─ signers[1].signature_image_s3 = "signatures/req-123/salarie.png"

4. Scellement PAdES (API /seal-document)
   ├─ Lambda sign avec signers[0] → /Name="Entreprise SARL" /Reason="Signature employeur"
   │  └─ PDF devient: signed-pades/contract-123-step1.pdf (1 signature PAdES)
   │
   └─ Lambda sign avec signers[1] → /Name="Jean Dupont" /Reason="Signature salarié"
      └─ PDF final: signed-pades/contract-123-final.pdf (2 signatures PAdES)

5. Résultat
   └─ sign_assets.signed_pdf_s3_key = "signed-pades/contract-123-final.pdf"
```

## 🔧 Modifications nécessaires

### 1. Migration Supabase
**Fichier** : `supabase/migrations/20251029_add_signature_metadata_to_signers.sql`

```sql
ALTER TABLE signers
ADD COLUMN signature_name TEXT NOT NULL,
ADD COLUMN signature_reason TEXT NOT NULL,
ADD COLUMN signature_location TEXT DEFAULT 'France',
ADD COLUMN signature_contact_info TEXT;
```

### 2. Lambda `odentas-pades-sign`
**Input modifié** :
```javascript
{
  "s3Key": "source/contract-123.pdf",
  "signatureMetadata": {
    "name": "Entreprise SARL",           // → /Name dans le dictionnaire de signature
    "reason": "Signature employeur",     // → /Reason
    "location": "Paris, France",         // → /Location
    "contactInfo": "contact@entreprise.com" // → /ContactInfo
  },
  "signerOrder": 1  // 1ère signature ou 2ème
}
```

**Dans la Lambda**, lors de la création du dictionnaire de signature :
```javascript
const signatureDict = {
  Type: 'Sig',
  Filter: 'Adobe.PPKLite',
  SubFilter: 'ETSI.CAdES.detached',
  Name: signatureMetadata.name,        // ← ICI
  Reason: signatureMetadata.reason,    // ← ICI
  Location: signatureMetadata.location, // ← ICI
  ContactInfo: signatureMetadata.contactInfo, // ← ICI
  M: `D:${timestamp}`,
  ByteRange: [0, 0, 0, 0],
  Contents: '<signature_hex>'
};
```

### 3. API Route `/api/odentas-sign/seal-document`
**Fichier** : `app/api/odentas-sign/seal-document/route.ts`

Cette route :
1. Récupère tous les `signers` ayant signé
2. Les trie par ordre chronologique (`signed_at`)
3. Appelle la Lambda séquentiellement pour chaque signataire
4. Chaque appel Lambda utilise les métadonnées du signataire (`signature_name`, `signature_reason`)
5. Le PDF de sortie d'une signature devient l'entrée de la suivante
6. Enregistre le PDF final dans `sign_assets`

### 4. Quand créer les signataires
**Dans** : `app/api/odentas-sign/requests/create/route.ts`

```typescript
const signersData = body.signers.map((s) => ({
  request_id: signRequest.id,
  role: s.role,
  name: s.name,
  email: s.email,
  // Nouvelles colonnes
  signature_name: s.name, // ou entreprise.name pour l'employeur
  signature_reason: `Signature du contrat ${signRequest.ref} en tant que ${s.role.toLowerCase()}`,
  signature_location: 'France',
  signature_contact_info: s.email,
}));
```

## 📊 Résultat dans Adobe Acrobat

Quand vous ouvrez le PDF final dans Adobe :

```
┌─────────────────────────────────────────┐
│ Signatures du document (2)              │
├─────────────────────────────────────────┤
│ ✓ Odentas Media SAS                     │ ← Certificat technique
│   Nom: Entreprise SARL                  │ ← /Name
│   Raison: Signature employeur           │ ← /Reason
│   Lieu: Paris, France                   │ ← /Location
│   Contact: contact@entreprise.com       │ ← /ContactInfo
│   Date: 29/10/2025 14:30:00            │
├─────────────────────────────────────────┤
│ ✓ Odentas Media SAS                     │ ← Même certificat
│   Nom: Jean Dupont                      │ ← /Name différent
│   Raison: Signature salarié             │ ← /Reason différent
│   Lieu: France                          │
│   Contact: jean.dupont@example.com      │
│   Date: 29/10/2025 15:45:00            │
└─────────────────────────────────────────┘
```

## 🔄 Flux complet

```mermaid
sequenceDiagram
    participant UI as Interface Web
    participant API as API Odentas Sign
    participant DB as Supabase
    participant Lambda as Lambda PAdES Sign
    participant S3 as AWS S3

    UI->>API: POST /requests/create
    API->>DB: INSERT sign_requests
    API->>DB: INSERT signers (avec signature_name/reason)
    API->>S3: Upload PDF source
    
    UI->>API: Employeur signe (interface)
    API->>DB: UPDATE signers[0].signed_at
    API->>S3: Upload signature image
    
    UI->>API: Salarié signe (interface)
    API->>DB: UPDATE signers[1].signed_at
    API->>S3: Upload signature image
    
    UI->>API: POST /seal-document
    API->>DB: SELECT signers ORDER BY signed_at
    
    loop Pour chaque signataire
        API->>Lambda: Invoke avec signature_metadata
        Lambda->>S3: GET PDF (source ou précédent)
        Lambda->>Lambda: Ajouter signature PAdES
        Lambda->>S3: PUT PDF signé
        Lambda-->>API: signedS3Key
    end
    
    API->>DB: INSERT sign_assets (PDF final)
    API->>DB: UPDATE sign_requests (status: completed)
    API-->>UI: Document scellé
```

## ✅ Avantages

1. **Pas de nouvelles tables** : Réutilise `signers` existant
2. **Flexible** : Peut gérer 2, 3 ou N signatures
3. **Conforme PAdES** : Chaque signature est indépendante et valide
4. **Audit trail** : `sign_events` trace tout le processus
5. **Compatible Adobe** : Affiche correctement les noms dans Adobe Acrobat
6. **Identique DocuSeal** : Même principe technique

## 🎯 Prochaines étapes

1. ✅ Appliquer la migration Supabase
2. ⏳ Modifier la Lambda pour accepter `signatureMetadata`
3. ⏳ Tester avec un contrat CDDU
4. ⏳ Vérifier dans Adobe que `/Name` et `/Reason` apparaissent correctement
5. ⏳ Intégrer l'appel à `/seal-document` dans votre workflow existant

## 📝 Notes

- Le **certificat est toujours Odentas** (émis par AWS KMS)
- Les **métadonnées changent** pour chaque signataire
- Les signatures sont **appliquées séquentiellement** (importante pour la validité)
- Chaque signature **englobe la précédente** (signature incrémentale PAdES)
