@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,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DML IN LOOP FIX PATTERN
|
|
3
|
+
*
|
|
4
|
+
* Problem: DML operations inside loops consume governor limits rapidly
|
|
5
|
+
* Detection: DEBUG LOG shows repeated DML_BEGIN entries
|
|
6
|
+
* Limits:
|
|
7
|
+
* - 150 DML statements per transaction
|
|
8
|
+
* - 10,000 DML rows per transaction
|
|
9
|
+
*
|
|
10
|
+
* This template demonstrates the collection pattern to fix DML in loops.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
14
|
+
// BEFORE: DML IN LOOP (PROBLEMATIC)
|
|
15
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
16
|
+
|
|
17
|
+
public class ContactService_BEFORE {
|
|
18
|
+
|
|
19
|
+
// This method will fail if accounts.size() > 150
|
|
20
|
+
public void createContactsForAccounts(List<Account> accounts) {
|
|
21
|
+
for (Account acc : accounts) {
|
|
22
|
+
// DML inside loop - each iteration uses 1 DML statement
|
|
23
|
+
Contact c = new Contact(
|
|
24
|
+
FirstName = 'Primary',
|
|
25
|
+
LastName = 'Contact',
|
|
26
|
+
AccountId = acc.Id,
|
|
27
|
+
Email = acc.Name.replaceAll(' ', '') + '@example.com'
|
|
28
|
+
);
|
|
29
|
+
insert c; // DML in loop!
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Updates in loop - also problematic
|
|
34
|
+
public void updateAccountStatuses(List<Account> accounts, String newStatus) {
|
|
35
|
+
for (Account acc : accounts) {
|
|
36
|
+
acc.Status__c = newStatus;
|
|
37
|
+
update acc; // DML in loop!
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
43
|
+
// AFTER: COLLECTION PATTERN (CORRECT)
|
|
44
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
45
|
+
|
|
46
|
+
public class ContactService_AFTER {
|
|
47
|
+
|
|
48
|
+
// This method uses only 1 DML statement regardless of accounts.size()
|
|
49
|
+
public void createContactsForAccounts(List<Account> accounts) {
|
|
50
|
+
// Step 1: Build list of records to insert
|
|
51
|
+
List<Contact> contactsToInsert = new List<Contact>();
|
|
52
|
+
|
|
53
|
+
for (Account acc : accounts) {
|
|
54
|
+
Contact c = new Contact(
|
|
55
|
+
FirstName = 'Primary',
|
|
56
|
+
LastName = 'Contact',
|
|
57
|
+
AccountId = acc.Id,
|
|
58
|
+
Email = acc.Name.replaceAll(' ', '') + '@example.com'
|
|
59
|
+
);
|
|
60
|
+
contactsToInsert.add(c); // Add to list, no DML
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Step 2: Single DML statement AFTER the loop
|
|
64
|
+
if (!contactsToInsert.isEmpty()) {
|
|
65
|
+
insert contactsToInsert;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Updates outside loop - correct pattern
|
|
70
|
+
public void updateAccountStatuses(List<Account> accounts, String newStatus) {
|
|
71
|
+
// Modify in loop (no DML)
|
|
72
|
+
for (Account acc : accounts) {
|
|
73
|
+
acc.Status__c = newStatus;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Single DML after loop
|
|
77
|
+
if (!accounts.isEmpty()) {
|
|
78
|
+
update accounts;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
84
|
+
// ADVANCED: MIXED INSERT/UPDATE/DELETE PATTERN
|
|
85
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
86
|
+
|
|
87
|
+
public class RecordProcessor_Bulkified {
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Process records with conditional insert/update/delete
|
|
91
|
+
* Uses collections for all DML operations
|
|
92
|
+
*/
|
|
93
|
+
public void processRecords(List<Account> accounts) {
|
|
94
|
+
// Collections for different DML operations
|
|
95
|
+
List<Contact> contactsToInsert = new List<Contact>();
|
|
96
|
+
List<Contact> contactsToUpdate = new List<Contact>();
|
|
97
|
+
List<Contact> contactsToDelete = new List<Contact>();
|
|
98
|
+
|
|
99
|
+
// Query existing contacts once
|
|
100
|
+
Set<Id> accountIds = new Set<Id>();
|
|
101
|
+
for (Account acc : accounts) {
|
|
102
|
+
accountIds.add(acc.Id);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
Map<Id, Contact> existingContacts = new Map<Id, Contact>();
|
|
106
|
+
for (Contact c : [
|
|
107
|
+
SELECT Id, AccountId, Email, IsInactive__c
|
|
108
|
+
FROM Contact
|
|
109
|
+
WHERE AccountId IN :accountIds
|
|
110
|
+
]) {
|
|
111
|
+
existingContacts.put(c.AccountId, c);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Process and categorize
|
|
115
|
+
for (Account acc : accounts) {
|
|
116
|
+
Contact existing = existingContacts.get(acc.Id);
|
|
117
|
+
|
|
118
|
+
if (existing == null) {
|
|
119
|
+
// No contact exists - INSERT
|
|
120
|
+
contactsToInsert.add(new Contact(
|
|
121
|
+
FirstName = 'Auto',
|
|
122
|
+
LastName = 'Generated',
|
|
123
|
+
AccountId = acc.Id
|
|
124
|
+
));
|
|
125
|
+
} else if (existing.IsInactive__c) {
|
|
126
|
+
// Inactive contact - DELETE
|
|
127
|
+
contactsToDelete.add(existing);
|
|
128
|
+
} else {
|
|
129
|
+
// Active contact - UPDATE
|
|
130
|
+
existing.LastActivityDate__c = Date.today();
|
|
131
|
+
contactsToUpdate.add(existing);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Execute DML operations (3 statements max, regardless of record count)
|
|
136
|
+
if (!contactsToInsert.isEmpty()) {
|
|
137
|
+
insert contactsToInsert;
|
|
138
|
+
}
|
|
139
|
+
if (!contactsToUpdate.isEmpty()) {
|
|
140
|
+
update contactsToUpdate;
|
|
141
|
+
}
|
|
142
|
+
if (!contactsToDelete.isEmpty()) {
|
|
143
|
+
delete contactsToDelete;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
149
|
+
// PATTERN: UPSERT FOR INSERT-OR-UPDATE LOGIC
|
|
150
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
151
|
+
|
|
152
|
+
public class UpsertPatternService {
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* When you need to insert if not exists, update if exists
|
|
156
|
+
* Use UPSERT with an External ID field
|
|
157
|
+
*/
|
|
158
|
+
public void syncExternalContacts(List<ExternalContact> externalData) {
|
|
159
|
+
List<Contact> contactsToUpsert = new List<Contact>();
|
|
160
|
+
|
|
161
|
+
for (ExternalContact ext : externalData) {
|
|
162
|
+
Contact c = new Contact(
|
|
163
|
+
External_Id__c = ext.id, // External ID field
|
|
164
|
+
FirstName = ext.firstName,
|
|
165
|
+
LastName = ext.lastName,
|
|
166
|
+
Email = ext.email
|
|
167
|
+
);
|
|
168
|
+
contactsToUpsert.add(c);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Single upsert handles both insert and update
|
|
172
|
+
if (!contactsToUpsert.isEmpty()) {
|
|
173
|
+
upsert contactsToUpsert External_Id__c;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Wrapper class for external data
|
|
178
|
+
public class ExternalContact {
|
|
179
|
+
public String id;
|
|
180
|
+
public String firstName;
|
|
181
|
+
public String lastName;
|
|
182
|
+
public String email;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
187
|
+
// PATTERN: PARTIAL SUCCESS HANDLING
|
|
188
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
189
|
+
|
|
190
|
+
public class PartialSuccessService {
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Handle partial failures gracefully
|
|
194
|
+
* Use Database.insert with allOrNone = false
|
|
195
|
+
*/
|
|
196
|
+
public List<Database.SaveResult> insertWithPartialSuccess(List<Contact> contacts) {
|
|
197
|
+
if (contacts.isEmpty()) {
|
|
198
|
+
return new List<Database.SaveResult>();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// allOrNone = false allows partial success
|
|
202
|
+
List<Database.SaveResult> results = Database.insert(contacts, false);
|
|
203
|
+
|
|
204
|
+
// Log failures for analysis
|
|
205
|
+
for (Integer i = 0; i < results.size(); i++) {
|
|
206
|
+
Database.SaveResult sr = results[i];
|
|
207
|
+
if (!sr.isSuccess()) {
|
|
208
|
+
for (Database.Error err : sr.getErrors()) {
|
|
209
|
+
System.debug(LoggingLevel.ERROR,
|
|
210
|
+
'Failed to insert contact: ' + contacts[i] +
|
|
211
|
+
' Error: ' + err.getMessage()
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return results;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NULL POINTER EXCEPTION FIX PATTERNS
|
|
3
|
+
*
|
|
4
|
+
* Problem: System.NullPointerException when accessing null object properties
|
|
5
|
+
* Detection: DEBUG LOG shows EXCEPTION_THROWN|NullPointerException
|
|
6
|
+
*
|
|
7
|
+
* This template demonstrates null-safe coding patterns.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
11
|
+
// PATTERN 1: SOQL QUERY RETURNING NO RESULTS
|
|
12
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
13
|
+
|
|
14
|
+
public class QueryNullSafety {
|
|
15
|
+
|
|
16
|
+
// BEFORE: Dangerous - throws exception if no results
|
|
17
|
+
public String getAccountNameUNSAFE(Id accountId) {
|
|
18
|
+
Account acc = [SELECT Name FROM Account WHERE Id = :accountId];
|
|
19
|
+
return acc.Name; // NullPointerException if query returns nothing!
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// AFTER: Safe - using List and isEmpty check
|
|
23
|
+
public String getAccountNameSAFE(Id accountId) {
|
|
24
|
+
List<Account> accounts = [SELECT Name FROM Account WHERE Id = :accountId LIMIT 1];
|
|
25
|
+
|
|
26
|
+
if (accounts.isEmpty()) {
|
|
27
|
+
return null; // Or throw custom exception, or return default
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return accounts[0].Name;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// AFTER: Safe - using Safe Navigation Operator (API 62.0+)
|
|
34
|
+
public String getAccountNameSafeNav(Id accountId) {
|
|
35
|
+
Account acc = [SELECT Name FROM Account WHERE Id = :accountId LIMIT 1];
|
|
36
|
+
return acc?.Name; // Returns null instead of throwing exception
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// AFTER: With default value
|
|
40
|
+
public String getAccountNameWithDefault(Id accountId, String defaultName) {
|
|
41
|
+
List<Account> accounts = [SELECT Name FROM Account WHERE Id = :accountId LIMIT 1];
|
|
42
|
+
return accounts.isEmpty() ? defaultName : accounts[0].Name;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
47
|
+
// PATTERN 2: MAP ACCESS
|
|
48
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
49
|
+
|
|
50
|
+
public class MapNullSafety {
|
|
51
|
+
|
|
52
|
+
// BEFORE: Dangerous - Map.get() returns null for missing keys
|
|
53
|
+
public void processAccountUNSAFE(Map<Id, Account> accountMap, Id targetId) {
|
|
54
|
+
Account acc = accountMap.get(targetId);
|
|
55
|
+
String name = acc.Name; // NullPointerException if targetId not in map!
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// AFTER: Check containsKey first
|
|
59
|
+
public void processAccountSAFE(Map<Id, Account> accountMap, Id targetId) {
|
|
60
|
+
if (accountMap.containsKey(targetId)) {
|
|
61
|
+
Account acc = accountMap.get(targetId);
|
|
62
|
+
String name = acc.Name;
|
|
63
|
+
// Process...
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// AFTER: Check for null after get
|
|
68
|
+
public void processAccountNullCheck(Map<Id, Account> accountMap, Id targetId) {
|
|
69
|
+
Account acc = accountMap.get(targetId);
|
|
70
|
+
if (acc != null) {
|
|
71
|
+
String name = acc.Name;
|
|
72
|
+
// Process...
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// AFTER: Safe navigation (API 62.0+)
|
|
77
|
+
public String getAccountNameFromMap(Map<Id, Account> accountMap, Id targetId) {
|
|
78
|
+
return accountMap.get(targetId)?.Name;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
83
|
+
// PATTERN 3: RELATIONSHIP FIELDS
|
|
84
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
85
|
+
|
|
86
|
+
public class RelationshipNullSafety {
|
|
87
|
+
|
|
88
|
+
// BEFORE: Dangerous - parent record might be null
|
|
89
|
+
public String getOwnerEmailUNSAFE(Contact c) {
|
|
90
|
+
return c.Account.Owner.Email; // Multiple potential null points!
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// AFTER: Check each level
|
|
94
|
+
public String getOwnerEmailSAFE(Contact c) {
|
|
95
|
+
if (c == null) return null;
|
|
96
|
+
if (c.Account == null) return null;
|
|
97
|
+
if (c.Account.Owner == null) return null;
|
|
98
|
+
return c.Account.Owner.Email;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// AFTER: Safe navigation chain (API 62.0+)
|
|
102
|
+
public String getOwnerEmailSafeNav(Contact c) {
|
|
103
|
+
return c?.Account?.Owner?.Email;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// AFTER: With default value
|
|
107
|
+
public String getOwnerEmailWithDefault(Contact c, String defaultEmail) {
|
|
108
|
+
String email = c?.Account?.Owner?.Email;
|
|
109
|
+
return String.isBlank(email) ? defaultEmail : email;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
114
|
+
// PATTERN 4: LIST ACCESS
|
|
115
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
116
|
+
|
|
117
|
+
public class ListNullSafety {
|
|
118
|
+
|
|
119
|
+
// BEFORE: Dangerous - list might be null or empty
|
|
120
|
+
public Contact getFirstContactUNSAFE(List<Contact> contacts) {
|
|
121
|
+
return contacts[0]; // IndexOutOfBoundsException if empty!
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// AFTER: Check null and empty
|
|
125
|
+
public Contact getFirstContactSAFE(List<Contact> contacts) {
|
|
126
|
+
if (contacts == null || contacts.isEmpty()) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
return contacts[0];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Pattern: Null-safe iteration
|
|
133
|
+
public void processContactsSAFE(List<Contact> contacts) {
|
|
134
|
+
// This is safe - for loop on null list doesn't execute
|
|
135
|
+
for (Contact c : contacts ?? new List<Contact>()) {
|
|
136
|
+
// Process contact
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Alternative: Early return
|
|
141
|
+
public void processContactsEarlyReturn(List<Contact> contacts) {
|
|
142
|
+
if (contacts == null || contacts.isEmpty()) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (Contact c : contacts) {
|
|
147
|
+
// Process contact
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
153
|
+
// PATTERN 5: STRING OPERATIONS
|
|
154
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
155
|
+
|
|
156
|
+
public class StringNullSafety {
|
|
157
|
+
|
|
158
|
+
// BEFORE: Dangerous - string might be null
|
|
159
|
+
public Boolean containsKeywordUNSAFE(String text, String keyword) {
|
|
160
|
+
return text.contains(keyword); // NullPointerException if text is null!
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// AFTER: Use String.isNotBlank() or String.isBlank()
|
|
164
|
+
public Boolean containsKeywordSAFE(String text, String keyword) {
|
|
165
|
+
if (String.isBlank(text) || String.isBlank(keyword)) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return text.contains(keyword);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Pattern: Null-safe string comparison
|
|
172
|
+
public Boolean isEqualSAFE(String a, String b) {
|
|
173
|
+
// Both null = equal
|
|
174
|
+
if (a == null && b == null) return true;
|
|
175
|
+
// One null = not equal
|
|
176
|
+
if (a == null || b == null) return false;
|
|
177
|
+
// Both non-null = compare
|
|
178
|
+
return a.equals(b);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Pattern: Default value for null strings
|
|
182
|
+
public String getNameWithDefault(Account acc) {
|
|
183
|
+
return String.isBlank(acc?.Name) ? 'Unnamed Account' : acc.Name;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
188
|
+
// PATTERN 6: TRIGGER CONTEXT
|
|
189
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
190
|
+
|
|
191
|
+
public class TriggerNullSafety {
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* In triggers, old values might not exist (insert)
|
|
195
|
+
* and new values might not exist (delete)
|
|
196
|
+
*/
|
|
197
|
+
public void handleTrigger() {
|
|
198
|
+
// Safe: Check context first
|
|
199
|
+
if (Trigger.isInsert) {
|
|
200
|
+
// Trigger.old is null in insert context
|
|
201
|
+
for (Account acc : (List<Account>)Trigger.new) {
|
|
202
|
+
// Process new records
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (Trigger.isUpdate) {
|
|
207
|
+
Map<Id, Account> oldMap = (Map<Id, Account>)Trigger.oldMap;
|
|
208
|
+
for (Account newAcc : (List<Account>)Trigger.new) {
|
|
209
|
+
Account oldAcc = oldMap.get(newAcc.Id);
|
|
210
|
+
// Both old and new are available
|
|
211
|
+
if (oldAcc.Status__c != newAcc.Status__c) {
|
|
212
|
+
// Status changed
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (Trigger.isDelete) {
|
|
218
|
+
// Trigger.new is null in delete context
|
|
219
|
+
for (Account acc : (List<Account>)Trigger.old) {
|
|
220
|
+
// Process deleted records
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
227
|
+
// ANTI-PATTERN: OVER-DEFENSIVE CODING
|
|
228
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
229
|
+
|
|
230
|
+
public class OverDefensiveCoding {
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Don't check for null when it's impossible
|
|
234
|
+
* This adds unnecessary code and cognitive load
|
|
235
|
+
*/
|
|
236
|
+
|
|
237
|
+
// UNNECESSARY: Trigger.new is never null in insert/update context
|
|
238
|
+
public void badExample() {
|
|
239
|
+
if (Trigger.new != null && !Trigger.new.isEmpty()) {
|
|
240
|
+
for (SObject record : Trigger.new) {
|
|
241
|
+
// Trigger.new is guaranteed non-null in before/after insert/update
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// CORRECT: Trust the platform guarantees
|
|
247
|
+
public void goodExample() {
|
|
248
|
+
for (Account acc : (List<Account>)Trigger.new) {
|
|
249
|
+
// Just use it - Trigger.new is guaranteed in this context
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SOQL IN LOOP FIX PATTERN
|
|
3
|
+
*
|
|
4
|
+
* Problem: SOQL queries inside loops consume governor limits rapidly
|
|
5
|
+
* Detection: DEBUG LOG shows repeated SOQL_EXECUTE_BEGIN entries
|
|
6
|
+
* Limit: 100 SOQL queries per synchronous transaction
|
|
7
|
+
*
|
|
8
|
+
* This template demonstrates the bulkification pattern to fix SOQL in loops.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
12
|
+
// BEFORE: SOQL IN LOOP (PROBLEMATIC)
|
|
13
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
14
|
+
|
|
15
|
+
public class AccountService_BEFORE {
|
|
16
|
+
|
|
17
|
+
// This method will fail if accounts.size() > 100
|
|
18
|
+
public void processAccounts(List<Account> accounts) {
|
|
19
|
+
for (Account acc : accounts) {
|
|
20
|
+
// SOQL inside loop - each iteration uses 1 query
|
|
21
|
+
Contact primaryContact = [
|
|
22
|
+
SELECT Id, Email, Phone
|
|
23
|
+
FROM Contact
|
|
24
|
+
WHERE AccountId = :acc.Id
|
|
25
|
+
AND IsPrimary__c = true
|
|
26
|
+
LIMIT 1
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
if (primaryContact != null) {
|
|
30
|
+
acc.Primary_Contact_Email__c = primaryContact.Email;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
37
|
+
// AFTER: BULKIFIED PATTERN (CORRECT)
|
|
38
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
39
|
+
|
|
40
|
+
public class AccountService_AFTER {
|
|
41
|
+
|
|
42
|
+
// This method uses only 1 SOQL query regardless of accounts.size()
|
|
43
|
+
public void processAccounts(List<Account> accounts) {
|
|
44
|
+
// Step 1: Collect all Account IDs
|
|
45
|
+
Set<Id> accountIds = new Set<Id>();
|
|
46
|
+
for (Account acc : accounts) {
|
|
47
|
+
accountIds.add(acc.Id);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Step 2: Single SOQL query BEFORE the loop
|
|
51
|
+
Map<Id, Contact> primaryContactsByAccountId = new Map<Id, Contact>();
|
|
52
|
+
for (Contact c : [
|
|
53
|
+
SELECT Id, Email, Phone, AccountId
|
|
54
|
+
FROM Contact
|
|
55
|
+
WHERE AccountId IN :accountIds
|
|
56
|
+
AND IsPrimary__c = true
|
|
57
|
+
]) {
|
|
58
|
+
primaryContactsByAccountId.put(c.AccountId, c);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Step 3: Access from Map inside loop (no SOQL)
|
|
62
|
+
for (Account acc : accounts) {
|
|
63
|
+
Contact primaryContact = primaryContactsByAccountId.get(acc.Id);
|
|
64
|
+
if (primaryContact != null) {
|
|
65
|
+
acc.Primary_Contact_Email__c = primaryContact.Email;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
72
|
+
// ADVANCED: NESTED RELATIONSHIP PATTERN
|
|
73
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
74
|
+
|
|
75
|
+
public class OrderService_Bulkified {
|
|
76
|
+
|
|
77
|
+
// Complex scenario: Orders → Accounts → Contacts
|
|
78
|
+
public void processOrders(List<Order> orders) {
|
|
79
|
+
// Collect all Account IDs from Orders
|
|
80
|
+
Set<Id> accountIds = new Set<Id>();
|
|
81
|
+
for (Order o : orders) {
|
|
82
|
+
if (o.AccountId != null) {
|
|
83
|
+
accountIds.add(o.AccountId);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Query Accounts with related Contacts in ONE query (relationship query)
|
|
88
|
+
Map<Id, Account> accountsWithContacts = new Map<Id, Account>([
|
|
89
|
+
SELECT Id, Name,
|
|
90
|
+
(SELECT Id, Email FROM Contacts WHERE IsPrimary__c = true LIMIT 1)
|
|
91
|
+
FROM Account
|
|
92
|
+
WHERE Id IN :accountIds
|
|
93
|
+
]);
|
|
94
|
+
|
|
95
|
+
// Process orders using the pre-queried data
|
|
96
|
+
for (Order o : orders) {
|
|
97
|
+
Account acc = accountsWithContacts.get(o.AccountId);
|
|
98
|
+
if (acc != null && !acc.Contacts.isEmpty()) {
|
|
99
|
+
o.Notification_Email__c = acc.Contacts[0].Email;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
106
|
+
// PATTERN: MAP FACTORY FOR REUSABLE QUERIES
|
|
107
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
108
|
+
|
|
109
|
+
public class ContactQueryService {
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Factory method to get primary contacts by Account ID
|
|
113
|
+
* Reusable across multiple services
|
|
114
|
+
*/
|
|
115
|
+
public static Map<Id, Contact> getPrimaryContactsByAccountId(Set<Id> accountIds) {
|
|
116
|
+
Map<Id, Contact> result = new Map<Id, Contact>();
|
|
117
|
+
|
|
118
|
+
if (accountIds.isEmpty()) {
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
for (Contact c : [
|
|
123
|
+
SELECT Id, FirstName, LastName, Email, Phone, AccountId
|
|
124
|
+
FROM Contact
|
|
125
|
+
WHERE AccountId IN :accountIds
|
|
126
|
+
AND IsPrimary__c = true
|
|
127
|
+
]) {
|
|
128
|
+
result.put(c.AccountId, c);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get all contacts grouped by Account ID
|
|
136
|
+
* Returns Map<AccountId, List<Contact>>
|
|
137
|
+
*/
|
|
138
|
+
public static Map<Id, List<Contact>> getContactsGroupedByAccount(Set<Id> accountIds) {
|
|
139
|
+
Map<Id, List<Contact>> result = new Map<Id, List<Contact>>();
|
|
140
|
+
|
|
141
|
+
// Initialize empty lists for all accounts
|
|
142
|
+
for (Id accId : accountIds) {
|
|
143
|
+
result.put(accId, new List<Contact>());
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (Contact c : [
|
|
147
|
+
SELECT Id, FirstName, LastName, Email, Phone, AccountId
|
|
148
|
+
FROM Contact
|
|
149
|
+
WHERE AccountId IN :accountIds
|
|
150
|
+
ORDER BY CreatedDate DESC
|
|
151
|
+
]) {
|
|
152
|
+
result.get(c.AccountId).add(c);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Debug Analysis Playbook
|
|
2
|
+
|
|
3
|
+
Use this playbook when `debugging-apex-logs` is active and you need the expanded workflow.
|
|
4
|
+
|
|
5
|
+
## 1. Gather context
|
|
6
|
+
|
|
7
|
+
Collect:
|
|
8
|
+
- org alias
|
|
9
|
+
- failing transaction or test context
|
|
10
|
+
- approximate time window
|
|
11
|
+
- relevant user / record / request identifiers
|
|
12
|
+
|
|
13
|
+
## 2. Retrieve logs
|
|
14
|
+
|
|
15
|
+
Preferred commands:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
sf apex list log --target-org <alias> --json
|
|
19
|
+
sf apex get log --log-id <id> --target-org <alias>
|
|
20
|
+
sf apex tail log --target-org <alias> --color
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
See [cli-commands.md](cli-commands.md) for more options.
|
|
24
|
+
|
|
25
|
+
## 3. Analyze in this order
|
|
26
|
+
|
|
27
|
+
1. transaction entry point
|
|
28
|
+
2. exceptions and fatal errors
|
|
29
|
+
3. governor limits
|
|
30
|
+
4. SOQL / DML repetition patterns
|
|
31
|
+
5. CPU / heap hotspots
|
|
32
|
+
6. callout timing and external failures
|
|
33
|
+
|
|
34
|
+
## 4. Classify severity
|
|
35
|
+
|
|
36
|
+
- **Critical** — runtime failure, hard limit, data corruption risk
|
|
37
|
+
- **Warning** — near-limit, non-selective query, slow path
|
|
38
|
+
- **Info** — optimization opportunity, cleanup item, observability gap
|
|
39
|
+
|
|
40
|
+
## 5. Propose fixes
|
|
41
|
+
|
|
42
|
+
Prefer fixes that are:
|
|
43
|
+
- root-cause oriented
|
|
44
|
+
- bulk-safe
|
|
45
|
+
- testable
|
|
46
|
+
- deployable in one clean change set
|
|
47
|
+
|
|
48
|
+
## 6. Loop with adjacent skills
|
|
49
|
+
|
|
50
|
+
- use `sf-apex` for code fixes
|
|
51
|
+
- use `running-apex-tests` to reproduce and verify
|
|
52
|
+
- use `deploying-metadata` to deploy fixes
|
|
53
|
+
- use `handling-sf-data` when the issue depends on missing or malformed test data
|