751 lines
28 KiB
Markdown
751 lines
28 KiB
Markdown
# Design Document
|
||
|
||
**Project**: Salesforce Composite Envelope Builder
|
||
**Version**: 1.1
|
||
**Date**: February 23, 2026 (updated March 11, 2026)
|
||
**Author**: Paul Huliganga
|
||
|
||
---
|
||
|
||
## 1. Architecture Overview
|
||
|
||
### 1.1 System Context
|
||
|
||
```
|
||
┌──────────────────┐
|
||
│ Salesforce User │
|
||
└────────┬─────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────┐
|
||
│ Salesforce Platform │
|
||
│ ┌──────────────┐ ┌───────────────┐ │
|
||
│ │ Screen Flow │───▶│ Apex Class │ │
|
||
│ │ (Template │ │ (Composite │ │
|
||
│ │ Selection) │ │ Builder) │ │
|
||
│ └──────────────┘ └───────┬───────┘ │
|
||
│ │ │
|
||
└──────────────────────────────┼───────────┘
|
||
│
|
||
▼ HTTPS/REST API
|
||
┌──────────────────────┐
|
||
│ Docusign REST API │
|
||
│ (Composite │
|
||
│ Templates) │
|
||
└──────────────────────┘
|
||
```
|
||
|
||
### 1.2 Component Architecture
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────────┐
|
||
│ Salesforce Org │
|
||
│ │
|
||
│ ┌─────────────────────────────────────────────────┐ │
|
||
│ │ Presentation Layer (Screen Flow) │ │
|
||
│ │ - Language selection │ │
|
||
│ │ - Template display (checkbox collection) │ │
|
||
│ │ - Success/error messaging │ │
|
||
│ └──────────────────┬──────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌─────────────────▼──────────────────────────────┐ │
|
||
│ │ Business Logic Layer (Apex) │ │
|
||
│ │ │ │
|
||
│ │ ┌─────────────────────────────────────────┐ │ │
|
||
│ │ │ DocusignCompositeEnvelopeBuilder │ │ │
|
||
│ │ │ - @InvocableMethod entry point │ │ │
|
||
│ │ │ - Input validation │ │ │
|
||
│ │ │ - Multi-copy template expansion │ │ │
|
||
│ │ │ - Composite JSON construction │ │ │
|
||
│ │ │ - Envelope ID return │ │ │
|
||
│ │ └──────────────────┬──────────────────────┘ │ │
|
||
│ │ │ │ │
|
||
│ │ ┌─────────────────▼──────────────────────┐ │ │
|
||
│ │ │ DocusignAPIService │ │ │
|
||
│ │ │ - API authentication │ │ │
|
||
│ │ │ - HTTP callout construction │ │ │
|
||
│ │ │ - Response parsing │ │ │
|
||
│ │ │ - Error handling │ │ │
|
||
│ │ └──────────────────┬──────────────────────┘ │ │
|
||
│ │ │ │ │
|
||
│ │ ┌─────────────────▼──────────────────────┐ │ │
|
||
│ │ │ DocusignCredentials │ │ │
|
||
│ │ │ - Credential retrieval │ │ │
|
||
│ │ │ - Token management │ │ │
|
||
│ │ └─────────────────────────────────────────┘ │ │
|
||
│ └──────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌──────────────────────────────────────────────┐ │
|
||
│ │ Data Layer │ │
|
||
│ │ - Named Credential (Docusign API creds) │ │
|
||
│ │ - Custom Settings (configuration) │ │
|
||
│ └──────────────────────────────────────────────┘ │
|
||
└───────────────────────────────────────────────────────┘
|
||
│
|
||
▼ HTTPS REST API
|
||
┌──────────────────────┐
|
||
│ Docusign Platform │
|
||
└──────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 2. Detailed Component Design
|
||
|
||
### 2.1 DocusignCompositeEnvelopeBuilder (Main Class)
|
||
|
||
**Purpose**: Invocable Apex class that combines multiple Docusign templates into a single envelope
|
||
|
||
**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; // 1–3; only used when that template is selected
|
||
|
||
@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)
|
||
|
||
**Purpose**: Handles all Docusign REST API interactions
|
||
|
||
**Responsibilities**:
|
||
- Construct HTTP requests
|
||
- Make callouts to Docusign API
|
||
- Parse responses
|
||
- Handle errors and retries
|
||
- Log API interactions
|
||
|
||
**Methods**:
|
||
|
||
```apex
|
||
public static String createCompositeEnvelope(
|
||
String envelopeJSON,
|
||
DocusignCredentials creds
|
||
)
|
||
|
||
public static HttpResponse callDocusignAPI(
|
||
String endpoint,
|
||
String method,
|
||
String body,
|
||
Map<String, String> headers
|
||
)
|
||
|
||
public static String parseEnvelopeId(HttpResponse response)
|
||
|
||
private static void logAPICall(
|
||
HttpRequest req,
|
||
HttpResponse res,
|
||
Long durationMs
|
||
)
|
||
|
||
private static void handleAPIError(HttpResponse response)
|
||
```
|
||
|
||
---
|
||
|
||
### 2.3 DocusignCredentials (Credential Management)
|
||
|
||
**Purpose**: Retrieve and manage Docusign API credentials securely
|
||
|
||
**Responsibilities**:
|
||
- Fetch credentials from Named Credential or Custom Settings
|
||
- Handle token refresh (JWT/OAuth2)
|
||
- Provide credential object to service layer
|
||
|
||
**Methods**:
|
||
|
||
```apex
|
||
public static DocusignCredentials getInstance()
|
||
|
||
public String getAccessToken()
|
||
|
||
public String getAccountId()
|
||
|
||
public String getBaseUrl()
|
||
|
||
private static String refreshAccessToken() // JWT or OAuth2 refresh
|
||
|
||
public class CredentialException extends Exception {}
|
||
```
|
||
|
||
**Properties**:
|
||
|
||
```apex
|
||
public String baseUrl { get; private set; }
|
||
public String accountId { get; private set; }
|
||
public String accessToken { get; private set; }
|
||
public DateTime tokenExpiry { get; private set; }
|
||
```
|
||
|
||
---
|
||
|
||
## 2.4 Multi-Copy Template Feature (v1.1)
|
||
|
||
### Overview
|
||
|
||
Certain templates may need to be included multiple times in a single envelope (e.g. the **Authorization to Release Information** form, available in both English and Spanish). Rather than requiring users to build separate envelopes, the flow detects this template and prompts for a copy count before sending.
|
||
|
||
### Configuration
|
||
|
||
The template is identified by a **single constant** in `DocusignCompositeEnvelopeBuilder.cls`:
|
||
|
||
```apex
|
||
// ============================================================
|
||
// MULTI-COPY TEMPLATE: Update this if the template name changes.
|
||
// Both English and Spanish versions share this base name.
|
||
// ============================================================
|
||
@TestVisible
|
||
private static final String MULTI_COPY_TEMPLATE_NAME = 'Authorization to Release Information';
|
||
```
|
||
|
||
To rename the template, update this one constant. The Apex code uses a `LIKE '%<name>%'` SOQL query, so the match is case-insensitive and partial — it covers both language variants automatically.
|
||
|
||
The Flow also has a single `Contains` check in the `Does_Row_Contain_Auth_Release` decision node, which must be updated to match.
|
||
|
||
### Flow Changes
|
||
|
||
The following new elements were added to `Docusign_Envelope_Templates_V3`:
|
||
|
||
| Element | Type | Purpose |
|
||
|---------|------|---------|
|
||
| `Scan_For_Auth_Release_Template` | Loop | Iterates all selected rows to look for the target template |
|
||
| `Does_Row_Contain_Auth_Release` | Decision | Checks if the current row's `Name` contains `"Authorization to Release Information"` |
|
||
| `Flag_Auth_Release_Selected` | Assignment | Sets `authReleaseTemplateSelected = true` when match is found |
|
||
| `Is_Auth_Release_Selected` | Decision | After scan loop: routes to copies screen if flag is true, otherwise skips |
|
||
| `Authorization_Copies_Screen` | Screen | Shows instruction text + radio buttons (1 copy / 2 copies / 3 copies) |
|
||
| `authReleaseFormCopies` | Variable (Number, default 1) | Stores the user's copy-count selection |
|
||
| `authReleaseTemplateSelected` | Variable (Boolean, default false) | Flag set during the scan loop |
|
||
| `AuthCopies_1/2/3` | Choices | Radio button options with numeric values 1 / 2 / 3 |
|
||
|
||
The `authReleaseFormCopies` variable is passed to the Apex Invocable Action as a new input parameter.
|
||
|
||
#### Updated Flow Path (after row selection)
|
||
|
||
```
|
||
Check_Row_Selection → Scan_For_Auth_Release_Template (loop)
|
||
│ per row → Does_Row_Contain_Auth_Release
|
||
│ Yes → Flag_Auth_Release_Selected → (continue loop)
|
||
│ No → (continue loop)
|
||
└ loop ends → Is_Auth_Release_Selected
|
||
Yes → Authorization_Copies_Screen → Build_Template_ID_Collection
|
||
No → Build_Template_ID_Collection (unchanged)
|
||
```
|
||
|
||
### Apex Changes
|
||
|
||
**`DocusignEnvelopeRequest.cls`** — new `@InvocableVariable`:
|
||
```apex
|
||
@InvocableVariable(
|
||
label='Authorization to Release Form Copies'
|
||
description='Number of times to include the Authorization to Release Information template (1-3).'
|
||
required=false
|
||
)
|
||
global Integer authReleaseFormCopies;
|
||
```
|
||
|
||
**`DocusignCompositeEnvelopeBuilder.cls`** — multi-copy expansion logic runs before the document list is built:
|
||
|
||
```apex
|
||
// Expand multi-copy templates
|
||
List<String> expandedTemplateIds = new List<String>(req.templateIds);
|
||
Integer copies = (req.authReleaseFormCopies != null && req.authReleaseFormCopies > 1)
|
||
? Math.min(req.authReleaseFormCopies, 3) : 1;
|
||
if (copies > 1) {
|
||
List<String> multiCopyIds = [
|
||
SELECT dfsle__DocuSignId__c FROM dfsle__EnvelopeConfiguration__c
|
||
WHERE dfsle__DocuSignId__c IN :req.templateIds
|
||
AND Name LIKE :('%' + MULTI_COPY_TEMPLATE_NAME + '%')
|
||
].dfsle__DocuSignId__c;
|
||
for (String id : multiCopyIds) {
|
||
for (Integer i = 1; i < copies; i++) {
|
||
expandedTemplateIds.add(id);
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
Duplicate template IDs are intentionally **not deduplicated** when multi-copy is in effect. The label builder appends `" (Copy 2)"` / `" (Copy 3)"` suffixes to keep document labels distinct within the envelope.
|
||
|
||
---
|
||
|
||
## 3. Data Flow
|
||
|
||
### 3.1 Sequence Diagram: Send Composite Envelope
|
||
|
||
```
|
||
User Flow Apex Service Docusign API
|
||
│ │ │ │ │
|
||
│ Select │ │ │ │
|
||
│ Templates │ │ │ │
|
||
├────────────▶│ │ │ │
|
||
│ │ │ │ │
|
||
│ │ Invoke Apex │ │ │
|
||
│ │ Action │ │ │
|
||
│ ├──────────────▶│ │ │
|
||
│ │ (templateIds) │ │ │
|
||
│ │ │ │ │
|
||
│ │ │ Validate inputs │ │
|
||
│ │ ├────────┐ │ │
|
||
│ │ │ │ │ │
|
||
│ │ │◀───────┘ │ │
|
||
│ │ │ │ │
|
||
│ │ │ Build JSON │ │
|
||
│ │ ├────────┐ │ │
|
||
│ │ │ │ │ │
|
||
│ │ │◀───────┘ │ │
|
||
│ │ │ │ │
|
||
│ │ │ Get credentials │ │
|
||
│ │ ├───────────────────▶│ │
|
||
│ │ │ │ │
|
||
│ │ │◀───────────────────┤ │
|
||
│ │ │ (creds) │ │
|
||
│ │ │ │ │
|
||
│ │ │ Call API │ │
|
||
│ │ ├───────────────────▶│ │
|
||
│ │ │ (JSON, creds) │ │
|
||
│ │ │ │ │
|
||
│ │ │ │ POST /envelopes │
|
||
│ │ │ ├─────────────────▶│
|
||
│ │ │ │ │
|
||
│ │ │ │ 201 Created │
|
||
│ │ │ │ {envelopeId} │
|
||
│ │ │ │◀─────────────────┤
|
||
│ │ │ │ │
|
||
│ │ │ envelopeId │ │
|
||
│ │ │◀───────────────────┤ │
|
||
│ │ │ │ │
|
||
│ │ Result │ │ │
|
||
│ │ (envelopeId) │ │ │
|
||
│ │◀──────────────┤ │ │
|
||
│ │ │ │ │
|
||
│ Success │ │ │ │
|
||
│ Message │ │ │ │
|
||
│◀────────────┤ │ │ │
|
||
│ │ │ │ │
|
||
```
|
||
|
||
### 3.2 Error Handling Flow
|
||
|
||
```
|
||
Apex Service Docusign API
|
||
│ │ │
|
||
│ Call API │ │
|
||
├────────────────▶│ │
|
||
│ │ POST /envelopes │
|
||
│ ├─────────────────▶│
|
||
│ │ │
|
||
│ │ 400 Bad Request │
|
||
│ │ (error JSON) │
|
||
│ │◀─────────────────┤
|
||
│ │ │
|
||
│ │ Parse error │
|
||
│ ├──────┐ │
|
||
│ │ │ │
|
||
│ │◀─────┘ │
|
||
│ │ │
|
||
│ │ Throw exception │
|
||
│ │ │
|
||
│ Catch exception │ │
|
||
│◀────────────────┤ │
|
||
│ │ │
|
||
│ Log error │ │
|
||
├──────┐ │ │
|
||
│ │ │ │
|
||
│◀─────┘ │ │
|
||
│ │ │
|
||
│ Return Result │ │
|
||
│ (success=false, │ │
|
||
│ errorMessage) │ │
|
||
│ │ │
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Docusign Composite Template JSON Structure
|
||
|
||
### 4.1 Request Format
|
||
|
||
```json
|
||
{
|
||
"status": "sent",
|
||
"emailSubject": "Please review and sign these forms",
|
||
"compositeTemplates": [
|
||
{
|
||
"compositeTemplateId": "1",
|
||
"serverTemplates": [
|
||
{
|
||
"sequence": "1",
|
||
"templateId": "TEMPLATE_ID_FORM_A"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"compositeTemplateId": "2",
|
||
"serverTemplates": [
|
||
{
|
||
"sequence": "2",
|
||
"templateId": "TEMPLATE_ID_FORM_B"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"compositeTemplateId": "3",
|
||
"serverTemplates": [
|
||
{
|
||
"sequence": "3",
|
||
"templateId": "TEMPLATE_ID_FORM_C"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 4.2 Apex JSON Construction
|
||
|
||
**Approach**: Use `Map<String, Object>` + `JSON.serialize()` for dynamic construction
|
||
|
||
```apex
|
||
List<Object> compositeTemplates = new List<Object>();
|
||
|
||
Integer sequence = 1;
|
||
for (String templateId : sortedTemplateIds) {
|
||
Map<String, Object> template = new Map<String, Object>{
|
||
'compositeTemplateId' => String.valueOf(sequence),
|
||
'serverTemplates' => new List<Object>{
|
||
new Map<String, Object>{
|
||
'sequence' => String.valueOf(sequence),
|
||
'templateId' => templateId
|
||
}
|
||
}
|
||
};
|
||
compositeTemplates.add(template);
|
||
sequence++;
|
||
}
|
||
|
||
Map<String, Object> envelope = new Map<String, Object>{
|
||
'status' => 'sent',
|
||
'emailSubject' => emailSubject,
|
||
'compositeTemplates' => compositeTemplates
|
||
};
|
||
|
||
String envelopeJSON = JSON.serialize(envelope);
|
||
```
|
||
|
||
---
|
||
|
||
## 5. API Integration Details
|
||
|
||
### 5.1 Endpoint
|
||
|
||
**POST** `https://{baseUrl}/restapi/v2.1/accounts/{accountId}/envelopes`
|
||
|
||
Where:
|
||
- `{baseUrl}`: e.g., `na3.docusign.net` (from Named Credential)
|
||
- `{accountId}`: Docusign account GUID (from Named Credential or Custom Settings)
|
||
|
||
### 5.2 Headers
|
||
|
||
```
|
||
Authorization: Bearer {access_token}
|
||
Content-Type: application/json
|
||
Accept: application/json
|
||
```
|
||
|
||
### 5.3 Authentication
|
||
|
||
**JWT (JSON Web Token) - Preferred**:
|
||
- Use RSA key pair stored in Named Credential
|
||
- Generate JWT, exchange for access token
|
||
- Token valid for 1 hour, cache and refresh as needed
|
||
|
||
**OAuth2 Authorization Code - Alternative**:
|
||
- User-based authentication
|
||
- Access token + refresh token
|
||
- Requires user interaction for initial authorization
|
||
|
||
### 5.4 Response Codes
|
||
|
||
| Code | Meaning | Action |
|
||
|------|---------|--------|
|
||
| 201 | Created | Success - parse envelope ID |
|
||
| 400 | Bad Request | Invalid JSON or parameters - log and return error |
|
||
| 401 | Unauthorized | Token expired - refresh and retry |
|
||
| 403 | Forbidden | Insufficient permissions - log and return error |
|
||
| 429 | Too Many Requests | Rate limit - retry after delay |
|
||
| 500 | Server Error | Docusign issue - log and return error |
|
||
|
||
---
|
||
|
||
## 6. Governor Limit Considerations
|
||
|
||
### 6.1 Heap Size
|
||
- **Limit**: 6 MB (synchronous), 12 MB (asynchronous)
|
||
- **Mitigation**:
|
||
- Serialize JSON incrementally
|
||
- Avoid loading large objects into memory
|
||
- Process template IDs in batches if needed (future enhancement)
|
||
|
||
### 6.2 CPU Time
|
||
- **Limit**: 10,000 ms (synchronous)
|
||
- **Mitigation**:
|
||
- Minimize loops and complex logic
|
||
- Delegate heavy work to Docusign API
|
||
|
||
### 6.3 Callouts
|
||
- **Limit**: 100 callouts per transaction, 10-second timeout per callout
|
||
- **Mitigation**:
|
||
- Single API call per envelope
|
||
- Use asynchronous callouts (@future) for bulk operations (future enhancement)
|
||
|
||
### 6.4 SOQL Queries
|
||
- **Limit**: 100 queries per transaction
|
||
- **Mitigation**:
|
||
- Minimize queries in loop (not applicable for this design)
|
||
- Cache credentials if fetched via SOQL
|
||
|
||
---
|
||
|
||
## 7. Security Design
|
||
|
||
### 7.1 Credential Storage
|
||
|
||
**Option 1: Named Credential (Preferred)**
|
||
- Credentials encrypted by Salesforce
|
||
- No code changes needed for credential updates
|
||
- OAuth flows managed by platform
|
||
|
||
**Option 2: Protected Custom Settings**
|
||
- API credentials stored encrypted
|
||
- Accessible only via Apex
|
||
- Manual token refresh required
|
||
|
||
### 7.2 Access Control
|
||
|
||
- Apex class runs in **user context** (sharing rules enforced)
|
||
- Users must have:
|
||
- Permission to execute Flows
|
||
- Read access to Salesforce record
|
||
- Docusign send permission (managed via Docusign)
|
||
|
||
### 7.3 Data Protection
|
||
|
||
- No sensitive data logged in debug statements
|
||
- API credentials never exposed in logs or error messages
|
||
- HTTPS for all API communication
|
||
|
||
---
|
||
|
||
## 8. Testing Strategy
|
||
|
||
### 8.1 Unit Tests
|
||
|
||
**Test Coverage Goal**: >75% (Salesforce requirement)
|
||
|
||
**Test Classes**:
|
||
- `DocusignCompositeEnvelopeBuilderTest`
|
||
- `DocusignAPIServiceTest`
|
||
- `DocusignCredentialsTest`
|
||
|
||
**Test Scenarios**:
|
||
1. **Success case**: 3 templates combined, envelope created
|
||
2. **Edge case**: 1 template (minimum)
|
||
3. **Edge case**: 14 templates (maximum)
|
||
4. **Error case**: Invalid template ID
|
||
5. **Error case**: API returns 400
|
||
6. **Error case**: API returns 401 (token expired)
|
||
7. **Error case**: API timeout
|
||
8. **Mock callouts**: Use `HttpCalloutMock` for Docusign API
|
||
|
||
### 8.2 Integration Tests
|
||
|
||
**Manual Testing**:
|
||
1. Create test Docusign templates in sandbox
|
||
2. Configure Named Credential with sandbox credentials
|
||
3. Execute Screen Flow with various template combinations
|
||
4. Verify envelope creation in Docusign sandbox
|
||
5. Verify documents written back to Salesforce
|
||
|
||
### 8.3 Performance Tests
|
||
|
||
- Test with maximum templates (14)
|
||
- Measure Apex CPU time
|
||
- Verify heap size usage
|
||
- Test concurrent requests (multiple users)
|
||
|
||
---
|
||
|
||
## 9. Deployment Architecture
|
||
|
||
### 9.1 Deployment Components
|
||
|
||
**Metadata to Deploy**:
|
||
1. Apex classes:
|
||
- `DocusignCompositeEnvelopeBuilder.cls`
|
||
- `DocusignAPIService.cls`
|
||
- `DocusignCredentials.cls`
|
||
- Test classes (3 files)
|
||
2. Named Credential configuration
|
||
3. Remote Site Settings (for Docusign API URL)
|
||
4. Permission Sets (optional, for access control)
|
||
|
||
### 9.2 Deployment Steps
|
||
|
||
1. **Sandbox deployment** (via VS Code or CLI):
|
||
```bash
|
||
sf project deploy start --target-org sandbox
|
||
```
|
||
|
||
2. **Run unit tests**:
|
||
```bash
|
||
sf apex run test --wait 5
|
||
```
|
||
|
||
3. **Validate production** (without deployment):
|
||
```bash
|
||
sf project deploy validate --target-org production
|
||
```
|
||
|
||
4. **Deploy to production**:
|
||
```bash
|
||
sf project deploy start --target-org production
|
||
```
|
||
|
||
### 9.3 Rollback Plan
|
||
|
||
- Version control: Git repository tracks all changes
|
||
- Destructive changes: Remove Apex classes if needed
|
||
- Flow modification: Update Flow to call old logic temporarily
|
||
|
||
---
|
||
|
||
## 10. Monitoring & Maintenance
|
||
|
||
### 10.1 Logging
|
||
|
||
**Debug Logs**:
|
||
- Log API request/response (sanitized, no credentials)
|
||
- Log execution time
|
||
- Log errors with stack traces
|
||
|
||
**Custom Object (Optional)**:
|
||
- Store API call history in custom object `Docusign_API_Log__c`
|
||
- Fields: Timestamp, Envelope ID, Template Count, Status, Error Message
|
||
|
||
### 10.2 Alerts
|
||
|
||
- Email alerts for repeated API failures
|
||
- Platform Event for real-time monitoring (future enhancement)
|
||
|
||
### 10.3 Maintenance Tasks
|
||
|
||
- Monitor Docusign API rate limits
|
||
- Review logs for errors
|
||
- Update templates as business needs change
|
||
- Refresh API credentials before expiry
|
||
|
||
---
|
||
|
||
## 11. Future Enhancements
|
||
|
||
### 11.1 Phase 2 Features
|
||
|
||
1. **Dynamic recipient selection**: Override template recipients
|
||
2. **Conditional form selection**: Show/hide forms based on Salesforce data
|
||
3. **Bulk sending**: Send envelopes to multiple records
|
||
4. **Template caching**: Cache template metadata to reduce API calls
|
||
|
||
### 11.2 Technical Improvements
|
||
|
||
1. **Asynchronous processing**: Use `@future` or Queueable for large batches
|
||
2. **Retry logic**: Automatic retry for transient failures
|
||
3. **Rate limit handling**: Intelligent backoff and retry
|
||
4. **Analytics dashboard**: Lightning component for usage reporting
|
||
|
||
---
|
||
|
||
## 12. Glossary
|
||
|
||
| Term | Definition |
|
||
|------|------------|
|
||
| **Composite Template** | Docusign feature to combine multiple templates into one envelope |
|
||
| **Invocable Method** | Apex method callable from Screen Flows, Process Builder |
|
||
| **Named Credential** | Salesforce feature for secure external credential storage |
|
||
| **JWT** | JSON Web Token - authentication method for server-to-server integration |
|
||
| **Governor Limits** | Salesforce platform resource limits (CPU, heap, callouts) |
|
||
|
||
---
|
||
|
||
**Document Status**: Draft
|
||
**Next Steps**: Review with stakeholders, begin Apex development
|
||
**Estimated Effort**: 3-5 days development + 2 days testing
|
||
|
||
---
|
||
|
||
## Change Log
|
||
|
||
| Version | Date | Author | Summary |
|
||
|---------|------|--------|---------|
|
||
| 1.0 | 2026-02-23 | Paul Huliganga | Initial release |
|
||
| 1.1 | 2026-03-11 | Paul Huliganga | Added section 2.4 — multi-copy Authorization to Release Information feature; updated component diagram, Request inner class, and sequence diagram |
|