docs: update QUICK_START, deployment, and design documentation

This commit is contained in:
Paul Huliganga 2026-04-03 11:46:24 -04:00
parent dece2b6569
commit 1286925765
4 changed files with 239 additions and 215 deletions

View File

@ -4,23 +4,22 @@
All Apex classes and tests have been created! Here's what you have: All Apex classes and tests have been created! Here's what you have:
### 📦 Code Files Created (6 classes) ### 📦 Code Files Included in This Package
**Main Classes:** **Main Classes:**
1. `DocusignCompositeEnvelopeBuilder.cls` (11.5 KB) - Invocable method for Flow integration 1. `DocusignCompositeEnvelopeBuilder.cls` - Invocable method for Flow integration (uses dfsle toolkit)
2. `DocusignAPIService.cls` (10.5 KB) - REST API service layer 2. `DocusignEnvelopeRequest.cls` - Invocable request parameter object
3. `DocusignCredentials.cls` (5.9 KB) - Credential management 3. `DocusignEnvelopeRequestHandler.cls` - Request validation helper
4. `DocusignEnvelopeResult.cls` - Invocable result object
**Test Classes:** **Test Classes:**
4. `DocusignCompositeEnvelopeBuilderTest.cls` (13.8 KB) - 12 test methods - `DocusignCompositeEnvelopeBuilderTest.cls`
5. `DocusignAPIServiceTest.cls` (11.7 KB) - 14 test methods - `DocusignEnvelopeRequestHandlerTest.cls`
6. `DocusignCredentialsTest.cls` (8.0 KB) - 13 test methods
**Total:** 39 test methods for comprehensive coverage! **Notes on legacy artifacts:**
- The repository contains a legacy `Docusign_Configuration__c` custom object and older REST-helper classes in docs, but the active implementation uses the `dfsle` (DocuSign for Salesforce managed package) toolkit and `dfsle__EnvelopeConfiguration__c` records. The legacy custom setting/object is not required for the current Flow + Apex approach.
**Metadata:** **All `.cls-meta.xml` files** use API version 60/61 as shown in each file.
- Custom Setting: `Docusign_Configuration__c` with `Account_Id__c` and `Base_URL__c` fields
- All `.cls-meta.xml` files (API version 61.0)
--- ---
@ -99,25 +98,18 @@ Pass Rate: 100%
Code Coverage: 85%+ Code Coverage: 85%+
``` ```
### Step 7: Configure Docusign Credentials ### Step 7: DocuSign Integration / Credentials (note)
1. **Create Named Credential** (see docs/deployment-guide.md section 3.1) - The current implementation uses the `dfsle` Apex Toolkit from the DocuSign for Salesforce managed package to send composite envelopes. That toolkit stores and references its templates/configuration using managed-package objects such as `dfsle__EnvelopeConfiguration__c`.
- Setup → Named Credentials → New Named Credential
- Name: `DocusignAPI`
- URL: `https://na3.docusign.net/restapi/v2.1` (or your data center)
2. **Configure Custom Settings** - You do NOT need to create the legacy Named Credential / custom setting (`Docusign_Configuration__c`) for the dfsle-based flow. Ensure the `DocuSign for Salesforce (dfsle)` managed package is installed and its envelope configurations/templates exist in Production.
- Setup → Custom Settings → Docusign Configuration → Manage
- Click "New" (organization-wide default)
- Account Id: `{Your Docusign Account GUID}`
- Base URL: `callout:DocusignAPI`
- Save
3. **Add Remote Site Settings** - If you intentionally plan to use the older REST-based helper classes (legacy), then follow the steps below **only**:
- Setup → Remote Site Settings → New Remote Site 1. Create a Named Credential (Setup → Named Credentials → New)
- Name: `Docusign_API` - Example name: `DocusignAPI`
- URL: `https://na3.docusign.net` - Example URL: `https://na3.docusign.net/restapi/v2.1`
- Active: ✓ 2. (Optional legacy) Configure `Docusign_Configuration__c` custom setting/object with `Account_Id__c` and `Base_URL__c` if your older REST helpers require it.
3. Add Remote Site or appropriate callout permissions for external DocuSign endpoints.
### Step 8: Update Screen Flow ### Step 8: Update Screen Flow

View File

@ -132,11 +132,12 @@ sf apex run test --class-names DocusignCompositeEnvelopeBuilderTest --wait 10 --
# Test the request handler # Test the request handler
sf apex run test --class-names DocusignEnvelopeRequestHandlerTest --wait 10 --result-format human --code-coverage --target-org dev-org sf apex run test --class-names DocusignEnvelopeRequestHandlerTest --wait 10 --result-format human --code-coverage --target-org dev-org
# Test the API service # Legacy REST-helper tests (optional)
sf apex run test --class-names DocusignAPIServiceTest --wait 10 --result-format human --code-coverage --target-org dev-org # The REST-based `DocusignAPIService` and `DocusignCredentials` tests are part of a
# legacy implementation and are not required for the current dfsle-based Flow.
# Test the credentials helper # Run these only if you have intentionally included the older REST helper classes in your package:
sf apex run test --class-names DocusignCredentialsTest --wait 10 --result-format human --code-coverage --target-org dev-org # sf apex run test --class-names DocusignAPIServiceTest --wait 10 --result-format human --code-coverage --target-org dev-org
# sf apex run test --class-names DocusignCredentialsTest --wait 10 --result-format human --code-coverage --target-org dev-org
``` ```
PowerShell: PowerShell:

View File

@ -212,11 +212,13 @@ Deploying v60.0 metadata to my-sandbox using the v60.0 SOAP API
Status: Succeeded Status: Succeeded
Component Deployed: Component Deployed:
ApexClass DocusignCompositeEnvelopeBuilder ApexClass DocusignCompositeEnvelopeBuilder
ApexClass DocusignAPIService ApexClass DocusignEnvelopeRequest
ApexClass DocusignCredentials ApexClass DocusignEnvelopeRequestHandler
ApexClass DocusignEnvelopeResult
ApexClass DocusignCompositeEnvelopeBuilderTest ApexClass DocusignCompositeEnvelopeBuilderTest
ApexClass DocusignAPIServiceTest ApexClass DocusignEnvelopeRequestHandlerTest
ApexClass DocusignCredentialsTest
Note: The older `DocusignAPIService` / `DocusignCredentials` classes and their tests are part of a legacy REST-based implementation. The active implementation uses the `dfsle` toolkit and does not require those classes; include them only if you intentionally retain the legacy REST helpers.
``` ```
### 4.4 Run Unit Tests ### 4.4 Run Unit Tests

View File

@ -1,203 +1,232 @@
# Design Document # Design — Composite Envelope Builder (Updated)
**Project**: Salesforce Composite Envelope Builder **Project**: Salesforce Composite Envelope Builder
**Version**: 1.2 **Version**: 2.0
**Date**: February 23, 2026 (updated March 15, 2026) **Date**: 2026-03-25
**Author**: Paul Huliganga **Author**: (auto-generated; update author/owner as needed)
--- ---
## 1. Architecture Overview ## 1. Summary
### 1.1 System Context This document describes the current implementation of the Composite Envelope Builder: how Screen Flows, Apex, and the dfsle toolkit collaborate to build and send a single DocuSign envelope composed from multiple DocuSign templates. It reflects the latest code and metadata in the repository (March 2026), including:
``` - Flow V3 (existing, email-only path) and Flow V4 (new, SMS collection path when recipient email is blank)
┌──────────────────┐ - Apex invocable: `DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope` and supporting classes
│ Salesforce User │ - SMS delivery support for recipients without an email (via `dfsle.Recipient.withSmsDelivery()`)
└────────┬─────────┘ - Multi-copy support for the "Authorization to Release Information" template (up to 5 copies)
- Email subject & body composition rules: prefix `Docusign: `, truncation, greeting/signoff handling and Spanish detection
- Key constants: `SMS_PLACEHOLDER_EMAIL`, `MULTI_COPY_TEMPLATE_NAME`
┌─────────────────────────────────────────┐
│ Salesforce Platform │
│ ┌──────────────┐ ┌───────────────┐ │
│ │ Screen Flow │───▶│ Apex Class │ │
│ │ (Template │ │ (Composite │ │
│ │ Selection) │ │ Builder) │ │
│ └──────────────┘ └───────┬───────┘ │
│ │ │
└──────────────────────────────┼───────────┘
▼ HTTPS/REST API
┌──────────────────────┐
│ Docusign REST API │
│ (Composite │
│ Templates) │
└──────────────────────┘
```
### 1.2 Component Architecture This is the canonical design doc for developers, release engineers, and reviewers.
``` ---
┌────────────────────────────────────────────────────────┐
│ Salesforce Org │ ## 2. Architecture Overview
│ │
│ ┌─────────────────────────────────────────────────┐ │ High-level flow:
│ │ Presentation Layer (Screen Flow) │ │
│ │ - Language selection │ │ - User launches Screen Flow (Flow V3 or V4)
│ │ - Template display (checkbox collection) │ │ - User selects language (English/Spanish) and templates
│ │ - Success/error messaging │ │ - Flow optionally collects SMS phone when recipient email is blank (V4)
│ └──────────────────┬──────────────────────────────┘ │ - Flow invokes Apex action `Send Composite Docusign Envelope` with inputs
│ │ │ - Apex builds compound envelope JSON using selected templates (expands multi-copy templates as configured)
│ ┌─────────────────▼──────────────────────────────┐ │ - Apex uses dfsle toolkit to send envelope; returns envelopeId and success/error
│ │ Business Logic Layer (Apex) │ │
│ │ │ │ Components:
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ DocusignCompositeEnvelopeBuilder │ │ │ - Screen Flows: `Docusign_Envelope_Templates_V3` (email path), `Docusign_Envelope_Templates_V4` (collect SMS phone when needed)
│ │ │ - @InvocableMethod entry point │ │ │ - Apex:
│ │ │ - Input validation │ │ │ - `DocusignCompositeEnvelopeBuilder.cls` (invocable entrypoint + implementation)
│ │ │ - Multi-copy template expansion │ │ │ - `DocusignEnvelopeRequest.cls` (invocable request contract)
│ │ │ - SMS delivery (withSmsDelivery) │ │ │ - `DocusignEnvelopeResult.cls` (invocable result contract)
│ │ │ - Composite JSON construction │ │ │ - `DocusignAPIService.cls`, `DocusignCredentials.cls` (service & credential management)
│ │ │ - Envelope ID return │ │ │ - DocuSign: Composite Templates API (via dfsle toolkit integration)
│ │ └──────────────────┬──────────────────────┘ │ │
│ │ │ │ │ ---
│ │ ┌─────────────────▼──────────────────────┐ │ │
│ │ │ DocusignAPIService │ │ │ ## 3. Flow Behavior (V3 and V4)
│ │ │ - API authentication │ │ │
│ │ │ - HTTP callout construction │ │ │ ### 3.1 Shared behavior (V3 & V4)
│ │ │ - Response parsing │ │ │
│ │ │ - Error handling │ │ │ - Language selection screen: user selects `English` or `Spanish`.
│ │ └──────────────────┬──────────────────────┘ │ │ - Template selection screen: multi-select list of templates filtered by selected language.
│ │ │ │ │ - After selection, a loop scans selected templates to detect the multi-copy template ("Authorization to Release Information").
│ │ ┌─────────────────▼──────────────────────┐ │ │ - If detected, a copies screen appears (radio 15) that sets `authReleaseFormCopies`.
│ │ │ DocusignCredentials │ │ │ - Flow gathers `compositeTemplateIds` (selected template IDs) and passes them to Apex action.
│ │ │ - Credential retrieval │ │ │
│ │ │ - Token management │ │ │ ### 3.2 Flow V3
│ │ └─────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────┘ │ - Used when standard email delivery is expected.
│ │ - No SMS collection screen is present.
│ ┌──────────────────────────────────────────────┐ │ - Behavior is unchanged from previous releases except choices include 15 copies.
│ │ Data Layer │ │
│ │ - Named Credential (Docusign API creds) │ │ ### 3.3 Flow V4 (SMS-aware)
│ │ - Custom Settings (configuration) │ │
│ └──────────────────────────────────────────────┘ │ - Added pre-send recipient lookup path:
└───────────────────────────────────────────────────────┘ - `Get_Records` (Client_Case__c) → `Get_Recipient_Contact` (Contact lookup)
- `Is_Recipient_Email_Blank` decision checks Contact.Email
▼ HTTPS REST API - If email is blank → `SMS_Phone_Screen` (field `smsPhoneInput` required, E.164 format recommended) → `Store_SMS_Phone` assignment assigns to `recipientSmsPhone` variable → continue
┌──────────────────────┐ - If email present → skip SMS_Phone_Screen and continue
│ Docusign Platform │ - The `recipientSmsPhone` variable is passed into the Apex action; when non-blank the Apex sets up SMS delivery for Docusign Recipient #1.
└──────────────────────┘ - Flow element names to reference in code and docs: `SMS_Phone_Screen`, `smsPhoneInput`, `Store_SMS_Phone`, `recipientSmsPhone`.
Note: Flow metadata must keep element blocks contiguous (assignments, decisions, screens, etc.) to avoid deployment errors. The committed `Docusign_Envelope_Templates_V4.flow-meta.xml` already follows these rules.
---
## 4. Apex Implementation Details
### 4.1 Invocable contract (`DocusignEnvelopeRequest`)
Key input fields (invocable variables):
- `List<String> templateIds` (required) — list of selected DocuSign template IDs
- `String recordId` (required) — Salesforce Client Case Id
- `String language` (optional) — e.g., `en`, `es`, `Spanish`, `Español` (language detection is normalized in Apex)
- `String emailSubject` (optional) — optional override; Apex still prefixes with `Docusign: ` and truncates to 100 chars
- `Integer authReleaseFormCopies` (optional) — 15; counts for Authorization template
- `String recipientSmsPhone` (optional) — when provided, Apex will enable SMS delivery for Docusign Recipient #1
Outputs:
- `String envelopeId`
- `Boolean success`
- `String errorMessage`
### 4.2 Main behavior (`DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope`)
1. Validate inputs; throw friendly errors if invalid.
2. Expand multi-copy templates:
- Find template IDs whose `Name` contains the constant `MULTI_COPY_TEMPLATE_NAME`.
- If `authReleaseFormCopies` > 1, append (copies - 1) additional entries for each matched template ID.
- Cap copies to 5 (Math.min(..., 5)).
3. Build document list (documents = fromTemplate(templateId, label)) and label duplicates as ` (Copy N)` to preserve uniqueness.
4. Build deduplicated display names for subject/body (merge repeated templates into count markers like `X (3)`).
5. Compose envelope subject & body (see section 5 for rules).
6. Resolve recipients via `resolveRecipients(recordId, recipientSmsPhone)`:
- Query Client_Case__c for lookup fields
- For Docusign Recipient #1: if linked Contact has no Email and `recipientSmsPhone` is provided, set recipientEmail to `SMS_PLACEHOLDER_EMAIL` and call `recipient.withSmsDelivery(smsPhone)`.
7. Use dfsle toolkit to build envelope with documents and recipients and call send.
8. Return `envelopeId` and `success`.
### 4.3 Important constants
- `SMS_PLACEHOLDER_EMAIL` (defined in `DocusignCompositeEnvelopeBuilder.cls`): placeholder email used when recipient has no email; required by DocuSign API even for SMS deliveries.
- `MULTI_COPY_TEMPLATE_NAME` (defined in same class): base name used to identify the Authorization to Release Information template (covers English + Spanish variations via LIKE).
### 4.4 i18n detection
- The code normalizes `req.language` to lowercase and treats as Spanish if any of the following are true:
- `lang.startsWith('es')` (e.g. `es`, `es-CO`)
- `lang.contains('spanish')`
- `lang.contains('espa')` (to capture `español` / `espanol`)
- On Spanish detection, Apex uses Spanish greeting/signoff; otherwise English is used.
---
## 5. Email Subject & Body Composition Rules
- Subject:
- Prefix: `Docusign: ` is prepended to the subject to make the source explicit.
- Truncation: After prefixing, subject is truncated to a maximum of 100 characters (Docusign requirement). The code uses `left(97) + '...'` if longer.
- If user supplies `emailSubject`, prefix and truncation still apply.
- Body:
- Built as: GREETING + (template bodies joined by DIVIDER) + SIGNOFF
- DIVIDER: `"\n\n" + '─'.repeat(40) + "\n\n"` (visual separator)
- Greeting/Sign-off: English default; Spanish strings used when language detection matches Spanish variants. Examples:
- English greeting: `Hello,\n\nPlease complete the DocuSign signature request from Early Intervention Colorado.\n\n`
- Spanish greeting: `Hola,\n\nPor favor, firme la solicitud de DocuSign de parte de Intervención Temprana Colorado.\n\n`
---
## 6. Multi-copy Behavior
- Single constant drives detection: `MULTI_COPY_TEMPLATE_NAME = 'Authorization to Release Information'`.
- Flow shows a copies screen when the template is present; operator selects 15 copies.
- Apex expands the templateId list before building documents to include multiple entries; duplicates are intentionally kept so each copy becomes a separate document in the envelope.
- Document labels: duplicates are labeled with ` (Copy N)` so they appear distinct in DocuSign Status.
---
## 7. SMS Delivery Details
- Trigger: Flow V4 routes to `SMS_Phone_Screen` if the Contact linked by `Docusign_Recipient_1__c` has empty `Email`.
- The screen collects `smsPhoneInput` which is assigned to `recipientSmsPhone` variable and passed to Apex.
- In Apex, when `recipientSmsPhone` is non-blank for Docusign Recipient #1:
- If recipient record has no email, set `recipientEmail = SMS_PLACEHOLDER_EMAIL`.
- Call `recipient = recipient.withSmsDelivery(smsPhone)` to enable SMS delivery via dfsle toolkit.
- Service Coordinator recipient always uses email delivery (unchanged).
- Important setup requirement (documented): `Docusign_Recipient_1__c` on the Client Case must be populated with a Contact. The Contact must have `Name` and (for SMS flow) may have blank `Email`. If the Contact is null, the recipient will be omitted and envelope will be missing that signer.
---
## 8. Flows & Metadata Notes
- Flow element naming conventions are important (screen fields bind by their `name`). For the SMS flow, the screen field is `smsPhoneInput` and the assignment must use `<elementReference>smsPhoneInput</elementReference>` (not `ScreenName.smsPhoneInput`).
- Flow metadata must keep element blocks contiguous (screens, assignments, recordLookups, decisions, loops, choices) to avoid Salesforce Flow XML validation failures. The repo's V4 flow file was normalized accordingly.
---
## 9. Tests, Validation & CI
- Unit tests: ensure `DocusignCompositeEnvelopeBuilderTest` covers:
- English and Spanish subject/body composition
- Multi-copy expansion with 15 copies
- SMS flow path: when Contact.Email blank + recipientSmsPhone provided, mailbox placeholder used and `withSmsDelivery` applied
- Error branches and API failures
- CI: add a PR validation job that does:
- sfdx auth to a validation org
- For changed flow or Apex files, run `sfdx force:source:deploy --checkonly` for those components
- Fail PR if check-only returns errors
- Pre-deploy: run check-only deploy to target org before actual deploy. Example local command:
```bash
sfdx force:source:deploy -p force-app/main/default/flows/Docusign_Envelope_Templates_V4.flow-meta.xml,force-app/main/default/classes/DocusignCompositeEnvelopeBuilder.cls -u dev-org --checkonly --testlevel NoTestRun
``` ```
--- ---
## 2. Detailed Component Design ## 10. Edge Cases and Known Gotchas
### 2.1 DocusignCompositeEnvelopeBuilder (Main Class) - If operator edits a flow in the org and does not retrieve+commit the changes, repo and org diverge. Use mdapi `retrieve` or `sf project retrieve` to pull the authoritative version and commit immediately.
- Flow Builder sometimes reorders or normalizes XML: prefer re-checking contiguity of element blocks after Flow Builder saves.
**Purpose**: Invocable Apex class that combines multiple Docusign templates into a single envelope - Ensure the Flow variable `recipientSmsPhone` is passed to Apex action and that the assignment uses `smsPhoneInput` as elementReference.
- The DocuSign API requires an email field on every recipient even when SMS is used; `SMS_PLACEHOLDER_EMAIL` is central and must be kept updated in Apex if changed.
**Responsibilities**:
- Receive template IDs from Screen Flow
- Validate inputs
- Expand multi-copy templates (e.g. Authorization to Release Information)
- Construct composite template JSON
- Delegate API call to service class
- Return envelope ID to Flow
**Methods**:
```apex
// Flow-invocable entry point
@InvocableMethod(
label='Send Composite Docusign Envelope'
description='Combines multiple templates into one envelope'
)
public static List<Result> sendCompositeEnvelope(List<Request> requests)
// Private helper methods
private static String buildCompositeEnvelopeJSON(
List<String> templateIds,
String recordId,
String language,
Map<String, String> customFields
)
private static void validateInputs(Request req)
private static List<String> sortTemplatesAlphabetically(List<String> templateIds)
```
**Inner Classes**:
```apex
public class Request {
@InvocableVariable(required=true label='Template IDs')
public List<String> templateIds;
@InvocableVariable(required=true label='Salesforce Record ID')
public String recordId;
@InvocableVariable(required=false label='Language')
public String language; // 'en' or 'es'
@InvocableVariable(required=false label='Email Subject')
public String emailSubject;
@InvocableVariable(required=false label='Authorization to Release Form Copies')
public Integer authReleaseFormCopies; // 15; only used when that template is selected
@InvocableVariable(required=false label='Recipient SMS Phone')
public String recipientSmsPhone; // E.164 preferred (+15551234567); triggers SMS delivery for Docusign Recipient #1
@InvocableVariable(required=false label='Custom Fields')
public Map<String, String> customFields; // For merge fields
}
public class Result {
@InvocableVariable(label='Envelope ID')
public String envelopeId;
@InvocableVariable(label='Success')
public Boolean success;
@InvocableVariable(label='Error Message')
public String errorMessage;
}
```
--- ---
### 2.2 DocusignAPIService (Service Class) ## 11. Deployment Checklist
**Purpose**: Handles all Docusign REST API interactions 1. Confirm `force-app/main/default/flows/Docusign_Envelope_Templates_V4.flow-meta.xml` matches the active version in org (if you intend to deploy active draft)
2. Confirm `force-app/main/default/classes/DocusignCompositeEnvelopeBuilder.cls` and related classes/tests are committed
3. Run `sfdx force:source:deploy --checkonly` for affected components against a validation org
4. Run Apex tests (or allow CI to run tests during deploy)
5. Deploy to sandbox, perform a manual Flow Builder inspection of V4
6. Activate the desired Flow version if runtime activation is needed
**Responsibilities**: ---
- Construct HTTP requests
- Make callouts to Docusign API
- Parse responses
- Handle errors and retries
- Log API interactions
**Methods**: ## 12. Change Log (high level)
```apex - 2.0 (2026-03-25): Updated design to reflect:
public static String createCompositeEnvelope( - Flow V4 (SMS path) retrieval & Active flow committed
String envelopeJSON, - Spanish greeting/signoff and broadened language detection
DocusignCredentials creds - Envelope subject prefix `Docusign: ` and truncation to 100 chars
) - Increased Authorization multi-copy support to 5 copies
- Flow element and metadata normalization
public static HttpResponse callDocusignAPI( ---
String endpoint,
String method,
String body,
Map<String, String> headers
)
public static String parseEnvelopeId(HttpResponse response) ## 13. Contact & Ownership
- Primary developer: Paul Huliganga (update as appropriate)
- Repo: `composite-envelope-builder`
- For deployment questions: refer to `docs/DEPLOYMENT_AND_TESTING.md`
---
*This document was generated to represent the repository state as of March 25, 2026. Update the change log and ownership fields when you make future changes.*
private static void logAPICall(
HttpRequest req,
HttpResponse res, HttpResponse res,
Long durationMs Long durationMs
) )