espace-paie-odentas/ODENTAS_SIGN_TEST_GUIDE.md
odentas b790faf12c feat: Implémentation complète du système Odentas Sign
- Remplacement de DocuSeal par solution souveraine Odentas Sign
- Système d'authentification OTP pour signataires (bcryptjs + JWT)
- 8 routes API: send-otp, verify-otp, sign, pdf-url, positions, status, webhook, signers
- Interface moderne avec canvas de signature et animations (framer-motion, confetti)
- Système de templates pour auto-détection des positions de signature (CDDU, RG, avenants)
- PDF viewer avec @react-pdf-viewer (compatible Next.js)
- Stockage S3: source/, signatures/, evidence/, signed/, certs/
- Tables Supabase: sign_requests, signers, sign_positions, sign_events, sign_assets
- Evidence bundle automatique (JSON metadata + timestamps)
- Templates emails: OTP et completion
- Scripts Lambda prêts: pades-sign (KMS seal) et tsaStamp (RFC3161)
- Mode test détecté automatiquement (emails whitelist)
- Tests complets avec PDF CDDU réel (2 signataires)
2025-10-27 19:03:07 +01:00

9.3 KiB

Guide de Test - Odentas Sign

Ce guide vous permet de tester Odentas Sign sans déclencher Odentas Seal, pour valider le workflow complet de signature électronique en environnement de développement.

🧪 Mode Test

Le système détecte automatiquement le mode test quand :

  • La référence du contrat commence par TEST-
  • Le PDF source est dans source/test/
  • Les emails contiennent test@ ou @example.com

En mode test :

  • Création de la demande de signature
  • Authentification OTP (code affiché dans les logs)
  • Capture et upload de la signature
  • Bundle de preuves (evidence)
  • Scellage PAdES désactivé
  • Horodatage TSA désactivé
  • Archivage Object Lock désactivé
  • Envoi d'emails désactivé

🚀 Étape 1 : Créer une demande de test

Option A : Via l'API de test (recommandé)

curl -X POST http://localhost:3000/api/odentas-sign/test/create-mock \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Contrat CDDU Test",
    "signerName": "Marie Test",
    "signerEmail": "marie.test@example.com"
  }'

Réponse :

{
  "success": true,
  "test_mode": true,
  "request": {
    "id": "xxx",
    "ref": "TEST-...",
    "title": "Contrat CDDU Test",
    "status": "pending"
  },
  "signers": [
    {
      "signerId": "yyy",
      "role": "Employeur",
      "name": "Jean Dupont (Test)",
      "email": "employeur-test@example.com",
      "signatureUrl": "http://localhost:3000/signer/xxx/yyy"
    },
    {
      "signerId": "zzz",
      "role": "Salarié",
      "name": "Marie Test",
      "email": "marie.test@example.com",
      "signatureUrl": "http://localhost:3000/signer/xxx/zzz"
    }
  ]
}

Option B : Via l'API normale avec un vrai contrat

Si vous avez déjà un PDF uploadé dans S3 :

curl -X POST http://localhost:3000/api/odentas-sign/requests/create \
  -H "Content-Type: application/json" \
  -d '{
    "contractId": "votre-contract-id",
    "contractRef": "TEST-2025-0001",
    "pdfS3Key": "source/test/contrat-test.pdf",
    "title": "Contrat de travail CDDU",
    "signers": [
      {
        "role": "Employeur",
        "name": "Votre Nom",
        "email": "vous-test@example.com"
      },
      {
        "role": "Salarié",
        "name": "Salarié Test",
        "email": "salarie-test@example.com"
      }
    ],
    "positions": [
      {
        "role": "Employeur",
        "page": 1,
        "x": 100,
        "y": 650,
        "w": 200,
        "h": 60
      },
      {
        "role": "Salarié",
        "page": 1,
        "x": 350,
        "y": 650,
        "w": 200,
        "h": 60
      }
    ]
  }'

🔐 Étape 2 : Tester le flux de signature

2.1. Ouvrir l'URL de signature

Utilisez l'URL retournée dans signers[].signatureUrl.

Note : L'interface frontend n'existe pas encore, donc pour l'instant on teste uniquement les APIs.

2.2. Demander un code OTP

curl -X POST http://localhost:3000/api/odentas-sign/signers/[SIGNER_ID]/send-otp

Réponse :

{
  "success": true,
  "test_mode": true,
  "otp_code_in_logs": true,
  "message": "Mode test : le code OTP est affiché dans les logs serveur",
  "expires_at": "2025-10-27T15:30:00.000Z"
}

⚠️ Important : Le code OTP apparaît dans les logs serveur (terminal où Next.js tourne) :

[OTP] 🧪 MODE TEST détecté
[OTP] ========================================
[OTP] 🔐 CODE OTP POUR marie.test@example.com:
[OTP] ➡️  123456
[OTP] ========================================

2.3. Vérifier le code OTP

curl -X POST http://localhost:3000/api/odentas-sign/signers/[SIGNER_ID]/verify-otp \
  -H "Content-Type: application/json" \
  -d '{"otp": "123456"}'

Réponse :

{
  "success": true,
  "sessionToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "signer": {
    "id": "xxx",
    "name": "Marie Test",
    "email": "marie.test@example.com",
    "role": "Salarié"
  },
  "request": {
    "id": "yyy",
    "ref": "TEST-...",
    "title": "Contrat CDDU Test"
  }
}

Copiez le sessionToken pour l'étape suivante.

2.4. Enregistrer la signature

Créez une image de signature en base64 (pour tester, voici un petit carré rouge) :

# Image 100x50 pixels, carré rouge simple
SIGNATURE_B64="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAyCAYAAACqNX6+AAAABmJLR0QA/wD/AP+gvaeTAAAAeklEQVR4nO3QMQEAAAjAMMC/52ECvlRA00ASAgECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQcNkFzQABOWLnlYwAAAAASUVORK5CYII="

curl -X POST http://localhost:3000/api/odentas-sign/signers/[SIGNER_ID]/sign \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer [SESSION_TOKEN]" \
  -d "{
    \"signatureImageBase64\": \"$SIGNATURE_B64\",
    \"consentText\": \"Je consens à signer électroniquement ce document.\"
  }"

Réponse :

{
  "success": true,
  "message": "Signature enregistrée avec succès",
  "signed_at": "2025-10-27T15:25:00.000Z",
  "all_signed": false,
  "signer": {
    "id": "xxx",
    "name": "Marie Test",
    "role": "Salarié"
  }
}

2.5. Signer avec le deuxième signataire

Répétez les étapes 2.2 à 2.4 avec le deuxième signerId.

Quand le dernier signataire signe, "all_signed": true et le webhook de completion est déclenché.

📊 Étape 3 : Vérifier les résultats

3.1. Vérifier le statut de la demande

curl http://localhost:3000/api/odentas-sign/requests/[REQUEST_ID]

Réponse :

{
  "success": true,
  "request": {
    "id": "xxx",
    "ref": "TEST-...",
    "status": "completed",
    "progress": {
      "total": 2,
      "signed": 2,
      "percentage": 100
    }
  },
  "signers": [
    {
      "id": "yyy",
      "role": "Employeur",
      "signed_at": "2025-10-27T15:20:00.000Z",
      "signature_image_s3": "signatures/xxx/yyy.png"
    },
    {
      "id": "zzz",
      "role": "Salarié",
      "signed_at": "2025-10-27T15:25:00.000Z",
      "signature_image_s3": "signatures/xxx/zzz.png"
    }
  ]
}

3.2. Vérifier dans Supabase

Allez dans Supabase et vérifiez les tables :

sign_requests

SELECT * FROM sign_requests WHERE ref LIKE 'TEST-%' ORDER BY created_at DESC;

signers

SELECT * FROM signers WHERE request_id = '[REQUEST_ID]';

sign_events

SELECT * FROM sign_events WHERE request_id = '[REQUEST_ID]' ORDER BY ts ASC;

sign_assets

SELECT * FROM sign_assets WHERE request_id = '[REQUEST_ID]';

3.3. Vérifier dans S3

Le bucket odentas-sign doit contenir :

odentas-sign/
├── source/test/
│   └── TEST-xxx.pdf           # PDF source de test
├── signatures/
│   └── [request_id]/
│       ├── [signer1_id].png   # Signature employeur
│       └── [signer2_id].png   # Signature salarié
└── evidence/
    └── TEST-xxx.json          # Bundle de preuves

📋 Logs attendus

Dans votre terminal Next.js, vous devriez voir :

[TEST] PDF de test créé: source/test/TEST-xxx.pdf
[CREATE REQUEST] Création demande: TEST-xxx
[OTP] 🧪 MODE TEST détecté
[OTP] 🔐 CODE OTP POUR employeur-test@example.com: 123456
[OTP] ✅ Mode test - Code affiché dans les logs
[SIGN] Enregistrement signature pour employeur-test@example.com...
[SIGN] ✅ Image uploadée: signatures/xxx/yyy.png
[SIGN] ✅ Signataire mis à jour
[SIGN] 🎉 Tous les signataires ont signé !
[WEBHOOK COMPLETION] 🧪 MODE TEST détecté - scellage PAdES désactivé
[WEBHOOK] 🧪 MODE TEST : Scellage PAdES/TSA/Archive SAUTE
[WEBHOOK COMPLETION] ✅ Traitement terminé pour TEST-xxx (MODE TEST)

🧹 Nettoyage après test

Pour nettoyer les données de test :

-- Supprimer les demandes de test (cascade sur signers, positions, events)
DELETE FROM sign_requests WHERE ref LIKE 'TEST-%';

-- Supprimer les assets de test
DELETE FROM sign_assets WHERE request_id IN (
  SELECT id FROM sign_requests WHERE ref LIKE 'TEST-%'
);

Dans S3, supprimer manuellement :

  • source/test/
  • signatures/[request_ids de test]/
  • evidence/TEST-*.json

🎯 Checklist de validation

  • Création de demande de test réussie
  • Code OTP visible dans les logs
  • Vérification OTP réussie avec session token
  • Upload de la signature réussie
  • Images de signature présentes dans S3
  • Statut completed après signature complète
  • Logs confirment le mode test (pas de scellage)
  • Evidence bundle créé dans S3
  • Tables Supabase cohérentes
  • Événements d'audit enregistrés

⏭️ Prochaine étape

Une fois les APIs validées, vous pourrez :

  1. Créer l'interface frontend (/app/signer/[requestId]/[signerId]/page.tsx)
  2. Intégrer avec vos contrats existants
  3. Créer la Lambda d'orchestration pour le scellage
  4. Activer le mode production (sans TEST-)

🐛 Dépannage

Le code OTP n'apparaît pas dans les logs

  • Vérifiez que l'email contient test@ ou @example.com
  • Ou que la ref commence par TEST-

Erreur "Session invalide"

  • Le JWT expire après 30 minutes
  • Redemandez un OTP et re-vérifiez

Erreur S3

  • Vérifiez que le bucket odentas-sign existe
  • Vérifiez les credentials AWS dans .env.local

Erreur Supabase

  • Vérifiez que les tables existent (voir définitions dans README)
  • Vérifiez les RLS policies

Dernière mise à jour : 27 octobre 2025