The IAccountManagementPATCH Apex interface provides extensibility for PATCH operations through Apex pre- and post-hooks and GraphQL query customization. Implementations can validate incoming requests, modify query structures, and refine the response to support business-specific retrieval rules while maintaining TMF-compliant behavior.
Resolves a caller-provided business key or external identifier to the canonical Salesforce Account ID before validation and update processing begins.
- Resolve an ERP customer number - Map a billing-system identifier to an Account ID - Translate a partner-specific key - Resolve a legacy Account reference
Allows callers to address Account records using their own identifiers instead of requiring a Salesforce ID.
Default or Enrich Fields Before Update
transformRequest
Normalizes the incoming partial update and supplies default, derived, or contextual values before validation. This reduces the amount of data clients must provide and ensures consistent input.
- Normalize phone numbers and addresses - Derive a region from the country code - Supply a source-system value from the request context - Standardize status or classification values
Reduces client payload complexity and ensures consistent Account data before it is written.
Validate State Transitions and Business Rules
applyCustomValidations
Evaluates the proposed partial update against organization-specific lifecycle rules and business constraints before the mutation is built.
- Reject an invalid Active to Closed transition - Prevent status changes while open balances exist - Require a reason when suspending an Account - Restrict sensitive updates to authorized roles
Rejects invalid partial updates early and protects Account lifecycle and data integrity.
Enable Conditional Validators for Partial Updates
configureDefaultValidations
Enables validation flags according to the fields included in the partial update. Validators for nested objects run only when the corresponding data is present.
- Validate relatedParty when included - Validate Contact sub-objects when supplied - Enable address validation only when an address changes - Apply stricter checks when regulated fields are updated
Applies relevant validation without requiring absent fields or running unnecessary checks during partial updates.
Auto-Populate or Override Mutation Fields
customiseMutationPayload
Adds or replaces fields in the GraphQL mutation payload before execution, including organization-specific values that are not represented in the TMF schema.
- Set lastModifiedBy and lastModifiedAt - Add a source-system or correlation ID - Override a derived lifecycle status - Populate internal classification or compliance fields
Persists organization-specific fields and provenance beyond the standard TMF schema.
Update Related Records Not Covered by PATCH
customiseMutationPayload (insertGraphQlSnippet)
Inserts an additional GraphQL operation into the mutation so related records can be updated atomically with the Account.
Updates junctions and other related records in the same mutation, reducing extra API calls and inconsistent intermediate states.
Create an Audit Trail or Trigger Downstream Processing
handlePostOperation
Runs after the update mutation succeeds and uses the operation result to perform compliance logging, publish events, or invoke downstream integrations.
- Write an Account-update audit record - Publish an Account-changed event - Synchronize changes with billing or CRM systems - Trigger compliance review or notifications - Invalidate related caches or indexes
Supports compliance and integration side effects while keeping them separate from the core update operation.
transformRequest
This hook transforms the request context before processing any operation. It is invoked early in the request lifecycle, allowing implementers to adjust the context for subsequent extensibility hooks.
Resolve an external identifier into the Salesforce ID.
1global class AccountMgmtTransformRequestPatchExt implements comms_apex_ext.IAccountManagementPATCH {234 global static Map<String, Object> transformRequest(Map<String, Object> context) {5 if (context == null) {6 return context;7 }8910 // If the caller addressed the record by an external key, resolve it to the SF id.11 Object idObj = context.get('id');12 if (idObj instanceof String && ((String) idObj).startsWith('EXT-')) {13 String externalKey = (String) idObj;14 List<BillingAccount> matches = [15 SELECT Id FROM BillingAccount WHERE ExtlBillingAccountId__c = :externalKey LIMIT 116 ];17 if (!matches.isEmpty()) {18 context.put('id', matches[0].Id);19 }20 }21 return context;22 }232425 // ... other hooks return null / empty map ...26}
configureDefaultValidations
This hook enables, disables, or modifies the built-in validation rules before they execute.
1global class AccountMgmtValidationConfigPatchExt implements comms_apex_ext.IAccountManagementPATCH {234 global static Map<String, Boolean> configureDefaultValidations(5 Map<String, Boolean> defaultValidationConfiguration,6 Map<String, Object> context7 ) {8 // Start from the passed-in default and enable only the conditional validators.9 Map<String, Boolean> spec = defaultValidationConfiguration != null10 ? defaultValidationConfiguration.clone()11 : new Map<String, Boolean>();12 spec.put('mandatoryFieldsValidation', false); // keep OFF for merge-patch13 spec.put('relatedPartyValidation', true); // conditional: only fires if relatedParty is present14 spec.put('contactValidation', true); // conditional: only fires if contact is present15 return spec;16 }171819 // ... other hooks return null / empty map ...20}
Do not enable mandatoryFieldsValidation for a typical PATCH request. It requires a non-empty relatedParty array and name, which merge-patch callers may omit, causing valid partial updates to be rejected. The PATCH handler only updates BillingAccount scalar fields; relatedParty and contact values in the request are validated, if those validators are enabled, but are not persisted as junction changes.
Note
applyCustomValidations
This hook validates custom business logic before retrieving customer record. If validation fails, it rejects the request and returns an error response.
The handler processes return values as follows.
Success:
Return a map with validationStatus set to “pass” (case-insensitive).
The API request continues normally.
Other fields in the map are logged but not used.
Failure:
Return a map with validationStatus set to “fail” (case-insensitive).
The API request is terminated immediately.
Raise a ValidationException containing
message: value from validationMessage key (or “Validation failed” by default)
details: value from validationDetails key (optional)