@salesforce/afv-skills 1.8.0 → 1.9.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/package.json +1 -1
- package/skills/activating-datacloud/CREDITS.md +5 -0
- package/skills/activating-datacloud/README.md +39 -0
- package/skills/activating-datacloud/SKILL.md +118 -0
- package/skills/analyzing-omnistudio-dependencies/CREDITS.md +5 -0
- package/skills/analyzing-omnistudio-dependencies/SKILL.md +477 -0
- package/skills/analyzing-omnistudio-dependencies/references/dependency-patterns.md +508 -0
- package/skills/analyzing-omnistudio-dependencies/references/namespace-guide.md +300 -0
- package/skills/building-omnistudio-callable-apex/CREDITS.md +9 -0
- package/skills/building-omnistudio-callable-apex/README.md +80 -0
- package/skills/building-omnistudio-callable-apex/SKILL.md +276 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_callable_openinterface.cls +40 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_callable_vanilla.cls +32 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_migration.cls +54 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_openinterface.cls +45 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_test_class.cls +65 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/IndustriesCallableException.cls +7 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/Industries_QuoteByProductCallable.cls +115 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/Industries_QuoteByProductCallableTest.cls +189 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/TRANSCRIPT.md +115 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/IndustriesCallableException.cls +7 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/MyCustomCallable.cls +74 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/MyCustomCallableTest.cls +146 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/MyCustomRemoteClass.cls +16 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/TRANSCRIPT.md +120 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/IndustriesCallableException.cls +7 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/MyCustomCallable.cls +73 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/MyCustomCallableTest.cls +128 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/MyCustomVlocityOpenInterface2.cls +23 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/TRANSCRIPT.md +75 -0
- package/skills/building-omnistudio-datamapper/CREDITS.md +5 -0
- package/skills/building-omnistudio-datamapper/SKILL.md +270 -0
- package/skills/building-omnistudio-datamapper/assets/completion-summary-template.md +28 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-extract.json +6 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-item.json +12 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-load.json +6 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-transform.json +6 -0
- package/skills/building-omnistudio-datamapper/references/best-practices.md +277 -0
- package/skills/building-omnistudio-datamapper/references/naming-conventions.md +145 -0
- package/skills/building-omnistudio-flexcard/CREDITS.md +5 -0
- package/skills/building-omnistudio-flexcard/SKILL.md +325 -0
- package/skills/building-omnistudio-flexcard/assets/omni-ui-card.json +10 -0
- package/skills/building-omnistudio-flexcard/references/best-practices.md +291 -0
- package/skills/building-omnistudio-flexcard/references/data-binding-guide.md +311 -0
- package/skills/building-omnistudio-flexcard/references/scoring-rubric.md +66 -0
- package/skills/building-omnistudio-flexcard/scripts/flexcard-commands.sh +24 -0
- package/skills/building-omnistudio-integration-procedure/CREDITS.md +5 -0
- package/skills/building-omnistudio-integration-procedure/SKILL.md +275 -0
- package/skills/building-omnistudio-integration-procedure/assets/omni-process-element-dr-extract.json +10 -0
- package/skills/building-omnistudio-integration-procedure/assets/omni-process-element-set-values.json +10 -0
- package/skills/building-omnistudio-integration-procedure/assets/omni-process-ip.json +12 -0
- package/skills/building-omnistudio-integration-procedure/assets/scoring-report-format.txt +14 -0
- package/skills/building-omnistudio-integration-procedure/references/best-practices.md +388 -0
- package/skills/building-omnistudio-integration-procedure/references/element-types.md +588 -0
- package/skills/building-omnistudio-integration-procedure/scripts/cli-commands.sh +18 -0
- package/skills/building-omnistudio-omniscript/CREDITS.md +5 -0
- package/skills/building-omnistudio-omniscript/SKILL.md +367 -0
- package/skills/building-omnistudio-omniscript/assets/omni-process-element-step.json +10 -0
- package/skills/building-omnistudio-omniscript/assets/omni-process-element-text-block.json +11 -0
- package/skills/building-omnistudio-omniscript/assets/omni-process-omniscript.json +12 -0
- package/skills/building-omnistudio-omniscript/references/best-practices.md +480 -0
- package/skills/building-omnistudio-omniscript/references/element-types.md +1172 -0
- package/skills/building-omnistudio-omniscript/scripts/check-duplicate-omniscript.sh +13 -0
- package/skills/building-omnistudio-omniscript/scripts/cli-reference.sh +21 -0
- package/skills/building-omnistudio-omniscript/scripts/deploy-omniscript.sh +29 -0
- package/skills/building-sf-integrations/CREDITS.md +5 -0
- package/skills/building-sf-integrations/README.md +95 -0
- package/skills/building-sf-integrations/SKILL.md +192 -0
- package/skills/building-sf-integrations/assets/callouts/callout-retry-handler.cls +167 -0
- package/skills/building-sf-integrations/assets/callouts/http-response-handler.cls +257 -0
- package/skills/building-sf-integrations/assets/callouts/rest-queueable-callout.cls +262 -0
- package/skills/building-sf-integrations/assets/callouts/rest-sync-callout.cls +211 -0
- package/skills/building-sf-integrations/assets/cdc/cdc-handler.cls +246 -0
- package/skills/building-sf-integrations/assets/cdc/cdc-subscriber-trigger.trigger +139 -0
- package/skills/building-sf-integrations/assets/endpoint-security/example.cspTrustedSite-meta.xml +58 -0
- package/skills/building-sf-integrations/assets/endpoint-security/example.remoteSite-meta.xml +39 -0
- package/skills/building-sf-integrations/assets/external-credentials/jwt-external-credential.externalCredential-meta.xml +90 -0
- package/skills/building-sf-integrations/assets/external-credentials/oauth-external-credential.externalCredential-meta.xml +87 -0
- package/skills/building-sf-integrations/assets/external-services/external-service-operations.md +221 -0
- package/skills/building-sf-integrations/assets/external-services/openapi-registration.externalServiceRegistration-meta.xml +193 -0
- package/skills/building-sf-integrations/assets/named-credentials/certificate-auth.namedCredential-meta.xml +62 -0
- package/skills/building-sf-integrations/assets/named-credentials/custom-auth.namedCredential-meta.xml +71 -0
- package/skills/building-sf-integrations/assets/named-credentials/oauth-client-credentials.namedCredential-meta.xml +51 -0
- package/skills/building-sf-integrations/assets/named-credentials/oauth-jwt-bearer.namedCredential-meta.xml +67 -0
- package/skills/building-sf-integrations/assets/platform-events/event-publisher.cls +191 -0
- package/skills/building-sf-integrations/assets/platform-events/event-subscriber-action.cls +295 -0
- package/skills/building-sf-integrations/assets/platform-events/event-subscriber-trigger.trigger +108 -0
- package/skills/building-sf-integrations/assets/platform-events/platform-event-definition.object-meta.xml +124 -0
- package/skills/building-sf-integrations/assets/soap/soap-callout-service.cls +186 -0
- package/skills/building-sf-integrations/assets/soap/wsdl2apex-guide.md +213 -0
- package/skills/building-sf-integrations/hooks/scripts/suggest_credential_setup.py +271 -0
- package/skills/building-sf-integrations/hooks/scripts/validate_integration.py +363 -0
- package/skills/building-sf-integrations/references/callout-patterns.md +719 -0
- package/skills/building-sf-integrations/references/cdc-guide.md +288 -0
- package/skills/building-sf-integrations/references/cli-reference.md +94 -0
- package/skills/building-sf-integrations/references/event-driven-architecture-guide.md +266 -0
- package/skills/building-sf-integrations/references/event-patterns.md +838 -0
- package/skills/building-sf-integrations/references/external-services-guide.md +303 -0
- package/skills/building-sf-integrations/references/messaging-api-v2.md +609 -0
- package/skills/building-sf-integrations/references/named-credentials-automation.md +201 -0
- package/skills/building-sf-integrations/references/named-credentials-guide.md +173 -0
- package/skills/building-sf-integrations/references/platform-events-guide.md +288 -0
- package/skills/building-sf-integrations/references/rest-callout-patterns.md +288 -0
- package/skills/building-sf-integrations/references/scoring-rubric.md +59 -0
- package/skills/building-sf-integrations/references/security-best-practices.md +248 -0
- package/skills/building-sf-integrations/scripts/README.md +100 -0
- package/skills/building-sf-integrations/scripts/configure-named-credential.sh +236 -0
- package/skills/building-sf-integrations/scripts/set-api-credential.sh +146 -0
- package/skills/building-sf-integrations/scripts/templates/setup-credentials-with-csp.sh +158 -0
- package/skills/configuring-connected-apps/CREDITS.md +3 -0
- package/skills/configuring-connected-apps/README.md +99 -0
- package/skills/configuring-connected-apps/SKILL.md +224 -0
- package/skills/configuring-connected-apps/assets/connected-app-basic.xml +29 -0
- package/skills/configuring-connected-apps/assets/connected-app-canvas.xml +62 -0
- package/skills/configuring-connected-apps/assets/connected-app-jwt.xml +49 -0
- package/skills/configuring-connected-apps/assets/connected-app-oauth.xml +65 -0
- package/skills/configuring-connected-apps/assets/eca-global-oauth.xml +36 -0
- package/skills/configuring-connected-apps/assets/eca-oauth-settings.xml +36 -0
- package/skills/configuring-connected-apps/assets/eca-policies.xml +36 -0
- package/skills/configuring-connected-apps/assets/external-client-app.xml +35 -0
- package/skills/configuring-connected-apps/references/example-usage.md +256 -0
- package/skills/configuring-connected-apps/references/migration-guide.md +328 -0
- package/skills/configuring-connected-apps/references/oauth-flows-reference.md +660 -0
- package/skills/configuring-connected-apps/references/security-checklist.md +209 -0
- package/skills/configuring-connected-apps/references/testing-validation-guide.md +275 -0
- package/skills/connecting-datacloud/CREDITS.md +5 -0
- package/skills/connecting-datacloud/README.md +59 -0
- package/skills/connecting-datacloud/SKILL.md +155 -0
- package/skills/connecting-datacloud/examples/connections/heroku-postgres.json +15 -0
- package/skills/connecting-datacloud/examples/connections/ingest-api-connection.json +5 -0
- package/skills/connecting-datacloud/examples/connections/ingest-api-schema.json +31 -0
- package/skills/connecting-datacloud/examples/connections/redshift.json +16 -0
- package/skills/connecting-datacloud/examples/connections/sharepoint-unstructured.json +20 -0
- package/skills/connecting-datacloud/examples/connections/snowflake-connection.json +42 -0
- package/skills/debugging-apex-logs/CREDITS.md +22 -0
- package/skills/debugging-apex-logs/README.md +74 -0
- package/skills/debugging-apex-logs/SKILL.md +172 -0
- package/skills/debugging-apex-logs/assets/benchmarking-template.cls +327 -0
- package/skills/debugging-apex-logs/assets/cpu-heap-optimization.cls +307 -0
- package/skills/debugging-apex-logs/assets/dml-in-loop-fix.cls +219 -0
- package/skills/debugging-apex-logs/assets/null-pointer-fix.cls +252 -0
- package/skills/debugging-apex-logs/assets/soql-in-loop-fix.cls +157 -0
- package/skills/debugging-apex-logs/references/analysis-playbook.md +53 -0
- package/skills/debugging-apex-logs/references/benchmarking-guide.md +287 -0
- package/skills/debugging-apex-logs/references/cli-commands.md +368 -0
- package/skills/debugging-apex-logs/references/common-issues.md +68 -0
- package/skills/debugging-apex-logs/references/debug-log-reference.md +328 -0
- package/skills/debugging-apex-logs/references/log-analysis-tools.md +248 -0
- package/skills/debugging-apex-logs/references/scoring-rubric.md +21 -0
- package/skills/deploying-metadata/CREDITS.md +25 -0
- package/skills/deploying-metadata/README.md +104 -0
- package/skills/deploying-metadata/SKILL.md +214 -0
- package/skills/deploying-metadata/assets/destructiveChanges.xml +143 -0
- package/skills/deploying-metadata/assets/package.xml +121 -0
- package/skills/deploying-metadata/references/agent-deployment-guide.md +628 -0
- package/skills/deploying-metadata/references/deploy.sh +73 -0
- package/skills/deploying-metadata/references/deployment-report-template.md +89 -0
- package/skills/deploying-metadata/references/deployment-workflows.md +395 -0
- package/skills/deploying-metadata/references/orchestration.md +183 -0
- package/skills/deploying-metadata/references/trigger-deployment-safety.md +376 -0
- package/skills/deploying-omnistudio-datapacks/CREDITS.md +5 -0
- package/skills/deploying-omnistudio-datapacks/README.md +88 -0
- package/skills/deploying-omnistudio-datapacks/SKILL.md +174 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle/TRANSCRIPT.md +124 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle/deploy-business-internet-plus-bundle.yaml +11 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle-deploy/TRANSCRIPT.md +142 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle-deploy/deploy-business-internet-plus-bundle.yaml +10 -0
- package/skills/deploying-omnistudio-datapacks/references/job-file-template.md +42 -0
- package/skills/deploying-omnistudio-datapacks/references/troubleshooting-matrix.md +24 -0
- package/skills/developing-agentforce/assets/metadata/http-callout-flow.flow-meta.xml +1 -1
- package/skills/developing-agentforce/references/actions-reference.md +8 -8
- package/skills/fetching-salesforce-docs/README.md +66 -0
- package/skills/fetching-salesforce-docs/SKILL.md +209 -0
- package/skills/fetching-salesforce-docs/requirements.txt +2 -0
- package/skills/fetching-salesforce-docs/scripts/extract_help_salesforce.py +497 -0
- package/skills/fetching-salesforce-docs/scripts/extract_salesforce_doc.py +357 -0
- package/skills/fetching-salesforce-docs/scripts/runtime_bootstrap.py +58 -0
- package/skills/generating-apex/CREDITS.md +1 -26
- package/skills/generating-apex-test/CREDITS.md +2 -27
- package/skills/generating-lwc-components/CREDITS.md +5 -0
- package/skills/generating-lwc-components/README.md +126 -0
- package/skills/generating-lwc-components/SKILL.md +191 -0
- package/skills/generating-lwc-components/assets/apex-controller/LwcController.cls +327 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.css +72 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.html +111 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.js +163 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.js-meta.xml +137 -0
- package/skills/generating-lwc-components/assets/datatable-component/datatableComponent.html +111 -0
- package/skills/generating-lwc-components/assets/datatable-component/datatableComponent.js +367 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.css +63 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.html +154 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.js +348 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.js-meta.xml +87 -0
- package/skills/generating-lwc-components/assets/form-component/formComponent.html +165 -0
- package/skills/generating-lwc-components/assets/form-component/formComponent.js +275 -0
- package/skills/generating-lwc-components/assets/graphql-component/graphqlComponent.html +100 -0
- package/skills/generating-lwc-components/assets/graphql-component/graphqlComponent.js +336 -0
- package/skills/generating-lwc-components/assets/jest-test/componentName.test.js.example +371 -0
- package/skills/generating-lwc-components/assets/message-channel/RecordSelected.messageChannel-meta.xml +71 -0
- package/skills/generating-lwc-components/assets/message-channel/lmsPublisher.js +103 -0
- package/skills/generating-lwc-components/assets/message-channel/lmsSubscriber.js +181 -0
- package/skills/generating-lwc-components/assets/modal-component/modalComponent.html +85 -0
- package/skills/generating-lwc-components/assets/modal-component/modalComponent.js +199 -0
- package/skills/generating-lwc-components/assets/record-picker/recordPicker.html +55 -0
- package/skills/generating-lwc-components/assets/record-picker/recordPicker.js +199 -0
- package/skills/generating-lwc-components/assets/state-store/store.js +282 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.css +65 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.html +95 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.js-meta.xml +75 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.test.ts.example +301 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.ts +295 -0
- package/skills/generating-lwc-components/assets/workspace-api/workspaceComponent.html +71 -0
- package/skills/generating-lwc-components/assets/workspace-api/workspaceComponent.js +316 -0
- package/skills/generating-lwc-components/hooks/scripts/lwc-lsp-validate.py +295 -0
- package/skills/generating-lwc-components/hooks/scripts/post-tool-validate.py +347 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_data/deprecated_patterns.json +74 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_data/styling_hooks.json +111 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_data/valid_slds_classes.json +127 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_linter_wrapper.py +294 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_rules/__init__.py +22 -0
- package/skills/generating-lwc-components/hooks/scripts/template_validator.py +332 -0
- package/skills/generating-lwc-components/hooks/scripts/validate_slds.py +595 -0
- package/skills/generating-lwc-components/references/accessibility-guide.md +843 -0
- package/skills/generating-lwc-components/references/advanced-features.md +108 -0
- package/skills/generating-lwc-components/references/async-notification-patterns.md +661 -0
- package/skills/generating-lwc-components/references/cli-commands.md +545 -0
- package/skills/generating-lwc-components/references/component-patterns.md +1476 -0
- package/skills/generating-lwc-components/references/flow-integration-guide.md +675 -0
- package/skills/generating-lwc-components/references/jest-testing.md +1011 -0
- package/skills/generating-lwc-components/references/lms-guide.md +860 -0
- package/skills/generating-lwc-components/references/lwc-best-practices.md +1310 -0
- package/skills/generating-lwc-components/references/performance-guide.md +861 -0
- package/skills/generating-lwc-components/references/scoring-and-testing.md +116 -0
- package/skills/generating-lwc-components/references/slds-blueprints.json +14389 -0
- package/skills/generating-lwc-components/references/slds-design-guide.md +166 -0
- package/skills/generating-lwc-components/references/state-management.md +642 -0
- package/skills/generating-lwc-components/references/template-anti-patterns.md +948 -0
- package/skills/generating-lwc-components/references/triangle-pattern.md +365 -0
- package/skills/generating-lwc-components/scripts/local-dev-preview.sh +34 -0
- package/skills/generating-mermaid-diagrams/CREDITS.md +46 -0
- package/skills/generating-mermaid-diagrams/README.md +114 -0
- package/skills/generating-mermaid-diagrams/SKILL.md +218 -0
- package/skills/generating-mermaid-diagrams/assets/agentforce/agent-flow.md +313 -0
- package/skills/generating-mermaid-diagrams/assets/architecture/system-landscape.md +351 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/b2b-commerce-erd.md +317 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/campaigns-erd.md +195 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/consent-erd.md +262 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/files-erd.md +266 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/forecasting-erd.md +261 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/fsl-erd.md +332 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/party-model-erd.md +237 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/quote-order-erd.md +277 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/revenue-cloud-erd.md +343 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/sales-cloud-erd.md +192 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/salesforce-erd.md +209 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/scheduler-erd.md +276 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/service-cloud-erd.md +217 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/territory-management-erd.md +241 -0
- package/skills/generating-mermaid-diagrams/assets/integration/api-sequence.md +387 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/authorization-code-pkce.md +197 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/authorization-code.md +152 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/client-credentials.md +233 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/device-authorization.md +295 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/jwt-bearer.md +256 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/refresh-token.md +281 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/user-agent-social-sign-on.md +281 -0
- package/skills/generating-mermaid-diagrams/assets/role-hierarchy/user-hierarchy.md +322 -0
- package/skills/generating-mermaid-diagrams/references/color-palette.md +464 -0
- package/skills/generating-mermaid-diagrams/references/diagram-conventions.md +313 -0
- package/skills/generating-mermaid-diagrams/references/erd-conventions.md +320 -0
- package/skills/generating-mermaid-diagrams/references/mermaid-reference.md +434 -0
- package/skills/generating-mermaid-diagrams/references/mermaid-styling.md +81 -0
- package/skills/generating-mermaid-diagrams/references/preview-guide.md +49 -0
- package/skills/generating-mermaid-diagrams/references/usage-examples.md +340 -0
- package/skills/generating-mermaid-diagrams/scripts/README.md +160 -0
- package/skills/generating-mermaid-diagrams/scripts/mermaid_preview.py +654 -0
- package/skills/generating-mermaid-diagrams/scripts/query-org-metadata.py +293 -0
- package/skills/generating-visual-diagrams/CREDITS.md +80 -0
- package/skills/generating-visual-diagrams/README.md +83 -0
- package/skills/generating-visual-diagrams/SKILL.md +208 -0
- package/skills/generating-visual-diagrams/assets/architecture/integration-flow.md +55 -0
- package/skills/generating-visual-diagrams/assets/erd/core-objects.md +131 -0
- package/skills/generating-visual-diagrams/assets/erd/custom-objects.md +60 -0
- package/skills/generating-visual-diagrams/assets/lwc/dashboard-card.md +45 -0
- package/skills/generating-visual-diagrams/assets/lwc/data-table.md +57 -0
- package/skills/generating-visual-diagrams/assets/lwc/record-form.md +60 -0
- package/skills/generating-visual-diagrams/assets/review/apex-review.md +57 -0
- package/skills/generating-visual-diagrams/assets/review/lwc-review.md +48 -0
- package/skills/generating-visual-diagrams/references/architect-aesthetic-guide.md +257 -0
- package/skills/generating-visual-diagrams/references/examples-index.md +35 -0
- package/skills/generating-visual-diagrams/references/gemini-cli-setup.md +65 -0
- package/skills/generating-visual-diagrams/references/interview-questions.md +529 -0
- package/skills/generating-visual-diagrams/references/iteration-workflow.md +173 -0
- package/skills/generating-visual-diagrams/scripts/check-prerequisites.sh +101 -0
- package/skills/generating-visual-diagrams/scripts/generate_image.py +243 -0
- package/skills/handling-sf-data/CREDITS.md +5 -0
- package/skills/handling-sf-data/README.md +112 -0
- package/skills/handling-sf-data/SKILL.md +235 -0
- package/skills/handling-sf-data/assets/bulk/bulk-insert-10000.apex +293 -0
- package/skills/handling-sf-data/assets/bulk/bulk-insert-200.apex +208 -0
- package/skills/handling-sf-data/assets/bulk/bulk-insert-500.apex +219 -0
- package/skills/handling-sf-data/assets/bulk/bulk-upsert-external-id.apex +324 -0
- package/skills/handling-sf-data/assets/cleanup/delete-by-created-date.apex +319 -0
- package/skills/handling-sf-data/assets/cleanup/delete-by-name.apex +240 -0
- package/skills/handling-sf-data/assets/cleanup/delete-test-data.apex +311 -0
- package/skills/handling-sf-data/assets/cleanup/rollback-transaction.apex +266 -0
- package/skills/handling-sf-data/assets/csv/account-import.csv +11 -0
- package/skills/handling-sf-data/assets/csv/contact-import.csv +11 -0
- package/skills/handling-sf-data/assets/csv/custom-object-import.csv +11 -0
- package/skills/handling-sf-data/assets/csv/opportunity-import.csv +11 -0
- package/skills/handling-sf-data/assets/factories/account-factory.apex +165 -0
- package/skills/handling-sf-data/assets/factories/case-factory.apex +237 -0
- package/skills/handling-sf-data/assets/factories/contact-factory.apex +168 -0
- package/skills/handling-sf-data/assets/factories/custom-object-factory.apex +260 -0
- package/skills/handling-sf-data/assets/factories/event-factory.apex +275 -0
- package/skills/handling-sf-data/assets/factories/hierarchy-factory.apex +372 -0
- package/skills/handling-sf-data/assets/factories/lead-factory.apex +190 -0
- package/skills/handling-sf-data/assets/factories/opportunity-factory.apex +206 -0
- package/skills/handling-sf-data/assets/factories/task-factory.apex +246 -0
- package/skills/handling-sf-data/assets/factories/user-factory.apex +278 -0
- package/skills/handling-sf-data/assets/json/account-contact-tree.json +130 -0
- package/skills/handling-sf-data/assets/json/account-opportunity-tree.json +110 -0
- package/skills/handling-sf-data/assets/json/full-hierarchy-tree.json +188 -0
- package/skills/handling-sf-data/assets/soql/aggregate.soql +226 -0
- package/skills/handling-sf-data/assets/soql/child-to-parent.soql +162 -0
- package/skills/handling-sf-data/assets/soql/parent-to-child.soql +153 -0
- package/skills/handling-sf-data/assets/soql/polymorphic.soql +198 -0
- package/skills/handling-sf-data/assets/soql/subquery.soql +287 -0
- package/skills/handling-sf-data/references/anonymous-apex-guide.md +98 -0
- package/skills/handling-sf-data/references/bulk-operations-guide.md +94 -0
- package/skills/handling-sf-data/references/bulk-testing-example.md +194 -0
- package/skills/handling-sf-data/references/cleanup-rollback-example.md +322 -0
- package/skills/handling-sf-data/references/cleanup-rollback-guide.md +84 -0
- package/skills/handling-sf-data/references/crud-workflow-example.md +183 -0
- package/skills/handling-sf-data/references/governor-limits-reference.md +74 -0
- package/skills/handling-sf-data/references/orchestration.md +174 -0
- package/skills/handling-sf-data/references/relationship-query-examples.md +249 -0
- package/skills/handling-sf-data/references/sf-cli-data-commands.md +158 -0
- package/skills/handling-sf-data/references/soql-relationship-guide.md +84 -0
- package/skills/handling-sf-data/references/test-data-best-practices.md +104 -0
- package/skills/handling-sf-data/references/test-data-factory-usage.md +290 -0
- package/skills/handling-sf-data/references/test-data-patterns.md +98 -0
- package/skills/handling-sf-data/scripts/soql_validator.py +292 -0
- package/skills/handling-sf-data/scripts/validate_data_operation.py +379 -0
- package/skills/harmonizing-datacloud/CREDITS.md +3 -0
- package/skills/harmonizing-datacloud/README.md +31 -0
- package/skills/harmonizing-datacloud/SKILL.md +117 -0
- package/skills/modeling-omnistudio-epc-catalog/CREDITS.md +14 -0
- package/skills/modeling-omnistudio-epc-catalog/README.md +89 -0
- package/skills/modeling-omnistudio-epc-catalog/SKILL.md +395 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/attribute-assignment-template.json +402 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/compiled-attribute-overrides-template.json +43 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/completion-block-template.txt +8 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/decomposition-relationships-template.json +233 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_AttributeAssignments.json +514 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_CompiledAttributeOverrides.json +21 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_DataPack.json +649 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_DecompositionRelationships.json +200 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_ObjectFieldAttributes.json +138 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_OrchestrationScenarios.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_OverrideDefinitions.json +266 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_ParentKeys.json +23 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_PriceListEntries.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_ProductChildItems.json +34 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_RuleAssignments.json +21 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_AttributeAssignments.json +410 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_DataPack.json +535 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_DecompositionRelationships.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_ObjectFieldAttributes.json +138 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_OrchestrationScenarios.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_ParentKeys.json +23 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_PriceListEntries.json +220 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_ProductChildItems.json +414 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_AttributeAssignments.json +382 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_DataPack.json +565 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_DecompositionRelationships.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_ObjectFieldAttributes.json +104 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_OrchestrationScenarios.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_ParentKeys.json +13 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_PriceListEntries.json +106 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_ProductChildItems.json +72 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_AttributeAssignments.json +142 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_DataPack.json +377 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_DecompositionRelationships.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_ObjectFieldAttributes.json +36 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_ParentKeys.json +8 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_PriceListEntries.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_ProductChildItems.json +34 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/object-field-attributes-template.json +138 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/orchestration-scenarios-template.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/override-definitions-template.json +134 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/parent-keys-template.json +29 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/price-list-entries-template.json +158 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/pricebook-entries-template.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/product-child-item-template.json +338 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/product2-offer-template.json +527 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/.gitkeep +1 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_AttributeAssignments.json +95 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_CompiledAttributeOverrides.json +1 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_DataPack.json +214 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_DecompositionRelationships.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_ObjectFieldAttributes.json +98 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_OrchestrationScenarios.json +22 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_OverrideDefinitions.json +1 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_ParentKeys.json +13 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_PriceListEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_PricebookEntries.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_ProductChildItems.json +110 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/TRANSCRIPT.md +58 -0
- package/skills/modeling-omnistudio-epc-catalog/references/epc-field-guide.md +90 -0
- package/skills/modeling-omnistudio-epc-catalog/references/naming-conventions.md +80 -0
- package/skills/modeling-omnistudio-epc-catalog/references/scoring-model.md +57 -0
- package/skills/modeling-omnistudio-epc-catalog/scripts/cli-validation-commands.sh +19 -0
- package/skills/modeling-omnistudio-epc-catalog/scripts/sample-invocations.sh +18 -0
- package/skills/orchestrating-datacloud/CREDITS.md +15 -0
- package/skills/orchestrating-datacloud/README.md +129 -0
- package/skills/orchestrating-datacloud/SKILL.md +236 -0
- package/skills/orchestrating-datacloud/UPSTREAM.md +45 -0
- package/skills/orchestrating-datacloud/assets/definitions/activation-target.template.json +5 -0
- package/skills/orchestrating-datacloud/assets/definitions/activation.template.json +7 -0
- package/skills/orchestrating-datacloud/assets/definitions/calculated-insight.template.json +7 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-action-target.template.json +5 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-action.template.json +5 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-graph.template.json +21 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-stream.template.json +55 -0
- package/skills/orchestrating-datacloud/assets/definitions/dmo.template.json +17 -0
- package/skills/orchestrating-datacloud/assets/definitions/identity-resolution.template.json +30 -0
- package/skills/orchestrating-datacloud/assets/definitions/mapping.template.json +14 -0
- package/skills/orchestrating-datacloud/assets/definitions/relationship.template.json +12 -0
- package/skills/orchestrating-datacloud/assets/definitions/search-index.template.json +9 -0
- package/skills/orchestrating-datacloud/assets/definitions/segment.template.json +16 -0
- package/skills/orchestrating-datacloud/references/feature-readiness.md +157 -0
- package/skills/orchestrating-datacloud/references/plugin-setup.md +140 -0
- package/skills/orchestrating-datacloud/scripts/bootstrap-plugin.sh +53 -0
- package/skills/orchestrating-datacloud/scripts/diagnose-org.mjs +511 -0
- package/skills/orchestrating-datacloud/scripts/generate-manifest.mjs +68 -0
- package/skills/orchestrating-datacloud/scripts/verify-plugin.sh +58 -0
- package/skills/preparing-datacloud/CREDITS.md +7 -0
- package/skills/preparing-datacloud/README.md +51 -0
- package/skills/preparing-datacloud/SKILL.md +191 -0
- package/skills/preparing-datacloud/examples/ingestion-api/.env.example +8 -0
- package/skills/preparing-datacloud/examples/ingestion-api/README.md +48 -0
- package/skills/preparing-datacloud/examples/ingestion-api/send-data.py +144 -0
- package/skills/querying-soql/CREDITS.md +21 -0
- package/skills/querying-soql/README.md +41 -0
- package/skills/querying-soql/SKILL.md +143 -0
- package/skills/querying-soql/assets/aggregate-queries.soql +242 -0
- package/skills/querying-soql/assets/basic-queries.soql +188 -0
- package/skills/querying-soql/assets/bulkified-query-pattern.cls +280 -0
- package/skills/querying-soql/assets/optimization-patterns.soql +259 -0
- package/skills/querying-soql/assets/relationship-queries.soql +203 -0
- package/skills/querying-soql/assets/selector-class.cls +219 -0
- package/skills/querying-soql/references/anti-patterns.md +348 -0
- package/skills/querying-soql/references/cli-commands.md +358 -0
- package/skills/querying-soql/references/field-coverage-rules.md +514 -0
- package/skills/querying-soql/references/query-optimization.md +142 -0
- package/skills/querying-soql/references/selector-patterns.md +479 -0
- package/skills/querying-soql/references/soql-reference.md +227 -0
- package/skills/querying-soql/references/soql-syntax-reference.md +208 -0
- package/skills/querying-soql/scripts/post-tool-validate.py +322 -0
- package/skills/retrieving-datacloud/CREDITS.md +7 -0
- package/skills/retrieving-datacloud/README.md +44 -0
- package/skills/retrieving-datacloud/SKILL.md +120 -0
- package/skills/retrieving-datacloud/examples/search-indexes/hybrid-structured.json +44 -0
- package/skills/retrieving-datacloud/examples/search-indexes/vector-knowledge.json +43 -0
- package/skills/running-apex-tests/CREDITS.md +22 -0
- package/skills/running-apex-tests/README.md +94 -0
- package/skills/running-apex-tests/SKILL.md +158 -0
- package/skills/running-apex-tests/assets/basic-test.cls +169 -0
- package/skills/running-apex-tests/assets/bulk-test.cls +255 -0
- package/skills/running-apex-tests/assets/dml-mock.cls +339 -0
- package/skills/running-apex-tests/assets/mock-callout-test.cls +353 -0
- package/skills/running-apex-tests/assets/stub-provider-example.cls +364 -0
- package/skills/running-apex-tests/assets/test-data-factory.cls +328 -0
- package/skills/running-apex-tests/hooks/scripts/parse-test-results.py +364 -0
- package/skills/running-apex-tests/references/cli-commands.md +289 -0
- package/skills/running-apex-tests/references/mocking-patterns.md +500 -0
- package/skills/running-apex-tests/references/performance-optimization.md +283 -0
- package/skills/running-apex-tests/references/test-fix-loop.md +49 -0
- package/skills/running-apex-tests/references/test-patterns.md +154 -0
- package/skills/running-apex-tests/references/testing-best-practices.md +509 -0
- package/skills/segmenting-datacloud/CREDITS.md +3 -0
- package/skills/segmenting-datacloud/README.md +36 -0
- package/skills/segmenting-datacloud/SKILL.md +115 -0
|
@@ -0,0 +1,838 @@
|
|
|
1
|
+
<!-- Parent: building-sf-integrations/SKILL.md -->
|
|
2
|
+
# Event-Driven Integration Patterns
|
|
3
|
+
|
|
4
|
+
This document provides detailed implementation patterns for Platform Events and Change Data Capture (CDC) in Salesforce integrations.
|
|
5
|
+
|
|
6
|
+
> **Parent Document**: [building-sf-integrations/SKILL.md](../SKILL.md)
|
|
7
|
+
> **Related**: [callout-patterns.md](./callout-patterns.md)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Table of Contents
|
|
12
|
+
|
|
13
|
+
- [Platform Events](#platform-events)
|
|
14
|
+
- [Platform Event Definition](#platform-event-definition)
|
|
15
|
+
- [Event Publisher](#event-publisher)
|
|
16
|
+
- [Event Subscriber Trigger](#event-subscriber-trigger)
|
|
17
|
+
- [High-Volume vs Standard-Volume Events](#high-volume-vs-standard-volume-events)
|
|
18
|
+
- [Change Data Capture (CDC)](#change-data-capture-cdc)
|
|
19
|
+
- [CDC Enablement](#cdc-enablement)
|
|
20
|
+
- [CDC Subscriber Trigger](#cdc-subscriber-trigger)
|
|
21
|
+
- [CDC Handler Service](#cdc-handler-service)
|
|
22
|
+
- [Field-Specific Change Detection](#field-specific-change-detection)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Platform Events
|
|
27
|
+
|
|
28
|
+
Platform Events enable asynchronous, event-driven communication between applications. They provide a publish-subscribe model where publishers fire events and subscribers listen for them.
|
|
29
|
+
|
|
30
|
+
### Platform Event Definition
|
|
31
|
+
|
|
32
|
+
**Use Case**: Asynchronous, event-driven communication
|
|
33
|
+
|
|
34
|
+
**Template**: `assets/platform-events/platform-event-definition.object-meta.xml`
|
|
35
|
+
|
|
36
|
+
#### Standard Volume Event
|
|
37
|
+
|
|
38
|
+
Best for moderate event volumes (~2,000 events/hour):
|
|
39
|
+
|
|
40
|
+
```xml
|
|
41
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
42
|
+
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
43
|
+
<deploymentStatus>Deployed</deploymentStatus>
|
|
44
|
+
<eventType>StandardVolume</eventType>
|
|
45
|
+
<label>{{EventLabel}}</label>
|
|
46
|
+
<pluralLabel>{{EventPluralLabel}}</pluralLabel>
|
|
47
|
+
<publishBehavior>PublishAfterCommit</publishBehavior>
|
|
48
|
+
|
|
49
|
+
<fields>
|
|
50
|
+
<fullName>{{FieldName}}__c</fullName>
|
|
51
|
+
<label>{{FieldLabel}}</label>
|
|
52
|
+
<type>Text</type>
|
|
53
|
+
<length>255</length>
|
|
54
|
+
</fields>
|
|
55
|
+
|
|
56
|
+
<fields>
|
|
57
|
+
<fullName>RecordId__c</fullName>
|
|
58
|
+
<label>Record ID</label>
|
|
59
|
+
<type>Text</type>
|
|
60
|
+
<length>18</length>
|
|
61
|
+
<description>Salesforce record ID related to this event</description>
|
|
62
|
+
</fields>
|
|
63
|
+
|
|
64
|
+
<fields>
|
|
65
|
+
<fullName>Timestamp__c</fullName>
|
|
66
|
+
<label>Timestamp</label>
|
|
67
|
+
<type>DateTime</type>
|
|
68
|
+
<description>When the event was triggered</description>
|
|
69
|
+
</fields>
|
|
70
|
+
</CustomObject>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### High-Volume Event
|
|
74
|
+
|
|
75
|
+
Best for millions of events per day:
|
|
76
|
+
|
|
77
|
+
```xml
|
|
78
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
79
|
+
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
80
|
+
<deploymentStatus>Deployed</deploymentStatus>
|
|
81
|
+
<eventType>HighVolume</eventType>
|
|
82
|
+
<label>{{EventLabel}}</label>
|
|
83
|
+
<pluralLabel>{{EventPluralLabel}}</pluralLabel>
|
|
84
|
+
<publishBehavior>PublishAfterCommit</publishBehavior>
|
|
85
|
+
|
|
86
|
+
<fields>
|
|
87
|
+
<fullName>{{FieldName}}__c</fullName>
|
|
88
|
+
<label>{{FieldLabel}}</label>
|
|
89
|
+
<type>Text</type>
|
|
90
|
+
<length>255</length>
|
|
91
|
+
</fields>
|
|
92
|
+
</CustomObject>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Key Configuration Options
|
|
96
|
+
|
|
97
|
+
| Option | Values | Description |
|
|
98
|
+
|--------|--------|-------------|
|
|
99
|
+
| **eventType** | `StandardVolume`, `HighVolume` | Event throughput capacity |
|
|
100
|
+
| **publishBehavior** | `PublishAfterCommit`, `PublishImmediately` | When events are published |
|
|
101
|
+
| **deploymentStatus** | `Deployed`, `InDevelopment` | Deployment status |
|
|
102
|
+
|
|
103
|
+
**PublishBehavior Details**:
|
|
104
|
+
- `PublishAfterCommit`: Event published only if transaction commits (recommended)
|
|
105
|
+
- `PublishImmediately`: Event published immediately, even if transaction rolls back
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
### Event Publisher
|
|
110
|
+
|
|
111
|
+
**Template**: `assets/platform-events/event-publisher.cls`
|
|
112
|
+
|
|
113
|
+
#### Bulk Event Publisher
|
|
114
|
+
|
|
115
|
+
```apex
|
|
116
|
+
public with sharing class {{EventName}}Publisher {
|
|
117
|
+
|
|
118
|
+
public static void publishEvents(List<{{EventName}}__e> events) {
|
|
119
|
+
if (events == null || events.isEmpty()) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
List<Database.SaveResult> results = EventBus.publish(events);
|
|
124
|
+
|
|
125
|
+
for (Integer i = 0; i < results.size(); i++) {
|
|
126
|
+
Database.SaveResult sr = results[i];
|
|
127
|
+
if (!sr.isSuccess()) {
|
|
128
|
+
for (Database.Error err : sr.getErrors()) {
|
|
129
|
+
System.debug(LoggingLevel.ERROR,
|
|
130
|
+
'Event publish error: ' + err.getStatusCode() + ' - ' + err.getMessage());
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
public static void publishSingleEvent(Map<String, Object> eventData) {
|
|
137
|
+
{{EventName}}__e event = new {{EventName}}__e();
|
|
138
|
+
|
|
139
|
+
// Map fields from eventData
|
|
140
|
+
event.{{FieldName}}__c = (String) eventData.get('{{fieldKey}}');
|
|
141
|
+
event.RecordId__c = (String) eventData.get('recordId');
|
|
142
|
+
event.Timestamp__c = DateTime.now();
|
|
143
|
+
|
|
144
|
+
Database.SaveResult sr = EventBus.publish(event);
|
|
145
|
+
if (!sr.isSuccess()) {
|
|
146
|
+
throw new EventPublishException('Failed to publish event: ' + sr.getErrors());
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
public class EventPublishException extends Exception {}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### Usage Examples
|
|
155
|
+
|
|
156
|
+
**Single Event**:
|
|
157
|
+
```apex
|
|
158
|
+
Map<String, Object> eventData = new Map<String, Object>{
|
|
159
|
+
'recordId' => '001xx000003DXXXAAA',
|
|
160
|
+
'status' => 'Completed',
|
|
161
|
+
'amount' => 1000.00
|
|
162
|
+
};
|
|
163
|
+
OrderStatusPublisher.publishSingleEvent(eventData);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Bulk Events**:
|
|
167
|
+
```apex
|
|
168
|
+
List<Order_Status__e> events = new List<Order_Status__e>();
|
|
169
|
+
|
|
170
|
+
for (Order order : orders) {
|
|
171
|
+
Order_Status__e event = new Order_Status__e();
|
|
172
|
+
event.RecordId__c = order.Id;
|
|
173
|
+
event.Status__c = order.Status;
|
|
174
|
+
event.Timestamp__c = DateTime.now();
|
|
175
|
+
events.add(event);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
OrderStatusPublisher.publishEvents(events);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
#### Best Practices for Publishing
|
|
182
|
+
|
|
183
|
+
1. **Batch Events**: Publish up to 2,000 events per transaction (governor limit)
|
|
184
|
+
2. **Error Handling**: Always check `Database.SaveResult` for failures
|
|
185
|
+
3. **Transaction Context**: Use `PublishAfterCommit` to ensure events only fire on successful transactions
|
|
186
|
+
4. **Field Population**: Populate all required fields before publishing
|
|
187
|
+
5. **Logging**: Log failed event publishes for debugging
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
### Event Subscriber Trigger
|
|
192
|
+
|
|
193
|
+
**Template**: `assets/platform-events/event-subscriber-trigger.trigger`
|
|
194
|
+
|
|
195
|
+
#### Standard Volume Subscriber
|
|
196
|
+
|
|
197
|
+
```apex
|
|
198
|
+
trigger {{EventName}}Subscriber on {{EventName}}__e (after insert) {
|
|
199
|
+
// Get replay ID for resumption
|
|
200
|
+
String lastReplayId = '';
|
|
201
|
+
|
|
202
|
+
for ({{EventName}}__e event : Trigger.new) {
|
|
203
|
+
// Store replay ID for potential resume
|
|
204
|
+
lastReplayId = event.ReplayId;
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
// Process event
|
|
208
|
+
{{EventName}}Handler.processEvent(event);
|
|
209
|
+
} catch (Exception e) {
|
|
210
|
+
// Log error but don't throw - allow other events to process
|
|
211
|
+
System.debug(LoggingLevel.ERROR,
|
|
212
|
+
'Event processing error: ' + e.getMessage() +
|
|
213
|
+
' ReplayId: ' + event.ReplayId);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
#### High-Volume Subscriber (with Resume Checkpoint)
|
|
220
|
+
|
|
221
|
+
```apex
|
|
222
|
+
trigger {{EventName}}Subscriber on {{EventName}}__e (after insert) {
|
|
223
|
+
String lastReplayId = '';
|
|
224
|
+
|
|
225
|
+
for ({{EventName}}__e event : Trigger.new) {
|
|
226
|
+
lastReplayId = event.ReplayId;
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
{{EventName}}Handler.processEvent(event);
|
|
230
|
+
} catch (Exception e) {
|
|
231
|
+
System.debug(LoggingLevel.ERROR,
|
|
232
|
+
'Event processing error: ' + e.getMessage() +
|
|
233
|
+
' ReplayId: ' + event.ReplayId);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Set resume checkpoint for high-volume events
|
|
238
|
+
// Allows resuming from this point if subscriber fails
|
|
239
|
+
EventBus.TriggerContext.currentContext().setResumeCheckpoint(lastReplayId);
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### Event Handler Class
|
|
244
|
+
|
|
245
|
+
```apex
|
|
246
|
+
public with sharing class {{EventName}}Handler {
|
|
247
|
+
|
|
248
|
+
public static void processEvent({{EventName}}__e event) {
|
|
249
|
+
// Extract event data
|
|
250
|
+
String recordId = event.RecordId__c;
|
|
251
|
+
String status = event.Status__c;
|
|
252
|
+
DateTime timestamp = event.Timestamp__c;
|
|
253
|
+
|
|
254
|
+
System.debug('Processing event - RecordId: ' + recordId +
|
|
255
|
+
', Status: ' + status +
|
|
256
|
+
', ReplayId: ' + event.ReplayId);
|
|
257
|
+
|
|
258
|
+
// Business logic
|
|
259
|
+
updateRelatedRecords(recordId, status);
|
|
260
|
+
syncToExternalSystem(recordId, status);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
private static void updateRelatedRecords(String recordId, String status) {
|
|
264
|
+
// Update related records based on event
|
|
265
|
+
List<Task> tasks = [
|
|
266
|
+
SELECT Id, Status
|
|
267
|
+
FROM Task
|
|
268
|
+
WHERE WhatId = :recordId
|
|
269
|
+
WITH USER_MODE
|
|
270
|
+
];
|
|
271
|
+
|
|
272
|
+
for (Task t : tasks) {
|
|
273
|
+
t.Status = status;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
update as user tasks;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
private static void syncToExternalSystem(String recordId, String status) {
|
|
280
|
+
// Queue async callout
|
|
281
|
+
Map<String, Object> payload = new Map<String, Object>{
|
|
282
|
+
'recordId' => recordId,
|
|
283
|
+
'status' => status
|
|
284
|
+
};
|
|
285
|
+
System.enqueueJob(new ExternalSyncQueueable(payload));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
<a id="high-volume-vs-standard-volume-events"></a>
|
|
293
|
+
|
|
294
|
+
### High-Volume vs Standard-Volume Events
|
|
295
|
+
|
|
296
|
+
| Feature | Standard-Volume | High-Volume |
|
|
297
|
+
|---------|----------------|-------------|
|
|
298
|
+
| **Throughput** | ~2,000 events/hour | Millions/day |
|
|
299
|
+
| **Delivery** | Exactly-once | At-least-once (may deliver duplicates) |
|
|
300
|
+
| **Retention** | 3 days (72 hours) | 24 hours |
|
|
301
|
+
| **Replay** | ReplayId from last 3 days | ReplayId from last 24 hours |
|
|
302
|
+
| **Use Case** | Low-volume integrations, workflows | IoT, real-time analytics, high-traffic |
|
|
303
|
+
| **Cost** | Included in platform | Additional licensing |
|
|
304
|
+
|
|
305
|
+
#### When to Use High-Volume Events
|
|
306
|
+
|
|
307
|
+
- **IoT Data**: Sensor data, device telemetry
|
|
308
|
+
- **Real-Time Analytics**: Clickstream, user behavior tracking
|
|
309
|
+
- **High-Traffic Systems**: E-commerce order processing, stock updates
|
|
310
|
+
- **Event Sourcing**: Append-only event logs
|
|
311
|
+
|
|
312
|
+
#### When to Use Standard-Volume Events
|
|
313
|
+
|
|
314
|
+
- **Business Workflows**: Order status updates, approval processes
|
|
315
|
+
- **Integration Events**: Sync to external CRM, ERP systems
|
|
316
|
+
- **Notifications**: Email triggers, Slack notifications
|
|
317
|
+
- **Audit Trails**: Record-level change notifications
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## Change Data Capture (CDC)
|
|
322
|
+
|
|
323
|
+
Change Data Capture publishes change events whenever records are created, updated, deleted, or undeleted in Salesforce. CDC events are published automatically—no custom code needed.
|
|
324
|
+
|
|
325
|
+
### CDC Enablement
|
|
326
|
+
|
|
327
|
+
#### Enable via Setup UI
|
|
328
|
+
|
|
329
|
+
1. Navigate to **Setup** → **Integrations** → **Change Data Capture**
|
|
330
|
+
2. Select objects to enable (Standard or Custom)
|
|
331
|
+
3. Save
|
|
332
|
+
|
|
333
|
+
#### Enable via Metadata API
|
|
334
|
+
|
|
335
|
+
**File**: `force-app/main/default/changeDataCaptures/AccountChangeEvent.cdc-meta.xml`
|
|
336
|
+
|
|
337
|
+
```xml
|
|
338
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
339
|
+
<ChangeDataCapture xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
340
|
+
<entityName>Account</entityName>
|
|
341
|
+
<isEnabled>true</isEnabled>
|
|
342
|
+
</ChangeDataCapture>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
#### Channel Naming Convention
|
|
346
|
+
|
|
347
|
+
CDC channels follow the pattern: `{{ObjectAPIName}}ChangeEvent`
|
|
348
|
+
|
|
349
|
+
**Examples**:
|
|
350
|
+
- `AccountChangeEvent` (Standard object)
|
|
351
|
+
- `Order__ChangeEvent` (Custom object)
|
|
352
|
+
- `OpportunityChangeEvent`
|
|
353
|
+
- `Contact_Request__ChangeEvent`
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
### CDC Subscriber Trigger
|
|
358
|
+
|
|
359
|
+
**Template**: `assets/cdc/cdc-subscriber-trigger.trigger`
|
|
360
|
+
|
|
361
|
+
#### Basic CDC Subscriber
|
|
362
|
+
|
|
363
|
+
```apex
|
|
364
|
+
trigger {{ObjectName}}CDCSubscriber on {{ObjectName}}ChangeEvent (after insert) {
|
|
365
|
+
|
|
366
|
+
for ({{ObjectName}}ChangeEvent event : Trigger.new) {
|
|
367
|
+
// Get change event header
|
|
368
|
+
EventBus.ChangeEventHeader header = event.ChangeEventHeader;
|
|
369
|
+
|
|
370
|
+
String changeType = header.getChangeType();
|
|
371
|
+
List<String> changedFields = header.getChangedFields();
|
|
372
|
+
String recordId = header.getRecordIds()[0]; // First record ID
|
|
373
|
+
|
|
374
|
+
System.debug('CDC Event - Type: ' + changeType +
|
|
375
|
+
', RecordId: ' + recordId +
|
|
376
|
+
', Changed Fields: ' + changedFields);
|
|
377
|
+
|
|
378
|
+
// Route based on change type
|
|
379
|
+
switch on changeType {
|
|
380
|
+
when 'CREATE' {
|
|
381
|
+
// Handle new record
|
|
382
|
+
{{ObjectName}}CDCHandler.handleCreate(event);
|
|
383
|
+
}
|
|
384
|
+
when 'UPDATE' {
|
|
385
|
+
// Handle update
|
|
386
|
+
{{ObjectName}}CDCHandler.handleUpdate(event, changedFields);
|
|
387
|
+
}
|
|
388
|
+
when 'DELETE' {
|
|
389
|
+
// Handle delete
|
|
390
|
+
{{ObjectName}}CDCHandler.handleDelete(recordId);
|
|
391
|
+
}
|
|
392
|
+
when 'UNDELETE' {
|
|
393
|
+
// Handle undelete
|
|
394
|
+
{{ObjectName}}CDCHandler.handleUndelete(event);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
#### ChangeEventHeader Fields
|
|
402
|
+
|
|
403
|
+
| Field | Type | Description |
|
|
404
|
+
|-------|------|-------------|
|
|
405
|
+
| `getChangeType()` | String | CREATE, UPDATE, DELETE, UNDELETE |
|
|
406
|
+
| `getRecordIds()` | List<String> | Record IDs affected (usually 1, up to 5 for related changes) |
|
|
407
|
+
| `getChangedFields()` | List<String> | Field API names that changed (UPDATE only) |
|
|
408
|
+
| `getCommitTimestamp()` | Long | Transaction commit timestamp |
|
|
409
|
+
| `getCommitUser()` | String | User ID who made the change |
|
|
410
|
+
| `getCommitNumber()` | Long | Monotonically increasing commit number |
|
|
411
|
+
| `getEntityName()` | String | Object API name |
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
### CDC Handler Service
|
|
416
|
+
|
|
417
|
+
**Template**: `assets/cdc/cdc-handler.cls`
|
|
418
|
+
|
|
419
|
+
```apex
|
|
420
|
+
public with sharing class {{ObjectName}}CDCHandler {
|
|
421
|
+
|
|
422
|
+
public static void handleCreate({{ObjectName}}ChangeEvent event) {
|
|
423
|
+
// Sync to external system on create
|
|
424
|
+
Map<String, Object> payload = buildPayload(event);
|
|
425
|
+
System.enqueueJob(new ExternalSystemSyncQueueable(payload, 'CREATE'));
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
public static void handleUpdate({{ObjectName}}ChangeEvent event, List<String> changedFields) {
|
|
429
|
+
// Only sync if relevant fields changed
|
|
430
|
+
Set<String> fieldsToWatch = new Set<String>{'Name', 'Status__c', 'Amount__c'};
|
|
431
|
+
|
|
432
|
+
Boolean relevantChange = false;
|
|
433
|
+
for (String field : changedFields) {
|
|
434
|
+
if (fieldsToWatch.contains(field)) {
|
|
435
|
+
relevantChange = true;
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (relevantChange) {
|
|
441
|
+
Map<String, Object> payload = buildPayload(event);
|
|
442
|
+
payload.put('changedFields', changedFields);
|
|
443
|
+
System.enqueueJob(new ExternalSystemSyncQueueable(payload, 'UPDATE'));
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
public static void handleDelete(String recordId) {
|
|
448
|
+
Map<String, Object> payload = new Map<String, Object>{'recordId' => recordId};
|
|
449
|
+
System.enqueueJob(new ExternalSystemSyncQueueable(payload, 'DELETE'));
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
public static void handleUndelete({{ObjectName}}ChangeEvent event) {
|
|
453
|
+
handleCreate(event); // Treat undelete like create
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
private static Map<String, Object> buildPayload({{ObjectName}}ChangeEvent event) {
|
|
457
|
+
return new Map<String, Object>{
|
|
458
|
+
'recordId' => event.ChangeEventHeader.getRecordIds()[0],
|
|
459
|
+
'commitTimestamp' => event.ChangeEventHeader.getCommitTimestamp(),
|
|
460
|
+
'commitUser' => event.ChangeEventHeader.getCommitUser(),
|
|
461
|
+
// Add event field values
|
|
462
|
+
'name' => event.Name,
|
|
463
|
+
'status' => event.Status__c
|
|
464
|
+
// Add more fields
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
<a id="field-specific-change-detection"></a>
|
|
473
|
+
|
|
474
|
+
### Field-Specific Change Detection
|
|
475
|
+
|
|
476
|
+
#### Filtering by Changed Fields
|
|
477
|
+
|
|
478
|
+
```apex
|
|
479
|
+
public static void handleUpdate(AccountChangeEvent event, List<String> changedFields) {
|
|
480
|
+
// Only process if billing address changed
|
|
481
|
+
Set<String> billingFields = new Set<String>{
|
|
482
|
+
'BillingStreet',
|
|
483
|
+
'BillingCity',
|
|
484
|
+
'BillingState',
|
|
485
|
+
'BillingPostalCode',
|
|
486
|
+
'BillingCountry'
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
Boolean billingChanged = false;
|
|
490
|
+
for (String field : changedFields) {
|
|
491
|
+
if (billingFields.contains(field)) {
|
|
492
|
+
billingChanged = true;
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
if (billingChanged) {
|
|
498
|
+
updateShippingPartner(event);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
#### Multi-Field Change Logic
|
|
504
|
+
|
|
505
|
+
```apex
|
|
506
|
+
public static void handleUpdate(OpportunityChangeEvent event, List<String> changedFields) {
|
|
507
|
+
Set<String> changedFieldSet = new Set<String>(changedFields);
|
|
508
|
+
|
|
509
|
+
// Check if stage AND amount both changed
|
|
510
|
+
if (changedFieldSet.contains('StageName') && changedFieldSet.contains('Amount')) {
|
|
511
|
+
// Alert sales ops about significant deal change
|
|
512
|
+
sendAlert('Deal stage and amount changed', event);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Check if close date moved backward
|
|
516
|
+
if (changedFieldSet.contains('CloseDate')) {
|
|
517
|
+
checkCloseDateRegression(event);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## CDC vs Platform Events: When to Use Which
|
|
525
|
+
|
|
526
|
+
| Use Case | Platform Events | Change Data Capture |
|
|
527
|
+
|----------|----------------|---------------------|
|
|
528
|
+
| **Custom business events** | **Preferred** | Not applicable |
|
|
529
|
+
| **Record change notifications** | Requires custom trigger | **Automatic** (no code) |
|
|
530
|
+
| **External system sync** | Both work | **CDC** (lower maintenance) |
|
|
531
|
+
| **Custom event fields** | Fully customizable | Limited to object fields |
|
|
532
|
+
| **Event filtering** | Filter in publisher code | Filter in subscriber code |
|
|
533
|
+
| **Performance overhead** | Manual event creation | Automatic (minimal overhead) |
|
|
534
|
+
|
|
535
|
+
### Decision Matrix
|
|
536
|
+
|
|
537
|
+
```
|
|
538
|
+
┌───────────────────────────────────────────────────────────────────────┐
|
|
539
|
+
│ WHEN TO USE PLATFORM EVENTS vs CHANGE DATA CAPTURE │
|
|
540
|
+
├───────────────────────────────────────────────────────────────────────┤
|
|
541
|
+
│ Use PLATFORM EVENTS when: │
|
|
542
|
+
│ • Custom business event (not tied to record changes) │
|
|
543
|
+
│ • Event needs custom fields not on object │
|
|
544
|
+
│ • Need to batch/aggregate data before publishing │
|
|
545
|
+
│ • Publishing from external system to Salesforce │
|
|
546
|
+
│ • Complex event logic (multi-object aggregation) │
|
|
547
|
+
│ │
|
|
548
|
+
│ Use CHANGE DATA CAPTURE when: │
|
|
549
|
+
│ • Syncing record changes to external system │
|
|
550
|
+
│ • Audit trail of all record modifications │
|
|
551
|
+
│ • Real-time replication to data warehouse │
|
|
552
|
+
│ • Event sourcing from Salesforce objects │
|
|
553
|
+
│ • Zero-code event publishing required │
|
|
554
|
+
└───────────────────────────────────────────────────────────────────────┘
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
---
|
|
558
|
+
|
|
559
|
+
## Advanced Patterns
|
|
560
|
+
|
|
561
|
+
### Combining CDC with Callouts
|
|
562
|
+
|
|
563
|
+
```apex
|
|
564
|
+
public with sharing class AccountCDCHandler {
|
|
565
|
+
|
|
566
|
+
public static void handleUpdate(AccountChangeEvent event, List<String> changedFields) {
|
|
567
|
+
// Extract data
|
|
568
|
+
String recordId = event.ChangeEventHeader.getRecordIds()[0];
|
|
569
|
+
String accountName = event.Name;
|
|
570
|
+
|
|
571
|
+
// Queue async callout to external CRM
|
|
572
|
+
Map<String, Object> payload = new Map<String, Object>{
|
|
573
|
+
'salesforceId' => recordId,
|
|
574
|
+
'name' => accountName,
|
|
575
|
+
'changedFields' => changedFields,
|
|
576
|
+
'timestamp' => event.ChangeEventHeader.getCommitTimestamp()
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
System.enqueueJob(new CRMSyncQueueable(payload));
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### Event Replay with Stored ReplayId
|
|
585
|
+
|
|
586
|
+
```apex
|
|
587
|
+
public with sharing class EventReplayService {
|
|
588
|
+
|
|
589
|
+
@future(callout=true)
|
|
590
|
+
public static void replayFromLastCheckpoint(String eventChannel) {
|
|
591
|
+
// Get last stored replay ID
|
|
592
|
+
Event_Checkpoint__c checkpoint = [
|
|
593
|
+
SELECT ReplayId__c
|
|
594
|
+
FROM Event_Checkpoint__c
|
|
595
|
+
WHERE Channel__c = :eventChannel
|
|
596
|
+
LIMIT 1
|
|
597
|
+
];
|
|
598
|
+
|
|
599
|
+
if (checkpoint != null) {
|
|
600
|
+
// Use stored replay ID to resume from last successful event
|
|
601
|
+
// Note: Replay is typically done via API/streaming API, not Apex
|
|
602
|
+
System.debug('Last replay ID: ' + checkpoint.ReplayId__c);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
public static void storeCheckpoint(String channel, String replayId) {
|
|
607
|
+
Event_Checkpoint__c checkpoint = new Event_Checkpoint__c(
|
|
608
|
+
Channel__c = channel,
|
|
609
|
+
ReplayId__c = replayId,
|
|
610
|
+
Last_Updated__c = DateTime.now()
|
|
611
|
+
);
|
|
612
|
+
upsert checkpoint Channel__c;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### Error Handling with Dead Letter Queue
|
|
618
|
+
|
|
619
|
+
```apex
|
|
620
|
+
trigger OrderEventSubscriber on Order_Status__e (after insert) {
|
|
621
|
+
for (Order_Status__e event : Trigger.new) {
|
|
622
|
+
try {
|
|
623
|
+
OrderEventHandler.processEvent(event);
|
|
624
|
+
} catch (Exception e) {
|
|
625
|
+
// Log to dead letter queue for manual review
|
|
626
|
+
Event_Error_Log__c errorLog = new Event_Error_Log__c(
|
|
627
|
+
Event_Type__c = 'Order_Status__e',
|
|
628
|
+
Replay_Id__c = event.ReplayId,
|
|
629
|
+
Error_Message__c = e.getMessage(),
|
|
630
|
+
Event_Payload__c = JSON.serialize(event),
|
|
631
|
+
Occurred_At__c = DateTime.now()
|
|
632
|
+
);
|
|
633
|
+
insert as user errorLog;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
641
|
+
## Best Practices
|
|
642
|
+
|
|
643
|
+
### Platform Events
|
|
644
|
+
|
|
645
|
+
1. **Batch Publishing**: Publish events in batches (up to 2,000 per transaction)
|
|
646
|
+
2. **Idempotent Subscribers**: Design subscribers to handle duplicate events (especially for high-volume)
|
|
647
|
+
3. **ReplayId Tracking**: Store ReplayIds for resume capability
|
|
648
|
+
4. **Error Isolation**: Catch exceptions in subscriber loops to process remaining events
|
|
649
|
+
5. **Resume Checkpoints**: Use `setResumeCheckpoint()` for high-volume events
|
|
650
|
+
|
|
651
|
+
### Change Data Capture
|
|
652
|
+
|
|
653
|
+
1. **Field Filtering**: Only process relevant field changes to reduce processing overhead
|
|
654
|
+
2. **Async Processing**: Use Queueable/Future for callouts or long-running operations
|
|
655
|
+
3. **ChangeType Routing**: Use switch statements for different change types
|
|
656
|
+
4. **RecordIds Array**: Handle multiple RecordIds (CDC can batch related changes)
|
|
657
|
+
5. **Commit Metadata**: Use `getCommitTimestamp()` and `getCommitUser()` for audit trails
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
## Governor Limits
|
|
662
|
+
|
|
663
|
+
| Limit | Value | Notes |
|
|
664
|
+
|-------|-------|-------|
|
|
665
|
+
| Platform Events published/transaction | 2,000 | Both Standard and High-Volume |
|
|
666
|
+
| Platform Event delivery | Asynchronous | Delivered to subscribers after commit |
|
|
667
|
+
| CDC events/hour (per object) | 250,000 | Auto-throttled if exceeded |
|
|
668
|
+
| Event message size | 1 MB | Total size of all fields |
|
|
669
|
+
| Event retention (Standard) | 3 days | ReplayId available for 72 hours |
|
|
670
|
+
| Event retention (High-Volume) | 24 hours | ReplayId available for 24 hours |
|
|
671
|
+
|
|
672
|
+
---
|
|
673
|
+
|
|
674
|
+
## Testing Event-Driven Integrations
|
|
675
|
+
|
|
676
|
+
### Platform Event Test
|
|
677
|
+
|
|
678
|
+
```apex
|
|
679
|
+
@isTest
|
|
680
|
+
private class OrderEventTest {
|
|
681
|
+
|
|
682
|
+
@isTest
|
|
683
|
+
static void testEventPublish() {
|
|
684
|
+
Test.startTest();
|
|
685
|
+
|
|
686
|
+
Order_Status__e event = new Order_Status__e(
|
|
687
|
+
RecordId__c = '006xx000000XXXAAA',
|
|
688
|
+
Status__c = 'Completed'
|
|
689
|
+
);
|
|
690
|
+
Database.SaveResult sr = EventBus.publish(event);
|
|
691
|
+
|
|
692
|
+
Test.stopTest();
|
|
693
|
+
|
|
694
|
+
System.assert(sr.isSuccess(), 'Event should publish successfully');
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
@isTest
|
|
698
|
+
static void testEventSubscriber() {
|
|
699
|
+
// Subscriber triggers execute synchronously in tests
|
|
700
|
+
Test.startTest();
|
|
701
|
+
|
|
702
|
+
Order_Status__e event = new Order_Status__e(
|
|
703
|
+
RecordId__c = '006xx000000XXXAAA',
|
|
704
|
+
Status__c = 'Completed'
|
|
705
|
+
);
|
|
706
|
+
EventBus.publish(event);
|
|
707
|
+
|
|
708
|
+
Test.stopTest();
|
|
709
|
+
|
|
710
|
+
// Verify subscriber logic executed
|
|
711
|
+
// (check that handler updated related records)
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### CDC Test
|
|
717
|
+
|
|
718
|
+
```apex
|
|
719
|
+
@isTest
|
|
720
|
+
private class AccountCDCTest {
|
|
721
|
+
|
|
722
|
+
@isTest
|
|
723
|
+
static void testAccountUpdate() {
|
|
724
|
+
Account acc = new Account(Name = 'Test Account');
|
|
725
|
+
insert acc;
|
|
726
|
+
|
|
727
|
+
Test.startTest();
|
|
728
|
+
|
|
729
|
+
acc.BillingCity = 'San Francisco';
|
|
730
|
+
update acc;
|
|
731
|
+
|
|
732
|
+
Test.stopTest();
|
|
733
|
+
|
|
734
|
+
// CDC events don't fire in test context
|
|
735
|
+
// Must test handler methods directly
|
|
736
|
+
AccountChangeEvent mockEvent = new AccountChangeEvent();
|
|
737
|
+
// Note: Can't instantiate ChangeEvent in Apex
|
|
738
|
+
// Test handler logic with mock data instead
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
---
|
|
744
|
+
|
|
745
|
+
## Pub/Sub API (Recommended for External Consumers)
|
|
746
|
+
|
|
747
|
+
The Pub/Sub API is the **recommended mechanism** for external systems subscribing to Platform Events and CDC events. It replaces the legacy Streaming API (CometD).
|
|
748
|
+
|
|
749
|
+
### Why Pub/Sub API
|
|
750
|
+
|
|
751
|
+
| Feature | Pub/Sub API | Legacy Streaming API |
|
|
752
|
+
|---------|-------------|---------------------|
|
|
753
|
+
| **Protocol** | gRPC (binary, high performance) | CometD (long-polling, HTTP overhead) |
|
|
754
|
+
| **Authentication** | OAuth 2.0 | Session-based |
|
|
755
|
+
| **Event Types** | Platform Events, CDC, Custom Channels | PushTopic, Generic Events |
|
|
756
|
+
| **Status** | **Current** | **Deprecated — no new investments** |
|
|
757
|
+
|
|
758
|
+
### Subscription Modes
|
|
759
|
+
|
|
760
|
+
- **Subscribe**: Stream events from a given replay ID forward
|
|
761
|
+
- **PublishStream**: Bi-directional — publish events via gRPC
|
|
762
|
+
- **ManagedSubscribe**: Salesforce manages replay state (simplest)
|
|
763
|
+
|
|
764
|
+
### LWC Internal Subscription
|
|
765
|
+
|
|
766
|
+
For Lightning Web Components, use the `empApi` module:
|
|
767
|
+
|
|
768
|
+
```javascript
|
|
769
|
+
import { subscribe, unsubscribe, onError } from 'lightning/empApi';
|
|
770
|
+
|
|
771
|
+
connectedCallback() {
|
|
772
|
+
subscribe('/event/Order_Status__e', -1, (response) => {
|
|
773
|
+
this.handleEvent(response.data.payload);
|
|
774
|
+
}).then((sub) => { this.subscription = sub; });
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
disconnectedCallback() {
|
|
778
|
+
unsubscribe(this.subscription);
|
|
779
|
+
}
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
> **Note**: `empApi` uses CometD internally but is the supported LWC API. For external consumers, always use the gRPC-based Pub/Sub API.
|
|
783
|
+
|
|
784
|
+
---
|
|
785
|
+
|
|
786
|
+
## Platform Event Anti-Patterns
|
|
787
|
+
|
|
788
|
+
### 1. Publishing from Trigger on Same Event Object → Infinite Loop
|
|
789
|
+
|
|
790
|
+
```apex
|
|
791
|
+
// ❌ WRONG: Trigger on Order_Status__e publishes Order_Status__e
|
|
792
|
+
trigger OrderStatusSubscriber on Order_Status__e (after insert) {
|
|
793
|
+
for (Order_Status__e event : Trigger.new) {
|
|
794
|
+
// This creates an infinite loop!
|
|
795
|
+
EventBus.publish(new Order_Status__e(Status__c = 'Processed'));
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
**Fix**: Never publish the same event type from its own subscriber trigger. Use a different event type or update a record instead.
|
|
801
|
+
|
|
802
|
+
### 2. PublishImmediately When Data Integrity Matters
|
|
803
|
+
|
|
804
|
+
```apex
|
|
805
|
+
// ❌ WRONG: Event fires even if the transaction rolls back
|
|
806
|
+
Order_Status__e event = new Order_Status__e();
|
|
807
|
+
event.Status__c = 'Completed';
|
|
808
|
+
// publishBehavior = PublishImmediately in event definition
|
|
809
|
+
EventBus.publish(event);
|
|
810
|
+
|
|
811
|
+
// If subsequent DML fails, the event was already published
|
|
812
|
+
// External system thinks order is "Completed" but it's not
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
**Fix**: Use `PublishAfterCommit` (the default) when the event represents a state change that depends on the transaction succeeding.
|
|
816
|
+
|
|
817
|
+
### 3. Using Platform Events for Synchronous-Style Flow Orchestration
|
|
818
|
+
|
|
819
|
+
```
|
|
820
|
+
// ❌ WRONG: Using events to simulate synchronous request/response
|
|
821
|
+
Flow A → Publish "Request" Event → Subscriber triggers Flow B → Publish "Response" Event → ???
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
**Fix**: Platform Events are asynchronous and unordered. For synchronous orchestration, use Subflows, @InvocableMethod, or direct Apex calls. Events are for decoupled, fire-and-forget communication.
|
|
825
|
+
|
|
826
|
+
### 4. Oversized Event Payloads
|
|
827
|
+
|
|
828
|
+
> **1 MB message size limit.** Balance payload size — smaller = faster delivery, larger = fewer API calls. Include record IDs and essential context; let consumers query Salesforce for full records if needed.
|
|
829
|
+
|
|
830
|
+
---
|
|
831
|
+
|
|
832
|
+
## Related Resources
|
|
833
|
+
|
|
834
|
+
- [Callout Patterns](./callout-patterns.md) - REST and SOAP callout implementations
|
|
835
|
+
- [Event-Driven Architecture Guide](./event-driven-architecture-guide.md) - EDA patterns, Pub/Sub API deep dive, monitoring
|
|
836
|
+
- [Main Skill Documentation](../SKILL.md) - building-sf-integrations overview
|
|
837
|
+
- [Platform Event Templates](../assets/platform-events/) - Event definitions and triggers
|
|
838
|
+
- [CDC Templates](../assets/cdc/) - Change Data Capture triggers
|