Update documentation to reflect current architecture
SALESFORCE_SETUP.md: - Rewrite "What was added" to cover all current fields, metadata types, Apex classes, LWC components, named credentials, and permission sets - Add DocusignESignatureServiceTest to the test run command README.md: - Replace absolute /home/paulh/... paths with relative ./FILE.md links CLM_INTEGRATION.md: - Pattern 1: replace wrong 3-arg trigger callout with correct Queueable pattern (triggers cannot make direct callouts) - Pattern 2: mark LWC quick action as implemented (no longer a recommendation) - Pattern 3: update REST resource to use CLMAdminService.generateDocument signature - Payload/request/response: replace old pre-XML format with current documentxmlmergetasks JSON and XML structure - Template design: replace Handlebars syntax with CLM XML merge description NEXT_STEPS_DOCGEN.md: - Mark Option B (LWC quick action) as complete - Replace open-ended "what to confirm" with forward-looking guidance on extending to NOD, Education, and Intent to Remove letter types Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
45814dc2d5
commit
fe337efe63
|
|
@ -1,5 +1,7 @@
|
|||
# CLM Doc Gen Integration Guide
|
||||
|
||||
> Status note (2026-04-07): the repo is now standardized on the XML merge path built on `AppraiserCasePayloadBuilder` and `CLMDocGenCallout`, using `Appraiser_Case_Deficiency__c` as the canonical child object. See `CURRENT_STATUS.md` before using this guide as the sole source of truth.
|
||||
|
||||
## Overview
|
||||
This guide explains how to integrate Salesforce with DocuSign CLM to generate Appraiser Review Letters dynamically from Appraiser Case records.
|
||||
|
||||
|
|
@ -80,42 +82,57 @@ Recipient Email
|
|||
|
||||
## Usage Patterns
|
||||
|
||||
### Pattern 1: Apex Trigger (Automatic)
|
||||
### Pattern 1: Queueable Apex (Automatic/Trigger-Driven)
|
||||
|
||||
**Scenario**: Generate letter automatically when Appraiser Case status reaches "Ready for Review"
|
||||
**Scenario**: Generate letter automatically from a trigger or process (callouts cannot be made synchronously from triggers — use a queueable)
|
||||
|
||||
```apex
|
||||
// In a trigger on Appraiser_Case__c AFTER UPDATE
|
||||
if (oldMap.get(record.Id).Status__c != 'Ready for Review' &&
|
||||
record.Status__c == 'Ready for Review') {
|
||||
|
||||
CLMDocGenCallout.CLMDocGenResponse response = CLMDocGenCallout.generateDocument(
|
||||
record.Id,
|
||||
'TEMPLATE_ID_FROM_CLM', // e.g., '123456'
|
||||
record.Reviewer_Email__c
|
||||
);
|
||||
|
||||
if (!response.success) {
|
||||
// Log error or send notification
|
||||
System.debug('CLM Doc Gen failed: ' + response.message);
|
||||
public class AppraiserCaseDocGenJob implements Queueable, Database.AllowsCallouts {
|
||||
private Id caseId;
|
||||
private String accountCode;
|
||||
private String templateDocHref;
|
||||
private String destinationFolderHref;
|
||||
private String destinationDocName;
|
||||
|
||||
public AppraiserCaseDocGenJob(Id caseId, String accountCode,
|
||||
String templateDocHref, String destinationFolderHref, String destinationDocName) {
|
||||
this.caseId = caseId;
|
||||
this.accountCode = accountCode;
|
||||
this.templateDocHref = templateDocHref;
|
||||
this.destinationFolderHref = destinationFolderHref;
|
||||
this.destinationDocName = destinationDocName;
|
||||
}
|
||||
|
||||
public void execute(QueueableContext ctx) {
|
||||
CLMDocGenCallout.CLMDocGenResponse response = CLMAdminService.generateDocument(
|
||||
caseId, templateDocHref, destinationFolderHref, destinationDocName, accountCode
|
||||
);
|
||||
if (!response.success) {
|
||||
System.debug('CLM Doc Gen failed: ' + response.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enqueue from a trigger:
|
||||
System.enqueueJob(new AppraiserCaseDocGenJob(
|
||||
record.Id,
|
||||
'DTC_CLM_Demo',
|
||||
letterSettings.defaultTemplateDocumentHref,
|
||||
letterSettings.destinationRootFolderHref,
|
||||
'Review_' + record.Name + '.docx'
|
||||
));
|
||||
```
|
||||
|
||||
### Pattern 2: Flow (UI-Driven)
|
||||
### Pattern 2: LWC Quick Action (UI-Driven) ✅ Implemented
|
||||
|
||||
**Scenario**: User clicks button to generate letter on-demand
|
||||
The `clmDocGenWorkbench` component, launched from the **Generate Review Letter** quick action, is the current implemented UI path. It calls `CLMAdminService` to:
|
||||
- Browse available accounts and letter types
|
||||
- Browse CLM template and destination folders
|
||||
- Submit a merge task via `generateDocument()`
|
||||
- Poll task status via `getTaskStatus()`
|
||||
- Attach the generated file to the case via `attachGeneratedDocumentToCase()`
|
||||
|
||||
1. Create a Record-Triggered Flow on Appraiser_Case__c
|
||||
2. Add an Action step:
|
||||
- Action Type: "Apex Action"
|
||||
- Apex Class: Choose custom Apex action that wraps `CLMDocGenCallout.generateDocument()`
|
||||
3. Pass:
|
||||
- recordId (the Appraiser Case)
|
||||
- templateId (hardcoded or allow user to select)
|
||||
- recipientEmail (from record or user input)
|
||||
4. On success: Show toast, store document URL on record
|
||||
5. On error: Show error message
|
||||
No additional configuration is needed beyond deploying the metadata and setting up Named Credentials.
|
||||
|
||||
### Pattern 3: REST API (External System)
|
||||
|
||||
|
|
@ -125,12 +142,16 @@ if (oldMap.get(record.Id).Status__c != 'Ready for Review' &&
|
|||
@RestResource(urlMapping='/appraiser-case-generate-letter')
|
||||
global class AppraiserCaseDocGenRest {
|
||||
@HttpPost
|
||||
global static void generateLetter(String caseId, String templateId, String recipientEmail) {
|
||||
CLMDocGenCallout.CLMDocGenResponse response = CLMDocGenCallout.generateDocument(
|
||||
caseId, templateId, recipientEmail
|
||||
global static void generateLetter(
|
||||
String caseId,
|
||||
String accountCode,
|
||||
String templateDocHref,
|
||||
String destinationFolderHref,
|
||||
String destinationDocName
|
||||
) {
|
||||
CLMDocGenCallout.CLMDocGenResponse response = CLMAdminService.generateDocument(
|
||||
(Id) caseId, templateDocHref, destinationFolderHref, destinationDocName, accountCode
|
||||
);
|
||||
|
||||
// Return response
|
||||
RestContext.response.statusCode = response.success ? 200 : 400;
|
||||
RestContext.response.responseBody = Blob.valueOf(JSON.serialize(response));
|
||||
}
|
||||
|
|
@ -141,97 +162,72 @@ global class AppraiserCaseDocGenRest {
|
|||
|
||||
## Payload Structure
|
||||
|
||||
### Input
|
||||
### AppraiserCasePayloadBuilder output (intermediate JSON)
|
||||
```json
|
||||
{
|
||||
"AppraiserCaseNumber": "AC-00001",
|
||||
"AppraiserFieldReviewDate": "2026-04-02",
|
||||
"PropertyAddress": "123 Main St, Denver, CO 80202",
|
||||
"AppraiserCaseNumber": "AC-000001",
|
||||
"AppraiserFieldReviewDate": "Apr 02, 2026",
|
||||
"LetterSentDate": "Apr 09, 2026",
|
||||
"FHACaseNumber": "123-4567890",
|
||||
"AppraiserName": "Jamie Appraiser",
|
||||
"AppraiserSalutation": "Ms.",
|
||||
"AppraiserLastName": "Appraiser",
|
||||
"AppraiserEmail": "jamie@example.com",
|
||||
"AppraiserAddress": "245 Lexington Ave, New York, NY 10016, USA",
|
||||
"PropertyAddress": "123 Main St, Denver, CO 80202, USA",
|
||||
"DeficiencyList": [
|
||||
{
|
||||
"deficiencyNumber": 1,
|
||||
"description": "Missing comparable sale adjustment detail.",
|
||||
"resolution": "Added adjustment rationale and supporting calculations."
|
||||
},
|
||||
{
|
||||
"deficiencyNumber": 2,
|
||||
"description": "Neighborhood trend explanation insufficient.",
|
||||
"resolution": "Expanded market trend narrative with MLS evidence."
|
||||
},
|
||||
{
|
||||
"deficiencyNumber": 3,
|
||||
"description": "Photo date stamps were not included.",
|
||||
"resolution": "Re-uploaded photos with date metadata and captions."
|
||||
}
|
||||
{ "deficiencyNumber": 1, "description": "...", "resolution": "...", "reference": "VC-1" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### CLM API Request (what CLMDocGenCallout sends)
|
||||
### CLM API Request (what CLMDocGenCallout sends to `/documentxmlmergetasks`)
|
||||
```json
|
||||
{
|
||||
"templateId": "TEMPLATE_ID_FROM_CLM",
|
||||
"mergeData": { ...payload above... },
|
||||
"delivery": {
|
||||
"recipientEmail": "reviewer@example.com",
|
||||
"documentName": "AppraiserReviewLetter_1743724800000"
|
||||
},
|
||||
"metadata": {
|
||||
"salesforceRecordId": "a0wKW000007OIiCYAW",
|
||||
"generatedAt": "2026-04-02T05:27:44Z"
|
||||
}
|
||||
"TemplateDocument": { "Href": "https://.../documents/<template-guid>" },
|
||||
"DataXML": "<TemplateFieldData><AppraiserCaseNumber>AC-000001</AppraiserCaseNumber>...<DeficiencyList><Deficiency><Number>1</Number>...</Deficiency></DeficiencyList></TemplateFieldData>",
|
||||
"DestinationDocumentName": "Review_AC-000001.docx",
|
||||
"DestinationFolder": { "Href": "https://.../folders/<folder-guid>" }
|
||||
}
|
||||
```
|
||||
|
||||
### CLM API Response (on success)
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"documentUrl": "https://clm-instance.docusign.com/documents/ABC123XYZ",
|
||||
"documentId": "DOC-001",
|
||||
"message": "Document generated successfully"
|
||||
"Href": "https://apiuatna11.springcm.com/v2/<account-id>/documentxmlmergetasks/<task-guid>",
|
||||
"Status": "Queued",
|
||||
"Result": { "Href": "https://apiuatna11.springcm.com/v2/<account-id>/documents/<doc-guid>" }
|
||||
}
|
||||
```
|
||||
|
||||
The response is persisted to `Appraiser_Case__c` tracking fields by `CLMAdminService.persistDocGenResult()`.
|
||||
|
||||
---
|
||||
|
||||
## CLM Template Design
|
||||
|
||||
### Template Merge Tags (Handlebars syntax)
|
||||
The implementation uses the DocuSign CLM **XML merge** (`documentxmlmergetasks`) API, not a Handlebars/template-key approach. Template field tags in the `.docx` file use CLM's Word merge syntax (typically `«FieldName»` merge fields or CLM repeat-block markers). Refer to your CLM tenant documentation for the exact syntax.
|
||||
|
||||
**Flat fields**:
|
||||
```handlebars
|
||||
<p>Case Number: {{AppraiserCaseNumber}}</p>
|
||||
<p>Review Date: {{AppraiserFieldReviewDate}}</p>
|
||||
<p>Property: {{PropertyAddress}}</p>
|
||||
**Flat field example** (Word merge field in the .docx):
|
||||
```
|
||||
«AppraiserCaseNumber» «AppraiserFieldReviewDate»
|
||||
«PropertyAddress»
|
||||
```
|
||||
|
||||
**Deficiency repeat block**:
|
||||
```handlebars
|
||||
<table>
|
||||
<tr>
|
||||
<th>Deficiency #</th>
|
||||
<th>Description</th>
|
||||
<th>Resolution</th>
|
||||
</tr>
|
||||
{{#each DeficiencyList}}
|
||||
<tr>
|
||||
<td>{{deficiencyNumber}}</td>
|
||||
<td>{{description}}</td>
|
||||
<td>{{resolution}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
**Deficiency repeat block** — the XML structure sent is:
|
||||
```xml
|
||||
<DeficiencyList>
|
||||
<Deficiency>
|
||||
<Number>1</Number>
|
||||
<Description>Missing comparable sale adjustment detail.</Description>
|
||||
<Resolution>Added adjustment rationale and supporting calculations.</Resolution>
|
||||
<Reference>VC-1</Reference>
|
||||
</Deficiency>
|
||||
</DeficiencyList>
|
||||
<DeficiencyCount>1</DeficiencyCount>
|
||||
```
|
||||
|
||||
**Conditional (if no deficiencies)**:
|
||||
```handlebars
|
||||
{{#if DeficiencyList.length}}
|
||||
<!-- Deficiency table -->
|
||||
{{else}}
|
||||
<p>No deficiencies found.</p>
|
||||
{{/if}}
|
||||
```
|
||||
Configure a repeat region in your CLM template over `DeficiencyList/Deficiency`, binding `Number`, `Description`, `Resolution`, and `Reference` within the loop.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# DocuSign CLM Template Mapping Snippet
|
||||
|
||||
This project assumes Salesforce is the system of record and DocuSign CLM doc gen receives a payload built from `Appraiser_Case__c` and its related `Appraiser_Deficiency__c` records.
|
||||
This document reflects an older JSON-oriented payload experiment and is retained only as historical reference. The current working implementation uses `Appraiser_Case__c` and `Appraiser_Case_Deficiency__c` through the XML merge path.
|
||||
|
||||
## Suggested Merge Payload
|
||||
|
||||
|
|
@ -66,6 +66,5 @@ Use the actual DocuSign CLM token syntax used in your tenant, but the field mode
|
|||
|
||||
## Notes
|
||||
|
||||
- Keep `deficiencies` as a repeatable child collection, not a flattened text blob.
|
||||
- If DocuSign CLM requires a REST callout payload, `AppraiserCaseDocGenService.buildDocGenRequestJson()` is a good source payload to hand to your integration layer.
|
||||
- If your CLM tenant uses a different collection token syntax, map the same logical field names there.
|
||||
- Keep deficiency rows as repeatable child data, not a flattened text blob.
|
||||
- The active implementation in this repo now uses `AppraiserCasePayloadBuilder` plus `CLMDocGenCallout` rather than `AppraiserCaseDocGenService`.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
# Current Status — 2026-04-09
|
||||
|
||||
## Executive summary
|
||||
The project is now a working Salesforce proof of concept for both DocuSign CLM document generation and basic eSignature API exploration. The app is standardized on `Appraiser_Case__c` plus `Appraiser_Case_Deficiency__c`, uses account-based DocuSign configuration through `CLM_Account_Setting__mdt`, and provides two operator-facing LWCs:
|
||||
- `clmDocGenWorkbench` for CLM document generation
|
||||
- `docusignEsignWorkbench` for eSignature API browsing
|
||||
|
||||
## What is implemented
|
||||
- canonical Salesforce parent object:
|
||||
- `Appraiser_Case__c`
|
||||
- canonical Salesforce child object:
|
||||
- `Appraiser_Case_Deficiency__c`
|
||||
- CLM merge payload builder:
|
||||
- `AppraiserCasePayloadBuilder`
|
||||
- CLM callout service:
|
||||
- `CLMDocGenCallout`
|
||||
- CLM UI orchestration:
|
||||
- `CLMAdminService`
|
||||
- CLM quick-action workbench:
|
||||
- `clmDocGenWorkbench`
|
||||
- eSignature service layer:
|
||||
- `DocusignESignatureService`
|
||||
- eSignature record-page workbench:
|
||||
- `docusignEsignWorkbench`
|
||||
- account-based config through:
|
||||
- `CLM_Account_Setting__mdt`
|
||||
- letter-definition config through:
|
||||
- `CLM_Letter_Definition__mdt`
|
||||
- task and generated-document tracking on `Appraiser_Case__c`
|
||||
- generated-document attachment to Salesforce Files
|
||||
- Apex tests for payload generation, CLM callouts/admin service, and eSignature service
|
||||
|
||||
## What is working
|
||||
- generating CLM review letters from a Salesforce record page
|
||||
- selecting letter types through metadata-backed defaults while preserving the current appraiser letter
|
||||
- browsing CLM templates and destination folders by configured account
|
||||
- polling CLM task status
|
||||
- attaching generated CLM documents back to the case
|
||||
- browsing eSignature login info, user info, accounts, templates, and envelopes from Salesforce UI
|
||||
|
||||
## What is still not finished
|
||||
- only the current appraiser review letter is seeded; the additional three letters still need template records and CLM template build-out
|
||||
- no envelope creation/send workflow yet
|
||||
- no template detail or envelope detail UI yet
|
||||
- no long-term productized admin/config UI beyond Salesforce Setup
|
||||
- some historical docs remain useful but are not authoritative
|
||||
|
||||
## Current source of truth
|
||||
- product-level summary:
|
||||
- [PRODUCT_SPEC.md](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/docs/PRODUCT_SPEC.md)
|
||||
- setup and environment notes:
|
||||
- [SALESFORCE_SETUP.md](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/docs/SALESFORCE_SETUP.md)
|
||||
- implementation:
|
||||
- Apex classes and LWCs in `force-app/main/default`
|
||||
|
||||
## Immediate recommendation
|
||||
Treat the codebase as a solid platform baseline. The next phase should focus on product enhancements rather than architecture cleanup: better eSignature workflows, richer record-page UX, and clearer admin/operational controls.
|
||||
|
|
@ -6,29 +6,22 @@ I added a placeholder Quick Action metadata file so there is an explicit place i
|
|||
|
||||
DocuSign CLM launch configuration varies by package and org setup. Because of that, the action in this repo is a scaffold/placeholder, not a guaranteed final production action.
|
||||
|
||||
## Recommended implementation path
|
||||
## Implementation status
|
||||
|
||||
### Option A — Screen Flow (recommended first)
|
||||
- Create a Screen Flow or autolaunched Flow that accepts `recordId`
|
||||
- Call an Apex invocable or Apex action that builds the payload
|
||||
- Hand that payload to your DocuSign CLM mechanism
|
||||
- Redirect user to resulting document or status page
|
||||
### Option B — LWC / Quick action ✅ Complete
|
||||
The `clmDocGenWorkbench` LWC quick action is fully implemented and deployed. It uses `CLMAdminService` and `CLMDocGenCallout` for the full generate → poll → attach workflow.
|
||||
|
||||
### Option B — LWC / Aura quick action
|
||||
- Use a Lightning Web Component quick action on `Appraiser_Case__c`
|
||||
- Call `AppraiserCaseDocGenService.buildDocGenRequestJson(recordId, templateKey)`
|
||||
- Send the payload to the installed DocuSign CLM endpoint or orchestration layer
|
||||
### Option A — Screen Flow (alternative entry point)
|
||||
If a Flow-based launch is preferred (e.g., to add approval steps or prefill inputs):
|
||||
- Create a Screen Flow that accepts `recordId`
|
||||
- Call `CLMAdminService.generateDocument()` via an Apex Action step, passing account code, template href, destination folder href, and destination filename
|
||||
- Show task status by polling `CLMAdminService.getTaskStatus()`
|
||||
|
||||
### Option C — Button / URL hack
|
||||
- Usually fast, usually brittle. I don’t recommend it unless your CLM package explicitly documents it.
|
||||
Not recommended.
|
||||
|
||||
## What to confirm in your org
|
||||
## What to confirm before extending to additional letter types
|
||||
|
||||
1. Exact DocuSign CLM package/API available in Salesforce
|
||||
2. Whether generation is initiated by package component, Flow action, Apex callout, or named credential call
|
||||
3. Template identifier format (`templateKey`, template Id, or external document key)
|
||||
4. Returned artifact behavior (attach to record, email, save to CLM repository, etc.)
|
||||
|
||||
## Good next move
|
||||
|
||||
Once you know the exact DocuSign package artifact available in the org, I can wire the placeholder into a real Flow/LWC/Apex launch path.
|
||||
1. CLM template hrefs for NOD, Education, and Intent to Remove letters
|
||||
2. Whether those letters use the same destination folder structure or need separate `CLM_Letter_Definition__mdt` folder overrides
|
||||
3. Any differences in deficiency display or field set for those letter types
|
||||
|
|
|
|||
|
|
@ -0,0 +1,291 @@
|
|||
# Product Spec — Appraiser Review Letter Platform
|
||||
|
||||
## Purpose
|
||||
This project is a Salesforce-based operator tool for generating appraiser review letters in DocuSign CLM from `Appraiser_Case__c` data, while also serving as a proof-of-concept platform for broader DocuSign API integrations across CLM and eSignature.
|
||||
|
||||
## Product goals
|
||||
- Let a user open an `Appraiser Case` in Salesforce and generate a review letter in DocuSign CLM without using Execute Anonymous.
|
||||
- Keep CLM account, folder, template, and destination selection configurable per account.
|
||||
- Persist generation status and generated-document references back to Salesforce.
|
||||
- Allow operators to browse and test eSignature API data from the same Salesforce app.
|
||||
- Provide a clean foundation for future workflows such as template selection, envelope creation, and richer document operations.
|
||||
|
||||
## Primary users
|
||||
- Salesforce admins configuring DocuSign connectivity and defaults
|
||||
- Business users generating review letters from `Appraiser Case` records
|
||||
- Technical users validating CLM and eSignature API behavior in a safe UI
|
||||
|
||||
## Current in-scope workflows
|
||||
|
||||
### 1. CLM document generation
|
||||
- User opens an `Appraiser Case` record.
|
||||
- User launches the `Generate Review Letter` quick action.
|
||||
- User selects a configured CLM account.
|
||||
- User selects a configured letter type.
|
||||
- User browses CLM folders and templates or uses saved defaults.
|
||||
- User generates a document through CLM `documentxmlmergetasks`.
|
||||
- User checks task status.
|
||||
- User attaches the generated CLM document back to Salesforce as a File.
|
||||
|
||||
### 2. eSignature API browsing
|
||||
- User opens an `Appraiser Case` record.
|
||||
- User navigates to the `Docusign eSignature` tab on the record page.
|
||||
- User selects a configured account.
|
||||
- User loads:
|
||||
- login information
|
||||
- OAuth user info
|
||||
- discovered eSignature accounts
|
||||
- account templates
|
||||
- recent envelopes
|
||||
|
||||
## Canonical Salesforce data model
|
||||
|
||||
### Appraiser Case
|
||||
`Appraiser_Case__c` is the primary business record.
|
||||
|
||||
Current functional fields include:
|
||||
- `Name`
|
||||
- `Appraiser_Field_Review_Date__c`
|
||||
- `Letter_Sent_Date__c`
|
||||
- `FHA_Case_Number__c`
|
||||
- `Appraiser_Name__c`
|
||||
- `Appraiser_Last_Name__c`
|
||||
- `Appraiser_Street__c`
|
||||
- `Appraiser_City__c`
|
||||
- `Appraiser_State_Province__c`
|
||||
- `Appraiser_Postal_Code__c`
|
||||
- `Appraiser_Country__c`
|
||||
- `Property_Street__c`
|
||||
- `Property_City__c`
|
||||
- `Property_State_Province__c`
|
||||
- `Property_Postal_Code__c`
|
||||
- `Property_Country__c`
|
||||
|
||||
Current CLM tracking fields include:
|
||||
- `Last_CLM_Account_Code__c`
|
||||
- `Last_DocGen_Status__c`
|
||||
- `Last_DocGen_Message__c`
|
||||
- `Last_DocGen_Task_Id__c`
|
||||
- `Last_DocGen_Task_Url__c`
|
||||
- `Generated_Document_Id__c`
|
||||
- `Generated_Document_Url__c`
|
||||
- `Last_DocGen_Requested_At__c`
|
||||
- `Last_DocGen_Completed_At__c`
|
||||
- `Last_Template_Document_Href__c`
|
||||
- `Last_Destination_Folder_Href__c`
|
||||
- `Attached_File_Content_Document_Id__c`
|
||||
- `Attached_File_Url__c`
|
||||
|
||||
### Appraiser Case Deficiency
|
||||
`Appraiser_Case_Deficiency__c` is the canonical child object.
|
||||
|
||||
Fields:
|
||||
- `Appraiser_Case__c`
|
||||
- `Deficiency_Number__c`
|
||||
- `Description__c`
|
||||
- `Reference__c`
|
||||
- `Resolution__c`
|
||||
|
||||
Validation:
|
||||
- blank deficiency records are blocked by validation
|
||||
|
||||
### CLM account configuration
|
||||
`CLM_Account_Setting__mdt` is the account-level configuration source of truth.
|
||||
|
||||
Fields include:
|
||||
- account identity
|
||||
- `Account_Code__c`
|
||||
- `Account_Display_Name__c`
|
||||
- `Environment_Code__c`
|
||||
- `Active__c`
|
||||
- CLM configuration
|
||||
- `CLM_Account_Id__c`
|
||||
- `CLM_Api_Named_Credential__c`
|
||||
- `CLM_Download_Named_Credential__c`
|
||||
- `Template_Root_Folder_Href__c`
|
||||
- `Destination_Root_Folder_Href__c`
|
||||
- `Default_Template_Document_Href__c`
|
||||
- `Default_Destination_Document_Name_Prefix__c`
|
||||
- eSignature configuration
|
||||
- `ESignature_Auth_Named_Credential__c`
|
||||
- `ESignature_Rest_Named_Credential__c`
|
||||
- `ESignature_Account_Id__c`
|
||||
|
||||
Current active example accounts:
|
||||
- `DTC CLM Demo`
|
||||
- `DTC IAM Enterprise`
|
||||
- `DTC HUD Demo`
|
||||
|
||||
### Letter definition configuration
|
||||
`CLM_Letter_Definition__mdt` is the extensibility layer for letter types.
|
||||
|
||||
Each record can define:
|
||||
- account code
|
||||
- letter code
|
||||
- display name
|
||||
- default flag
|
||||
- sort order
|
||||
- default template href
|
||||
- template root folder href
|
||||
- destination root folder href
|
||||
- default filename prefix
|
||||
|
||||
Current seeded letter definition:
|
||||
- `APPRAISER_REVIEW`
|
||||
|
||||
Design intent:
|
||||
- keep the current appraiser review letter working
|
||||
- allow three additional letters to be added without redesigning the workbench
|
||||
- support more letters later by metadata rather than code branching
|
||||
|
||||
## Canonical CLM architecture
|
||||
|
||||
### Payload generation
|
||||
[AppraiserCasePayloadBuilder.cls](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/classes/AppraiserCasePayloadBuilder.cls) builds the document payload from `Appraiser_Case__c` and `Appraiser_Case_Deficiency__c`.
|
||||
|
||||
Current payload fields:
|
||||
- `AppraiserCaseNumber`
|
||||
- `AppraiserFieldReviewDate`
|
||||
- `LetterSentDate`
|
||||
- `FHACaseNumber`
|
||||
- `AppraiserName`
|
||||
- `AppraiserLastName`
|
||||
- `AppraiserStreet`
|
||||
- `AppraiserCity`
|
||||
- `AppraiserStateProvince`
|
||||
- `AppraiserPostalCode`
|
||||
- `AppraiserCountry`
|
||||
- `AppraiserAddress`
|
||||
- `PropertyStreet`
|
||||
- `PropertyCity`
|
||||
- `PropertyStateProvince`
|
||||
- `PropertyPostalCode`
|
||||
- `PropertyCountry`
|
||||
- `PropertyAddress`
|
||||
- `DeficiencyList[]`
|
||||
|
||||
### CLM callouts
|
||||
[CLMDocGenCallout.cls](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/classes/CLMDocGenCallout.cls) is the canonical CLM integration class.
|
||||
|
||||
Current supported operations:
|
||||
- submit `documentxmlmergetasks`
|
||||
- poll task status
|
||||
- browse folders/documents through generic resource requests
|
||||
- download generated documents
|
||||
|
||||
### CLM orchestration
|
||||
[CLMAdminService.cls](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/classes/CLMAdminService.cls) is the UI-facing orchestration layer.
|
||||
|
||||
Current supported operations:
|
||||
- account selection and defaults
|
||||
- case context retrieval
|
||||
- folder/document browsing
|
||||
- document generation
|
||||
- task polling
|
||||
- generated document attachment to Salesforce Files
|
||||
|
||||
### CLM UI
|
||||
[clmDocGenWorkbench](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/lwc/clmDocGenWorkbench/clmDocGenWorkbench.js) is the current operator UI.
|
||||
|
||||
Current behavior:
|
||||
- launched from the `Generate Review Letter` quick action
|
||||
- uses account-based CLM config
|
||||
- uses account + letter-type selection
|
||||
- supports template browsing
|
||||
- supports destination browsing
|
||||
- supports destination filename selection
|
||||
- shows case deficiencies before generation
|
||||
- shows task details and file attachment status
|
||||
|
||||
## Canonical eSignature architecture
|
||||
|
||||
### eSignature service layer
|
||||
[DocusignESignatureService.cls](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/classes/DocusignESignatureService.cls) is the current eSignature integration layer.
|
||||
|
||||
Current supported operations:
|
||||
- `getAccountConfig`
|
||||
- `getLoginInformation`
|
||||
- `getUserInfo`
|
||||
- `listAccounts`
|
||||
- `getAccountInformation`
|
||||
- `listTemplates`
|
||||
- `listEnvelopes`
|
||||
|
||||
### eSignature UI
|
||||
[docusignEsignWorkbench](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/lwc/docusignEsignWorkbench/docusignEsignWorkbench.js) is the current exploratory UI.
|
||||
|
||||
Current behavior:
|
||||
- placed on its own `Docusign eSignature` record tab
|
||||
- supports account selection
|
||||
- shows raw login info and user info
|
||||
- shows discovered eSignature accounts
|
||||
- shows templates
|
||||
- shows recent envelopes filtered by `from_date`
|
||||
|
||||
## Named credential model
|
||||
|
||||
### CLM
|
||||
- UAT CLM API: `CLMuatNamedCreds`
|
||||
- UAT CLM download: `CLMuatDownload`
|
||||
- S1 CLM API: `CLMs1NamedCreds`
|
||||
- S1 CLM download: `CLMs1Download`
|
||||
|
||||
### eSignature
|
||||
- eSignature REST: `Esignature_Demo_NamedCreds`
|
||||
- OAuth/account server: `AcctDemo_NamedCreds`
|
||||
|
||||
## Current product behavior
|
||||
|
||||
### What is working now
|
||||
- record-based CLM doc generation from Salesforce UI
|
||||
- XML merge with repeating deficiencies
|
||||
- account-based CLM config
|
||||
- metadata-based letter-type selection with backward-compatible default behavior
|
||||
- generated document status persistence on the case
|
||||
- generated document attachment to the case as a Salesforce File
|
||||
- account-based eSignature API exploration
|
||||
- eSignature template listing
|
||||
- eSignature envelope listing
|
||||
|
||||
### Known limitations
|
||||
- no end-user workflow yet for creating or sending envelopes
|
||||
- no template or envelope detail drill-down in the eSignature UI
|
||||
- no persistent eSignature activity tracking on the case
|
||||
- no dedicated admin UI yet for managing account configuration beyond Salesforce Setup
|
||||
- some older docs still contain historical planning content
|
||||
|
||||
## Current template contract
|
||||
|
||||
### CLM XML merge fields
|
||||
- `//AppraiserCaseNumber`
|
||||
- `//AppraiserFieldReviewDate`
|
||||
- `//PropertyAddress`
|
||||
- `//PropertyStreet`
|
||||
- `//PropertyCity`
|
||||
- `//PropertyStateProvince`
|
||||
- `//PropertyPostalCode`
|
||||
- `//PropertyCountry`
|
||||
|
||||
### Deficiency repeating block
|
||||
- row select: `//DeficiencyList/Deficiency`
|
||||
- fields:
|
||||
- `./Number`
|
||||
- `./Description`
|
||||
- `./Reference`
|
||||
- `./Resolution`
|
||||
|
||||
## Near-term roadmap
|
||||
- add eSignature detail calls for template detail and envelope detail
|
||||
- add envelope creation and draft-send flows
|
||||
- add better operator UX for large account lists and debugging output
|
||||
- tighten documentation around setup and account configuration
|
||||
- decide whether to retire `Property_Address__c` completely from metadata
|
||||
|
||||
## Out of scope for the current proof of concept
|
||||
- full production-grade approval workflow
|
||||
- end-user template authoring inside Salesforce
|
||||
- large-scale reporting or analytics
|
||||
- middleware outside Salesforce
|
||||
|
||||
---
|
||||
Last updated: 2026-04-09
|
||||
|
|
@ -1,28 +1,26 @@
|
|||
# Appraiser Review Letter Generator (Salesforce + DocuSign CLM)
|
||||
|
||||
## Welcome!
|
||||
This project contains documentation and guides for building Appraiser Review Letter templates for use in Salesforce CLM (Contract Lifecycle Management).
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
This application automates generation of personalized appraiser review letters within Salesforce, merging Q&A responses and related data into a DocuSign CLM-powered letter. Content and layout adjust dynamically to each review scenario.
|
||||
This repo contains a Salesforce metadata project for generating appraiser review letters from `Appraiser_Case__c` data in DocuSign CLM, while also providing a growing proof-of-concept surface for DocuSign eSignature API workflows.
|
||||
|
||||
## Architecture Overview
|
||||
- Templates are rendered using dynamic data from Salesforce objects
|
||||
- All merge fields and arrays are mapped from Salesforce data model
|
||||
- Modular blocks for easy maintenance and expansion
|
||||
## Current status
|
||||
- The repo is standardized on the XML CLM merge path built around `AppraiserCasePayloadBuilder` + `CLMDocGenCallout`.
|
||||
- `Appraiser_Case_Deficiency__c` is the canonical child deficiency object used by both the UI and document generation.
|
||||
- Account-based DocuSign configuration lives in `CLM_Account_Setting__mdt`.
|
||||
- The current Salesforce UI includes:
|
||||
- the `Generate Review Letter` quick action for CLM doc gen
|
||||
- the `Docusign eSignature` record tab for eSignature browsing
|
||||
- CLM generation, task tracking, file attachment, and eSignature template/envelope browsing are all implemented.
|
||||
|
||||
## Key Features
|
||||
- Dynamic merge of Appraiser Review answers (tables, paragraphs)
|
||||
- Salesforce-initiated CLM document generation and delivery
|
||||
- Robust requirements, data, and design documentation
|
||||
## Read this first
|
||||
- [PRODUCT_SPEC.md](./PRODUCT_SPEC.md): current product definition and architecture
|
||||
- [CURRENT_STATUS.md](./CURRENT_STATUS.md): implementation snapshot and current recommendations
|
||||
- [SALESFORCE_SETUP.md](./SALESFORCE_SETUP.md): metadata and org setup notes
|
||||
- [CLM_INTEGRATION.md](./CLM_INTEGRATION.md): CLM integration details
|
||||
- [requirements.md](./requirements.md) and [design.md](./design.md): condensed companion docs aligned to the product spec
|
||||
|
||||
## Onboarding
|
||||
- Clone docs directory into your Salesforce project repo
|
||||
- Review CLM_TEMPLATE_GUIDE.md for template logic and examples
|
||||
- See requirements.md for merge field details
|
||||
## Documentation note
|
||||
Older planning docs still exist, but `PRODUCT_SPEC.md`, `CURRENT_STATUS.md`, `SALESFORCE_SETUP.md`, and the source code are now the best reflection of the project.
|
||||
|
||||
---
|
||||
_Last updated: 2026-02-26 13:23 PM_
|
||||
_Work in progress: Add quick-start workflow and test recommendations._
|
||||
_Last updated: 2026-04-09_
|
||||
|
|
|
|||
|
|
@ -1,36 +1,60 @@
|
|||
# Salesforce Setup — Appraiser Case + DocuSign CLM
|
||||
|
||||
> Status note (2026-04-07): the project is now standardized on `Appraiser_Case_Deficiency__c` for both UI display and CLM document generation.
|
||||
|
||||
## What was added
|
||||
|
||||
### Custom object: `Appraiser_Case__c`
|
||||
- Auto-number name field labeled **Appraiser Case Number**
|
||||
- `Appraiser_Field_Review_Date__c` (Date)
|
||||
- `Property_Street__c` (Text 255)
|
||||
- `Property_City__c` (Text 80)
|
||||
- `Property_State_Province__c` (Text 80)
|
||||
- `Property_Postal_Code__c` (Text 20)
|
||||
- `Property_Country__c` (Text 80)
|
||||
- Dates: `Appraiser_Field_Review_Date__c`, `Letter_Sent_Date__c`
|
||||
- Appraiser identity: `Appraiser_Name__c`, `Appraiser_Last_Name__c`, `Appraiser_Salutation__c`, `Appraiser_Email__c`
|
||||
- Appraiser address: `Appraiser_Street__c`, `Appraiser_City__c`, `Appraiser_State_Province__c`, `Appraiser_Postal_Code__c`, `Appraiser_Country__c`
|
||||
- Property address: `Property_Street__c`, `Property_City__c`, `Property_State_Province__c`, `Property_Postal_Code__c`, `Property_Country__c`
|
||||
- Case metadata: `FHA_Case_Number__c`
|
||||
- CLM tracking: `Last_CLM_Account_Code__c`, `Last_DocGen_Status__c`, `Last_DocGen_Message__c`, `Last_DocGen_Task_Id__c`, `Last_DocGen_Task_Url__c`, `Last_Template_Document_Href__c`, `Last_Destination_Folder_Href__c`, `Last_DocGen_Requested_At__c`, `Last_DocGen_Completed_At__c`
|
||||
- Generated document: `Generated_Document_Id__c`, `Generated_Document_Url__c`
|
||||
- Attached file: `Attached_File_Content_Document_Id__c`, `Attached_File_Url__c`
|
||||
|
||||
### Child custom object: `Appraiser_Deficiency__c`
|
||||
### Child custom object: `Appraiser_Case_Deficiency__c`
|
||||
- Master-detail to `Appraiser_Case__c`
|
||||
- `Deficiency_Number__c` (Text 50)
|
||||
- `Deficiency_Number__c` (Number)
|
||||
- `Description__c` (Long Text Area)
|
||||
- `Resolution__c` (Long Text Area)
|
||||
- `Sort_Order__c` (Number)
|
||||
- `Reference__c` (Text)
|
||||
|
||||
### Layouts
|
||||
- Basic page layout for Appraiser Case
|
||||
- Basic page layout for Appraiser Deficiency
|
||||
### Custom metadata types
|
||||
- `CLM_Account_Setting__mdt` — per-account CLM and eSignature configuration (Named Credentials, folder hrefs, template hrefs)
|
||||
- `CLM_Letter_Definition__mdt` — per-account letter type definitions with optional folder/template overrides
|
||||
- `CLM_Environment_Setting__mdt` — legacy environment defaults (UAT/S1); superseded by account settings
|
||||
|
||||
### Apex classes
|
||||
- `AppraiserCasePayloadBuilder.cls` + test
|
||||
- `CLMDocGenCallout.cls` + test
|
||||
- `CLMAdminService.cls` + test
|
||||
- `DocusignESignatureService.cls` + test
|
||||
|
||||
### Lightning Web Components
|
||||
- `clmDocGenWorkbench` — CLM document generation UI (account selection, folder browsing, merge task submission, status polling, file attachment)
|
||||
- `docusignEsignWorkbench` — eSignature API browsing (accounts, templates, envelopes)
|
||||
- `clmRequestPreview` — merge request preview utility
|
||||
|
||||
### Named credentials
|
||||
- `CLMuatNamedCreds`, `CLMs1NamedCreds` — CLM API calls
|
||||
- `CLMuatDownload`, `CLMs1Download` — CLM document downloads
|
||||
- `Esignature_Demo_NamedCreds` — eSignature REST API
|
||||
- `AcctDemo_NamedCreds` — eSignature OAuth/userinfo
|
||||
|
||||
### Layouts and UI
|
||||
- Page layouts for `Appraiser_Case__c` and `Appraiser_Case_Deficiency__c`
|
||||
- Related list on Appraiser Case for deficiencies
|
||||
- Basic list view on Appraiser Case
|
||||
|
||||
### Tabs and permissions
|
||||
- Record page: `Appraiser_Case_Record_Page`
|
||||
- Quick action: `Generate Review Letter` (launches `clmDocGenWorkbench`)
|
||||
- Custom tabs for both objects
|
||||
- Permission set: `Appraiser_Case_Admin`
|
||||
- Custom app: `Appraiser_Review`
|
||||
|
||||
### Apex
|
||||
- `AppraiserCaseDocGenService.cls`
|
||||
- `AppraiserCaseDocGenServiceTest.cls`
|
||||
### Permissions
|
||||
- `Appraiser_Case_Admin` — full access
|
||||
- `Appraiser_Case_Access` — read/create access
|
||||
|
||||
### Sample data
|
||||
- Anonymous Apex script: `scripts/apex/createSampleAppraiserCase.apex`
|
||||
|
|
@ -52,7 +76,7 @@ sf project deploy start --source-dir /home/paulh/.openclaw/workspace/projects/sa
|
|||
## Test Apex
|
||||
|
||||
```bash
|
||||
sf apex run test --tests AppraiserCaseDocGenServiceTest --result-format human
|
||||
sf apex run test --tests AppraiserCasePayloadBuilderTest --tests CLMAdminServiceTest --tests CLMDocGenCalloutTest --tests DocusignESignatureServiceTest --result-format human
|
||||
```
|
||||
|
||||
## Load sample data
|
||||
|
|
@ -73,12 +97,12 @@ sf org assign permset --name Appraiser_Case_Admin
|
|||
2. Assign permission set.
|
||||
3. Run the sample Apex script.
|
||||
4. Open the `Appraiser Case` tab and verify the record + related deficiencies.
|
||||
5. Validate the JSON payload in debug logs or by running the Apex methods directly.
|
||||
6. Wire the DocuSign CLM launch path based on the exact package capability in your org.
|
||||
5. Validate the XML merge payload path in debug logs or by running the Apex methods directly.
|
||||
6. Open an `Appraiser Case` record and use the `Generate Review Letter` action to browse folders/templates and submit a merge task.
|
||||
|
||||
## About the quick action
|
||||
|
||||
A placeholder quick action metadata file was added to mark the launch point, but DocuSign CLM launch mechanics vary by package/org. See `docs/NEXT_STEPS_DOCGEN.md` for the practical wiring options.
|
||||
The `Generate Review Letter` quick action is now wired to the `clmDocGenWorkbench` LWC for interactive CLM browsing and merge submission.
|
||||
|
||||
## About “page layout” and “default setup”
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,45 +1,48 @@
|
|||
# Design — Appraiser Review Letter Generator
|
||||
# Design — Appraiser Review Letter Platform
|
||||
|
||||
## Architecture
|
||||
Describe the template structure, merge field handling logic, and integration with Salesforce CLM.
|
||||
This document now serves as a compact architecture summary. The broader current-state reference is [PRODUCT_SPEC.md](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/docs/PRODUCT_SPEC.md).
|
||||
|
||||
## Current architecture
|
||||
|
||||
### Salesforce records
|
||||
- `Appraiser_Case__c` is the parent business object
|
||||
- `Appraiser_Case_Deficiency__c` is the canonical child object
|
||||
|
||||
### Configuration
|
||||
- `CLM_Account_Setting__mdt` stores account-level CLM and eSignature configuration
|
||||
|
||||
### CLM path
|
||||
- [AppraiserCasePayloadBuilder.cls](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/classes/AppraiserCasePayloadBuilder.cls)
|
||||
- [CLMDocGenCallout.cls](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/classes/CLMDocGenCallout.cls)
|
||||
- [CLMAdminService.cls](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/classes/CLMAdminService.cls)
|
||||
- [clmDocGenWorkbench](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/lwc/clmDocGenWorkbench/clmDocGenWorkbench.js)
|
||||
|
||||
### eSignature path
|
||||
- [DocusignESignatureService.cls](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/classes/DocusignESignatureService.cls)
|
||||
- [docusignEsignWorkbench](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app/main/default/lwc/docusignEsignWorkbench/docusignEsignWorkbench.js)
|
||||
|
||||
## CLM merge design
|
||||
- Salesforce builds XML merge data from the case and related deficiencies.
|
||||
- CLM document generation uses `documentxmlmergetasks`.
|
||||
- Folder and template selection are account-configurable and browsable in the UI.
|
||||
- Task results and generated-document references are persisted back to `Appraiser_Case__c`.
|
||||
- Generated CLM output can be downloaded via Named Credential and attached to the case as a Salesforce File.
|
||||
|
||||
## eSignature design
|
||||
- Separate Named Credentials are used for REST calls and account-server OAuth/userinfo calls.
|
||||
- The service currently supports:
|
||||
- login information
|
||||
- OAuth user info
|
||||
- discovered accounts
|
||||
- template listing
|
||||
- envelope listing
|
||||
- The current eSignature panel is an operator/admin browsing surface, not yet a business workflow.
|
||||
|
||||
## Design principles
|
||||
- prefer account-based config over environment-only config
|
||||
- keep DocuSign callouts in Apex behind UI-facing service methods
|
||||
- persist important CLM results onto the business record
|
||||
- use record-page or action-based LWCs for operator flows instead of Execute Anonymous
|
||||
|
||||
---
|
||||
|
||||
## Data Model
|
||||
- Appraiser_Review__c: main record
|
||||
- Appraiser_Review_Question__c: child (per Q&A)
|
||||
|
||||
## Merge Data (to CLM)
|
||||
- Flat fields: appraiser, address, etc.
|
||||
- Collection: reviewQuestions[] with Q, A, comments, etc.
|
||||
|
||||
## Template Structure
|
||||
- Modular blocks (Header/Body/Footer)
|
||||
- Dynamic sections for deficiencies, comments, summary
|
||||
- Use of template language (Handlebars/Mustache/etc)
|
||||
|
||||
## Merge Logic
|
||||
- Iterate lists (arrays) for tables
|
||||
- Conditional display for sections/questions
|
||||
- Null/empty handling (default text or suppression)
|
||||
|
||||
## Example Structure
|
||||
```handlebars
|
||||
{{#each DeficiencyList}}
|
||||
<tr><td>{{DeficiencyType}}</td><td>{{DeficiencyDescription}}</td></tr>
|
||||
{{/each}}
|
||||
```
|
||||
|
||||
## CLM Template Guidance
|
||||
- Repeat blocks/tables for reviewQuestions
|
||||
- Conditional/variable blocks for rich, dynamic output
|
||||
|
||||
---
|
||||
|
||||
## Questions/Decisions
|
||||
- Should merge logic be handled in Salesforce or intermediary middleware?
|
||||
- What template engine is ideal for maintainability and troubleshooting?
|
||||
|
||||
---
|
||||
_Last updated: 2026-02-26 13:20 PM_
|
||||
_Work in progress: More complete architecture diagrams and template examples forthcoming._
|
||||
Last updated: 2026-04-09
|
||||
|
|
|
|||
|
|
@ -1,47 +1,32 @@
|
|||
# Requirements — Appraiser Review Letter Generator
|
||||
# Requirements — Appraiser Review Letter Platform
|
||||
|
||||
## Purpose
|
||||
Outline technical and functional requirements for Appraiser Review Letter templates in Salesforce CLM. Include assumed merge fields, integration points, edge cases, and design goals.
|
||||
This document now serves as a short requirements summary. The full current product specification is in [PRODUCT_SPEC.md](/home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/docs/PRODUCT_SPEC.md).
|
||||
|
||||
## Functional requirements
|
||||
- A user can generate an appraiser review letter from an `Appraiser_Case__c` record in Salesforce.
|
||||
- The generated CLM document merges property data and a repeating deficiency list from Salesforce.
|
||||
- The user can choose a configured CLM account instead of hardcoding environment-specific values.
|
||||
- The user can browse CLM templates and destination folders in the UI.
|
||||
- The user can track CLM task status and attach the generated document back to the case.
|
||||
- The system can browse core eSignature account data, templates, and envelopes for configured accounts.
|
||||
|
||||
## Non-functional requirements
|
||||
- Account-specific configuration must be deployable and maintainable through Salesforce metadata.
|
||||
- The solution must support both UAT and S1 CLM/eSignature account setups.
|
||||
- The primary document-generation path must be test-covered in Apex.
|
||||
- The solution should remain usable as a proof-of-concept platform for additional DocuSign API work.
|
||||
|
||||
## Canonical requirements decisions
|
||||
- Canonical parent object: `Appraiser_Case__c`
|
||||
- Canonical child deficiency object: `Appraiser_Case_Deficiency__c`
|
||||
- Canonical CLM generation path: XML merge via `documentxmlmergetasks`
|
||||
- Canonical config source: `CLM_Account_Setting__mdt`
|
||||
- Structured property address fields are the source of truth; `Property_Address__c` is legacy
|
||||
|
||||
## Current open product questions
|
||||
- What should the first production-grade eSignature workflow be: template detail, envelope detail, draft creation, or send?
|
||||
- Should eSignature activity be persisted back onto `Appraiser_Case__c` the way CLM activity is?
|
||||
- Should the eSignature workbench remain a testing/admin surface or evolve into a business-user workflow?
|
||||
|
||||
---
|
||||
|
||||
## Functional
|
||||
- Reviewer completes form Q&A on Appraiser Review
|
||||
- Each response drives tailored content in final letter (questions, comments, tables/blocks)
|
||||
- Salesforce triggers CLM letter, merges data fields and Q&A collection
|
||||
|
||||
## Non-Functional
|
||||
- Configurable (new Qs/fields easy to add)
|
||||
- Audit and status tracking
|
||||
- Support for complex/dynamic tables in output
|
||||
|
||||
## Key Requirements
|
||||
- Support dynamic template merge fields (arrays/lists, booleans, enums)
|
||||
- Render tables, paragraphs, and conditional sections
|
||||
- Handle edge cases: nulls, empty lists, formatting gaps
|
||||
- Provide fallback text for empty sections (e.g., 'No deficiencies found')
|
||||
- Enable integration with Salesforce data model (objects: Appraisal, Deficiency, Reviewer)
|
||||
|
||||
## Example JSON
|
||||
```json
|
||||
{
|
||||
"AppraisalId": "a1b2c3",
|
||||
"DeficiencyList": [
|
||||
{
|
||||
"DeficiencyType": "Missing Docs",
|
||||
"DeficiencyDescription": "Appraisal report lacking required documents."
|
||||
}
|
||||
],
|
||||
"ReviewerComments": ["Well organized report."]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Questions/Decisions
|
||||
- What is the authoritative object and field schema for merge?
|
||||
- Are custom field mappings needed for relationships (e.g. lookup fields)?
|
||||
|
||||
---
|
||||
_Last updated: 2026-02-26 10:35 AM_
|
||||
_Work in progress: Integration and schema expansion next._
|
||||
Last updated: 2026-04-09
|
||||
|
|
|
|||
Loading…
Reference in New Issue