Objects & Metadata - Guide
Framework: KernDX Package Type: Managed Package
Target Audience:
- Developers - Understanding custom objects, metadata types, and configuration patterns for framework implementation
- Architects - Designing solutions leveraging framework objects, custom settings, and metadata-driven configuration
- Business Analysts - Understanding data model, configuration options, and cross-framework relationships
Table of Contents
Expand
- Quick Navigation
- Overview
- Architecture
- Quick Start
- Framework Documentation
- Cross-Framework Relationships
- Usage Patterns
- Testing
- Anti-Patterns
- Best Practices
- Related Documentation
- Appendix A: Mermaid ERD
Quick Navigation
| I am a... | I need to... | Go to... |
|---|---|---|
| Architect | Understand the data model | Architecture |
| Architect | See cross-framework relationships | Cross-Framework Relationships |
| Developer | Find object field references | Framework Documentation |
| Developer | See integration patterns | Usage Patterns |
| Analyst | Configure trigger settings | Trigger Action Framework |
| Analyst | Configure validation rules | Validation Framework |
| Analyst | Configure API settings | Web Service Framework |
| Analyst | Configure feature flags | Feature Management Framework |
Overview
> Responsibilities: This guide documents the data model and metadata configuration for the KernDX framework. The objects and metadata types > described here store configuration, logs, and operational data. They do not contain business logic -- that lives in the Apex classes > documented in other guides.
> Package Data Model: 10 custom objects, 15 custom metadata types, 57 pre-built metadata records, and 1 platform event. > These objects underpin the Logging, Trigger, Web Service, Feature Flag, Async, and Validation frameworks.
> For current framework statistics, see Metrics.
The KernDX managed package includes custom SObjects that provide enterprise-grade infrastructure for Salesforce development:
- Custom Objects - Persistent data storage for logs, configurations, and operational data
- Custom Settings - Runtime configuration and feature toggles
- Platform Events - Event-driven architecture for asynchronous processing
- Custom Metadata Types - Declarative configuration for framework behaviors
These objects work together to provide integrated frameworks: Logging, Trigger Actions, Web Services, Feature Management, Asynchronous Operations, and Data Management. For background on Salesforce Custom Metadata Types, Custom Objects, and Platform Events, see the Salesforce documentation.
Architecture
Custom Objects
| Object | Purpose | Key Features |
|---|---|---|
LogEntry__c | Persistent log storage | Severity levels, stack traces, record associations, correlation IDs |
ScheduledJob__c | Scheduled job management | Cron expressions, execution history, active/inactive control |
LoginFrequency__c | User login analytics | Tracks monthly login counts per user |
ApiCall__c | API orchestration & tracking | Request/response logging, retry logic, performance metrics |
ApiIssue__c | Failed API retry management | Error details, retry status, parameter hashing |
AsyncChainExecution__c | Async chain orchestration tracking | Step progress, duration, correlation IDs, context data |
Custom Settings
| Custom Setting | Type | Purpose |
|---|---|---|
ApiRuntimeSwitch__c | Hierarchy | Runtime API kill switch (disable all APIs per user/profile/org) |
LogSetting__c | Hierarchy | Log level thresholds and performance logging toggles (per user / profile / org) |
ScheduleSetting__c | List | Runtime state for scheduled jobs (last run time) |
Platform Events
| Event | Purpose | Consumed By |
|---|---|---|
LogEntryEvent__e | Asynchronous log publishing | TRG_LogEntryEvent trigger handler |
Custom Metadata Types
| Metadata Type | Purpose | Parent/Child Relationships |
|---|---|---|
AsynchronousJobSetting__mdt | Asynchronous job configuration | - |
ClassTypeResolver__mdt | Class name resolution | - |
FeatureFlag__mdt | Feature flag definitions | Parent of FeatureFlagStrategy__mdt |
FeatureFlagStrategy__mdt | Feature flag evaluation rules | Child of FeatureFlag__mdt |
FieldSetGroup__mdt | Field set grouping | - |
MaskingRule__mdt | Data masking rule definitions (what to mask and how) | Parent of MaskingTarget__mdt |
MaskingTarget__mdt | Rule-to-field wirings (where to apply each rule) | Child of MaskingRule__mdt |
TriggerAction__mdt | Trigger action definitions | Child of TriggerSetting__mdt via TriggerSetting__c |
TriggerSetting__mdt | Per-object trigger configuration | Parent of TriggerAction__mdt |
PostTriggerAction__mdt | Actions run once at end of the trigger transaction | Optional child of TriggerSetting__mdt via TriggerSetting__c |
ApiCredential__mdt | API credentials | Parent of ApiSetting__mdt |
ApiMock__mdt | API mock response configuration | - |
ApiSetting__mdt | API endpoint configuration | Child of ApiCredential__mdt |
ValidationRuleGroup__mdt | Validation rule grouping per object | Child of TriggerSetting__mdt, parent of ValidationRule__mdt |
ValidationRule__mdt | Individual validation rule configuration | Child of ValidationRuleGroup__mdt |
Quick Start
The most common metadata configuration tasks are setting up trigger actions and scheduling jobs. Here are the two most frequent patterns:
Configure a trigger action via custom metadata:
Create a TriggerSetting__mdt record for your object, then create a TriggerAction__mdt child record pointing to your handler class. The framework automatically discovers and executes your handler when the trigger fires.
TriggerSetting__mdt:
SObjectType__c = Foobar__c (EntityDefinition)
TriggerAction__mdt:
ApexClassName__c = 'TRG_SetFoobarDefaults'
TriggerSetting__c = [above record]
Event__c = 'Before Insert'
Order__c = 1Schedule a recurring job via ScheduledJob__c:
Create a ScheduledJob__c record with a cron expression and class name. Set IsActive__c = true and the framework schedules the job automatically.
ScheduledJob__c job = new ScheduledJob__c();
job.SchedulerName__c = 'Nightly Log Purge';
job.ClassName__c = 'SCHED_PurgeRecords';
job.CronExpression__c = '0 0 2 * * ?';
job.Parameters__c = new DTO_NameValues(new Map<String, String>{'objectName' => 'LogEntry__c', 'minimumNumberOfDays' => '90'}).serialize();
job.IsActive__c = true;
insert job;For deeper coverage, continue reading the sections below.
Framework Documentation
Logging Framework
Purpose: Provides asynchronous, persistent logging with categorization, severity levels, and record associations using LOG_Builder, LogEntry__c, LogEntryEvent__e and LogSetting__c. Sensitive content in logs is redacted by the shared data masking framework — see MaskingRule__mdt and MaskingTarget__mdt.
See also: Logging - Guide, Fast Start - Logging
Architecture Diagram
+-----------------------------------------------------------------+
| LOG_Builder (Apex Code) UTIL_PerformanceTimer |
| |
| Logging Methods: Context Methods: Performance: |
| .info() .startCorrelation() .start() |
| .warn() .setCorrelationId() .stop() |
| .error() .setGlobalContext() .stopSilent() |
| .debug() .clearGlobalContext() |
| .serializeContext() Buffering: |
| .hydrateContext() .suspendSaving() |
| .resumeSaving() |
+-----------------+-----------------------------------------------+
| publishes
v
+-----------------------------------------------------------------+
| LogEntryEvent__e (Platform Event) |
| - Message, LogLevel, ClassMethod, RecordId |
| - CorrelationId, TransactionId, ParentTransactionId |
| - ContextData (JSON), DurationMs |
+-----------------+-----------------------------------------------+
| consumed by
v
+-----------------+
| TRG_LogEntryEvent | (Trigger Handler)
+--------+--------+
| creates
v
+-----------------------------+
| LogEntry__c |
| - Message, ClassMethod |
| - LogLevel, StackTrace |
| - RecordId, UserId |
| - CorrelationId | Configuration:
| - TransactionId | +-----------------------------+
| - ParentTransactionId | | MaskingRule__mdt |
| - ContextData | | - Mode (Regex/JsonKey/Exact)|
| - DurationMs | | - Pattern, Replacement |
+-----------------------------+ | - FailureAction, IsActive |
+-----------------------------+
+-----------------------------+
| MaskingTarget__mdt |
| - Rule, SObjectType, Field |
| - CallerClass, IsActive |
+-----------------------------+
+-----------------------------+
| LogSetting__c |
| - IsEnabled |
| - LogLevelThreshold |
| - EnablePerformanceLogging |
| - PerformanceThresholdMs |
| - MaxContextDataSize |
+-----------------------------+Objects
LogEntry__c (Custom Object)
Description: Stores all log messages generated from Apex code.
Fields:
| Field | Type | Description |
|---|---|---|
ContextData__c | Long Text Area(32768) | Structured context data as JSON (key-value pairs for debugging) |
CorrelationId__c | Text(36) | Correlation ID linking related log entries across transactions |
DurationMs__c | Number(18,0) | Duration in milliseconds (for performance-timed operations) |
ExceptionType__c | Text(255) | Exception type associated with the log |
ExecutionEvent__c | Picklist | Salesforce execution context (Quiddity): SYNCHRONOUS, BATCH_APEX, FUTURE, QUEUEABLE, etc. |
Limits__c | Long Text Area(1024) | JSON snapshot of Salesforce governor limits at the time the event was logged |
LineNumber__c | Number(8,0) | Source code line number where the exception occurred |
LogLevel__c | Picklist | Logging level: DEBUG, INFO, WARN, ERROR |
Message__c | Long Text Area(32768) | The actual log message |
ParentTransactionId__c | Text(36) | Parent transaction ID for hierarchical transaction tracking |
RecordId__c | Text(18) | Optional record ID this log is associated with |
RecordLink__c | Formula(Text) | Hyperlink to the associated record |
ClassMethod__c | Text(255) | Source of log message (ClassName.MethodName) |
ShortMessage__c | Text(255) | Brief summary of the log message, safe for SOQL WHERE and GROUP BY clauses |
StackTrace__c | Long Text Area(32768) | Stack trace information if applicable |
TransactionId__c | Text(36) | Unique transaction ID for grouping logs within a single execution |
UserId__c | Text(18) | The user ID who triggered this log |
UserLink__c | Formula(Text) | Hyperlink to the user who produced this log |
Fingerprint__c | Text(216) | Flood-control grouping key (External ID, unique); blank on ungrouped entries |
OccurrenceCount__c | Number(12,0) | Occurrences collapsed into a daily rollup row; populated on rollup rows only |
Relationships:
UserId__cstores the User ID (text field, not a lookup)
Usage:
// Log an error with record association
LOG_Builder.build().error(ex).at('MyClass.myMethod').forRecord(recordId).emit();
// Log informational message with record association
LOG_Builder.build().info('Processing completed successfully').at('MyClass.myMethod').forRecord(recordId).emit();
// Use correlation for distributed tracing
LOG_Builder.startCorrelation();
LOG_Builder.setGlobalContext('accountId', accountId);
LOG_Builder.build().info('Processing started').emitAt('MyClass.myMethod');LogEntryEvent__e (Platform Event)
Description: Platform event for asynchronous log message publishing.
Fields:
| Field | Type | Description |
|---|---|---|
ContextData__c | Long Text Area(5000) | Structured context data as JSON |
CorrelationId__c | Text(36) | Correlation ID linking related log entries |
DurationMs__c | Number(18,0) | Duration in milliseconds for timed operations |
ExceptionType__c | Text(255) | Exception type |
ExecutionEvent__c | Text(40) | Salesforce execution context (Quiddity): SYNCHRONOUS, BATCH_APEX, FUTURE, QUEUEABLE, etc. |
Limits__c | Long Text Area(1024) | JSON snapshot of Salesforce governor limits at the time the event was logged |
LineNumber__c | Number(8,0) | Source code line number where the exception occurred |
LogLevel__c | Text(20) | Logging level (DEBUG, INFO, WARN, ERROR) |
Message__c | Long Text Area(5000) | Log message |
ParentTransactionId__c | Text(36) | Parent transaction ID for hierarchical tracking |
RecordId__c | Text(18) | Optional record ID |
ClassMethod__c | Text(255) | Source (ClassName.MethodName) |
ShortMessage__c | Text(255) | Brief summary of the log message, safe for SOQL WHERE and GROUP BY clauses |
StackTrace__c | Long Text Area(5000) | Stack trace |
TransactionId__c | Text(36) | Unique transaction ID |
UserId__c | Text(18) | The user ID who triggered this event |
Usage:
- Published automatically by
LOG_Builder - Consumed by
TRG_LogEntryEventtrigger to createLogEntry__crecords - Enables asynchronous logging without impacting transaction performance
- Supports distributed tracing via correlation and transaction IDs
Sensitive data in log entries is redacted by the data masking framework (MaskingRule__mdt + MaskingTarget__mdt) before the platform event is published. The default ship set wildcards the active MaskSecretKeys and MaskPaymentCard rules onto LogEntryEvent__e, so nothing in the log-entry pipeline persists a raw secret or card number out of the box.
LogSetting__c (Hierarchy Custom Setting)
Description: Controls logging thresholds and performance logging configuration. As a hierarchy custom setting, values can be set at org-default, profile, or user level. Code-level defaults are provided by LOG_Engine.getLogSetting().
Fields:
| Field | Type | Description |
|---|---|---|
IsEnabled__c | Checkbox | Whether logging is enabled |
LogLevelThreshold__c | Text | Minimum log level threshold: DEBUG, INFO, WARN, ERROR |
EnablePerformanceLogging__c | Checkbox | Enable webservice performance timer logging |
EnableQueryPerformanceLogging__c | Checkbox | Enable query performance logging |
EnableTriggerPerformanceLogging__c | Checkbox | Enable trigger action performance logging |
EnableValidationPerformanceLogging__c | Checkbox | Enable validation context performance logging |
MaxContextDataSize__c | Number(6,0) | Maximum size of context data to log (bytes) |
PerformanceThresholdMs__c | Number(10,0) | Webservice performance threshold (ms, Default: 10000 = 10 seconds) |
QueryPerformanceThresholdMs__c | Number(10,0) | Query performance threshold (ms, Default: 1000 = 1 second) |
TriggerPerformanceThresholdMs__c | Number(10,0) | Trigger action performance threshold (ms) |
ValidationPerformanceThresholdMs__c | Number(10,0) | Validation context performance threshold (ms) |
Usage:
- Org Default: Global settings applied to all users (e.g., enable performance logging globally)
- Profile: Override settings for a specific profile
- User: Override settings for a specific user
Performance Logging Configuration:
- Webservice Performance: Uses
EnablePerformanceLogging__candPerformanceThresholdMs__c(10s default - appropriate for network calls) - Query Performance: Uses
EnableQueryPerformanceLogging__candQueryPerformanceThresholdMs__c(1s default - appropriate for database queries) - Trigger Performance: Uses
EnableTriggerPerformanceLogging__candTriggerPerformanceThresholdMs__c - Validation Performance: Uses
EnableValidationPerformanceLogging__candValidationPerformanceThresholdMs__c
Example Configuration:
LogSetting__c (Org Default):
- IsEnabled__c: true
- LogLevelThreshold__c: INFO
- EnablePerformanceLogging__c: true
- PerformanceThresholdMs__c: 10000 (log webservice calls > 10s)
- EnableQueryPerformanceLogging__c: true
- QueryPerformanceThresholdMs__c: 1000 (log queries > 1s)
Defaults are provided code-level by LOG_Engine.getLogSetting() when no custom setting record exists.Trigger Action Framework
Purpose: Metadata-driven trigger orchestration enabling modular, reusable, and testable trigger logic using TRG_Dispatcher, TRG_Base, IF_Trigger, TriggerSetting__mdt, and TriggerAction__mdt.
See also: Triggers - Guide, Fast Start - Trigger Actions
Architecture Diagram
+---------------------+
| Physical Trigger |
| TRG_Account |
| - All contexts |
+----------+----------+
| calls
v
+---------------------+
| TRG_Dispatcher |
| .run() |
+----------+----------+
| queries configuration
v
+---------------------+ 1:1 +---------------------+
| TriggerSetting__mdt |<-----------| Account SObject |
| - SObjectType | +---------------------+
| - BypassExecution |
| - RequiredPerm |
+----------+----------+
| 1:N (per context)
v
+---------------------+
| TriggerAction__mdt |
| - ApexClassName |
| - Order |
| - Event__c |--+
| - TriggerSetting__c | | (picklist + lookup)
| - BypassExecution | |
| - RequiredPerm | |
+----------+----------+ |
| |
| instantiates |
v |
+---------------------+ |
| TRG_AccountValidator| |
| extends | |
| TRG_Base | |
| implements | |
| IF_Trigger | |
| .BeforeInsert |<-+
+---------------------+Objects
TriggerSetting__mdt (Custom Metadata)
Description: Contains common configuration for trigger actions per SObject, including bypass settings and permissions.
Fields:
| Field | Type | Description |
|---|---|---|
SObjectType__c | MetadataRelationship(EntityDefinition) (Required) | The SObject this trigger setting applies to |
BypassExecution__c | Checkbox | Bypasses ALL trigger actions on this object (Default: false) |
BypassFeatureFlag__c | MetadataRelationship(FeatureFlag__mdt) | Feature Flag that bypasses triggers when enabled |
RequiredFeatureFlag__c | MetadataRelationship(FeatureFlag__mdt) | Feature Flag required for triggers to execute |
EnablePerformanceLogging__c | Checkbox | Master switch for performance logging on this object |
PerformanceThresholdMs__c | Number(10,0) | Object-level performance threshold (ms) |
ApplyMasking__c | Checkbox | Run the data masking pass on this object before insert/update (Default: true; uncheck to opt out) |
ObjectApiNameOverride__c | Text(255) | Optional override of SObjectType__c at dispatch — registers a CDC entity (e.g. Foobar__ChangeEvent) |
Relationships:
- Parent of
TriggerAction__mdtviaTriggerSetting__c(child relationship:TriggerActions__r) - Parent of
ValidationRuleGroup__mdtviaTriggerSetting__c(child relationship:ValidationRuleGroups__r)
Pre-built records (6 shipped): framework settings for objects the package itself triggers on (LogEntryEvent__e, ApiCall__c, ApiIssue__c, AsyncChainExecution__c, etc.). Subscribers add their own TriggerSetting__mdt records for their SObjects.
Usage:
Create one TriggerSetting__mdt record per SObject:
- Label: Account Trigger Settings
- SObjectType__c: Account (EntityDefinition)
- BypassExecution__c: falseTriggerAction__mdt (Custom Metadata)
Description: Defines individual trigger actions and their execution order within trigger contexts.
Fields:
| Field | Type | Description |
|---|---|---|
ApexClassName__c | Text(100) (Required) | Fully qualified action class name |
Description__c | Long Text Area | Action description |
Event__c | Picklist (Required) | Trigger event: Before Insert, After Insert, Before Update, After Update, Before Delete, After Delete, After Undelete |
TriggerSetting__c | MetadataRelationship(TriggerSetting__mdt) (Required) | Link to the parent TriggerSetting for the target SObject |
Order__c | Number(4,0) (Required) | Execution order (lower = earlier) |
BypassExecution__c | Checkbox | Bypass this specific action (Default: false) |
BypassFeatureFlag__c | MetadataRelationship(FeatureFlag__mdt) | Feature Flag that bypasses this action when enabled |
RequiredFeatureFlag__c | MetadataRelationship(FeatureFlag__mdt) | Feature Flag required for this action to execute |
AllowRecursion__c | Checkbox | Allow recursive execution |
AllowNonSelfInitiated__c | Checkbox | Allow execution from other triggers |
EntryCriteriaFormula__c | Long Text Area | Formula for conditional execution |
EntryCriteriaContextClassName__c | Text(100) | Context class for formula evaluation |
ForcePerformanceLogging__c | Checkbox | Always log performance for this action |
SuppressPerformanceLogging__c | Checkbox | Never log performance for this action |
PerformanceThresholdMs__c | Number(8,0) | Log if duration exceeds threshold (ms) |
Relationships:
- MetadataRelationship to
TriggerSetting__mdtviaTriggerSetting__c(child relationship:TriggerActions__r)
Pre-built records (6 shipped): framework actions on framework-owned objects (e.g., TRG_LogEntryEvent_AfterInsert, retry orchestration on ApiIssue__c). Subscribers add their own TriggerAction__mdt records to wire subscriber handler classes.
Usage:
Example Configuration:
- Label: Account Validator
- ApexClassName__c: TRG_AccountValidator
- Event__c: Before Insert
- TriggerSetting__c: Account (TriggerSetting__mdt)
- Order__c: 10
- BypassExecution__c: falsePostTriggerAction__mdt (Custom Metadata)
Description: Defines declarative actions that run once at the end of the trigger transaction, after every per-record trigger action has completed. Use post-trigger actions for transaction-level work such as a single rollup or one outbound notification per save. A post-action cannot perform DML — attempting it always fails the transaction.
Fields:
| Field | Type | Description |
|---|---|---|
ApexClassName__c | Text(100) | Class implementing IF_Trigger.PostAction (DML is not permitted inside a post-action) |
TriggerSetting__c | MetadataRelationship(TriggerSetting__mdt) | Optional. Set to scope the action to one SObject; leave blank to fire on every outermost dispatch |
FailureAction__c | Picklist | On error: Log and Continue (default — save proceeds) or Block DML (save stops, the error is shown to the user) |
Order__c | Number(3,0) | Execution order (lower runs first; leave gaps so new actions can be inserted) |
Description__c | Text | Action description |
EntryCriteriaContextClassName__c | Text(100) | Optional class implementing IF_Trigger.PostActionEntryCriteria; shouldRun(context) returning false skips it |
BypassExecution__c | Checkbox | Bypass this specific post-action |
BypassFeatureFlag__c | MetadataRelationship(FeatureFlag__mdt) | Feature Flag that bypasses this action when enabled |
RequiredFeatureFlag__c | MetadataRelationship(FeatureFlag__mdt) | Feature Flag required for this action to execute |
ForcePerformanceLogging__c | Checkbox | Always log performance for this action |
PerformanceThresholdMs__c | Number(8,0) | Log if duration exceeds threshold (ms) |
Relationships:
- Optional MetadataRelationship to
TriggerSetting__mdtviaTriggerSetting__c. UnlikeTriggerAction__mdt, this link is not required — leave it blank to run the action on every outermost trigger dispatch.
See also: Triggers - Guide for the IF_Trigger.PostAction contract and entry-criteria details.
Validation Framework
Purpose: Formula-driven declarative validation for advanced scenarios like cross-object validation, aggregate checks, and conditional bypass logic using UTIL_ValidationRule, TRG_ExecuteValidationRules, ValidationRuleGroup__mdt, and ValidationRule__mdt.
See also: Validation - Guide, Fast Start - Custom Validations
Objects
ValidationRuleGroup__mdt (Custom Metadata)
Description: Groups validation rules for a specific object and trigger context. Linked to TriggerSetting__mdt via TriggerSetting__c.
Fields:
| Field | Type | Description |
|---|---|---|
TriggerSetting__c | MetadataRelationship(TriggerSetting__mdt) (Required) | Links to the object's TriggerSetting |
TriggerTiming__c | Text (Required) | Semicolon-separated: Before, After |
TriggerOperations__c | Text (Required) | Semicolon-separated: Insert, Update, Delete, Undelete |
Description__c | Long Text Area (Required) | Business purpose of this group |
ContextClassName__c | Text(100) | Default context class for rules in this group |
ExecutionStrategy__c | Picklist | Accumulate (default) or Fail Fast |
BypassExecution__c | Checkbox | Bypass all rules in this group (Default: false) |
BypassFeatureFlag__c | MetadataRelationship(FeatureFlag__mdt) | Feature Flag that bypasses all rules when enabled |
RequiredFeatureFlag__c | MetadataRelationship(FeatureFlag__mdt) | Feature Flag required for rules to execute |
Relationships:
- MetadataRelationship to
TriggerSetting__mdtviaTriggerSetting__c - Parent of
ValidationRule__mdtviaValidationRuleGroup__c
Pre-built records: none — extensibility-only. Subscribers create ValidationRuleGroup__mdt records to configure validation rules.
Usage:
Example Configuration:
- Label: Account Field Validations
- TriggerSetting__c: Account (TriggerSetting__mdt)
- TriggerTiming__c: Before
- TriggerOperations__c: Insert;Update
- ExecutionStrategy__c: AccumulateValidationRule__mdt (Custom Metadata)
Description: Individual validation rule configuration. Formula returns true when validation fails.
Fields:
| Field | Type | Description |
|---|---|---|
ValidationRuleGroup__c | MetadataRelationship(ValidationRuleGroup__mdt) (Required) | Parent group |
RuleFormula__c | Long Text Area (Required) | Formula that returns true when validation fails |
ErrorMessage__c | Long Text Area (Required) | Message shown when validation fails |
ErrorDisplayField__c | Text(255) | API name of field to attach error to |
Severity__c | Picklist (Required) | Error (blocks save) or Warning (logs only) |
Order__c | Number(4,0) | Execution order (lower = first) |
Description__c | Long Text Area (Required) | Business purpose of this rule |
ContextClassName__c | Text(100) | Override context class for this rule |
ShadowMode__c | Checkbox | Log but don't block (testing mode, Default: false) |
BypassExecution__c | Checkbox | Bypass this rule (Default: false) |
BypassFeatureFlag__c | MetadataRelationship(FeatureFlag__mdt) | Feature Flag that bypasses this rule when enabled |
RequiredFeatureFlag__c | MetadataRelationship(FeatureFlag__mdt) | Feature Flag required for this rule to execute |
Relationships:
- MetadataRelationship to
ValidationRuleGroup__mdtviaValidationRuleGroup__c
Pre-built records: none — extensibility-only. Subscribers create ValidationRule__mdt records to configure rule formulas.
Usage:
Example Configuration:
- Label: Require Industry for Enterprise Accounts
- ValidationRuleGroup__c: Account Field Validations (ValidationRuleGroup__mdt)
- RuleFormula__c: newRecord.Type = 'Enterprise' && ISBLANK(newRecord.Industry)
- ErrorMessage__c: Industry is required for Enterprise accounts
- ErrorDisplayField__c: Industry
- Severity__c: Error
- Order__c: 10Web Service Framework
Purpose: Comprehensive HTTP/REST integration framework with automatic logging, retry logic, data masking, and orchestration using API_Outbound, API_Inbound, ApiCall__c, ApiIssue__c, ApiSetting__mdt, ApiCredential__mdt, and ApiMock__mdt. Request / response redaction is handled by the shared data masking framework — see MaskingRule__mdt and MaskingTarget__mdt.
See also: Web Services - Guide, Fast Start - Outbound APIs, Fast Start - Inbound APIs
Architecture Diagram
+---------------------+
| API Class |
| API_GetCustomer |
| extends |
| API_Outbound |
+----------+----------+
| reads configuration
v
+---------------------+ 1:1 +---------------------+
| ApiSetting__mdt |<-----------| ApiCredential__mdt |
| - ClassName | | - NamedCredential |
| - EndpointPath | +---------------------+
| - MaxRetryCount |
| - RetryBackoffSecs |
| - IdempotencyEnabled|
| - MockingEnabled |
| - LogIssues |
+----------+----------+
| executes API call
v
+---------------------+
| HTTP Request/ |
| Response |
+----------+----------+
| logs to
v
+---------------------+ +---------------------+
| ApiCall__c | | MaskingRule__mdt |
| - Request |<--redacted by--| - Mode |
| - Response | data masking | - Pattern |
| - Status | framework | - Replacement |
| - Retries | | - FailureAction |
| - CalloutDurationMs | +---------------------+
| - ErrorMessages | ^ wired by
+----------+----------+ +---------------------+
| MaskingTarget__mdt |
| - Rule, SObjectType |
| - Field, CallerClass|
+---------------------+
| 1:N
v
+---------------------+
| ApiIssue__c |
| - ErrorMessages |
| - RequestParameters |
| - Status |
+---------------------+Objects
ApiCall__c (Custom Object)
Description: Orchestrates and tracks all webservice calls (inbound and outbound) with comprehensive logging and retry management.
Fields:
| Field | Type | Description |
|---|---|---|
ServiceName__c | Text(100) | Fully qualified name of the API service handler class |
Direction__c | Picklist | Inbound, Outbound |
Status__c | Picklist | Queued, Processing, Completed, Failed, Retry, Retrying, Batched, Aborted |
HttpMethod__c | Picklist | HTTP method: GET, POST, PUT, PATCH, DELETE |
URL__c | URL | Full endpoint URL for the request |
Request__c | Long Text Area(131072) | Request payload |
RequestParameters__c | Long Text Area(131072) | Name-value pairs of request parameters |
Response__c | Long Text Area(131072) | Response payload |
StatusCode__c | Text(50) | HTTP status code |
ErrorMessages__c | Long Text Area(32768) | Errors encountered during processing |
IdempotencyKey__c | Text(255) | Unique key for duplicate detection (External ID) |
IsIdempotencyHit__c | Checkbox | True if response was returned from a previous call with the same idempotency key (Default: false) |
IsMockedResponse__c | Checkbox | True if response is mocked (Default: false) |
DeadLettered__c | Formula(Checkbox) | True when retries are exhausted or manually dead-lettered |
ManualDeadLetter__c | Checkbox | Admin override to permanently dead-letter a failed call (Default: false) |
Retries__c | Number(2,0) | Retry count (Default: 0) |
MaxRetries__c | Number | Maximum retry attempts for this API call |
NextRetry__c | Date Time | Time of next retry |
TraceId__c | Text(36) | W3C Trace Context trace ID for distributed tracing |
ParentSpanId__c | Text(16) | W3C Trace Context parent span ID (16 hex characters) |
CalloutDurationMs__c | Number(6,0) | HTTP callout time (milliseconds) |
HandlerDurationMs__c | Number(6,0) | Handler processing time (milliseconds) |
CommitDurationMs__c | Number(6,0) | DML commit time (milliseconds) |
TotalDurationMs__c | Number(6,0) | Total processing time (milliseconds) |
TriggeringRecordId__c | Text(80) | ID of record that triggered the call |
TriggeringRecordUrl__c | Formula(Text) | Hyperlink to triggering record |
LoggerContext__c | Long Text Area(32768) | Serialized logger context for async correlation |
Relationships:
- Parent of
ApiIssue__c(1:N)
Usage:
- Automatically created by API framework classes
- Provides audit trail for all API interactions
- Enables retry logic for failed calls
- Tracks performance metrics
- Auto-Correlation:
LoggerContext__cis automatically populated when queue items are created viaTST_Factory.newOutboundApiCall()methods. When the async job executes, the API dispatcher automatically hydrates the logger context, linking all logs in the async transaction to the original correlation ID.
ApiIssue__c (Custom Object)
Description: Stores failed API service details for retry management.
Fields:
| Field | Type | Description |
|---|---|---|
ApiCall__c | Lookup(ApiCall__c) | Parent call queue record |
ServiceName__c | Text(100) | Service class API name |
Direction__c | Picklist | Inbound or Outbound |
Status__c | Picklist | Open, Resolved (automatic retry batch job or manual retry via quick action) |
ErrorMessages__c | Long Text Area(131072) | Error messages encountered |
TriggeringRecordId__c | Text(18) | ID of triggering record |
OriginatingRecordId__c | Text(18) | Originating record ID (when different from triggering record) |
IdempotencyKey__c | Text(255) | Idempotency key from the original failed API call, preserved for retry |
RequestMethod__c | Text(10) | HTTP method of the original inbound request (GET, POST, etc.) |
RequestPath__c | Text(255) | URL path of the original inbound request for failure replay |
RequestBody__c | Long Text Area(131072) | Body of the original inbound request for failure replay |
RequestParameters__c | Long Text Area(131072) | Request parameters |
RequestParametersHash__c | Text(50) | Hash of request parameters (deduplication) |
ResolvedDate__c | DateTime | Date and time when the failure was resolved |
Relationships:
- Lookup to
ApiCall__c
Usage:
- Created when API calls fail
- Used by retry jobs to re-attempt failed calls
- Prevents duplicate retry attempts via hash
ApiSetting__mdt (Custom Metadata)
Description: Registers inbound and outbound web service handlers and their configuration.
Fields:
| Field | Type | Description |
|---|---|---|
ClassName__c | Text(100) (Unique) | Fully qualified API Handler class name |
EndpointPath__c | Text(255) | Relative path (appended to Named Credential URL) |
Direction__c | Picklist | Inbound or Outbound |
IsActive__c | Checkbox | Whether this API route is active |
Priority__c | Number(3,0) | Routing priority (lower = higher priority, Default: 100) |
MaxRetryCount__c | Number(2,0) | Maximum number of retries |
RetryBackoffSeconds__c | Number(3,0) | Backoff period between retries (seconds) |
LogIssues__c | Checkbox | Whether to log API failures (Default: false) |
RetryIssues__c | Checkbox | Whether to retry failures (Default: false) |
ResolveIssues__c | Checkbox | Whether to resolve failures (Default: false) |
IdempotencyEnabled__c | Checkbox | Enable idempotency key duplicate detection (Default: false) |
MockingEnabled__c | Checkbox | Enable mock responses from ApiMock__mdt records (Default: false) |
ApiCredential__c | Metadata Relationship | Link to credential configuration |
CircuitBreakerEnabled__c | Checkbox | Enable circuit breaker pattern |
CircuitBreakerFailureThreshold__c | Number(3,0) | Consecutive failures before opening circuit (Default: 10) |
CircuitBreakerSuccessThreshold__c | Number(2,0) | Consecutive successes in half-open state to close circuit (Default: 2) |
CircuitBreakerTimeout__c | Number(5,0) | Seconds before attempting to close the circuit (Default: 60) |
BypassFeatureFlag__c | Metadata Relationship | Feature Flag that bypasses this API when enabled |
RequiredFeatureFlag__c | Metadata Relationship | Feature Flag required for this API to execute |
Relationships:
- Metadata relationship to
ApiCredential__mdt
Pre-built records (4 shipped): framework-demo API settings (ApiMock endpoints, self-callout examples) used by the bundled sample services. Subscribers add their own ApiSetting__mdt for each of their handler classes.
Usage:
Example Configuration:
- Label: Customer API - Get Data
- ClassName__c: API_GetCustomerData
- EndpointPath__c: /customers/{customerId}
- MaxRetryCount__c: 3
- RetryBackoffSeconds__c: 60
- ApiCredential__c: Customer_API_CredentialsApiCredential__mdt (Custom Metadata)
Description: Links outbound API handlers to their Salesforce Named Credential for endpoint resolution and authentication.
Fields:
| Field | Type | Description |
|---|---|---|
NamedCredential__c | Text(255) | Named Credential reference for endpoint and authentication |
Relationships:
- Parent of
ApiSetting__mdt(1:N)
Pre-built records (3 shipped): framework-demo credentials matching the bundled sample API services. Subscribers add their own ApiCredential__mdt referencing their Named Credentials.
Usage:
Example Configuration:
- Label: Customer API Credentials
- NamedCredential__c: callout:CustomerAPIRedaction of API request / response payloads is handled by the shared data masking framework — see MaskingRule__mdt and MaskingTarget__mdt in the Data Masking section of this guide (or the reference pages directly). The default ship set wildcards MaskSecretKeys (JSON key redaction for password, token, apiKey, and similar) and MaskPaymentCard (13–19 digit sequences that pass the Luhn checksum, all major card brands) onto every text field of ApiCall__c and ApiIssue__c, so raw secrets and card numbers never land in the logged request or response.
ApiMock__mdt (Custom Metadata)
Description: Configures mock response scenarios for API services. Supports dynamic response interpolation, request body pattern matching, and fault simulation for both inbound and outbound APIs.
Fields:
| Field | Type | Description |
|---|---|---|
ApiSetting__c | Metadata Relationship (Required) | Link to the API Setting this mock belongs to |
IsActive__c | Checkbox | Whether mock is active |
ResponseBody__c | Long Text Area | Mock response body (JSON or XML) |
MatchRequestBodyPattern__c | Text(255) | Pattern to match against request body for scenario selection |
IsRegex__c | Checkbox | Treat match pattern as regex instead of simple contains |
StatusCode__c | Number(3,0) | HTTP status code to return |
Priority__c | Number | Match priority for this mock |
DelayMs__c | Number(6,0) | Simulated latency in milliseconds |
FailureRate__c | Number(5,2) | Percentage of requests that return a simulated failure (0-100) |
ResponseHeaders__c | Long Text Area(131072) | JSON object of response headers |
Relationships:
- Metadata relationship to
ApiSetting__mdt
Usage:
Example Mock Configuration:
- Label: Customer API Success Response
- ApiSetting__c: API_GetCustomerData (ApiSetting__mdt)
- IsActive__c: true
- ResponseBody__c: {"customerId": "C-12345", "name": "Test Customer"}
- StatusCode__c: 200MaskingRule__mdt (Custom Metadata)
Description: Reusable redaction rule describing what to find. Rules are object-agnostic and paired with MaskingTarget__mdt records that describe where to apply them.
Fields:
| Field | Type | Description |
|---|---|---|
Mode__c | Picklist | Regex, JsonKey (label "JSON by Key"), ExactMatch, or CreditCard (the pattern match plus a Luhn checksum) |
Pattern__c | Long Text Area | Regex pattern, JSON key regex, or literal string (depending on Mode__c) |
Replacement__c | Text(255) | Replacement text (e.g., [REDACTED]) |
CaseSensitive__c | Checkbox | Toggle case-insensitive matching (Default: false) |
FailureAction__c | Picklist | LogAndContinue, WriteFailureMarker, or BlockDml when a pattern throws |
MinInputLength__c | Number | Optional minimum input length — rule skipped for shorter values (zero-cost short-circuit for short fields) |
ApplicableFieldTypes__c | Text | Optional semicolon-delimited System.DisplayType.name() list (e.g., STRING;TEXTAREA;ENCRYPTEDSTRING) restricting the rule to specific field types; blank applies to every text-shaped field |
IsActive__c | Checkbox | Enable/disable rule globally |
Order__c | Number(4,0) | Rule application order |
Replaces__c | Text(40) | On a shipped replacement rule: developer name of the older rule it replaces — while both carry their shipped values, the newer rule does the work wherever both are wired. Managed by the package |
ReplacesFingerprint__c | Text(64) | Fingerprint of the replaced rule's original shipped values — any customisation you make to the older rule keeps it running. Managed by the package |
ShippedFingerprint__c | Text(64) | Fingerprint of this rule's own shipped values — customising the replacement rule turns the takeover off, and both rules run. Managed by the package |
Relationships:
- Parent of
MaskingTarget__mdt(1:N)
Pre-built records (18 shipped): 3 active — MaskSecretKeys (JSON key redaction scoped to STRING;TEXTAREA), MaskPaymentCard (13–19 digit Luhn-checked card numbers with MinInputLength=13, scoped to STRING;TEXTAREA;ENCRYPTEDSTRING), and MaskCreditCard (the original issuer-prefix card rule that MaskPaymentCard replaces — still shipped for compatibility with configurations that reference it). 15 inactive templates ship for SSN, IBAN, SWIFT/BIC, MBI, health keywords, email, US phone, JWT, AWS access key, URL basic auth, authorization header, private IPv4, postal address, free text, and international phone — flip IsActive__c=true and add a MaskingTarget__mdt when your org's data profile calls for them.
MaskingTarget__mdt (Custom Metadata)
Description: Wires a MaskingRule__mdt to a specific SObject + field (or wildcards across every text field), optionally scoped to a caller class.
Fields:
| Field | Type | Description |
|---|---|---|
Rule__c | MetadataRelationship(MaskingRule__mdt) (Required) | The rule to apply |
SObjectType__c | MetadataRelationship(EntityDefinition) (Required) | Target SObject (e.g., ApiCall__c, LogEntryEvent__e) |
Field__c | MetadataRelationship(FieldDefinition) | Specific field (picklist filtered by SObjectType__c), or blank for a wildcard across every text-shaped field on the SObject |
CallerClass__c | Text(100) | Optional scope — only fire when the caller class name matches |
IsActive__c | Checkbox | Enable/disable this wiring without touching the rule |
Relationships:
- Child of
MaskingRule__mdtviaRule__c
Pre-built records (12 shipped): the secrets, payment-card, and legacy credit-card rules are each wildcarded onto ApiCall__c, ApiIssue__c, AsyncChainExecution__c, and LogEntryEvent__e — so every persisted API / async-chain / log row passes through MaskSecretKeys and MaskPaymentCard out of the box (the legacy credit-card targets defer to the payment-card rule on those objects).
Interaction with ApplicableFieldTypes__c: Rule-level filters take precedence over per-target wiring. If a target wires a rule to a specific Field__c whose DisplayType is excluded by the rule's ApplicableFieldTypes__c, the rule will not fire on that field. The framework emits a one-time warn-level LogEntry__c with ClassMethod__c='UTIL_FrameworkMasker.filterTargetsByFieldType' to surface the misconfiguration.
Feature Management Framework
Purpose: Declarative feature flag system enabling runtime feature toggles at user, profile, and organization levels using UTIL_FeatureFlag, FeatureFlag__mdt, FeatureFlagStrategy__mdt, and ApiRuntimeSwitch__c.
See also: Fast Start - Feature Flags
Architecture Diagram
+---------------------+
| UTIL_FeatureFlag |
| .isEnabled() |
+----------+----------+
| queries
v
+---------------------+ 1:N +---------------------+
| FeatureFlag__mdt |<-----------| FeatureFlagStrategy |
| - IsActive | | __mdt |
| - Description | | - Type |
+---------------------+ | - Target |
| - Order |
+---------------------+
+---------------------+
| ApiRuntimeSwitch__c | (Hierarchy Custom Setting)
| - DisableAllApis |
+---------------------+Objects
FeatureFlag__mdt (Custom Metadata)
Description: Master record for a feature flag configuration.
Fields:
| Field | Type | Description |
|---|---|---|
IsActive__c | Checkbox | Master on/off switch (Default: false) |
Description__c | Text Area | Description of the feature |
IsEnabledByDefault__c | Checkbox | Default value for the flag if no strategies are defined |
ResultOnNoMatch__c | Picklist | Fallback result when strategies exist but none return true |
Relationships:
- Parent of
FeatureFlagStrategy__mdt(1:N)
Pre-built records (10 shipped): framework flags including UserModeQueries_Enabled, UserModeDml_Enabled (the secure-by-default posture kill-switches — both default true), DisableAllAPIs, MockAllInboundAPIs, and similar framework-scoped toggles. Subscribers add their own feature flags alongside these.
Usage:
// Check if feature is enabled for current user
Boolean isEnabled = UTIL_FeatureFlag.isEnabled('Advanced_Reporting');
if(isEnabled)
{
// Execute advanced reporting logic
}FeatureFlagStrategy__mdt (Custom Metadata)
Description: Defines evaluation rules for parent feature flags.
Fields:
| Field | Type | Description |
|---|---|---|
FeatureFlag__c | Metadata Relationship (Required) | Parent feature flag |
Type__c | Picklist (Required) | Evaluation strategy type |
Target__c | Text | Identifier, name, or path of the item to evaluate |
ExpectedValue__c | Text | Optional expected value for the strategy |
CustomHandler__c | Text | Optional custom Apex class implementing the strategy interface |
IsActive__c | Checkbox | Whether this strategy is active |
Order__c | Number(2,0) | Execution priority (lower = first) |
Relationships:
- Metadata relationship to
FeatureFlag__mdt(parent)
Pre-built records (2 shipped): strategies attached to framework flags. Subscribers add their own strategies on framework flags or their own flags.
Usage:
Example Strategy Configuration:
1. Enable for specific user:
- Type__c: User
- Target__c: 005000000000001AAA
2. Enable for System Administrators:
- Type__c: Profile
- Target__c: 00e00000000001AAA
3. Enable globally:
- Type__c: GlobalApiRuntimeSwitch__c (Hierarchy Custom Setting)
Description: Hierarchical custom setting providing a runtime API kill switch at the org, profile, or user level.
Fields:
| Field | Type | Description |
|---|---|---|
DisableAllApis__c | Checkbox | Disables all APIs — inbound and outbound (Default: false) |
For granular per-service control, use ApiSetting__mdt.IsActive__c. For feature-flag-driven disable/mock, use UTIL_FeatureFlag with the DisableAllAPIs or MockAllInboundAPIs feature flags.
Usage:
// Check if all APIs are disabled via feature flag (preferred)
if(UTIL_FeatureFlag.isEnabled('DisableAllAPIs'))
{
return; // Skip API logic
}
// Or use the hierarchy custom setting directly for per-user/profile control
ApiRuntimeSwitch__c settings = ApiRuntimeSwitch__c.getInstance();
if(settings.DisableAllApis__c)
{
return; // Skip API logic
}Asynchronous Operations Framework
Purpose: Declarative configuration for batch jobs, schedulers, and asynchronous processing with automatic execution strategy selection using UTIL_AsynchronousJobLauncher, AsynchronousJobSetting__mdt, ScheduledJob__c, and ScheduleSetting__c.
See also: Async Processing - Guide, Fast Start - Async Processing
Architecture Diagram
+---------------------+
| UTIL_Asynchronous |
| JobLauncher |
| .launch() |
+----------+----------+
| reads configuration
v
+---------------------+
| AsynchronousJob |
| Setting__mdt |
| - BatchSize |
+---------------------+
+---------------------+
| ScheduledJob__c |
| - ClassName |
| - CronExpression |
| - SchedulerName |
| - IsActive |
| - ScheduledJobId |
+---------------------+
+---------------------+
| ScheduleSetting__c | (List Custom Setting)
| - LastSuccessful |
| RunTime |
+---------------------+
+---------------------+ +------------------------+
| UTIL_AsyncChain |------>| AsyncChainExecution__c |
| .newChain().then() | | - Status |
| .execute() | | - CompletedSteps |
+---------------------+ | - TotalSteps |
| - StepLog (JSON) |
| - CorrelationId |
+------------------------+Objects
AsynchronousJobSetting__mdt (Custom Metadata)
Description: Declarative configuration for asynchronous job classes. The DeveloperName of each record should match the Apex class name it configures.
Fields:
| Field | Type | Description |
|---|---|---|
BatchSize__c | Number(4,0) | Number of records to process per execution (1-2000) |
Usage:
Example Configuration:
- DeveloperName: PROC_LoginFrequencyAggregator
- Label: PROC_LoginFrequencyAggregator
- BatchSize__c: 200ScheduledJob__c (Custom Object)
Description: Manages scheduled job configuration and execution history.
Fields:
| Field | Type | Description |
|---|---|---|
IsActive__c | Checkbox | Whether scheduled job is active |
SchedulerName__c | Text | User-friendly name for this scheduled job |
ClassName__c | Text(255) (Required) | Schedulable class name |
CronExpression__c | Text(255) (Required) | Cron expression for scheduling |
Description__c | Text Area | Description of scheduled job |
Parameters__c | Long Text Area(131072) | JSON-serialized DTO_NameValues containing name/value pairs passed to the scheduled class |
ScheduledJobId__c | Text(18) | Salesforce CronTrigger ID |
Usage:
// Create scheduled job
ScheduledJob__c job = new ScheduledJob__c(
SchedulerName__c = 'Nightly Data Cleanup',
ClassName__c = 'SCHED_NightlyCleanup',
CronExpression__c = '0 0 2 * * ?', // 2 AM daily
IsActive__c = true
);
insert job;ScheduleSetting__c (List Custom Setting)
Description: Stores runtime state for scheduled jobs, such as the last successful execution time.
Fields:
| Field | Type | Description |
|---|---|---|
LastSuccessfulRunTime__c | Datetime | Last successful run time of the schedule |
Usage:
- Stores runtime state for scheduled jobs (e.g., last successful execution time)
- Used by scheduled jobs for incremental processing based on changes since last run
AsyncChainExecution__c (Custom Object)
Description: Tracks async chain executions including state, step progress, shared context, and duration. Each record represents one chain execution lifecycle managed by UTIL_AsyncChain.
Fields:
| Field | Type | Description |
|---|---|---|
ChainName__c | Text(255), Required | Chain name from newChain() |
Status__c | Picklist | Running, Completed, Failed, Delayed, Aborted, Stalled |
TotalSteps__c | Number(5,0) | Total steps defined in the chain |
CompletedSteps__c | Number(5,0) | Steps that succeeded (failed steps are not counted) |
CurrentStepName__c | Text(255) | Name of the currently executing or last executed step |
StartedAt__c | DateTime | When chain execution began |
CompletedAt__c | DateTime | When chain execution finished |
DurationMs__c | Number(10,0) | Wall-clock duration in milliseconds from start to terminal state |
ErrorMessage__c | Long Text Area(32768) | Error details if failed; non-fatal failure summaries if completed with issues |
StepLog__c | Long Text Area(131072) | JSON array of step definitions enriched with runtime outcomes |
ContextData__c | Long Text Area(131072) | Serialized shared chain context (JSON) |
CorrelationId__c | Text(36), External ID, Unique | UUID for distributed log tracing across async boundaries |
Field history tracking is enabled on Status__c, CompletedSteps__c, CurrentStepName__c, and CompletedAt__c.
Usage:
// Query chain status
kern__AsyncChainExecution__c execution = [
SELECT kern__ChainName__c, kern__Status__c,
kern__CompletedSteps__c, kern__TotalSteps__c
FROM kern__AsyncChainExecution__c
WHERE kern__CorrelationId__c = :correlationId
];
// Use the fluent API (preferred)
Map<String, Object> status = kern.UTIL_AsyncChain.getStatus(executionId);Data Management & Configuration
Purpose: Utility objects and configuration types supporting class resolution and UI customization using ClassTypeResolver__mdt, FieldSetGroup__mdt, and LoginFrequency__c.
Objects
ClassTypeResolver__mdt (Custom Metadata)
Used with UTIL_TypeResolver.
Description: Registers subscriber-org classes that resolve Apex class names to Types at runtime. Required when subscriber classes used by the framework (e.g., trigger handlers, web services, DTOs) are not declared as global. Multiple resolvers are chained in a chain of responsibility pattern, ordered by Order__c ascending.
Fields:
| Field | Type | Manageability | Description |
|---|---|---|---|
ClassName__c | Text(100) (Unique) | Subscriber Controlled | Fully qualified class name implementing UTIL_TypeResolver.INT_ClassTypeResolver |
Order__c | Number(2,0) | Subscriber Controlled | Execution priority — resolvers are chained in ascending order (lowest first) |
How it works: The framework loads all ClassTypeResolver__mdt records ordered by Order__c, instantiates each resolver class, and chains them via setNext(). The built-in PackageClassResolver runs first (subscriber-first namespace resolution), then delegates to the custom resolver chain. The first resolver to return a non-null Type wins.
Subscriber example. You don't have to write this by hand — the Kern app's Health Check generates this class and a matching test for you (Class Type Resolver row → Setup); see Health Check in the Utilities Guide. The class must be global so the package can construct it across namespaces via Type.newInstance(); the resolveType override stays public.
// 1. Create a resolver class (this is what the Health Check generator produces):
@SuppressWarnings('PMD.AvoidGlobalModifier')
global with sharing class ACME_ClassTypeResolver extends kern.UTIL_TypeResolver.BaseClassResolver
{
public override Type resolveType(String className)
{
return getTypeForClassName(className) ?? (Type)nextResolver?.resolveType(className);
}
private static Type getTypeForClassName(String className)
{
Type classType;
if(String.isNotBlank(className))
{
String namespace = kern.UTIL_System.getNamespacePrefix(kern.UTIL_System.getClassNamespace(className), '.');
classType = Type.forName(namespace, className);
classType = classType == null && String.isNotBlank(namespace) ? Type.forName('', className) : classType;
}
return classType;
}
}
// 2. Register via ClassTypeResolver__mdt record:
// DeveloperName: AcmeResolver
// ClassName__c: ACME_ClassTypeResolver
// Order__c: 1FieldSetGroup__mdt (Custom Metadata)
Description: Groups field sets together for dynamic field set management in UIs.
Fields:
| Field | Type | Description |
|---|---|---|
FieldSetApiNames__c | Text Area (Required) | Comma-separated list of field set API names |
DefaultActiveSections__c | Text Area | Comma-separated list of section names expanded by default |
Usage:
Example Configuration:
- Label: Account Detail Sections
- FieldSetApiNames__c: Account_Basic_Info,Account_Address_Info,Account_Financial_Info
- DefaultActiveSections__c: Account_Basic_InfoLoginFrequency__c (Custom Object)
Description: Tracks user login frequency for analytics.
Fields:
| Field | Type | Description |
|---|---|---|
User__c | Lookup(User) (Required) | The user whose login activity is tracked |
LoginYear__c | Number(4,0) | Calendar year |
LoginMonth__c | Number(2,0) | Calendar month (1-12) |
TotalLoginCount__c | Number(10,0) | Total number of login events for the month |
UniqueLoginCount__c | Number(10,0) | Number of distinct days the user logged in |
CompositeKey__c | Text (Unique) | Composite key combining User ID, year, and month |
ReportingDate__c | Formula(Date) | First day of login month/year for report filtering |
Relationships:
- Lookup to
Userobject
Usage:
- Populated by
SCHED_ProcessLoginHistoryscheduled job - Enables monthly login frequency reporting and user engagement analytics
Cross-Framework Relationships
Framework Integration Points
+------------------------------------------------------------------+
| KernDX Framework Ecosystem |
+------------------------------------------------------------------+
LOGGING FRAMEWORK
+- LogEntryEvent__e -> LogEntry__c
+- Used by: ALL frameworks for error/info logging
+- Configuration: LogSetting__c
+- Redaction: MaskingRule__mdt + MaskingTarget__mdt (data masking framework)
TRIGGER ACTION FRAMEWORK
+- TriggerSetting__mdt <- TriggerAction__mdt
+- Runtime Control: ApiRuntimeSwitch__c, UTIL_FeatureFlag
+- Used by: Web Service orchestration
+- Logging: LOG_Builder -> LogEntry__c
VALIDATION FRAMEWORK
+- TriggerSetting__mdt <- ValidationRuleGroup__mdt <- ValidationRule__mdt
+- Executed by: TRG_ExecuteValidationRules (trigger action)
+- Logging: LOG_Builder -> LogEntry__c (shadow mode + warnings)
WEB SERVICE FRAMEWORK
+- ApiCredential__mdt <- ApiSetting__mdt
+- ApiCall__c <- ApiIssue__c
+- Configuration: ApiMock__mdt
+- Redaction: MaskingRule__mdt + MaskingTarget__mdt (data masking framework)
+- Logging: LOG_Builder -> LogEntry__c
+- Feature Control: ApiRuntimeSwitch__c, UTIL_FeatureFlag
FEATURE MANAGEMENT
+- FeatureFlag__mdt <- FeatureFlagStrategy__mdt
+- ApiRuntimeSwitch__c (API kill switch)
+- Used by: All frameworks for feature gating
ASYNC OPERATIONS
+- AsynchronousJobSetting__mdt
+- ScheduledJob__c
+- ScheduleSetting__c
+- Used by: Web Service retries, data processing
+- Logging: LOG_Builder -> LogEntry__c
DATA MANAGEMENT
+- ClassTypeResolver__mdt (All frameworks)
+- FieldSetGroup__mdt (UI components)
+- LoginFrequency__c (Analytics)Key Integration Patterns
- Universal Logging: All frameworks use
LOG_Builder->LogEntryEvent__e->LogEntry__c - Feature Gating:
FeatureFlag__mdtandApiRuntimeSwitch__ccontrol API runtime behavior - Metadata-Driven: Trigger Actions, Web Services use Custom Metadata Types for zero-code configuration
- Event-Driven: Platform Events enable asynchronous, scalable processing
- Audit Trail:
ApiCall__candLogEntry__cprovide comprehensive audit logs
Usage Patterns
Pattern 1: Metadata-Driven Trigger with Logging
// 1. Create Trigger Action class
public class TRG_AccountValidator extends TRG_Base
implements IF_Trigger.BeforeInsert
{
public void beforeInsert(List<Account> newAccounts)
{
for(Account account : newAccounts)
{
if(account.AnnualRevenue < 0)
{
account.AnnualRevenue.addError('Revenue cannot be negative');
// Log validation failure
LOG_Builder.build()
.warn('Negative revenue blocked for: ' + account.Name)
.at('TRG_AccountValidator.beforeInsert')
.forRecord(account.Id)
.emit();
}
}
}
}
// 2. Configure in TriggerAction__mdt:
// - ApexClassName__c: TRG_AccountValidator
// - Event__c: Before Insert
// - TriggerSetting__c: Account
// - Order__c: 10
// 3. Logs automatically flow:
// LOG_Builder -> LogEntryEvent__e -> LogEntry__cPattern 2: API Integration with Retry Logic
// 1. Create API class
public with sharing class API_GetCustomerData extends API_Outbound
{
public override void configure()
{
super.configure();
requestPayload = new DTO_Request();
responsePayload = new DTO_Response();
defaultMockBody = '{"customerId": "C-12345", "name": "Acme Corp"}';
}
// Implementation...
}
// 2. Configure in ApiSetting__mdt:
// - ClassName__c: API_GetCustomerData
// - MaxRetryCount__c: 3
// - RetryBackoffSeconds__c: 60
// - LogIssues__c: true
// 3. Configure credentials in ApiCredential__mdt:
// - NamedCredential__c: callout:CustomerAPI
// 4. Automatic flow:
// API call -> ApiCall__c (success)
// OR
// API call -> ApiCall__c + ApiIssue__c (failure)
// -> Retry job -> ApiCall__c (resolved)Pattern 3: Feature Flag with Multiple Strategies
// 1. Check feature in code
Boolean isAdvancedReportingEnabled = UTIL_FeatureFlag.isEnabled('Advanced_Reporting');
if(isAdvancedReportingEnabled)
{
// Execute advanced reporting logic
}
// 2. Configure in FeatureFlag__mdt:
// - Label: Advanced Reporting
// - IsActive__c: true
// 3. Configure strategies in FeatureFlagStrategy__mdt:
// Strategy 1: Enable for System Admins
// - Type__c: Profile
// - Target__c: 00e000000000001AAA
//
// Strategy 2: Enable for specific power users
// - Type__c: User
// - Target__c: 005000000000001AAATesting
Custom objects and metadata types are tested indirectly through the framework classes that consume them. The KernDX framework provides TST_Factory methods for creating test metadata records in memory without DML, enabling isolated and parallel-safe tests.
Testing trigger action metadata:
@IsTest
private static void shouldExecuteTriggerAction()
{
TriggerSetting__mdt setting = TST_Factory.newTriggerSetting('Foobar__c');
TriggerAction__mdt action = TST_Factory.newTriggerActionForContext(
'TRG_SetFoobarDefaults', setting, TriggerOperation.BEFORE_INSERT
);
Foobar__c record = (Foobar__c)TST_Builder.of(Foobar__c.SObjectType).build();
Assert.isNotNull(record.Id, 'Record should be inserted with trigger action applied');
}Testing scheduled job configuration:
Scheduled jobs configured via ScheduledJob__c are tested by verifying the scheduler class executes correctly with the expected attributes. Use TST_Factory to create in-memory attribute sets and invoke the scheduler's execute() method directly.
Testing feature flags:
@IsTest
private static void shouldRespectFeatureFlag()
{
Boolean isEnabled = UTIL_FeatureFlag.isEnabled('MyFeatureFlag');
Assert.isFalse(isEnabled, 'Feature should be disabled when no metadata record exists');
}Custom metadata records (TriggerSetting__mdt, TriggerAction__mdt, FeatureFlag__mdt, etc.) cannot be inserted via DML in tests. The framework's TST_Factory methods create in-memory representations that the framework consumes during test execution.
Anti-Patterns
| Anti-Pattern | Why It's Wrong | Instead |
|---|---|---|
Hardcoding DeveloperName strings to reference metadata records | Breaks silently when records are renamed; no compile-time safety | Use class name constants (e.g., ClassName.class.getName()) or @TestVisible constants |
| Using Custom Settings where Custom Metadata Types would suffice | Custom Settings require DML in tests and cannot be deployed across orgs | Use Custom Metadata Types (__mdt) for static configuration; reserve Custom Settings for hierarchy or user-specific values |
Leaving Description__c fields empty on metadata records | Makes configuration opaque to administrators and future developers | Always populate Description__c with a brief explanation of the record's purpose |
| Creating org-specific test data that assumes specific metadata exists | Tests break in different orgs or after metadata changes | Use TST_Factory to create metadata records in tests; never rely on pre-existing org data |
| Querying metadata with inline SOQL | Violates framework patterns and bypasses selector caching | Use SEL_* selectors or QRY_Builder for all metadata queries |
Best Practices
- Use custom metadata over custom settings for configuration that should be deployable. Custom metadata records deploy with change sets and packages; custom settings require post-deployment data loading.
- Document every metadata record using the
Description__cfield. Future administrators need to understand why each trigger action, feature flag, or API setting exists. - Use meaningful DeveloperNames for metadata records. Names like
TRG_SetFoobarDefaults_BeforeInsertare self-documenting; names likeAction1are not. - Keep trigger action execution order explicit by assigning
Order__cvalues with gaps (10, 20, 30) to allow future insertions without renumbering. - Prefer
TriggerSetting__mdt.BypassExecution__cover code-level bypass for temporary deactivation. Metadata bypasses are auditable and reversible without deployment. - Use
ApiCredential__mdtfor external service configuration rather than hardcoding endpoints or credentials. Named/external credentials are preferred when available;ApiCredential__mdtprovides a fallback. - Review
LogEntry__cretention regularly. ConfigureSCHED_PurgeRecordsviaScheduledJob__cto prevent storage growth from log accumulation. - Test with
@IsTest(SeeAllData=false)to ensure tests do not depend on org-specific metadata records. UseTST_Factoryto create test-specific metadata in memory.
Related Documentation
- Triggers - Guide -
TriggerSetting__mdtandTriggerAction__mdtconfiguration patterns - Validation - Guide -
ValidationRuleGroup__mdtandValidationRule__mdtconfiguration patterns - Web Services - Guide -
ApiSetting__mdt,ApiCredential__mdt,ApiMock__mdt, andApiCall__cusage - Async Processing - Guide -
ScheduledJob__c,AsynchronousJobSetting__mdt, andAsyncChainExecution__cconfiguration - Logging - Guide -
LogEntry__c,LogEntryEvent__e, and log filter metadata - Security - Guide -
ApiRuntimeSwitch__cfor runtime API kill switches - Utilities - Guide -
UTIL_FeatureFlagforFeatureFlag__mdtconsumption
Appendix A: Mermaid ERD
End of Document