scc-universal 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/.claude-plugin/plugin.json +44 -0
  2. package/.cursor/agents/deep-researcher.md +142 -0
  3. package/.cursor/agents/doc-updater.md +219 -0
  4. package/.cursor/agents/eval-runner.md +335 -0
  5. package/.cursor/agents/learning-engine.md +210 -0
  6. package/.cursor/agents/loop-operator.md +245 -0
  7. package/.cursor/agents/refactor-cleaner.md +119 -0
  8. package/.cursor/agents/sf-admin-agent.md +127 -0
  9. package/.cursor/agents/sf-agentforce-agent.md +126 -0
  10. package/.cursor/agents/sf-apex-agent.md +117 -0
  11. package/.cursor/agents/sf-architect.md +426 -0
  12. package/.cursor/agents/sf-aura-reviewer.md +369 -0
  13. package/.cursor/agents/sf-bugfix-agent.md +101 -0
  14. package/.cursor/agents/sf-flow-agent.md +155 -0
  15. package/.cursor/agents/sf-integration-agent.md +141 -0
  16. package/.cursor/agents/sf-lwc-agent.md +123 -0
  17. package/.cursor/agents/sf-review-agent.md +357 -0
  18. package/.cursor/agents/sf-visualforce-reviewer.md +465 -0
  19. package/.cursor/hooks/adapter.js +81 -0
  20. package/.cursor/hooks/after-file-edit.js +26 -0
  21. package/.cursor/hooks/after-mcp-execution.js +12 -0
  22. package/.cursor/hooks/after-shell-execution.js +30 -0
  23. package/.cursor/hooks/after-tab-file-edit.js +12 -0
  24. package/.cursor/hooks/before-mcp-execution.js +11 -0
  25. package/.cursor/hooks/before-read-file.js +13 -0
  26. package/.cursor/hooks/before-shell-execution.js +29 -0
  27. package/.cursor/hooks/before-submit-prompt.js +23 -0
  28. package/.cursor/hooks/pre-compact.js +7 -0
  29. package/.cursor/hooks/session-end.js +10 -0
  30. package/.cursor/hooks/session-start.js +10 -0
  31. package/.cursor/hooks/stop.js +18 -0
  32. package/.cursor/hooks/subagent-start.js +10 -0
  33. package/.cursor/hooks/subagent-stop.js +10 -0
  34. package/.cursor/hooks.json +107 -0
  35. package/.cursor/skills/aside/SKILL.md +115 -0
  36. package/.cursor/skills/checkpoint/SKILL.md +50 -0
  37. package/.cursor/skills/configure-scc/SKILL.md +160 -0
  38. package/.cursor/skills/continuous-agent-loop/SKILL.md +260 -0
  39. package/.cursor/skills/mcp-server-patterns/SKILL.md +142 -0
  40. package/.cursor/skills/model-route/SKILL.md +81 -0
  41. package/.cursor/skills/prompt-optimizer/SKILL.md +366 -0
  42. package/.cursor/skills/refactor-clean/SKILL.md +133 -0
  43. package/.cursor/skills/resume-session/SKILL.md +111 -0
  44. package/.cursor/skills/save-session/SKILL.md +183 -0
  45. package/.cursor/skills/search-first/SKILL.md +140 -0
  46. package/.cursor/skills/security-scan/SKILL.md +142 -0
  47. package/.cursor/skills/sessions/SKILL.md +124 -0
  48. package/.cursor/skills/sf-agentforce-development/SKILL.md +449 -0
  49. package/.cursor/skills/sf-apex-async-patterns/SKILL.md +324 -0
  50. package/.cursor/skills/sf-apex-best-practices/SKILL.md +421 -0
  51. package/.cursor/skills/sf-apex-constraints/SKILL.md +79 -0
  52. package/.cursor/skills/sf-apex-cursor/SKILL.md +336 -0
  53. package/.cursor/skills/sf-apex-enterprise-patterns/SKILL.md +344 -0
  54. package/.cursor/skills/sf-apex-testing/SKILL.md +407 -0
  55. package/.cursor/skills/sf-api-design/SKILL.md +237 -0
  56. package/.cursor/skills/sf-approval-processes/SKILL.md +312 -0
  57. package/.cursor/skills/sf-aura-development/SKILL.md +260 -0
  58. package/.cursor/skills/sf-build-fix/SKILL.md +120 -0
  59. package/.cursor/skills/sf-data-modeling/SKILL.md +274 -0
  60. package/.cursor/skills/sf-debugging/SKILL.md +362 -0
  61. package/.cursor/skills/sf-deployment/SKILL.md +291 -0
  62. package/.cursor/skills/sf-deployment-constraints/SKILL.md +153 -0
  63. package/.cursor/skills/sf-devops-ci-cd/SKILL.md +322 -0
  64. package/.cursor/skills/sf-docs-lookup/SKILL.md +100 -0
  65. package/.cursor/skills/sf-e2e-testing/SKILL.md +321 -0
  66. package/.cursor/skills/sf-experience-cloud/SKILL.md +248 -0
  67. package/.cursor/skills/sf-flow-development/SKILL.md +376 -0
  68. package/.cursor/skills/sf-governor-limits/SKILL.md +319 -0
  69. package/.cursor/skills/sf-harness-audit/SKILL.md +139 -0
  70. package/.cursor/skills/sf-help/SKILL.md +156 -0
  71. package/.cursor/skills/sf-integration/SKILL.md +479 -0
  72. package/.cursor/skills/sf-lwc-constraints/SKILL.md +128 -0
  73. package/.cursor/skills/sf-lwc-development/SKILL.md +302 -0
  74. package/.cursor/skills/sf-lwc-testing/SKILL.md +387 -0
  75. package/.cursor/skills/sf-metadata-management/SKILL.md +285 -0
  76. package/.cursor/skills/sf-platform-events-cdc/SKILL.md +372 -0
  77. package/.cursor/skills/sf-quickstart/SKILL.md +170 -0
  78. package/.cursor/skills/sf-security/SKILL.md +330 -0
  79. package/.cursor/skills/sf-security-constraints/SKILL.md +125 -0
  80. package/.cursor/skills/sf-soql-constraints/SKILL.md +129 -0
  81. package/.cursor/skills/sf-soql-optimization/SKILL.md +353 -0
  82. package/.cursor/skills/sf-tdd-workflow/SKILL.md +332 -0
  83. package/.cursor/skills/sf-testing-constraints/SKILL.md +198 -0
  84. package/.cursor/skills/sf-trigger-constraints/SKILL.md +88 -0
  85. package/.cursor/skills/sf-trigger-frameworks/SKILL.md +343 -0
  86. package/.cursor/skills/sf-visualforce-development/SKILL.md +259 -0
  87. package/.cursor/skills/strategic-compact/SKILL.md +205 -0
  88. package/.cursor/skills/update-docs/SKILL.md +162 -0
  89. package/.cursor/skills/update-platform-docs/SKILL.md +86 -0
  90. package/.cursor-plugin/plugin.json +26 -0
  91. package/LICENSE +21 -0
  92. package/README.md +522 -0
  93. package/agents/deep-researcher.md +145 -0
  94. package/agents/doc-updater.md +222 -0
  95. package/agents/eval-runner.md +340 -0
  96. package/agents/learning-engine.md +211 -0
  97. package/agents/loop-operator.md +247 -0
  98. package/agents/refactor-cleaner.md +122 -0
  99. package/agents/sf-admin-agent.md +131 -0
  100. package/agents/sf-agentforce-agent.md +132 -0
  101. package/agents/sf-apex-agent.md +124 -0
  102. package/agents/sf-architect.md +435 -0
  103. package/agents/sf-aura-reviewer.md +372 -0
  104. package/agents/sf-bugfix-agent.md +105 -0
  105. package/agents/sf-flow-agent.md +159 -0
  106. package/agents/sf-integration-agent.md +146 -0
  107. package/agents/sf-lwc-agent.md +127 -0
  108. package/agents/sf-review-agent.md +366 -0
  109. package/agents/sf-visualforce-reviewer.md +468 -0
  110. package/assets/logo.svg +18 -0
  111. package/docs/ARCHITECTURE.md +133 -0
  112. package/docs/authoring-guide.md +373 -0
  113. package/docs/hook-development.md +578 -0
  114. package/docs/token-optimization.md +139 -0
  115. package/docs/workflow-examples.md +645 -0
  116. package/examples/agentforce-action/README.md +227 -0
  117. package/examples/apex-trigger-handler/README.md +114 -0
  118. package/examples/devops-pipeline/README.md +325 -0
  119. package/examples/flow-automation/README.md +188 -0
  120. package/examples/integration-pattern/README.md +416 -0
  121. package/examples/lwc-component/README.md +180 -0
  122. package/examples/platform-events/README.md +492 -0
  123. package/examples/scratch-org-setup/README.md +138 -0
  124. package/examples/security-audit/README.md +244 -0
  125. package/examples/visualforce-migration/README.md +314 -0
  126. package/hooks/hooks.json +338 -0
  127. package/hooks/memory-persistence/README.md +73 -0
  128. package/manifests/install-modules.json +217 -0
  129. package/manifests/install-profiles.json +17 -0
  130. package/mcp-configs/mcp-servers.json +19 -0
  131. package/package.json +89 -0
  132. package/schemas/hooks.schema.json +123 -0
  133. package/schemas/install-modules.schema.json +76 -0
  134. package/schemas/install-profiles.schema.json +28 -0
  135. package/schemas/install-state.schema.json +73 -0
  136. package/schemas/package-manager.schema.json +18 -0
  137. package/schemas/plugin.schema.json +112 -0
  138. package/schemas/scc-install-config.schema.json +29 -0
  139. package/schemas/state-store.schema.json +111 -0
  140. package/scripts/cli/install-apply.js +170 -0
  141. package/scripts/cli/uninstall.js +193 -0
  142. package/scripts/hooks/check-console-log.js +101 -0
  143. package/scripts/hooks/check-hook-enabled.js +17 -0
  144. package/scripts/hooks/check-platform-docs-age.js +48 -0
  145. package/scripts/hooks/cost-tracker.js +78 -0
  146. package/scripts/hooks/doc-file-warning.js +63 -0
  147. package/scripts/hooks/evaluate-session.js +98 -0
  148. package/scripts/hooks/governor-check.js +220 -0
  149. package/scripts/hooks/learning-observe.sh +206 -0
  150. package/scripts/hooks/mcp-health-check.js +588 -0
  151. package/scripts/hooks/post-bash-build-complete.js +34 -0
  152. package/scripts/hooks/post-bash-pr-created.js +43 -0
  153. package/scripts/hooks/post-edit-console-warn.js +61 -0
  154. package/scripts/hooks/post-edit-format.js +79 -0
  155. package/scripts/hooks/post-edit-typecheck.js +98 -0
  156. package/scripts/hooks/post-write.js +168 -0
  157. package/scripts/hooks/pre-bash-git-push-reminder.js +35 -0
  158. package/scripts/hooks/pre-bash-tmux-reminder.js +47 -0
  159. package/scripts/hooks/pre-compact.js +51 -0
  160. package/scripts/hooks/pre-tool-use.js +163 -0
  161. package/scripts/hooks/pre-write-doc-warn.js +9 -0
  162. package/scripts/hooks/quality-gate.js +251 -0
  163. package/scripts/hooks/run-with-flags-shell.sh +32 -0
  164. package/scripts/hooks/run-with-flags.js +135 -0
  165. package/scripts/hooks/session-end-marker.js +29 -0
  166. package/scripts/hooks/session-end.js +311 -0
  167. package/scripts/hooks/session-start.js +202 -0
  168. package/scripts/hooks/sfdx-scanner-check.js +142 -0
  169. package/scripts/hooks/sfdx-validate.js +119 -0
  170. package/scripts/hooks/stop-hook.js +170 -0
  171. package/scripts/hooks/suggest-compact.js +67 -0
  172. package/scripts/lib/agent-adapter.js +82 -0
  173. package/scripts/lib/apex-analysis.js +194 -0
  174. package/scripts/lib/hook-flags.js +74 -0
  175. package/scripts/lib/install-config.js +73 -0
  176. package/scripts/lib/install-executor.js +363 -0
  177. package/scripts/lib/install-state.js +121 -0
  178. package/scripts/lib/orchestration-session.js +299 -0
  179. package/scripts/lib/package-manager.js +124 -0
  180. package/scripts/lib/project-detect.js +228 -0
  181. package/scripts/lib/schema-validator.js +190 -0
  182. package/scripts/lib/skill-adapter.js +100 -0
  183. package/scripts/lib/state-store.js +376 -0
  184. package/scripts/lib/tmux-worktree-orchestrator.js +598 -0
  185. package/scripts/lib/utils.js +313 -0
  186. package/scripts/scc.js +164 -0
  187. package/skills/_reference/AGENTFORCE_PATTERNS.md +112 -0
  188. package/skills/_reference/APEX_CURSOR.md +159 -0
  189. package/skills/_reference/API_VERSIONS.md +78 -0
  190. package/skills/_reference/APPROVAL_PROCESSES.md +105 -0
  191. package/skills/_reference/ASYNC_PATTERNS.md +163 -0
  192. package/skills/_reference/AURA_COMPONENTS.md +146 -0
  193. package/skills/_reference/DATA_MIGRATION_PATTERNS.md +151 -0
  194. package/skills/_reference/DATA_MODELING.md +124 -0
  195. package/skills/_reference/DEBUGGING_TOOLS.md +140 -0
  196. package/skills/_reference/DEPLOYMENT_CHECKLIST.md +87 -0
  197. package/skills/_reference/DEPRECATIONS.md +79 -0
  198. package/skills/_reference/DOCKER_CI_PATTERNS.md +138 -0
  199. package/skills/_reference/ENTERPRISE_PATTERNS.md +122 -0
  200. package/skills/_reference/EXPERIENCE_CLOUD.md +143 -0
  201. package/skills/_reference/FLOW_PATTERNS.md +113 -0
  202. package/skills/_reference/GOVERNOR_LIMITS.md +77 -0
  203. package/skills/_reference/INTEGRATION_PATTERNS.md +105 -0
  204. package/skills/_reference/LWC_PATTERNS.md +79 -0
  205. package/skills/_reference/METADATA_TYPES.md +115 -0
  206. package/skills/_reference/NAMING_CONVENTIONS.md +84 -0
  207. package/skills/_reference/PACKAGE_DEVELOPMENT.md +150 -0
  208. package/skills/_reference/PLATFORM_EVENTS.md +121 -0
  209. package/skills/_reference/REPORTING_API.md +143 -0
  210. package/skills/_reference/SCRATCH_ORG_PATTERNS.md +126 -0
  211. package/skills/_reference/SECURITY_PATTERNS.md +127 -0
  212. package/skills/_reference/SHARING_MODEL.md +120 -0
  213. package/skills/_reference/SOQL_PATTERNS.md +119 -0
  214. package/skills/_reference/TESTING_STANDARDS.md +96 -0
  215. package/skills/_reference/TRIGGER_PATTERNS.md +114 -0
  216. package/skills/_reference/VISUALFORCE_PATTERNS.md +121 -0
  217. package/skills/aside/SKILL.md +118 -0
  218. package/skills/checkpoint/SKILL.md +53 -0
  219. package/skills/configure-scc/SKILL.md +163 -0
  220. package/skills/continuous-agent-loop/SKILL.md +264 -0
  221. package/skills/mcp-server-patterns/SKILL.md +146 -0
  222. package/skills/model-route/SKILL.md +84 -0
  223. package/skills/prompt-optimizer/SKILL.md +369 -0
  224. package/skills/refactor-clean/SKILL.md +136 -0
  225. package/skills/resume-session/SKILL.md +114 -0
  226. package/skills/save-session/SKILL.md +186 -0
  227. package/skills/search-first/SKILL.md +144 -0
  228. package/skills/security-scan/SKILL.md +146 -0
  229. package/skills/sessions/SKILL.md +127 -0
  230. package/skills/sf-agentforce-development/SKILL.md +450 -0
  231. package/skills/sf-apex-async-patterns/SKILL.md +326 -0
  232. package/skills/sf-apex-best-practices/SKILL.md +425 -0
  233. package/skills/sf-apex-constraints/SKILL.md +81 -0
  234. package/skills/sf-apex-cursor/SKILL.md +338 -0
  235. package/skills/sf-apex-enterprise-patterns/SKILL.md +348 -0
  236. package/skills/sf-apex-testing/SKILL.md +409 -0
  237. package/skills/sf-api-design/SKILL.md +238 -0
  238. package/skills/sf-approval-processes/SKILL.md +315 -0
  239. package/skills/sf-aura-development/SKILL.md +263 -0
  240. package/skills/sf-build-fix/SKILL.md +121 -0
  241. package/skills/sf-data-modeling/SKILL.md +278 -0
  242. package/skills/sf-debugging/SKILL.md +363 -0
  243. package/skills/sf-deployment/SKILL.md +295 -0
  244. package/skills/sf-deployment-constraints/SKILL.md +155 -0
  245. package/skills/sf-devops-ci-cd/SKILL.md +325 -0
  246. package/skills/sf-docs-lookup/SKILL.md +103 -0
  247. package/skills/sf-e2e-testing/SKILL.md +324 -0
  248. package/skills/sf-experience-cloud/SKILL.md +249 -0
  249. package/skills/sf-flow-development/SKILL.md +377 -0
  250. package/skills/sf-governor-limits/SKILL.md +323 -0
  251. package/skills/sf-harness-audit/SKILL.md +142 -0
  252. package/skills/sf-help/SKILL.md +159 -0
  253. package/skills/sf-integration/SKILL.md +483 -0
  254. package/skills/sf-lwc-constraints/SKILL.md +130 -0
  255. package/skills/sf-lwc-development/SKILL.md +303 -0
  256. package/skills/sf-lwc-testing/SKILL.md +388 -0
  257. package/skills/sf-metadata-management/SKILL.md +288 -0
  258. package/skills/sf-platform-events-cdc/SKILL.md +375 -0
  259. package/skills/sf-quickstart/SKILL.md +173 -0
  260. package/skills/sf-security/SKILL.md +334 -0
  261. package/skills/sf-security-constraints/SKILL.md +127 -0
  262. package/skills/sf-soql-constraints/SKILL.md +131 -0
  263. package/skills/sf-soql-optimization/SKILL.md +354 -0
  264. package/skills/sf-tdd-workflow/SKILL.md +336 -0
  265. package/skills/sf-testing-constraints/SKILL.md +200 -0
  266. package/skills/sf-trigger-constraints/SKILL.md +90 -0
  267. package/skills/sf-trigger-frameworks/SKILL.md +347 -0
  268. package/skills/sf-visualforce-development/SKILL.md +260 -0
  269. package/skills/strategic-compact/SKILL.md +208 -0
  270. package/skills/update-docs/SKILL.md +165 -0
  271. package/skills/update-platform-docs/SKILL.md +90 -0
@@ -0,0 +1,324 @@
1
+ ---
2
+ name: sf-apex-async-patterns
3
+ description: >-
4
+ Async Apex patterns — @future, Queueable, Batch, Schedulable, Platform Events, chaining. Use when choosing or implementing async processing. Do NOT use for synchronous Apex or constraint enforcement.
5
+ ---
6
+
7
+ # Apex Async Patterns
8
+
9
+ Implementation guidance for asynchronous Apex. Covers when to use each pattern and how to implement it correctly. Governor limit numbers and hard rules live in the referenced files and `sf-apex-constraints`.
10
+
11
+ Reference: @../_reference/ASYNC_PATTERNS.md
12
+
13
+ ---
14
+
15
+ ## When to Use
16
+
17
+ - When synchronous Apex hits governor limits and needs a separate transaction
18
+ - When making HTTP callouts from trigger contexts
19
+ - When processing millions of records that exceed single-transaction limits
20
+ - When scheduling recurring Apex jobs on a cron-like schedule
21
+ - When decoupling event publishers from subscribers using Platform Events
22
+ - When deciding between `@future`, Queueable, Batch, Schedulable, or Platform Events
23
+
24
+ ---
25
+
26
+ ## Choosing the Right Pattern
27
+
28
+ | Requirement | Pattern |
29
+ |---|---|
30
+ | Simple async with no sObject params | `@future` |
31
+ | Need to pass sObjects or collections | `Queueable` |
32
+ | Need callouts from trigger context | `@future(callout=true)` |
33
+ | Need callouts with complex state | `Queueable + Database.AllowsCallouts` |
34
+ | Processing millions of records | `Batch Apex` |
35
+ | Need state across batches | `Batch Apex + Database.Stateful` |
36
+ | Run on a schedule | `Schedulable` (wraps Batch or Queueable) |
37
+ | Decouple publisher from subscriber | `Platform Events` |
38
+ | Chain jobs with delay | `Queueable + AsyncOptions` |
39
+
40
+ ---
41
+
42
+ ## @future Methods
43
+
44
+ The simplest async mechanism. Runs in a separate transaction with its own governor limits.
45
+
46
+ ```apex
47
+ public class ExternalDataSync {
48
+
49
+ @future(callout=true)
50
+ public static void syncAccountToERP(Id accountId) {
51
+ Account acc = [
52
+ SELECT Id, Name, BillingCity, AnnualRevenue
53
+ FROM Account WHERE Id = :accountId LIMIT 1
54
+ ];
55
+
56
+ HttpRequest req = new HttpRequest();
57
+ req.setEndpoint('callout:ERP_System/accounts');
58
+ req.setMethod('POST');
59
+ req.setHeader('Content-Type', 'application/json');
60
+ req.setBody(JSON.serialize(new ERPAccountPayload(acc)));
61
+
62
+ HttpResponse res = new Http().send(req);
63
+ if (res.getStatusCode() != 200) {
64
+ logSyncError(accountId, res.getStatusCode(), res.getBody());
65
+ }
66
+ }
67
+ }
68
+ ```
69
+
70
+ ### @future Constraints
71
+
72
+ - **No sObject parameters** — pass primitive types (Id, String) or serialized JSON. sObjects may change between enqueue and execution.
73
+ - **No chaining** — calling `@future` from another `@future` throws a runtime exception.
74
+ - **50 per transaction** — governor limit on future method invocations.
75
+ - **No return value** — fire-and-forget only.
76
+ - **Execution order not guaranteed**.
77
+
78
+ ---
79
+
80
+ ## Queueable Apex
81
+
82
+ More powerful than `@future`. Supports sObject parameters, chaining, and monitoring via `AsyncApexJob`.
83
+
84
+ ### Basic Queueable
85
+
86
+ ```apex
87
+ public class AccountEnrichmentJob implements Queueable {
88
+
89
+ private final List<Account> accounts;
90
+
91
+ public AccountEnrichmentJob(List<Account> accounts) {
92
+ this.accounts = accounts;
93
+ }
94
+
95
+ public void execute(QueueableContext context) {
96
+ List<Account> toUpdate = new List<Account>();
97
+ for (Account acc : accounts) {
98
+ if (acc.AnnualRevenue != null && acc.NumberOfEmployees != null
99
+ && acc.NumberOfEmployees > 0) {
100
+ toUpdate.add(new Account(
101
+ Id = acc.Id,
102
+ Revenue_Per_Employee__c = acc.AnnualRevenue / acc.NumberOfEmployees
103
+ ));
104
+ }
105
+ }
106
+ if (!toUpdate.isEmpty()) update toUpdate;
107
+ }
108
+ }
109
+
110
+ // Enqueue
111
+ System.enqueueJob(new AccountEnrichmentJob(accounts));
112
+ ```
113
+
114
+ ### Queueable with Callouts
115
+
116
+ Implement `Database.AllowsCallouts` alongside `Queueable`.
117
+
118
+ ```apex
119
+ public class ContactDataEnrichmentJob implements Queueable, Database.AllowsCallouts {
120
+ private final Set<Id> contactIds;
121
+
122
+ public ContactDataEnrichmentJob(Set<Id> contactIds) {
123
+ this.contactIds = contactIds;
124
+ }
125
+
126
+ public void execute(QueueableContext context) {
127
+ // Query, callout, update pattern
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### Chaining Queueable Jobs
133
+
134
+ Use chaining to process large data sets across multiple transactions. Use WHERE clauses to naturally shrink the result set instead of OFFSET (which has a 2,000-row hard limit).
135
+
136
+ ```apex
137
+ public class DataMigrationChainJob implements Queueable {
138
+
139
+ private static final Integer BATCH_SIZE = 200;
140
+
141
+ public void execute(QueueableContext context) {
142
+ List<Legacy_Record__c> batch = [
143
+ SELECT Id, Legacy_Field__c
144
+ FROM Legacy_Record__c
145
+ WHERE Migrated__c = false
146
+ ORDER BY CreatedDate
147
+ LIMIT :BATCH_SIZE
148
+ ];
149
+
150
+ if (batch.isEmpty()) return; // Migration complete
151
+
152
+ processBatch(batch);
153
+
154
+ // Chain next job — WHERE Migrated__c = false naturally shrinks each iteration
155
+ System.enqueueJob(new DataMigrationChainJob());
156
+ }
157
+ }
158
+ ```
159
+
160
+ ### AsyncOptions
161
+
162
+ ```apex
163
+ // Delay execution by 5 minutes
164
+ System.AsyncOptions opts = new System.AsyncOptions();
165
+ opts.minimumQueueableDelayInMinutes = 5;
166
+ System.enqueueJob(new MyQueueableJob(data), opts);
167
+
168
+ // Duplicate prevention with a unique key
169
+ System.AsyncOptions opts2 = new System.AsyncOptions();
170
+ opts2.duplicateSignature = 'account-sync-' + accountId;
171
+ System.enqueueJob(new AccountSyncJob(accountId), opts2);
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Batch Apex
177
+
178
+ For processing large data volumes (millions of records) that exceed single-transaction limits.
179
+
180
+ ### Basic Batch
181
+
182
+ ```apex
183
+ public class AccountAnnualReviewBatch
184
+ implements Database.Batchable<SObject>, Database.Stateful {
185
+
186
+ private Integer processedCount = 0;
187
+ private List<String> errors = new List<String>();
188
+
189
+ public Database.QueryLocator start(Database.BatchableContext bc) {
190
+ return Database.getQueryLocator([
191
+ SELECT Id, Name, AnnualRevenue, Last_Annual_Review__c, OwnerId
192
+ FROM Account
193
+ WHERE Type = 'Customer'
194
+ AND (Last_Annual_Review__c = null
195
+ OR Last_Annual_Review__c < LAST_N_DAYS:365)
196
+ ]);
197
+ }
198
+
199
+ public void execute(Database.BatchableContext bc, List<Account> scope) {
200
+ // Process scope — each execute() is its own transaction
201
+ // Default scope = 200 records
202
+ }
203
+
204
+ public void finish(Database.BatchableContext bc) {
205
+ // Cleanup and notifications
206
+ }
207
+ }
208
+
209
+ // Execute (default scope of 200)
210
+ Database.executeBatch(new AccountAnnualReviewBatch());
211
+
212
+ // Custom scope (smaller for complex processing or callouts)
213
+ Database.executeBatch(new AccountAnnualReviewBatch(), 50);
214
+ ```
215
+
216
+ ### Batch with Callouts
217
+
218
+ Implement `Database.AllowsCallouts` and set scope = 1 when each callout is per-record (each execute() is limited to 100 callouts).
219
+
220
+ ```apex
221
+ public class SingleRecordCalloutBatch
222
+ implements Database.Batchable<SObject>, Database.AllowsCallouts {
223
+ // scope = 1 in executeBatch call
224
+ }
225
+ Database.executeBatch(new SingleRecordCalloutBatch(), 1);
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Schedulable Apex
231
+
232
+ Runs Apex on a schedule. Best practice: schedulable should only coordinate, not do heavy work.
233
+
234
+ ```apex
235
+ public class WeeklyReportScheduler implements Schedulable {
236
+ public void execute(SchedulableContext sc) {
237
+ Database.executeBatch(new WeeklyReportBatch(), 200);
238
+ }
239
+ }
240
+
241
+ // Schedule
242
+ String cronExp = '0 0 6 ? * MON'; // Every Monday at 6:00 AM
243
+ System.schedule('Weekly Report - Monday 6AM', cronExp, new WeeklyReportScheduler());
244
+ ```
245
+
246
+ ### Cron Expression Reference
247
+
248
+ ```
249
+ 0 0 2 * * ? — Daily at 2:00 AM
250
+ 0 0 9 ? * MON-FRI — Weekdays at 9:00 AM
251
+ 0 0 0 1 * ? * — First day of every month at midnight
252
+ 0 30 8 ? * SAT — Every Saturday at 8:30 AM
253
+ ```
254
+
255
+ ---
256
+
257
+ ## Platform Events
258
+
259
+ Decouple publishers from subscribers. Subscribers run in their own transaction.
260
+
261
+ ### Publishing
262
+
263
+ ```apex
264
+ List<Order_Status_Change__e> events = new List<Order_Status_Change__e>();
265
+ for (Order__c order : orders) {
266
+ events.add(new Order_Status_Change__e(
267
+ Order_Id__c = order.Id,
268
+ New_Status__c = newStatus,
269
+ Changed_By__c = UserInfo.getUserId(),
270
+ Timestamp__c = Datetime.now()
271
+ ));
272
+ }
273
+ List<Database.SaveResult> results = EventBus.publish(events);
274
+ ```
275
+
276
+ > By default, high-volume platform events use "publish after commit" behavior. To publish immediately regardless of transaction outcome, configure the event's Publish Behavior to "Publish Immediately" in Setup.
277
+
278
+ ### Subscribing via Trigger
279
+
280
+ ```apex
281
+ trigger OrderStatusChangeTrigger on Order_Status_Change__e (after insert) {
282
+ for (Order_Status_Change__e event : Trigger.new) {
283
+ // Process event — runs in its own transaction
284
+ }
285
+ }
286
+ ```
287
+
288
+ ### High-Volume Events and ReplayId
289
+
290
+ ```apex
291
+ trigger HighVolumeEventTrigger on Analytics_Event__e (after insert) {
292
+ // Set resume checkpoint for retry-after-failure
293
+ EventBus.TriggerContext.currentContext().setResumeCheckpoint(
294
+ Trigger.new[Trigger.new.size() - 1].ReplayId
295
+ );
296
+ }
297
+ ```
298
+
299
+ ---
300
+
301
+ ## Testing Async Apex
302
+
303
+ `Test.startTest()` / `Test.stopTest()` forces @future, Queueable, and Batch jobs to execute synchronously. Platform events are also delivered synchronously within the test boundary.
304
+
305
+ ```apex
306
+ @isTest
307
+ static void testBatchUpdatesReviewDate() {
308
+ // Insert test data
309
+ Test.startTest();
310
+ Database.executeBatch(new AccountAnnualReviewBatch(), 200);
311
+ Test.stopTest(); // All batch methods run synchronously
312
+ // Assert results
313
+ }
314
+ ```
315
+
316
+ ---
317
+
318
+ ## Related
319
+
320
+ - **Agents**: `sf-review-agent`, `sf-apex-agent` — For interactive guidance
321
+
322
+ ### Guardrails
323
+
324
+ - `sf-apex-constraints` — Governs limits, bulkification rules, and naming conventions for all Apex code including async