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

123 lines
4.6 KiB
Markdown

# 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._