Claude-code-plugins-plus documenso-migration-deep-dive
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/documenso-pack/skills/documenso-migration-deep-dive" ~/.claude/skills/jeremylongshore-claude-code-plugins-plus-documenso-migration-deep-dive && rm -rf "$T"
manifest:
plugins/saas-packs/documenso-pack/skills/documenso-migration-deep-dive/SKILL.mdsource content
Documenso Migration Deep Dive
Current State
!
npm list 2>/dev/null | head -10
Overview
Comprehensive guide for migrating to Documenso from other e-signature platforms (DocuSign, HelloSign, PandaDoc, Adobe Sign). Uses the Strangler Fig pattern for zero-downtime migration with feature flags and rollback support.
Prerequisites
- Current signing platform documented (APIs, templates, webhooks)
- Documenso account configured (see
)documenso-install-auth - Feature flag infrastructure (LaunchDarkly, environment variables, etc.)
- Parallel run capability (both platforms active during migration)
Migration Strategy: Strangler Fig Pattern
Phase 1: Parallel Systems (Week 1-2) ┌──────────┐ ┌─────────────┐ │ Your App │────▶│ Old Platform │ (100% traffic) │ │ └─────────────┘ │ │────▶│ Documenso │ (shadow: log only, don't send) └──────────┘ └─────────────┘ Phase 2: Gradual Cutover (Week 3-4) ┌──────────┐ ┌─────────────┐ │ Your App │────▶│ Old Platform │ (50% traffic via feature flag) │ │ └─────────────┘ │ │────▶│ Documenso │ (50% traffic) └──────────┘ └─────────────┘ Phase 3: Full Migration (Week 5+) ┌──────────┐ ┌─────────────┐ │ Your App │────▶│ Documenso │ (100% traffic) └──────────┘ └─────────────┘ Old platform decommissioned
Instructions
Step 1: Pre-Migration Assessment
// scripts/assess-current-system.ts // Inventory your current signing platform usage interface MigrationAssessment { platform: string; activeTemplates: number; documentsPerMonth: number; webhookEndpoints: string[]; recipientRoles: string[]; fieldTypes: string[]; integrations: string[]; // CRM, database, etc. } async function assessCurrentSystem(): Promise<MigrationAssessment> { // Example for DocuSign return { platform: "DocuSign", activeTemplates: 15, documentsPerMonth: 200, webhookEndpoints: [ "https://api.yourapp.com/webhooks/docusign", ], recipientRoles: ["Signer", "CC", "In Person Signer"], fieldTypes: ["Signature", "Date", "Text", "Checkbox", "Initial"], integrations: ["Salesforce", "PostgreSQL"], }; }
Step 2: Feature Mapping
| DocuSign | HelloSign | Documenso | Notes |
|---|---|---|---|
| Envelope | Signature Request | Document | Documenso v2 also has Envelopes |
| Template | Template | Template | Create via UI, use via API |
| Signer | Signer | SIGNER role | Same concept |
| CC | CC | CC role | Same concept |
| In Person | N/A | Direct Link | Use embedded signing |
| Tabs/Fields | Form Fields | Fields | SIGNATURE, TEXT, DATE, etc. |
| Connect (webhooks) | Callbacks | Webhooks | document.completed, etc. |
| PowerForms | N/A | Direct Links | Public signing URLs |
Step 3: Template Migration
// Templates can't be migrated via API — recreate in Documenso // Keep template definitions in code for reproducibility interface TemplateDef { name: string; description: string; recipientRoles: Array<{ role: string; placeholder: string }>; fields: Array<{ recipientIndex: number; type: string; page: number; x: number; y: number; width: number; height: number; }>; } const TEMPLATES: TemplateDef[] = [ { name: "NDA — Standard", description: "Non-disclosure agreement template", recipientRoles: [ { role: "SIGNER", placeholder: "Counterparty" }, { role: "CC", placeholder: "Legal Team" }, ], fields: [ { recipientIndex: 0, type: "SIGNATURE", page: 2, x: 10, y: 80, width: 30, height: 5 }, { recipientIndex: 0, type: "DATE", page: 2, x: 60, y: 80, width: 20, height: 3 }, { recipientIndex: 0, type: "NAME", page: 2, x: 10, y: 75, width: 30, height: 3 }, ], }, // ... more templates ]; // Instructions: create each template in the Documenso UI using these specs // Then record the template IDs in your config
Step 4: Webhook Migration
// Map old platform events to Documenso events const EVENT_MAPPING: Record<string, string> = { // DocuSign → Documenso "envelope-completed": "document.completed", "envelope-sent": "document.sent", "envelope-declined": "document.rejected", "envelope-voided": "document.cancelled", "recipient-completed": "document.signed", // HelloSign → Documenso "signature_request_all_signed": "document.completed", "signature_request_sent": "document.sent", "signature_request_declined": "document.rejected", "signature_request_signed": "document.signed", }; // Unified handler that works with both platforms during migration async function handleSigningEvent(source: "old" | "documenso", event: string, payload: any) { const normalizedEvent = source === "old" ? EVENT_MAPPING[event] ?? event : event; switch (normalizedEvent) { case "document.completed": await onDocumentCompleted(payload); break; case "document.rejected": await onDocumentRejected(payload); break; } }
Step 5: Dual-Write with Feature Flag
// src/signing/router.ts const USE_DOCUMENSO = process.env.USE_DOCUMENSO === "true"; async function sendForSigning(request: SigningRequest) { if (USE_DOCUMENSO) { return sendViaDocumenso(request); } return sendViaLegacy(request); } // During parallel phase: send via both, compare results async function sendForSigningParallel(request: SigningRequest) { const legacyResult = await sendViaLegacy(request); // Shadow-send to Documenso (don't actually send to recipients) try { const doc = await documensoClient.documents.createV0({ title: request.title }); // Don't call sendV0 — just verify creation works await documensoClient.documents.deleteV0(doc.documentId); console.log("Documenso shadow test: OK"); } catch (err) { console.error("Documenso shadow test: FAIL", err); } return legacyResult; }
Step 6: Rollback Procedure
# If Documenso migration causes issues: # 1. Disable feature flag export USE_DOCUMENSO=false # Or toggle in LaunchDarkly/feature flag service # 2. Deploy the change # All new signing requests go to old platform immediately # 3. Handle in-flight Documenso documents # Documents already sent via Documenso will complete there # No action needed — they just use a different platform # 4. Investigate and fix the issue # Review logs, fix the integration, re-enable gradually
Migration Timeline
| Week | Phase | Action | Risk |
|---|---|---|---|
| 1 | Assessment | Inventory templates, webhooks, integrations | Low |
| 2 | Setup | Configure Documenso, recreate templates | Low |
| 3 | Shadow | Run parallel, compare results (no live traffic) | Low |
| 4 | Pilot | 10% of new documents via Documenso | Medium |
| 5 | Expand | 50% of new documents via Documenso | Medium |
| 6 | Cutover | 100% via Documenso, old platform read-only | Medium |
| 8 | Decommission | Remove old platform code and webhooks | Low |
Error Handling
| Migration Issue | Cause | Solution |
|---|---|---|
| Field position different | Different coordinate systems | Map percentage-based (Documenso) from pixel-based (old) |
| Webhook format change | Different payload structure | Use event normalizer/adapter |
| Template missing | Not recreated in Documenso | Create from template definitions |
| High error rate during cutover | Integration bug | Pause rollout, rollback, investigate |
Resources
Next Steps
Review related skills for comprehensive coverage of your new Documenso integration.