Skip to content

Class Name: OrderItemSummaryTriggerHandler

Last Updated: 2025-10-22 Source Code: https://github.com/AANP-IT/I2C.Salesforce.Metadata/blob/STAGING/force-app/main/default/classes/OrderItemSummaryTriggerHandler.cls

API Name: OrderItemSummaryTriggerHandler Type: Trigger Handler (Change Data Capture) Test Coverage: Target 85%+

Business Purpose

The OrderItemSummaryTriggerHandler class handles Platform Events for OrderItemSummaryChangeEvent, specifically triggering automated logic when order items are cancelled in the Order Management system. This handler enables near-real-time processing of order cancellations by: - Listening to OrderItemSummary change events - Delegating to CanceledOrderLogic for cancellation processing - Supporting asynchronous, event-driven order management workflows

Class Overview

  • Author: Ryan O'Sullivan
  • Created: 2025-01-22
  • Scope/Sharing: with sharing - Respects record-level security
  • Extends: TriggerHandler - Base trigger framework class
  • Supported Events: afterInsert only (change event pattern)
  • Key Responsibilities:
  • Receive OrderItemSummaryChangeEvent notifications
  • Route events to cancellation processing logic
  • Maintain separation between trigger infrastructure and business logic

Why Change Events?

This handler uses Salesforce Platform Events (OrderItemSummaryChangeEvent) rather than traditional triggers because: - Decoupling: Separates event capture from processing - Asynchronous: Processing can happen after transaction commits - Scalability: Handles high-volume order cancellations without blocking user transactions - Retry Logic: Failed event processing can be retried automatically - Multi-Org: Events can be published across org boundaries

Public Methods

afterInsert

protected override void afterInsert(Map<Id, SObject> newRecordsMap)

Purpose: Handles OrderItemSummaryChangeEvent after insert, delegating to cancellation logic.

Parameters: - newRecordsMap (Map) - Map of event IDs to OrderItemSummaryChangeEvent records

Returns: void

Business Logic: 1. Event Reception (line 10): Receives change event map from Platform Event framework 2. Type Casting (line 11): Casts Map<Id, SObject> to Map<Id, OrderItemSummaryChangeEvent> 3. Delegation (line 11): Passes events to CanceledOrderLogic.run() for processing

Implementation Details:

protected override void afterInsert(Map<Id, SObject> newRecordsMap) {
    CanceledOrderLogic.run((Map<Id,OrderItemSummaryChangeEvent>)newRecordsMap);
}

Issues/Concerns: - ⚠️ Unchecked Type Cast: Line 11 casts without validation (could throw ClassCastException) - ⚠️ No Null Check: Doesn't verify newRecordsMap is non-null - ⚠️ No Error Handling: No try-catch around delegation call - ⚠️ No Event Filtering: Passes ALL events regardless of Status or other criteria - May process events for Active, Fulfilled, or other non-cancellation statuses - Filtering likely happens in CanceledOrderLogic - ✅ Clean Separation: Delegates to business logic class rather than implementing inline - ✅ Minimal Handler: Keeps trigger handler simple and focused

Event Flow:

1. OrderItemSummary record updated (e.g., Status → 'Canceled')
2. Salesforce publishes OrderItemSummaryChangeEvent
3. OrderItemSummaryTriggerHandler.afterInsert() receives event
4. CanceledOrderLogic.run() processes cancellation
5. Business logic executes (refunds, notifications, etc.)

Recommended Improvements:

protected override void afterInsert(Map<Id, SObject> newRecordsMap) {
    if (newRecordsMap == null || newRecordsMap.isEmpty()) {
        return;
    }

    try {
        // Validate event type before casting
        if (newRecordsMap.values()[0] instanceof OrderItemSummaryChangeEvent) {
            Map<Id, OrderItemSummaryChangeEvent> eventMap =
                (Map<Id, OrderItemSummaryChangeEvent>)newRecordsMap;
            CanceledOrderLogic.run(eventMap);
        } else {
            System.debug(LoggingLevel.ERROR, 'Unexpected event type: ' + newRecordsMap.values()[0].getSObjectType());
        }
    } catch (Exception e) {
        System.debug(LoggingLevel.ERROR, 'Error processing OrderItemSummaryChangeEvent: ' + e.getMessage());
        // Consider inserting error log record for monitoring
    }
}

Trigger Context

Supported Operations

  • afterInsert: ✅ Implemented (line 10)
  • beforeInsert: ❌ Not applicable (change events are read-only)
  • beforeUpdate: ❌ Not applicable (change events don't support updates)
  • afterUpdate: ❌ Not applicable (change events are insert-only)
  • beforeDelete: ❌ Not applicable (change events are immutable)
  • afterDelete: ❌ Not applicable (change events are immutable)

Why Only afterInsert?

Platform Events (including Change Events) only support afterInsert because: - Immutable: Events cannot be modified once published - Fire-and-Forget: Events are published and consumed, not updated or deleted - Asynchronous: Processing happens after the publishing transaction commits

Dependencies

Salesforce Objects

OrderItemSummaryChangeEvent (Platform Event)

  • Type: Standard Change Event for OrderItemSummary
  • Fields: Contains changed fields from OrderItemSummary record
  • Id, Status, OrderSummaryId, etc.
  • Only changed fields are populated in event payload
  • Access: Subscribe (automatic via trigger)

OrderItemSummary (Standard Object - Order Management)

  • Relationship: Change Event represents changes to this object
  • Fields: Id, Status, OrderSummaryId, Quantity, etc.
  • Trigger: This handler processes changes to OrderItemSummary records

Custom Settings/Metadata

  • None directly (may be used by CanceledOrderLogic)

Other Classes

  • TriggerHandler (Base Class):
  • Framework for trigger orchestration
  • Provides afterInsert() override method
  • Manages trigger context (Trigger.new, Trigger.old, etc.)
  • CanceledOrderLogic:
  • Business logic for order cancellations
  • Processes OrderItemSummaryChangeEvents
  • Likely handles refunds, notifications, inventory updates

External Services

  • None directly (may be invoked by CanceledOrderLogic)

Design Patterns

  1. Trigger Handler Pattern: Extends TriggerHandler base class for consistent trigger management
  2. Separation of Concerns: Delegates business logic to dedicated service class
  3. Event-Driven Architecture: Uses Platform Events for asynchronous processing
  4. Single Responsibility: Handler only routes events, doesn't implement logic
  5. Change Data Capture (CDC): Leverages Salesforce CDC for OrderItemSummary changes

Governor Limits Considerations

Current Impact (Per Event Batch)

  • Platform Event Consumption: Receives up to 2,000 events per batch
  • SOQL Queries: 0 (delegated to CanceledOrderLogic)
  • DML Statements: 0 (delegated to CanceledOrderLogic)
  • CPU Time: Minimal (type cast + method call only)
  • Heap Size: Minimal (map reference passed)

Platform Event Limits

  • Event Publication: 250,000 events/day (not relevant here - consumption only)
  • Event Consumption: Auto-scaled by Salesforce
  • Replay Window: 72 hours (events retained for replay if subscriber fails)
  • Delivery: At-least-once delivery guarantee (duplicates possible)

Scalability Analysis

  • Asynchronous Processing: Doesn't block user transactions
  • Auto-Scaling: Salesforce manages event processing capacity
  • ⚠️ Bulk Processing: Handler must process events in bulk efficiently
  • ⚠️ Duplicate Events: At-least-once delivery means same event may process multiple times
  • CanceledOrderLogic must be idempotent

Event Processing Best Practices

  1. Idempotency: Ensure CanceledOrderLogic handles duplicate events gracefully
  2. Error Handling: Failed events are retried automatically
  3. Monitoring: Track event processing latency via Event Log Files
  4. Replay: Use ReplayId to replay events from specific point in time

Error Handling

Exception Types Thrown

  • ClassCastException: If newRecordsMap contains wrong event type
  • NullPointerException: If newRecordsMap is null (unlikely but possible)

Exception Types Caught

  • None - No try-catch blocks

Error Handling Strategy

  • No Local Handling: Exceptions bubble up to Platform Event framework
  • Framework Retry: Failed events automatically retried by Salesforce
  • Dead Letter Queue: After 3 failed attempts, events move to error queue
  • Monitoring: Use Event Log Files and Event Monitoring to track failures

Error Handling Gaps

  1. No Exception Logging: Failures not logged locally for debugging
  2. No Custom Retry Logic: Relies entirely on platform retry mechanism
  3. No Circuit Breaker: No protection against repeated failures
  4. No Dead Letter Handling: No custom logic for permanently failed events
// Query event delivery failures
SELECT EventType, ReplayId, CreatedDate, CreatedById
FROM EventLogFile
WHERE EventType = 'OrderItemSummaryChangeEvent'
  AND LogDate = TODAY
  AND Status = 'Failed'

// Monitor event processing latency
SELECT AVG(Duration), MAX(Duration)
FROM EventLogFile
WHERE EventType = 'OrderItemSummaryChangeEvent'
  AND LogDate = LAST_N_DAYS:7

Security Considerations

Sharing Model

  • WITH SHARING: Respects record-level security
  • Implication: Event processing runs in context of automated process user
  • Change Events: Delivered regardless of user's record access
  • Security must be enforced in CanceledOrderLogic if needed

Event Security

  • Subscribe Access: Requires "View All Data" or specific event permissions
  • Event Payload: Contains only changed fields (not full record)
  • Sensitive Data: Change events may contain PII or financial data
  • Ensure proper handling in downstream logic

Best Practices

  1. Field-Level Security: Validate FLS in CanceledOrderLogic if exposing data
  2. Audit Trail: Log event processing for compliance
  3. Data Masking: Mask sensitive fields before logging

Test Class Requirements

Required Test Coverage

@IsTest
public class OrderItemSummaryTriggerHandlerTest {

    @IsTest
    static void testAfterInsert_SingleEvent() {
        // Note: Testing Platform Events requires specific setup
        // This is a simplified example

        Test.startTest();

        // Create test OrderItemSummary (if possible in test context)
        // Or create mock change event

        // Publish change event
        // OrderItemSummaryChangeEvent event = new OrderItemSummaryChangeEvent(
        //     Status__c = 'Canceled'
        // );
        // EventBus.publish(event);

        Test.stopTest();

        // Verify CanceledOrderLogic was called
        // This requires mocking or observable side effects
    }

    @IsTest
    static void testAfterInsert_BulkEvents() {
        // Test with multiple events
        Test.startTest();

        // Publish multiple change events
        // List<OrderItemSummaryChangeEvent> events = new List<OrderItemSummaryChangeEvent>();
        // for (Integer i = 0; i < 200; i++) {
        //     events.add(new OrderItemSummaryChangeEvent(Status__c = 'Canceled'));
        // }
        // EventBus.publish(events);

        Test.stopTest();

        // Verify bulk processing
    }

    @IsTest
    static void testAfterInsert_ErrorHandling() {
        // Test error scenarios
        // Force CanceledOrderLogic to throw exception
        // Verify event retry mechanism

        Test.startTest();
        // Trigger error condition
        Test.stopTest();

        // Verify error was handled appropriately
    }

    @IsTest
    static void testTriggerHandler_OnlyAfterInsertSupported() {
        // Verify no other trigger contexts are implemented
        OrderItemSummaryTriggerHandler handler = new OrderItemSummaryTriggerHandler();

        // beforeInsert, afterUpdate, etc. should not be overridden
        // Reflection-based test to verify only afterInsert is implemented
    }
}

Test Data Requirements

  • OrderItemSummary: Requires Commerce Cloud Order Management
  • OrderItemSummaryChangeEvent: Platform Event (test framework handles)
  • CanceledOrderLogic Dependencies: Any objects/data that logic requires

Testing Challenges

  • Platform Events: Difficult to test in unit tests
  • Change Events: Cannot be manually created (published by system)
  • Asynchronous Processing: May need Test.getEventBus().deliver() in tests
  • CanceledOrderLogic: May need mocking if complex

Changes & History

Date Author Description
2025-01-22 Ryan O'Sullivan Initial implementation for OrderItemSummary change event handling
(Current) - Documentation added

Pre-Go-Live Concerns

CRITICAL

  • No Error Handling: Uncaught exceptions cause event retry loop
  • Add try-catch with error logging
  • Prevent infinite retry on persistent errors

HIGH

  • No Event Filtering: Processes ALL OrderItemSummary changes
  • Verify CanceledOrderLogic filters to Status='Canceled' events only
  • Consider filtering in handler to reduce processing overhead
  • No Duplicate Detection: At-least-once delivery guarantee
  • Ensure CanceledOrderLogic is idempotent
  • Add duplicate event detection logic

MEDIUM

  • No Type Validation: Unsafe cast on line 11
  • Add instanceof check before casting
  • No Monitoring: No custom logging or metrics
  • Add structured logging for event processing
  • Track processing latency and failure rates

LOW

  • No Comments: Minimal inline documentation
  • Add javadoc comments for method
  • Test Coverage: Platform Event testing may be incomplete
  • Ensure integration testing covers event end-to-end

Maintenance Notes

📋 Monitoring Recommendations

  • Event Delivery: Monitor Event Log Files for failed deliveries
  • Processing Latency: Track time from event publication to processing completion
  • Error Rate: Alert on high failure rates for this event type
  • Retry Volume: Monitor events being retried (indicates persistent issues)

🔧 Debugging Tips

// View recent OrderItemSummaryChangeEvent records
// (Events are retained for 72 hours)
SELECT Id, ReplayId, CreatedDate, Status__c, OrderSummaryId__c
FROM OrderItemSummaryChangeEvent
WHERE CreatedDate = TODAY
ORDER BY CreatedDate DESC
LIMIT 100

// Check Platform Event Allocations
SELECT DurableId, EventType, AllocatedEventDeliveries
FROM PlatformEventUsageMetric
WHERE EventType = 'OrderItemSummaryChangeEvent'

⚠️ Breaking Change Risks

  • Modifying afterInsert signature breaks TriggerHandler contract
  • Changing event processing logic in CanceledOrderLogic affects behavior
  • Disabling change events stops cancellation automation
  • TriggerHandler: Base trigger framework class
  • CanceledOrderLogic: Business logic for order cancellations
  • OrderItemSummary: Source object for change events
  • OrderItemSummaryChangeEvent: Platform Event for OrderItemSummary changes
  • Order Management Flows: Fulfillment and cancellation workflows

Business Owner

Primary Contact: Order Management / Fulfillment Team Technical Owner: Ryan O'Sullivan / Salesforce Development Team Created: 2025-01-22 Last Reviewed: [Date]


Documentation Status: ✅ Complete Code Review Status: ⚠️ Requires error handling and event filtering Test Coverage: Target 85%+ (Platform Event testing may require special setup) Order Management Dependency: Requires Commerce Cloud Order Management