salesforce-appraiser-review.../DECISIONS.md

4.6 KiB

Architecture Decision Records

Non-obvious decisions that agents must not undo. Read during Orient phase every iteration.


ADR-001: Option A (template-based envelope) for createEnvelope()

Date: 2026-04-09 Status: Accepted

Context: Two approaches were considered for creating a DocuSign eSignature envelope:

  • Option A: POST with a templateId — DocuSign template defines recipients/tabs, Salesforce only passes merge data at send time
  • Option B: POST with a raw document (download CLM blob, upload as base64) — Salesforce manages all recipient config

Decision: Use Option A. Simpler implementation, no blob download, recipient config lives in the DocuSign template where it belongs.

Consequences: Fewer lines of Apex (no ContentVersion download, no base64 encoding) Recipient/tab configuration lives in DocuSign where it is maintained Requires a matching eSignature template to exist in the DocuSign account If the template does not exist, the API returns a 400 — the operator must set up the template first

Alternatives Considered: Option B was rejected as unnecessary complexity for this proof-of-concept phase.


ADR-002: Named credentials for all DocuSign API calls

Date: 2026-04-09 Status: Accepted

Context: All CLM and eSignature API calls must go through Salesforce named credentials. No hardcoded tokens, passwords, or base URLs in Apex.

Decision: Named credential API name is always sourced from CLM_Account_Setting__mdt:

  • CLM calls use CLM_API_Named_Credential__c
  • eSignature calls use ESignature_Rest_Named_Credential__c

The eSignatureAccountId is also from CLM_Account_Setting__mdt.ESignature_Account_Id__c.

Consequences: No secrets in source code Works with Salesforce's credential management (OAuth token refresh, etc.) Named credentials must be manually configured in each org before the code works


ADR-003: persistEnvelopeResult follows persistDocGenResult pattern

Date: 2026-04-09 Status: Accepted

Context: The project already has CLMAdminService.persistDocGenResult() which writes CLM task results back to the case. The eSignature result persistence should follow the same pattern — not a new approach.

Decision: CLMAdminService.persistEnvelopeResult() is an @AuraEnabled static method that takes structured parameters (not a blob or generic map) and writes specific fields to the case via a SOQL update. Same structure as persistDocGenResult.

Consequences: Consistent code pattern, agent can learn from existing method Testable with the same approach as CLMAdminServiceTest


ADR-004: eSignature tracking fields belong on Appraiser_Case__c

Date: 2026-04-09 Status: Accepted

Context: The case is the central record. CLM tracking fields already live on Appraiser_Case__c. The eSignature tracking fields follow the same pattern.

Decision: All five eSignature lifecycle fields go on Appraiser_Case__c, not on a child record or a separate object.

Consequences: Single record for operator to view Consistent with existing CLM field placement Only one envelope tracked per case (sufficient for Phase 2)


ADR-005: Operator manually enters template ID in Phase 2

Date: 2026-04-09 Status: Accepted

Context: Option: auto-populate the template ID from CLM_Letter_Definition__mdt or present a template browser. Both require additional metadata fields or another API call and are out of scope for Phase 2.

Decision: The operator inputs the eSignature template ID directly into a text field in clmDocGenWorkbench. No auto-selection, no browser, no additional metadata field.

Consequences: Simpler Phase 2 scope No new metadata record changes needed Operator must know the template ID — acceptable for a proof-of-concept

Review after: Phase 3 could add a ESignature_Template_Id__c field to CLM_Letter_Definition__mdt and pre-populate the input.


ADR-006: HTTP mocks required for all Apex callout tests

Date: 2026-04-09 Status: Accepted

Context: Salesforce requires all HTTP callouts in test classes to use Test.setMock(HttpCalloutMock.class, ...). The existing test classes all follow this pattern.

Decision: All tests for createEnvelope() must mock the HTTP response using an inner MockHttpResponse class implementing HttpCalloutMock. Do not attempt live callouts in test methods.

Consequences: Tests run in any Salesforce org without external connectivity Consistent with existing test class patterns (see CLMDocGenCalloutTest)


Decisions don't drift if they're written down.