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.
- package/.claude-plugin/plugin.json +44 -0
- package/.cursor/agents/deep-researcher.md +142 -0
- package/.cursor/agents/doc-updater.md +219 -0
- package/.cursor/agents/eval-runner.md +335 -0
- package/.cursor/agents/learning-engine.md +210 -0
- package/.cursor/agents/loop-operator.md +245 -0
- package/.cursor/agents/refactor-cleaner.md +119 -0
- package/.cursor/agents/sf-admin-agent.md +127 -0
- package/.cursor/agents/sf-agentforce-agent.md +126 -0
- package/.cursor/agents/sf-apex-agent.md +117 -0
- package/.cursor/agents/sf-architect.md +426 -0
- package/.cursor/agents/sf-aura-reviewer.md +369 -0
- package/.cursor/agents/sf-bugfix-agent.md +101 -0
- package/.cursor/agents/sf-flow-agent.md +155 -0
- package/.cursor/agents/sf-integration-agent.md +141 -0
- package/.cursor/agents/sf-lwc-agent.md +123 -0
- package/.cursor/agents/sf-review-agent.md +357 -0
- package/.cursor/agents/sf-visualforce-reviewer.md +465 -0
- package/.cursor/hooks/adapter.js +81 -0
- package/.cursor/hooks/after-file-edit.js +26 -0
- package/.cursor/hooks/after-mcp-execution.js +12 -0
- package/.cursor/hooks/after-shell-execution.js +30 -0
- package/.cursor/hooks/after-tab-file-edit.js +12 -0
- package/.cursor/hooks/before-mcp-execution.js +11 -0
- package/.cursor/hooks/before-read-file.js +13 -0
- package/.cursor/hooks/before-shell-execution.js +29 -0
- package/.cursor/hooks/before-submit-prompt.js +23 -0
- package/.cursor/hooks/pre-compact.js +7 -0
- package/.cursor/hooks/session-end.js +10 -0
- package/.cursor/hooks/session-start.js +10 -0
- package/.cursor/hooks/stop.js +18 -0
- package/.cursor/hooks/subagent-start.js +10 -0
- package/.cursor/hooks/subagent-stop.js +10 -0
- package/.cursor/hooks.json +107 -0
- package/.cursor/skills/aside/SKILL.md +115 -0
- package/.cursor/skills/checkpoint/SKILL.md +50 -0
- package/.cursor/skills/configure-scc/SKILL.md +160 -0
- package/.cursor/skills/continuous-agent-loop/SKILL.md +260 -0
- package/.cursor/skills/mcp-server-patterns/SKILL.md +142 -0
- package/.cursor/skills/model-route/SKILL.md +81 -0
- package/.cursor/skills/prompt-optimizer/SKILL.md +366 -0
- package/.cursor/skills/refactor-clean/SKILL.md +133 -0
- package/.cursor/skills/resume-session/SKILL.md +111 -0
- package/.cursor/skills/save-session/SKILL.md +183 -0
- package/.cursor/skills/search-first/SKILL.md +140 -0
- package/.cursor/skills/security-scan/SKILL.md +142 -0
- package/.cursor/skills/sessions/SKILL.md +124 -0
- package/.cursor/skills/sf-agentforce-development/SKILL.md +449 -0
- package/.cursor/skills/sf-apex-async-patterns/SKILL.md +324 -0
- package/.cursor/skills/sf-apex-best-practices/SKILL.md +421 -0
- package/.cursor/skills/sf-apex-constraints/SKILL.md +79 -0
- package/.cursor/skills/sf-apex-cursor/SKILL.md +336 -0
- package/.cursor/skills/sf-apex-enterprise-patterns/SKILL.md +344 -0
- package/.cursor/skills/sf-apex-testing/SKILL.md +407 -0
- package/.cursor/skills/sf-api-design/SKILL.md +237 -0
- package/.cursor/skills/sf-approval-processes/SKILL.md +312 -0
- package/.cursor/skills/sf-aura-development/SKILL.md +260 -0
- package/.cursor/skills/sf-build-fix/SKILL.md +120 -0
- package/.cursor/skills/sf-data-modeling/SKILL.md +274 -0
- package/.cursor/skills/sf-debugging/SKILL.md +362 -0
- package/.cursor/skills/sf-deployment/SKILL.md +291 -0
- package/.cursor/skills/sf-deployment-constraints/SKILL.md +153 -0
- package/.cursor/skills/sf-devops-ci-cd/SKILL.md +322 -0
- package/.cursor/skills/sf-docs-lookup/SKILL.md +100 -0
- package/.cursor/skills/sf-e2e-testing/SKILL.md +321 -0
- package/.cursor/skills/sf-experience-cloud/SKILL.md +248 -0
- package/.cursor/skills/sf-flow-development/SKILL.md +376 -0
- package/.cursor/skills/sf-governor-limits/SKILL.md +319 -0
- package/.cursor/skills/sf-harness-audit/SKILL.md +139 -0
- package/.cursor/skills/sf-help/SKILL.md +156 -0
- package/.cursor/skills/sf-integration/SKILL.md +479 -0
- package/.cursor/skills/sf-lwc-constraints/SKILL.md +128 -0
- package/.cursor/skills/sf-lwc-development/SKILL.md +302 -0
- package/.cursor/skills/sf-lwc-testing/SKILL.md +387 -0
- package/.cursor/skills/sf-metadata-management/SKILL.md +285 -0
- package/.cursor/skills/sf-platform-events-cdc/SKILL.md +372 -0
- package/.cursor/skills/sf-quickstart/SKILL.md +170 -0
- package/.cursor/skills/sf-security/SKILL.md +330 -0
- package/.cursor/skills/sf-security-constraints/SKILL.md +125 -0
- package/.cursor/skills/sf-soql-constraints/SKILL.md +129 -0
- package/.cursor/skills/sf-soql-optimization/SKILL.md +353 -0
- package/.cursor/skills/sf-tdd-workflow/SKILL.md +332 -0
- package/.cursor/skills/sf-testing-constraints/SKILL.md +198 -0
- package/.cursor/skills/sf-trigger-constraints/SKILL.md +88 -0
- package/.cursor/skills/sf-trigger-frameworks/SKILL.md +343 -0
- package/.cursor/skills/sf-visualforce-development/SKILL.md +259 -0
- package/.cursor/skills/strategic-compact/SKILL.md +205 -0
- package/.cursor/skills/update-docs/SKILL.md +162 -0
- package/.cursor/skills/update-platform-docs/SKILL.md +86 -0
- package/.cursor-plugin/plugin.json +26 -0
- package/LICENSE +21 -0
- package/README.md +522 -0
- package/agents/deep-researcher.md +145 -0
- package/agents/doc-updater.md +222 -0
- package/agents/eval-runner.md +340 -0
- package/agents/learning-engine.md +211 -0
- package/agents/loop-operator.md +247 -0
- package/agents/refactor-cleaner.md +122 -0
- package/agents/sf-admin-agent.md +131 -0
- package/agents/sf-agentforce-agent.md +132 -0
- package/agents/sf-apex-agent.md +124 -0
- package/agents/sf-architect.md +435 -0
- package/agents/sf-aura-reviewer.md +372 -0
- package/agents/sf-bugfix-agent.md +105 -0
- package/agents/sf-flow-agent.md +159 -0
- package/agents/sf-integration-agent.md +146 -0
- package/agents/sf-lwc-agent.md +127 -0
- package/agents/sf-review-agent.md +366 -0
- package/agents/sf-visualforce-reviewer.md +468 -0
- package/assets/logo.svg +18 -0
- package/docs/ARCHITECTURE.md +133 -0
- package/docs/authoring-guide.md +373 -0
- package/docs/hook-development.md +578 -0
- package/docs/token-optimization.md +139 -0
- package/docs/workflow-examples.md +645 -0
- package/examples/agentforce-action/README.md +227 -0
- package/examples/apex-trigger-handler/README.md +114 -0
- package/examples/devops-pipeline/README.md +325 -0
- package/examples/flow-automation/README.md +188 -0
- package/examples/integration-pattern/README.md +416 -0
- package/examples/lwc-component/README.md +180 -0
- package/examples/platform-events/README.md +492 -0
- package/examples/scratch-org-setup/README.md +138 -0
- package/examples/security-audit/README.md +244 -0
- package/examples/visualforce-migration/README.md +314 -0
- package/hooks/hooks.json +338 -0
- package/hooks/memory-persistence/README.md +73 -0
- package/manifests/install-modules.json +217 -0
- package/manifests/install-profiles.json +17 -0
- package/mcp-configs/mcp-servers.json +19 -0
- package/package.json +89 -0
- package/schemas/hooks.schema.json +123 -0
- package/schemas/install-modules.schema.json +76 -0
- package/schemas/install-profiles.schema.json +28 -0
- package/schemas/install-state.schema.json +73 -0
- package/schemas/package-manager.schema.json +18 -0
- package/schemas/plugin.schema.json +112 -0
- package/schemas/scc-install-config.schema.json +29 -0
- package/schemas/state-store.schema.json +111 -0
- package/scripts/cli/install-apply.js +170 -0
- package/scripts/cli/uninstall.js +193 -0
- package/scripts/hooks/check-console-log.js +101 -0
- package/scripts/hooks/check-hook-enabled.js +17 -0
- package/scripts/hooks/check-platform-docs-age.js +48 -0
- package/scripts/hooks/cost-tracker.js +78 -0
- package/scripts/hooks/doc-file-warning.js +63 -0
- package/scripts/hooks/evaluate-session.js +98 -0
- package/scripts/hooks/governor-check.js +220 -0
- package/scripts/hooks/learning-observe.sh +206 -0
- package/scripts/hooks/mcp-health-check.js +588 -0
- package/scripts/hooks/post-bash-build-complete.js +34 -0
- package/scripts/hooks/post-bash-pr-created.js +43 -0
- package/scripts/hooks/post-edit-console-warn.js +61 -0
- package/scripts/hooks/post-edit-format.js +79 -0
- package/scripts/hooks/post-edit-typecheck.js +98 -0
- package/scripts/hooks/post-write.js +168 -0
- package/scripts/hooks/pre-bash-git-push-reminder.js +35 -0
- package/scripts/hooks/pre-bash-tmux-reminder.js +47 -0
- package/scripts/hooks/pre-compact.js +51 -0
- package/scripts/hooks/pre-tool-use.js +163 -0
- package/scripts/hooks/pre-write-doc-warn.js +9 -0
- package/scripts/hooks/quality-gate.js +251 -0
- package/scripts/hooks/run-with-flags-shell.sh +32 -0
- package/scripts/hooks/run-with-flags.js +135 -0
- package/scripts/hooks/session-end-marker.js +29 -0
- package/scripts/hooks/session-end.js +311 -0
- package/scripts/hooks/session-start.js +202 -0
- package/scripts/hooks/sfdx-scanner-check.js +142 -0
- package/scripts/hooks/sfdx-validate.js +119 -0
- package/scripts/hooks/stop-hook.js +170 -0
- package/scripts/hooks/suggest-compact.js +67 -0
- package/scripts/lib/agent-adapter.js +82 -0
- package/scripts/lib/apex-analysis.js +194 -0
- package/scripts/lib/hook-flags.js +74 -0
- package/scripts/lib/install-config.js +73 -0
- package/scripts/lib/install-executor.js +363 -0
- package/scripts/lib/install-state.js +121 -0
- package/scripts/lib/orchestration-session.js +299 -0
- package/scripts/lib/package-manager.js +124 -0
- package/scripts/lib/project-detect.js +228 -0
- package/scripts/lib/schema-validator.js +190 -0
- package/scripts/lib/skill-adapter.js +100 -0
- package/scripts/lib/state-store.js +376 -0
- package/scripts/lib/tmux-worktree-orchestrator.js +598 -0
- package/scripts/lib/utils.js +313 -0
- package/scripts/scc.js +164 -0
- package/skills/_reference/AGENTFORCE_PATTERNS.md +112 -0
- package/skills/_reference/APEX_CURSOR.md +159 -0
- package/skills/_reference/API_VERSIONS.md +78 -0
- package/skills/_reference/APPROVAL_PROCESSES.md +105 -0
- package/skills/_reference/ASYNC_PATTERNS.md +163 -0
- package/skills/_reference/AURA_COMPONENTS.md +146 -0
- package/skills/_reference/DATA_MIGRATION_PATTERNS.md +151 -0
- package/skills/_reference/DATA_MODELING.md +124 -0
- package/skills/_reference/DEBUGGING_TOOLS.md +140 -0
- package/skills/_reference/DEPLOYMENT_CHECKLIST.md +87 -0
- package/skills/_reference/DEPRECATIONS.md +79 -0
- package/skills/_reference/DOCKER_CI_PATTERNS.md +138 -0
- package/skills/_reference/ENTERPRISE_PATTERNS.md +122 -0
- package/skills/_reference/EXPERIENCE_CLOUD.md +143 -0
- package/skills/_reference/FLOW_PATTERNS.md +113 -0
- package/skills/_reference/GOVERNOR_LIMITS.md +77 -0
- package/skills/_reference/INTEGRATION_PATTERNS.md +105 -0
- package/skills/_reference/LWC_PATTERNS.md +79 -0
- package/skills/_reference/METADATA_TYPES.md +115 -0
- package/skills/_reference/NAMING_CONVENTIONS.md +84 -0
- package/skills/_reference/PACKAGE_DEVELOPMENT.md +150 -0
- package/skills/_reference/PLATFORM_EVENTS.md +121 -0
- package/skills/_reference/REPORTING_API.md +143 -0
- package/skills/_reference/SCRATCH_ORG_PATTERNS.md +126 -0
- package/skills/_reference/SECURITY_PATTERNS.md +127 -0
- package/skills/_reference/SHARING_MODEL.md +120 -0
- package/skills/_reference/SOQL_PATTERNS.md +119 -0
- package/skills/_reference/TESTING_STANDARDS.md +96 -0
- package/skills/_reference/TRIGGER_PATTERNS.md +114 -0
- package/skills/_reference/VISUALFORCE_PATTERNS.md +121 -0
- package/skills/aside/SKILL.md +118 -0
- package/skills/checkpoint/SKILL.md +53 -0
- package/skills/configure-scc/SKILL.md +163 -0
- package/skills/continuous-agent-loop/SKILL.md +264 -0
- package/skills/mcp-server-patterns/SKILL.md +146 -0
- package/skills/model-route/SKILL.md +84 -0
- package/skills/prompt-optimizer/SKILL.md +369 -0
- package/skills/refactor-clean/SKILL.md +136 -0
- package/skills/resume-session/SKILL.md +114 -0
- package/skills/save-session/SKILL.md +186 -0
- package/skills/search-first/SKILL.md +144 -0
- package/skills/security-scan/SKILL.md +146 -0
- package/skills/sessions/SKILL.md +127 -0
- package/skills/sf-agentforce-development/SKILL.md +450 -0
- package/skills/sf-apex-async-patterns/SKILL.md +326 -0
- package/skills/sf-apex-best-practices/SKILL.md +425 -0
- package/skills/sf-apex-constraints/SKILL.md +81 -0
- package/skills/sf-apex-cursor/SKILL.md +338 -0
- package/skills/sf-apex-enterprise-patterns/SKILL.md +348 -0
- package/skills/sf-apex-testing/SKILL.md +409 -0
- package/skills/sf-api-design/SKILL.md +238 -0
- package/skills/sf-approval-processes/SKILL.md +315 -0
- package/skills/sf-aura-development/SKILL.md +263 -0
- package/skills/sf-build-fix/SKILL.md +121 -0
- package/skills/sf-data-modeling/SKILL.md +278 -0
- package/skills/sf-debugging/SKILL.md +363 -0
- package/skills/sf-deployment/SKILL.md +295 -0
- package/skills/sf-deployment-constraints/SKILL.md +155 -0
- package/skills/sf-devops-ci-cd/SKILL.md +325 -0
- package/skills/sf-docs-lookup/SKILL.md +103 -0
- package/skills/sf-e2e-testing/SKILL.md +324 -0
- package/skills/sf-experience-cloud/SKILL.md +249 -0
- package/skills/sf-flow-development/SKILL.md +377 -0
- package/skills/sf-governor-limits/SKILL.md +323 -0
- package/skills/sf-harness-audit/SKILL.md +142 -0
- package/skills/sf-help/SKILL.md +159 -0
- package/skills/sf-integration/SKILL.md +483 -0
- package/skills/sf-lwc-constraints/SKILL.md +130 -0
- package/skills/sf-lwc-development/SKILL.md +303 -0
- package/skills/sf-lwc-testing/SKILL.md +388 -0
- package/skills/sf-metadata-management/SKILL.md +288 -0
- package/skills/sf-platform-events-cdc/SKILL.md +375 -0
- package/skills/sf-quickstart/SKILL.md +173 -0
- package/skills/sf-security/SKILL.md +334 -0
- package/skills/sf-security-constraints/SKILL.md +127 -0
- package/skills/sf-soql-constraints/SKILL.md +131 -0
- package/skills/sf-soql-optimization/SKILL.md +354 -0
- package/skills/sf-tdd-workflow/SKILL.md +336 -0
- package/skills/sf-testing-constraints/SKILL.md +200 -0
- package/skills/sf-trigger-constraints/SKILL.md +90 -0
- package/skills/sf-trigger-frameworks/SKILL.md +347 -0
- package/skills/sf-visualforce-development/SKILL.md +260 -0
- package/skills/strategic-compact/SKILL.md +208 -0
- package/skills/update-docs/SKILL.md +165 -0
- package/skills/update-platform-docs/SKILL.md +90 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sf-metadata-management
|
|
3
|
+
description: >-
|
|
4
|
+
Use when working with Salesforce metadata types, package.xml, or .forceignore.
|
|
5
|
+
Source vs metadata format, retrieval, deployment, and org comparison.
|
|
6
|
+
origin: SCC
|
|
7
|
+
user-invocable: false
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Salesforce Metadata Management
|
|
11
|
+
|
|
12
|
+
Reference: @../_reference/METADATA_TYPES.md
|
|
13
|
+
|
|
14
|
+
## When to Use
|
|
15
|
+
|
|
16
|
+
- Retrieving or deploying specific metadata types between Salesforce orgs
|
|
17
|
+
- Understanding the difference between source format (DX) and metadata API format
|
|
18
|
+
- Configuring `.forceignore` to control which files are tracked by SF CLI
|
|
19
|
+
- Managing profiles vs permission sets in source control and CI/CD workflows
|
|
20
|
+
- Comparing metadata between two orgs or handling org conflicts
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Source Format (DX) vs Metadata Format
|
|
25
|
+
|
|
26
|
+
### Source Format (Salesforce DX -- what you have locally)
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
force-app/
|
|
30
|
+
main/
|
|
31
|
+
default/
|
|
32
|
+
classes/
|
|
33
|
+
AccountService.cls
|
|
34
|
+
AccountService.cls-meta.xml
|
|
35
|
+
triggers/
|
|
36
|
+
AccountTrigger.trigger
|
|
37
|
+
AccountTrigger.trigger-meta.xml
|
|
38
|
+
lwc/
|
|
39
|
+
accountCard/
|
|
40
|
+
accountCard.js
|
|
41
|
+
accountCard.html
|
|
42
|
+
accountCard.css
|
|
43
|
+
accountCard.js-meta.xml
|
|
44
|
+
objects/
|
|
45
|
+
Account/
|
|
46
|
+
fields/
|
|
47
|
+
Status__c.field-meta.xml
|
|
48
|
+
recordTypes/
|
|
49
|
+
Enterprise.recordType-meta.xml
|
|
50
|
+
validationRules/
|
|
51
|
+
RequirePhone.validationRule-meta.xml
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Metadata Format (Metadata API / Change Sets)
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
unpackaged/
|
|
58
|
+
classes/
|
|
59
|
+
AccountService.cls
|
|
60
|
+
AccountService.cls-meta.xml
|
|
61
|
+
objects/
|
|
62
|
+
Account.object <-- single file with ALL fields, validation rules, etc.
|
|
63
|
+
package.xml
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Key difference: in source format, each component has its own file. In metadata format, objects are a single monolithic XML file.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Convert metadata format to source format
|
|
70
|
+
sf project convert mdapi --root-dir unpackaged --output-dir force-app
|
|
71
|
+
|
|
72
|
+
# Convert source format to metadata format
|
|
73
|
+
sf project convert source --source-dir force-app --output-dir unpackaged
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## sfdx-project.json Explained
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"packageDirectories": [
|
|
83
|
+
{
|
|
84
|
+
"path": "force-app",
|
|
85
|
+
"default": true,
|
|
86
|
+
"package": "MyApp",
|
|
87
|
+
"versionName": "ver 1.0",
|
|
88
|
+
"versionNumber": "1.0.0.NEXT",
|
|
89
|
+
"definitionFile": "config/project-scratch-def.json"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"path": "force-app-config",
|
|
93
|
+
"default": false
|
|
94
|
+
}
|
|
95
|
+
],
|
|
96
|
+
"namespace": "",
|
|
97
|
+
"sourceApiVersion": "66.0",
|
|
98
|
+
"sfdcLoginUrl": "https://login.salesforce.com",
|
|
99
|
+
"pushPackageDirectoriesSequentially": false,
|
|
100
|
+
"packageAliases": {
|
|
101
|
+
"MyApp": "0Ho...",
|
|
102
|
+
"MyApp@1.0.0-1": "04t..."
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
| Property | Purpose |
|
|
108
|
+
|-----------------------------|-------------------------------------------------------|
|
|
109
|
+
| `packageDirectories` | Directories containing Salesforce source |
|
|
110
|
+
| `path` | Relative path to source directory |
|
|
111
|
+
| `default` | Whether this is the default deploy target |
|
|
112
|
+
| `namespace` | Org namespace (empty string for most orgs) |
|
|
113
|
+
| `sourceApiVersion` | Metadata API version (update annually) |
|
|
114
|
+
| `pushPackageDirectoriesSequentially` | Deploy directories in order (for dependencies) |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## .forceignore
|
|
119
|
+
|
|
120
|
+
Controls which files SF CLI ignores during push/pull/deploy operations. Syntax mirrors .gitignore.
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
# .forceignore
|
|
124
|
+
|
|
125
|
+
# Profiles -- use Permission Sets instead
|
|
126
|
+
**/profiles/**
|
|
127
|
+
|
|
128
|
+
# Standard Value Sets (cannot deploy, org-managed)
|
|
129
|
+
**/standardValueSets/**
|
|
130
|
+
|
|
131
|
+
# Managed Package components -- read-only
|
|
132
|
+
**/force-app/main/default/classes/fflib_*
|
|
133
|
+
**/force-app/main/default/classes/NPSP_*
|
|
134
|
+
|
|
135
|
+
# Experience Cloud templates (large, rarely need deploying)
|
|
136
|
+
**/experiences/**
|
|
137
|
+
|
|
138
|
+
# Reports and Dashboards (manage via UI)
|
|
139
|
+
**/reports/**
|
|
140
|
+
**/dashboards/**
|
|
141
|
+
|
|
142
|
+
# Translations (if not managing)
|
|
143
|
+
**/translations/**
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Retrieving Metadata
|
|
149
|
+
|
|
150
|
+
### Retrieve by Metadata Type
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Retrieve all Apex classes
|
|
154
|
+
sf project retrieve start \
|
|
155
|
+
--metadata ApexClass \
|
|
156
|
+
--target-org myOrg \
|
|
157
|
+
--output-dir force-app
|
|
158
|
+
|
|
159
|
+
# Retrieve specific component
|
|
160
|
+
sf project retrieve start \
|
|
161
|
+
--metadata "ApexClass:AccountService" \
|
|
162
|
+
--target-org myOrg
|
|
163
|
+
|
|
164
|
+
# Retrieve multiple types
|
|
165
|
+
sf project retrieve start \
|
|
166
|
+
--metadata "ApexClass,ApexTrigger,LightningComponentBundle,CustomObject" \
|
|
167
|
+
--target-org myOrg
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Retrieve via package.xml
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
sf project retrieve start \
|
|
174
|
+
--manifest manifest/package.xml \
|
|
175
|
+
--target-org myOrg \
|
|
176
|
+
--output-dir force-app
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Retrieve with Source Tracking (scratch orgs)
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Only retrieves what changed in org since last sync
|
|
183
|
+
sf project retrieve start \
|
|
184
|
+
--source-dir force-app \
|
|
185
|
+
--target-org myScratch
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Org Comparison Strategies
|
|
191
|
+
|
|
192
|
+
### List Available Metadata
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
sf org list metadata-types --target-org myOrg
|
|
196
|
+
sf org list metadata --metadata-type ApexClass --target-org myOrg
|
|
197
|
+
sf org list metadata --metadata-type Flow --target-org myOrg
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Compare Two Orgs
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
# Retrieve from source and target orgs
|
|
204
|
+
sf project retrieve start --manifest manifest/package.xml --target-org sourceOrg --output-dir /tmp/source-org
|
|
205
|
+
sf project retrieve start --manifest manifest/package.xml --target-org targetOrg --output-dir /tmp/target-org
|
|
206
|
+
|
|
207
|
+
# Diff using standard tools
|
|
208
|
+
diff -r /tmp/source-org /tmp/target-org
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Managing Profiles vs Permission Sets
|
|
214
|
+
|
|
215
|
+
> Deploying a Profile from source replaces the entire profile definition in the target org. Any permissions that exist in the org but are not in your source file will be revoked. Use Permission Sets instead of Profiles for deployable permission management.
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Add profile to .forceignore to stop tracking
|
|
219
|
+
echo "**/profiles/**" >> .forceignore
|
|
220
|
+
|
|
221
|
+
# Deploy permission sets instead
|
|
222
|
+
sf project deploy start \
|
|
223
|
+
--metadata "PermissionSet:Sales_Manager_Permissions" \
|
|
224
|
+
--target-org myOrg
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
When profiles cannot be avoided:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Retrieve ONLY the profile
|
|
231
|
+
sf project retrieve start \
|
|
232
|
+
--metadata "Profile:Admin" \
|
|
233
|
+
--target-org myOrg
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Handling Org Conflicts
|
|
239
|
+
|
|
240
|
+
> `--ignore-conflicts` silently overwrites without prompting. Run `deploy preview` first to review what will be overwritten. Using `--ignore-conflicts` on a shared org can destroy another developer's uncommitted work.
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Preview conflicts before deploying
|
|
244
|
+
sf project deploy preview --source-dir force-app --target-org myScratch
|
|
245
|
+
|
|
246
|
+
# Force deploy (local wins)
|
|
247
|
+
sf project deploy start \
|
|
248
|
+
--source-dir force-app \
|
|
249
|
+
--ignore-conflicts \
|
|
250
|
+
--target-org myScratch
|
|
251
|
+
|
|
252
|
+
# Force retrieve (org wins)
|
|
253
|
+
sf project retrieve start \
|
|
254
|
+
--source-dir force-app \
|
|
255
|
+
--ignore-conflicts \
|
|
256
|
+
--target-org myScratch
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Custom Metadata Type Records
|
|
262
|
+
|
|
263
|
+
Custom Metadata Type records are metadata -- deploy them, not import them.
|
|
264
|
+
|
|
265
|
+
```xml
|
|
266
|
+
<!-- force-app/main/default/customMetadata/Service_Config.Production.md-meta.xml -->
|
|
267
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
268
|
+
<CustomMetadata xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
269
|
+
<label>Production Config</label>
|
|
270
|
+
<protected>false</protected>
|
|
271
|
+
<values>
|
|
272
|
+
<field>Endpoint_URL__c</field>
|
|
273
|
+
<value xsi:type="xsd:string">https://api.example.com</value>
|
|
274
|
+
</values>
|
|
275
|
+
<values>
|
|
276
|
+
<field>Timeout_Ms__c</field>
|
|
277
|
+
<value xsi:type="xsd:double">10000</value>
|
|
278
|
+
</values>
|
|
279
|
+
</CustomMetadata>
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Benefits over Custom Settings: deployable, available in flows and formula fields, no governor limit on reads, can be packaged.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Related
|
|
287
|
+
|
|
288
|
+
- **Constraints**: `sf-deployment-constraints` -- deployment safety rules
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sf-platform-events-cdc
|
|
3
|
+
description: >-
|
|
4
|
+
Salesforce Platform Events and CDC — Apex publish/subscribe, event replay,
|
|
5
|
+
testing patterns. Use when designing event-driven integrations or data sync.
|
|
6
|
+
origin: SCC
|
|
7
|
+
user-invocable: false
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Platform Events & Change Data Capture
|
|
11
|
+
|
|
12
|
+
Procedures for building event-driven integrations using Platform Events and CDC. Allocation limits, retention windows, publish behavior details, and testing API specifics live in the reference file.
|
|
13
|
+
|
|
14
|
+
@../_reference/PLATFORM_EVENTS.md
|
|
15
|
+
|
|
16
|
+
## When to Use
|
|
17
|
+
|
|
18
|
+
- Designing event-driven architecture within Salesforce or with external systems
|
|
19
|
+
- Implementing real-time data synchronization using Change Data Capture
|
|
20
|
+
- Building decoupled integrations with retry and replay capabilities
|
|
21
|
+
- Replacing polling-based integrations with push-based event notifications
|
|
22
|
+
- Implementing audit trails or data replication to external data stores
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Publishing Platform Events
|
|
27
|
+
|
|
28
|
+
### From Apex
|
|
29
|
+
|
|
30
|
+
```apex
|
|
31
|
+
public class OrderEventPublisher {
|
|
32
|
+
public static void publishOrderCompleted(List<Order> orders) {
|
|
33
|
+
List<Order_Completed__e> events = new List<Order_Completed__e>();
|
|
34
|
+
|
|
35
|
+
for (Order ord : orders) {
|
|
36
|
+
events.add(new Order_Completed__e(
|
|
37
|
+
Order_Id__c = ord.Id,
|
|
38
|
+
Total_Amount__c = ord.TotalAmount,
|
|
39
|
+
Customer_Id__c = ord.AccountId,
|
|
40
|
+
Fulfillment_Status__c = 'Pending'
|
|
41
|
+
));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
List<Database.SaveResult> results = EventBus.publish(events);
|
|
45
|
+
|
|
46
|
+
for (Integer i = 0; i < results.size(); i++) {
|
|
47
|
+
if (!results[i].isSuccess()) {
|
|
48
|
+
for (Database.Error err : results[i].getErrors()) {
|
|
49
|
+
System.debug(LoggingLevel.ERROR,
|
|
50
|
+
'Event publish failed: ' + err.getStatusCode() +
|
|
51
|
+
' - ' + err.getMessage());
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Publish After Commit vs Publish Immediately
|
|
60
|
+
|
|
61
|
+
- **Publish After Commit** (default): Events are lost if the transaction rolls back. Use for business events.
|
|
62
|
+
- **Publish Immediately** (set in event definition in Setup): Events publish even if the transaction fails. Use for audit/error logging. Configured at the event level, not via code parameters.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Subscribing to Platform Events
|
|
67
|
+
|
|
68
|
+
### Apex Trigger Subscriber
|
|
69
|
+
|
|
70
|
+
```apex
|
|
71
|
+
trigger OrderCompletedTrigger on Order_Completed__e (after insert) {
|
|
72
|
+
List<Task> followUpTasks = new List<Task>();
|
|
73
|
+
|
|
74
|
+
for (Order_Completed__e event : Trigger.new) {
|
|
75
|
+
followUpTasks.add(new Task(
|
|
76
|
+
Subject = 'Follow up on Order ' + event.Order_Id__c,
|
|
77
|
+
Description = 'Amount: ' + event.Total_Amount__c,
|
|
78
|
+
WhatId = Id.valueOf(event.Order_Id__c),
|
|
79
|
+
Status = 'Not Started',
|
|
80
|
+
Priority = event.Total_Amount__c > 100000 ? 'High' : 'Normal'
|
|
81
|
+
));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!followUpTasks.isEmpty()) {
|
|
85
|
+
insert followUpTasks;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Trigger subscriber behavior:**
|
|
91
|
+
|
|
92
|
+
- Runs in its own transaction (separate from publisher)
|
|
93
|
+
- High-volume events: automatic retry up to 9 times over 24 hours
|
|
94
|
+
- Standard volume events: no automatic retries
|
|
95
|
+
- Batch size: up to 2,000 per batch for high-volume events
|
|
96
|
+
|
|
97
|
+
### Retry and Checkpoint Pattern
|
|
98
|
+
|
|
99
|
+
```apex
|
|
100
|
+
trigger OrderCompletedTrigger on Order_Completed__e (after insert) {
|
|
101
|
+
if (EventBus.TriggerContext.currentContext().retries > 9) {
|
|
102
|
+
List<Error_Log__c> errorLogs = new List<Error_Log__c>();
|
|
103
|
+
for (Order_Completed__e event : Trigger.new) {
|
|
104
|
+
errorLogs.add(new Error_Log__c(
|
|
105
|
+
Source__c = 'OrderCompletedTrigger',
|
|
106
|
+
Message__c = 'Max retries for order: ' + event.Order_Id__c
|
|
107
|
+
));
|
|
108
|
+
}
|
|
109
|
+
insert errorLogs;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
// Process events with checkpointing to avoid poison-pill blocking.
|
|
115
|
+
// processOrder() MUST be idempotent — on retry, it runs again for
|
|
116
|
+
// events between last checkpoint and failure point.
|
|
117
|
+
for (Order_Completed__e event : Trigger.new) {
|
|
118
|
+
processOrder(event);
|
|
119
|
+
EventBus.TriggerContext.currentContext()
|
|
120
|
+
.setResumeCheckpoint(event.ReplayId);
|
|
121
|
+
}
|
|
122
|
+
} catch (Exception e) {
|
|
123
|
+
throw new EventBus.RetryableException(
|
|
124
|
+
'Transient failure: ' + e.getMessage());
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Flow Subscriber
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
Flow Type: Platform Event-Triggered Flow
|
|
133
|
+
Object: Order_Completed__e
|
|
134
|
+
Trigger: When a platform event message is received
|
|
135
|
+
|
|
136
|
+
Elements:
|
|
137
|
+
1. Get Records: Find matching Order by Order_Id__c
|
|
138
|
+
2. Decision: Check if order needs fulfillment
|
|
139
|
+
3. Update Records: Set Order.Status to 'Processing'
|
|
140
|
+
4. Create Records: Create Shipment__c record
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### External Subscribers
|
|
144
|
+
|
|
145
|
+
| Protocol | Use Case |
|
|
146
|
+
|----------|----------|
|
|
147
|
+
| CometD (Streaming API) | Legacy, browser-based (long polling) |
|
|
148
|
+
| Pub/Sub API (gRPC) | Modern, server-to-server (higher throughput) |
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Replay Mechanism
|
|
153
|
+
|
|
154
|
+
Every published event receives a **ReplayId** -- a monotonically increasing sequence number.
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
Replay Options:
|
|
158
|
+
-1 -> Tip of stream (new events only)
|
|
159
|
+
-2 -> Earliest available (all retained events)
|
|
160
|
+
<specific-id> -> From that ReplayId forward
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Managing ReplayId in Apex
|
|
164
|
+
|
|
165
|
+
```apex
|
|
166
|
+
public class EventReplayManager {
|
|
167
|
+
public static void updateReplayId(String eventType, String replayId) {
|
|
168
|
+
Event_Replay_Checkpoint__c checkpoint =
|
|
169
|
+
Event_Replay_Checkpoint__c.getInstance(eventType);
|
|
170
|
+
if (checkpoint == null) {
|
|
171
|
+
checkpoint = new Event_Replay_Checkpoint__c(
|
|
172
|
+
Name = eventType,
|
|
173
|
+
Last_Replay_Id__c = replayId
|
|
174
|
+
);
|
|
175
|
+
} else {
|
|
176
|
+
checkpoint.Last_Replay_Id__c = replayId;
|
|
177
|
+
}
|
|
178
|
+
upsert checkpoint;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Concurrency note: Multiple subscribers may read the same checkpoint and reprocess overlapping events. Use ReplayId for deduplication.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Change Data Capture (CDC)
|
|
188
|
+
|
|
189
|
+
CDC automatically publishes change events when records are created, updated, deleted, or undeleted.
|
|
190
|
+
|
|
191
|
+
### Enabling CDC
|
|
192
|
+
|
|
193
|
+
Enable per object in Setup > Change Data Capture.
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
Channel format:
|
|
197
|
+
Standard objects: /data/AccountChangeEvent
|
|
198
|
+
Custom objects: /data/MyObject__ChangeEvent
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Handling CDC in Apex
|
|
202
|
+
|
|
203
|
+
```apex
|
|
204
|
+
trigger AccountChangeEventTrigger on AccountChangeEvent (after insert) {
|
|
205
|
+
for (AccountChangeEvent event : Trigger.new) {
|
|
206
|
+
EventBus.ChangeEventHeader header = event.ChangeEventHeader;
|
|
207
|
+
|
|
208
|
+
if (header.changedFields.contains('BillingCity')) {
|
|
209
|
+
System.debug('BillingCity changed to: ' + event.BillingCity);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
switch on header.changeType {
|
|
213
|
+
when 'CREATE' { handleCreate(event); }
|
|
214
|
+
when 'UPDATE' { handleUpdate(event, header.changedFields); }
|
|
215
|
+
when 'DELETE' { handleDelete(header.recordIds); }
|
|
216
|
+
when 'UNDELETE' { handleUndelete(header.recordIds); }
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Gap and Overflow Events
|
|
223
|
+
|
|
224
|
+
Gap events indicate missed events -- trigger a full sync.
|
|
225
|
+
|
|
226
|
+
```apex
|
|
227
|
+
if (header.changeType == 'GAP_CREATE' || header.changeType == 'GAP_UPDATE'
|
|
228
|
+
|| header.changeType == 'GAP_DELETE' || header.changeType == 'GAP_UNDELETE'
|
|
229
|
+
|| header.changeType == 'GAP_OVERFLOW') {
|
|
230
|
+
initiateFullSync(header.entityName);
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Overflow events occur when a single transaction modifies >100,000 records.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Event-Driven Architecture Patterns
|
|
239
|
+
|
|
240
|
+
### Decoupled Integration
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
Salesforce (Publisher) ---> Platform Event ---> External System (Subscriber)
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Publisher does not know or care who subscribes. New subscribers added without modifying publisher code.
|
|
247
|
+
|
|
248
|
+
### Saga Pattern (Multi-Step Transaction)
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
Order Created -> PE: Order_Created__e
|
|
252
|
+
Inventory Reserved -> PE: Inventory_Reserved__e
|
|
253
|
+
Payment Processed -> PE: Payment_Processed__e
|
|
254
|
+
Order Fulfilled -> PE: Order_Fulfilled__e
|
|
255
|
+
If any step fails -> PE: Order_Compensation__e (rollback)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Each step is an independent transaction. Compensation events handle rollback.
|
|
259
|
+
|
|
260
|
+
### CDC for Real-Time Sync
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
Salesforce -> CDC Events -> Data Lake / Warehouse
|
|
264
|
+
(AccountChangeEvent, ContactChangeEvent, etc.)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Testing Platform Events
|
|
270
|
+
|
|
271
|
+
### Testing Event Publishing
|
|
272
|
+
|
|
273
|
+
```apex
|
|
274
|
+
@isTest
|
|
275
|
+
static void testOrderEventPublishing() {
|
|
276
|
+
Order testOrder = new Order(
|
|
277
|
+
AccountId = testAccountId,
|
|
278
|
+
TotalAmount = 50000,
|
|
279
|
+
Status = 'Draft'
|
|
280
|
+
);
|
|
281
|
+
insert testOrder;
|
|
282
|
+
|
|
283
|
+
Test.startTest();
|
|
284
|
+
OrderEventPublisher.publishOrderCompleted(new List<Order>{ testOrder });
|
|
285
|
+
Test.stopTest();
|
|
286
|
+
|
|
287
|
+
// Verify via SaveResult
|
|
288
|
+
List<Order_Completed__e> events = new List<Order_Completed__e>();
|
|
289
|
+
events.add(new Order_Completed__e(
|
|
290
|
+
Order_Id__c = testOrder.Id,
|
|
291
|
+
Total_Amount__c = testOrder.TotalAmount
|
|
292
|
+
));
|
|
293
|
+
List<Database.SaveResult> results = EventBus.publish(events);
|
|
294
|
+
Test.getEventBus().deliver();
|
|
295
|
+
|
|
296
|
+
Assert.isTrue(results[0].isSuccess());
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Testing Event Subscribers
|
|
301
|
+
|
|
302
|
+
```apex
|
|
303
|
+
@isTest
|
|
304
|
+
static void testOrderCompletedSubscriber() {
|
|
305
|
+
Account testAccount = new Account(Name = 'Test Account');
|
|
306
|
+
insert testAccount;
|
|
307
|
+
|
|
308
|
+
Order_Completed__e event = new Order_Completed__e(
|
|
309
|
+
Order_Id__c = 'ORD-001',
|
|
310
|
+
Total_Amount__c = 75000,
|
|
311
|
+
Customer_Id__c = testAccount.Id,
|
|
312
|
+
Fulfillment_Status__c = 'Pending'
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
Test.startTest();
|
|
316
|
+
EventBus.publish(event);
|
|
317
|
+
Test.getEventBus().deliver();
|
|
318
|
+
Test.stopTest();
|
|
319
|
+
|
|
320
|
+
List<Task> tasks = [SELECT Id, Priority FROM Task
|
|
321
|
+
WHERE Subject LIKE '%ORD-001%'];
|
|
322
|
+
System.assertEquals(1, tasks.size());
|
|
323
|
+
System.assertEquals('Normal', tasks[0].Priority);
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Testing CDC Triggers
|
|
328
|
+
|
|
329
|
+
```apex
|
|
330
|
+
@isTest
|
|
331
|
+
static void testAccountChangeEventTrigger() {
|
|
332
|
+
Account acc = new Account(Name = 'Original Name');
|
|
333
|
+
insert acc;
|
|
334
|
+
|
|
335
|
+
Test.startTest();
|
|
336
|
+
acc.Name = 'Updated Name';
|
|
337
|
+
acc.BillingCity = 'San Francisco';
|
|
338
|
+
update acc;
|
|
339
|
+
Test.getEventBus().deliver();
|
|
340
|
+
Test.stopTest();
|
|
341
|
+
|
|
342
|
+
// Assert on whatever side-effects your trigger produces
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Monitoring and Troubleshooting
|
|
349
|
+
|
|
350
|
+
### EventBusSubscriber Query
|
|
351
|
+
|
|
352
|
+
```apex
|
|
353
|
+
List<EventBusSubscriber> subscribers = [
|
|
354
|
+
SELECT Name, Position, Retries, LastError, Status, Topic
|
|
355
|
+
FROM EventBusSubscriber
|
|
356
|
+
WHERE Topic = '/event/Order_Completed__e'
|
|
357
|
+
];
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Common Issues
|
|
361
|
+
|
|
362
|
+
| Symptom | Cause | Fix |
|
|
363
|
+
|---------|-------|-----|
|
|
364
|
+
| Events not received | Subscriber suspended after max retries | Check EventBusSubscriber.Status, resume |
|
|
365
|
+
| Events out of order | Parallel processing | Use sequenceNumber to reorder |
|
|
366
|
+
| Missing events | Retention period exceeded | Implement checkpoint, reduce lag |
|
|
367
|
+
| Gap events received | System overload | Implement full-sync fallback |
|
|
368
|
+
| LIMIT_EXCEEDED on publish | Exceeded daily allocation | Batch publishes, check edition limits |
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Related
|
|
373
|
+
|
|
374
|
+
- Constraints: sf-apex-constraints
|
|
375
|
+
- Reference: @../_reference/PLATFORM_EVENTS.md, @../_reference/INTEGRATION_PATTERNS.md
|