/** * Queueable Apex class for {describe the async operation}. * Accepts data through the constructor for stateful processing. * Optionally implements Database.AllowsCallouts for external integrations. * @author Generated by Apex Class Writer Skill * * @example * // Enqueue the job * Id jobId = System.enqueueJob(new {ClassName}(recordIds)); */ public with sharing class {ClassName} implements Queueable /*, Database.AllowsCallouts */ { // ─── Constants ─────────────────────────────────────────────────────── private static final Integer MAX_CHAIN_DEPTH = 5; // ─── Instance Variables (Stateful) ─────────────────────────────────── private Set recordIds; private Integer chainDepth; // ─── Constructors ──────────────────────────────────────────────────── /** * Creates a new queueable job to process the specified records * @param recordIds Set of record Ids to process */ public {ClassName}(Set recordIds) { this(recordIds, 0); } /** * Creates a new queueable job with chain depth tracking * @param recordIds Set of record Ids to process * @param chainDepth Current depth in the queueable chain */ public {ClassName}(Set recordIds, Integer chainDepth) { this.recordIds = recordIds ?? new Set(); this.chainDepth = chainDepth; } // ─── Queueable Interface ───────────────────────────────────────────── /** * Executes the asynchronous work * @param context The queueable context */ public void execute(QueueableContext context) { if (this.recordIds.isEmpty()) { return; } try { // TODO: Implement the async processing logic // List<{SObject}> records = {SObject}Selector.selectByIds(this.recordIds); // ... process records ... // Chain to next job if there's more work and we haven't hit the depth limit chainIfNeeded(); } catch (Exception e) { handleError(context.getJobId(), e); } } // ─── Private Helpers ───────────────────────────────────────────────── /** * Chains to the next queueable job if needed, with depth guard */ private void chainIfNeeded() { // TODO: Determine if chaining is needed (e.g., remaining records to process) Set remainingIds = new Set(); if (!remainingIds.isEmpty() && this.chainDepth < MAX_CHAIN_DEPTH) { if (!Test.isRunningTest()) { System.enqueueJob(new {ClassName}(remainingIds, this.chainDepth + 1)); } } } /** * Handles errors during execution * @param jobId The async job Id * @param e The exception that occurred */ private void handleError(Id jobId, Exception e) { System.debug(LoggingLevel.ERROR, '{ClassName} failed (Job: ' + jobId + '): ' + e.getMessage() + '\n' + e.getStackTraceString() ); // TODO: Persist error to a log object or send notification } }