Darstellung
14 – DocuSign / Signing
Reifegrad: 🟢 produktiv · Schicht: src/lib/docusign.ts, src/app/api/docusign/*, src/app/api/signing/*, src/app/signing/complete, Tabelle envelope_mappings
Zweck
Rechtsverbindliche digitale Unterschrift von Angeboten und Rapporten (perspektivisch Rechnungen) durch den Kunden via DocuSign.
Authentifizierung (JWT Grant)
src/lib/docusign.ts implementiert den DocuSign JWT-Grant-Flow (Server-to-Server, keine User-Interaktion):
buildJwt()signiert ein RS256-JWT (Scopesignature impersonation, 9 min Gültigkeit) mit dem DocuSign-Private-Key;toPkcs8IfNeeded()konvertiert PKCS#1 → PKCS#8 falls nötig.getAccessToken()tauscht das JWT gegen ein Access-Token (Granturn:ietf:params:oauth:grant-type:jwt-bearer).- Env:
DOCUSIGN_AUTH_SERVER(Default Demoaccount-d.docusign.com),DOCUSIGN_CLIENT_ID,DOCUSIGN_USER_ID,DOCUSIGN_PRIVATE_KEY,DOCUSIGN_REDIRECT_URI(https://app.work7.net/api/docusign/callback).
Ablauf (Envelope)
Nutzer startet Signatur am Angebot/Rapport
→ /api/signing/{offer|rapport}/[id] erstellt DocuSign-Envelope (PDF aus Template)
→ envelope_mappings(envelope_id → {record_type, record_id})
→ Kunde signiert in DocuSign
→ Callback /api/signing/callback bzw. /api/docusign/callback
→ signiertes PDF wird am Datensatz gespeichert (signed_pdf, signed_at, signed_by_name/_email)
→ /signing/complete (Abschluss-Seite)- Envelope-Mapping (
envelope_mappings):envelope_id(PK) →record_type(rapport|offer) +record_id. So findet der Callback den Ursprungsdatensatz zurück. - Signaturablage:
offers.signed_pdf/_at/_by_*,rapports.signed_pdf/_at/_by_*,invoices.signed_pdf/_at/_by_*(Spalten vorhanden; Offer/Rapport aktiv genutzt).
API-Endpunkte
| Endpoint | Funktion |
|---|---|
GET /api/docusign/start · /callback | OAuth/Consent-Hilfsflow |
POST /api/signing/offer/[id] | Angebot zur Signatur senden |
POST /api/signing/rapport/[id] | Rapport zur Signatur senden |
GET/POST /api/signing/callback | Rücklauf nach Signatur (Envelope → Datensatz) |
UI: /signing/complete (Erfolgsseite), /test-docusign (Test-/Diagnoseseite).
Sicherheit
Callbacks sind sessionlos und werden über state/Envelope-Zuordnung validiert (envelope_mappings), konsistent mit dem Webhook-Trust-Modell aus adr-0002-shared-domain-layer.
Bekannte Befunde / offene Punkte
- Standard-
DOCUSIGN_AUTH_SERVERzeigt auf die Demo-Umgebung (account-d); für Prod aufaccount.docusign.comumstellen. /test-docusignist eine Entwickler-/Diagnoseseite – vor Go-Live ausblenden/entfernen.- Rechnungssignatur ist schemaseitig vorbereitet, aber im Signing-Flow (noch) nicht verdrahtet.