scc-universal 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +44 -0
- package/.cursor/agents/deep-researcher.md +142 -0
- package/.cursor/agents/doc-updater.md +219 -0
- package/.cursor/agents/eval-runner.md +335 -0
- package/.cursor/agents/learning-engine.md +210 -0
- package/.cursor/agents/loop-operator.md +245 -0
- package/.cursor/agents/refactor-cleaner.md +119 -0
- package/.cursor/agents/sf-admin-agent.md +127 -0
- package/.cursor/agents/sf-agentforce-agent.md +126 -0
- package/.cursor/agents/sf-apex-agent.md +117 -0
- package/.cursor/agents/sf-architect.md +426 -0
- package/.cursor/agents/sf-aura-reviewer.md +369 -0
- package/.cursor/agents/sf-bugfix-agent.md +101 -0
- package/.cursor/agents/sf-flow-agent.md +155 -0
- package/.cursor/agents/sf-integration-agent.md +141 -0
- package/.cursor/agents/sf-lwc-agent.md +123 -0
- package/.cursor/agents/sf-review-agent.md +357 -0
- package/.cursor/agents/sf-visualforce-reviewer.md +465 -0
- package/.cursor/hooks/adapter.js +81 -0
- package/.cursor/hooks/after-file-edit.js +26 -0
- package/.cursor/hooks/after-mcp-execution.js +12 -0
- package/.cursor/hooks/after-shell-execution.js +30 -0
- package/.cursor/hooks/after-tab-file-edit.js +12 -0
- package/.cursor/hooks/before-mcp-execution.js +11 -0
- package/.cursor/hooks/before-read-file.js +13 -0
- package/.cursor/hooks/before-shell-execution.js +29 -0
- package/.cursor/hooks/before-submit-prompt.js +23 -0
- package/.cursor/hooks/pre-compact.js +7 -0
- package/.cursor/hooks/session-end.js +10 -0
- package/.cursor/hooks/session-start.js +10 -0
- package/.cursor/hooks/stop.js +18 -0
- package/.cursor/hooks/subagent-start.js +10 -0
- package/.cursor/hooks/subagent-stop.js +10 -0
- package/.cursor/hooks.json +107 -0
- package/.cursor/skills/aside/SKILL.md +115 -0
- package/.cursor/skills/checkpoint/SKILL.md +50 -0
- package/.cursor/skills/configure-scc/SKILL.md +160 -0
- package/.cursor/skills/continuous-agent-loop/SKILL.md +260 -0
- package/.cursor/skills/mcp-server-patterns/SKILL.md +142 -0
- package/.cursor/skills/model-route/SKILL.md +81 -0
- package/.cursor/skills/prompt-optimizer/SKILL.md +366 -0
- package/.cursor/skills/refactor-clean/SKILL.md +133 -0
- package/.cursor/skills/resume-session/SKILL.md +111 -0
- package/.cursor/skills/save-session/SKILL.md +183 -0
- package/.cursor/skills/search-first/SKILL.md +140 -0
- package/.cursor/skills/security-scan/SKILL.md +142 -0
- package/.cursor/skills/sessions/SKILL.md +124 -0
- package/.cursor/skills/sf-agentforce-development/SKILL.md +449 -0
- package/.cursor/skills/sf-apex-async-patterns/SKILL.md +324 -0
- package/.cursor/skills/sf-apex-best-practices/SKILL.md +421 -0
- package/.cursor/skills/sf-apex-constraints/SKILL.md +79 -0
- package/.cursor/skills/sf-apex-cursor/SKILL.md +336 -0
- package/.cursor/skills/sf-apex-enterprise-patterns/SKILL.md +344 -0
- package/.cursor/skills/sf-apex-testing/SKILL.md +407 -0
- package/.cursor/skills/sf-api-design/SKILL.md +237 -0
- package/.cursor/skills/sf-approval-processes/SKILL.md +312 -0
- package/.cursor/skills/sf-aura-development/SKILL.md +260 -0
- package/.cursor/skills/sf-build-fix/SKILL.md +120 -0
- package/.cursor/skills/sf-data-modeling/SKILL.md +274 -0
- package/.cursor/skills/sf-debugging/SKILL.md +362 -0
- package/.cursor/skills/sf-deployment/SKILL.md +291 -0
- package/.cursor/skills/sf-deployment-constraints/SKILL.md +153 -0
- package/.cursor/skills/sf-devops-ci-cd/SKILL.md +322 -0
- package/.cursor/skills/sf-docs-lookup/SKILL.md +100 -0
- package/.cursor/skills/sf-e2e-testing/SKILL.md +321 -0
- package/.cursor/skills/sf-experience-cloud/SKILL.md +248 -0
- package/.cursor/skills/sf-flow-development/SKILL.md +376 -0
- package/.cursor/skills/sf-governor-limits/SKILL.md +319 -0
- package/.cursor/skills/sf-harness-audit/SKILL.md +139 -0
- package/.cursor/skills/sf-help/SKILL.md +156 -0
- package/.cursor/skills/sf-integration/SKILL.md +479 -0
- package/.cursor/skills/sf-lwc-constraints/SKILL.md +128 -0
- package/.cursor/skills/sf-lwc-development/SKILL.md +302 -0
- package/.cursor/skills/sf-lwc-testing/SKILL.md +387 -0
- package/.cursor/skills/sf-metadata-management/SKILL.md +285 -0
- package/.cursor/skills/sf-platform-events-cdc/SKILL.md +372 -0
- package/.cursor/skills/sf-quickstart/SKILL.md +170 -0
- package/.cursor/skills/sf-security/SKILL.md +330 -0
- package/.cursor/skills/sf-security-constraints/SKILL.md +125 -0
- package/.cursor/skills/sf-soql-constraints/SKILL.md +129 -0
- package/.cursor/skills/sf-soql-optimization/SKILL.md +353 -0
- package/.cursor/skills/sf-tdd-workflow/SKILL.md +332 -0
- package/.cursor/skills/sf-testing-constraints/SKILL.md +198 -0
- package/.cursor/skills/sf-trigger-constraints/SKILL.md +88 -0
- package/.cursor/skills/sf-trigger-frameworks/SKILL.md +343 -0
- package/.cursor/skills/sf-visualforce-development/SKILL.md +259 -0
- package/.cursor/skills/strategic-compact/SKILL.md +205 -0
- package/.cursor/skills/update-docs/SKILL.md +162 -0
- package/.cursor/skills/update-platform-docs/SKILL.md +86 -0
- package/.cursor-plugin/plugin.json +26 -0
- package/LICENSE +21 -0
- package/README.md +522 -0
- package/agents/deep-researcher.md +145 -0
- package/agents/doc-updater.md +222 -0
- package/agents/eval-runner.md +340 -0
- package/agents/learning-engine.md +211 -0
- package/agents/loop-operator.md +247 -0
- package/agents/refactor-cleaner.md +122 -0
- package/agents/sf-admin-agent.md +131 -0
- package/agents/sf-agentforce-agent.md +132 -0
- package/agents/sf-apex-agent.md +124 -0
- package/agents/sf-architect.md +435 -0
- package/agents/sf-aura-reviewer.md +372 -0
- package/agents/sf-bugfix-agent.md +105 -0
- package/agents/sf-flow-agent.md +159 -0
- package/agents/sf-integration-agent.md +146 -0
- package/agents/sf-lwc-agent.md +127 -0
- package/agents/sf-review-agent.md +366 -0
- package/agents/sf-visualforce-reviewer.md +468 -0
- package/assets/logo.svg +18 -0
- package/docs/ARCHITECTURE.md +133 -0
- package/docs/authoring-guide.md +373 -0
- package/docs/hook-development.md +578 -0
- package/docs/token-optimization.md +139 -0
- package/docs/workflow-examples.md +645 -0
- package/examples/agentforce-action/README.md +227 -0
- package/examples/apex-trigger-handler/README.md +114 -0
- package/examples/devops-pipeline/README.md +325 -0
- package/examples/flow-automation/README.md +188 -0
- package/examples/integration-pattern/README.md +416 -0
- package/examples/lwc-component/README.md +180 -0
- package/examples/platform-events/README.md +492 -0
- package/examples/scratch-org-setup/README.md +138 -0
- package/examples/security-audit/README.md +244 -0
- package/examples/visualforce-migration/README.md +314 -0
- package/hooks/hooks.json +338 -0
- package/hooks/memory-persistence/README.md +73 -0
- package/manifests/install-modules.json +217 -0
- package/manifests/install-profiles.json +17 -0
- package/mcp-configs/mcp-servers.json +19 -0
- package/package.json +89 -0
- package/schemas/hooks.schema.json +123 -0
- package/schemas/install-modules.schema.json +76 -0
- package/schemas/install-profiles.schema.json +28 -0
- package/schemas/install-state.schema.json +73 -0
- package/schemas/package-manager.schema.json +18 -0
- package/schemas/plugin.schema.json +112 -0
- package/schemas/scc-install-config.schema.json +29 -0
- package/schemas/state-store.schema.json +111 -0
- package/scripts/cli/install-apply.js +170 -0
- package/scripts/cli/uninstall.js +193 -0
- package/scripts/hooks/check-console-log.js +101 -0
- package/scripts/hooks/check-hook-enabled.js +17 -0
- package/scripts/hooks/check-platform-docs-age.js +48 -0
- package/scripts/hooks/cost-tracker.js +78 -0
- package/scripts/hooks/doc-file-warning.js +63 -0
- package/scripts/hooks/evaluate-session.js +98 -0
- package/scripts/hooks/governor-check.js +220 -0
- package/scripts/hooks/learning-observe.sh +206 -0
- package/scripts/hooks/mcp-health-check.js +588 -0
- package/scripts/hooks/post-bash-build-complete.js +34 -0
- package/scripts/hooks/post-bash-pr-created.js +43 -0
- package/scripts/hooks/post-edit-console-warn.js +61 -0
- package/scripts/hooks/post-edit-format.js +79 -0
- package/scripts/hooks/post-edit-typecheck.js +98 -0
- package/scripts/hooks/post-write.js +168 -0
- package/scripts/hooks/pre-bash-git-push-reminder.js +35 -0
- package/scripts/hooks/pre-bash-tmux-reminder.js +47 -0
- package/scripts/hooks/pre-compact.js +51 -0
- package/scripts/hooks/pre-tool-use.js +163 -0
- package/scripts/hooks/pre-write-doc-warn.js +9 -0
- package/scripts/hooks/quality-gate.js +251 -0
- package/scripts/hooks/run-with-flags-shell.sh +32 -0
- package/scripts/hooks/run-with-flags.js +135 -0
- package/scripts/hooks/session-end-marker.js +29 -0
- package/scripts/hooks/session-end.js +311 -0
- package/scripts/hooks/session-start.js +202 -0
- package/scripts/hooks/sfdx-scanner-check.js +142 -0
- package/scripts/hooks/sfdx-validate.js +119 -0
- package/scripts/hooks/stop-hook.js +170 -0
- package/scripts/hooks/suggest-compact.js +67 -0
- package/scripts/lib/agent-adapter.js +82 -0
- package/scripts/lib/apex-analysis.js +194 -0
- package/scripts/lib/hook-flags.js +74 -0
- package/scripts/lib/install-config.js +73 -0
- package/scripts/lib/install-executor.js +363 -0
- package/scripts/lib/install-state.js +121 -0
- package/scripts/lib/orchestration-session.js +299 -0
- package/scripts/lib/package-manager.js +124 -0
- package/scripts/lib/project-detect.js +228 -0
- package/scripts/lib/schema-validator.js +190 -0
- package/scripts/lib/skill-adapter.js +100 -0
- package/scripts/lib/state-store.js +376 -0
- package/scripts/lib/tmux-worktree-orchestrator.js +598 -0
- package/scripts/lib/utils.js +313 -0
- package/scripts/scc.js +164 -0
- package/skills/_reference/AGENTFORCE_PATTERNS.md +112 -0
- package/skills/_reference/APEX_CURSOR.md +159 -0
- package/skills/_reference/API_VERSIONS.md +78 -0
- package/skills/_reference/APPROVAL_PROCESSES.md +105 -0
- package/skills/_reference/ASYNC_PATTERNS.md +163 -0
- package/skills/_reference/AURA_COMPONENTS.md +146 -0
- package/skills/_reference/DATA_MIGRATION_PATTERNS.md +151 -0
- package/skills/_reference/DATA_MODELING.md +124 -0
- package/skills/_reference/DEBUGGING_TOOLS.md +140 -0
- package/skills/_reference/DEPLOYMENT_CHECKLIST.md +87 -0
- package/skills/_reference/DEPRECATIONS.md +79 -0
- package/skills/_reference/DOCKER_CI_PATTERNS.md +138 -0
- package/skills/_reference/ENTERPRISE_PATTERNS.md +122 -0
- package/skills/_reference/EXPERIENCE_CLOUD.md +143 -0
- package/skills/_reference/FLOW_PATTERNS.md +113 -0
- package/skills/_reference/GOVERNOR_LIMITS.md +77 -0
- package/skills/_reference/INTEGRATION_PATTERNS.md +105 -0
- package/skills/_reference/LWC_PATTERNS.md +79 -0
- package/skills/_reference/METADATA_TYPES.md +115 -0
- package/skills/_reference/NAMING_CONVENTIONS.md +84 -0
- package/skills/_reference/PACKAGE_DEVELOPMENT.md +150 -0
- package/skills/_reference/PLATFORM_EVENTS.md +121 -0
- package/skills/_reference/REPORTING_API.md +143 -0
- package/skills/_reference/SCRATCH_ORG_PATTERNS.md +126 -0
- package/skills/_reference/SECURITY_PATTERNS.md +127 -0
- package/skills/_reference/SHARING_MODEL.md +120 -0
- package/skills/_reference/SOQL_PATTERNS.md +119 -0
- package/skills/_reference/TESTING_STANDARDS.md +96 -0
- package/skills/_reference/TRIGGER_PATTERNS.md +114 -0
- package/skills/_reference/VISUALFORCE_PATTERNS.md +121 -0
- package/skills/aside/SKILL.md +118 -0
- package/skills/checkpoint/SKILL.md +53 -0
- package/skills/configure-scc/SKILL.md +163 -0
- package/skills/continuous-agent-loop/SKILL.md +264 -0
- package/skills/mcp-server-patterns/SKILL.md +146 -0
- package/skills/model-route/SKILL.md +84 -0
- package/skills/prompt-optimizer/SKILL.md +369 -0
- package/skills/refactor-clean/SKILL.md +136 -0
- package/skills/resume-session/SKILL.md +114 -0
- package/skills/save-session/SKILL.md +186 -0
- package/skills/search-first/SKILL.md +144 -0
- package/skills/security-scan/SKILL.md +146 -0
- package/skills/sessions/SKILL.md +127 -0
- package/skills/sf-agentforce-development/SKILL.md +450 -0
- package/skills/sf-apex-async-patterns/SKILL.md +326 -0
- package/skills/sf-apex-best-practices/SKILL.md +425 -0
- package/skills/sf-apex-constraints/SKILL.md +81 -0
- package/skills/sf-apex-cursor/SKILL.md +338 -0
- package/skills/sf-apex-enterprise-patterns/SKILL.md +348 -0
- package/skills/sf-apex-testing/SKILL.md +409 -0
- package/skills/sf-api-design/SKILL.md +238 -0
- package/skills/sf-approval-processes/SKILL.md +315 -0
- package/skills/sf-aura-development/SKILL.md +263 -0
- package/skills/sf-build-fix/SKILL.md +121 -0
- package/skills/sf-data-modeling/SKILL.md +278 -0
- package/skills/sf-debugging/SKILL.md +363 -0
- package/skills/sf-deployment/SKILL.md +295 -0
- package/skills/sf-deployment-constraints/SKILL.md +155 -0
- package/skills/sf-devops-ci-cd/SKILL.md +325 -0
- package/skills/sf-docs-lookup/SKILL.md +103 -0
- package/skills/sf-e2e-testing/SKILL.md +324 -0
- package/skills/sf-experience-cloud/SKILL.md +249 -0
- package/skills/sf-flow-development/SKILL.md +377 -0
- package/skills/sf-governor-limits/SKILL.md +323 -0
- package/skills/sf-harness-audit/SKILL.md +142 -0
- package/skills/sf-help/SKILL.md +159 -0
- package/skills/sf-integration/SKILL.md +483 -0
- package/skills/sf-lwc-constraints/SKILL.md +130 -0
- package/skills/sf-lwc-development/SKILL.md +303 -0
- package/skills/sf-lwc-testing/SKILL.md +388 -0
- package/skills/sf-metadata-management/SKILL.md +288 -0
- package/skills/sf-platform-events-cdc/SKILL.md +375 -0
- package/skills/sf-quickstart/SKILL.md +173 -0
- package/skills/sf-security/SKILL.md +334 -0
- package/skills/sf-security-constraints/SKILL.md +127 -0
- package/skills/sf-soql-constraints/SKILL.md +131 -0
- package/skills/sf-soql-optimization/SKILL.md +354 -0
- package/skills/sf-tdd-workflow/SKILL.md +336 -0
- package/skills/sf-testing-constraints/SKILL.md +200 -0
- package/skills/sf-trigger-constraints/SKILL.md +90 -0
- package/skills/sf-trigger-frameworks/SKILL.md +347 -0
- package/skills/sf-visualforce-development/SKILL.md +260 -0
- package/skills/strategic-compact/SKILL.md +208 -0
- package/skills/update-docs/SKILL.md +165 -0
- package/skills/update-platform-docs/SKILL.md +90 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sf-approval-processes
|
|
3
|
+
description: >-
|
|
4
|
+
Use when designing Salesforce Apex approval processes, multi-step approvals, or Flow-integrated submissions. Do NOT use for general Apex or Flow-only work.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Salesforce Approval Processes
|
|
8
|
+
|
|
9
|
+
@../_reference/APPROVAL_PROCESSES.md
|
|
10
|
+
|
|
11
|
+
## When to Use
|
|
12
|
+
|
|
13
|
+
- Designing multi-step approval workflows (discounts, expenses, contracts)
|
|
14
|
+
- Building Apex-driven approval submissions or programmatic approvals/rejections
|
|
15
|
+
- Integrating approval logic with Flows (Spring '26 Integrated Approval Screen component)
|
|
16
|
+
- Troubleshooting approval routing, locked records, or missing approval history
|
|
17
|
+
- Migrating from email-based approvals to in-app approval workflows
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Approval Process Architecture
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
┌─────────────────────────────────────────────────────┐
|
|
25
|
+
│ Approval Process │
|
|
26
|
+
├─────────────────────────────────────────────────────┤
|
|
27
|
+
│ Entry Criteria │ WHO can submit? WHEN? │
|
|
28
|
+
│ Initial Submitter │ Record owner, specific users │
|
|
29
|
+
├─────────────────────────────────────────────────────┤
|
|
30
|
+
│ Step 1: Manager │ Approver: Manager field │
|
|
31
|
+
│ Step 2: VP │ Approver: Related user field │
|
|
32
|
+
│ Step 3: Finance │ Approver: Queue │
|
|
33
|
+
├─────────────────────────────────────────────────────┤
|
|
34
|
+
│ Initial Actions │ Lock record, set Status │
|
|
35
|
+
│ Approval Actions │ Unlock, update field, email │
|
|
36
|
+
│ Rejection Actions │ Unlock, set Status to Rejected │
|
|
37
|
+
│ Recall Actions │ Unlock, clear approval fields │
|
|
38
|
+
└─────────────────────────────────────────────────────┘
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Entry Criteria
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Amount__c > 10000 AND Status__c = 'Draft'
|
|
45
|
+
RecordType.Name = 'Enterprise' AND Discount__c > 20
|
|
46
|
+
|
|
47
|
+
Formula:
|
|
48
|
+
AND(Amount__c > 10000, ISPICKVAL(Status__c, 'Draft'), NOT(ISBLANK(OwnerId)))
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Approval Steps
|
|
52
|
+
|
|
53
|
+
| Property | Options |
|
|
54
|
+
|---|---|
|
|
55
|
+
| Approver | User field, Manager field, Queue, Related user |
|
|
56
|
+
| Criteria | All records OR filter criteria (step-specific) |
|
|
57
|
+
| Reject behavior | Final rejection OR go to previous step |
|
|
58
|
+
| Unanimity | All must approve OR first response |
|
|
59
|
+
|
|
60
|
+
### Parallel Approvals
|
|
61
|
+
|
|
62
|
+
- **Unanimous**: All assigned approvers must approve
|
|
63
|
+
- **First Response**: First approver's decision applies
|
|
64
|
+
- For true parallel independent steps (Legal AND Finance simultaneously), use multiple processes or custom Apex
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Approval Actions
|
|
69
|
+
|
|
70
|
+
### Initial Submission Actions
|
|
71
|
+
|
|
72
|
+
- Field Update: `Status__c = "Pending Approval"`
|
|
73
|
+
- Email Alert: Notify approver(s)
|
|
74
|
+
- Record Lock: Prevent edits during approval
|
|
75
|
+
- Outbound Message: Notify external system
|
|
76
|
+
|
|
77
|
+
### Final Approval Actions
|
|
78
|
+
|
|
79
|
+
- Field Update: `Status__c = "Approved"`
|
|
80
|
+
- Email Alert: Notify submitter
|
|
81
|
+
- Record Unlock: Allow edits again
|
|
82
|
+
|
|
83
|
+
### Final Rejection Actions
|
|
84
|
+
|
|
85
|
+
- Field Update: `Status__c = "Rejected"`
|
|
86
|
+
- Email Alert: Notify submitter with rejection reason
|
|
87
|
+
- Record Unlock
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Apex Approval Processing
|
|
92
|
+
|
|
93
|
+
### Submitting a Record for Approval
|
|
94
|
+
|
|
95
|
+
```apex
|
|
96
|
+
public class ApprovalService {
|
|
97
|
+
public static void submitForApproval(Id recordId, String comments) {
|
|
98
|
+
Approval.ProcessSubmitRequest request = new Approval.ProcessSubmitRequest();
|
|
99
|
+
request.setObjectId(recordId);
|
|
100
|
+
request.setSubmitterId(UserInfo.getUserId());
|
|
101
|
+
request.setComments(comments);
|
|
102
|
+
|
|
103
|
+
Approval.ProcessResult result = Approval.process(request);
|
|
104
|
+
if (result.isSuccess()) {
|
|
105
|
+
System.debug('Submitted. Instance ID: ' + result.getInstanceId());
|
|
106
|
+
} else {
|
|
107
|
+
for (Database.Error err : result.getErrors()) {
|
|
108
|
+
System.debug(LoggingLevel.ERROR, 'Failed: ' + err.getMessage());
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Approving or Rejecting Programmatically
|
|
116
|
+
|
|
117
|
+
```apex
|
|
118
|
+
public static void approveRecord(Id workItemId, String comments) {
|
|
119
|
+
Approval.ProcessWorkitemRequest request = new Approval.ProcessWorkitemRequest();
|
|
120
|
+
request.setWorkitemId(workItemId);
|
|
121
|
+
request.setAction('Approve');
|
|
122
|
+
request.setComments(comments);
|
|
123
|
+
|
|
124
|
+
Approval.ProcessResult result = Approval.process(request);
|
|
125
|
+
if (!result.isSuccess()) {
|
|
126
|
+
throw new ApprovalException('Approval failed: ' + result.getErrors());
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public static void rejectRecord(Id workItemId, String comments) {
|
|
131
|
+
Approval.ProcessWorkitemRequest request = new Approval.ProcessWorkitemRequest();
|
|
132
|
+
request.setWorkitemId(workItemId);
|
|
133
|
+
request.setAction('Reject');
|
|
134
|
+
request.setComments(comments);
|
|
135
|
+
|
|
136
|
+
Approval.ProcessResult result = Approval.process(request);
|
|
137
|
+
if (!result.isSuccess()) {
|
|
138
|
+
throw new ApprovalException('Rejection failed: ' + result.getErrors());
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Querying Approval Status
|
|
144
|
+
|
|
145
|
+
```apex
|
|
146
|
+
// Pending work items for current user
|
|
147
|
+
List<ProcessInstanceWorkitem> pendingItems = [
|
|
148
|
+
SELECT Id, ProcessInstance.TargetObjectId, ProcessInstance.Status,
|
|
149
|
+
ProcessInstance.TargetObject.Name, CreatedDate
|
|
150
|
+
FROM ProcessInstanceWorkitem
|
|
151
|
+
WHERE ActorId = :UserInfo.getUserId()
|
|
152
|
+
ORDER BY CreatedDate DESC
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
// Approval history for a record
|
|
156
|
+
List<ProcessInstanceStep> history = [
|
|
157
|
+
SELECT StepStatus, Comments, Actor.Name, CreatedDate
|
|
158
|
+
FROM ProcessInstanceStep
|
|
159
|
+
WHERE ProcessInstance.TargetObjectId = :recordId
|
|
160
|
+
ORDER BY CreatedDate ASC
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
// Active work item for a specific record
|
|
164
|
+
ProcessInstanceWorkitem workItem = [
|
|
165
|
+
SELECT Id FROM ProcessInstanceWorkitem
|
|
166
|
+
WHERE ProcessInstance.TargetObjectId = :recordId
|
|
167
|
+
AND ProcessInstance.Status = 'Pending'
|
|
168
|
+
LIMIT 1
|
|
169
|
+
];
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Flow Integration
|
|
175
|
+
|
|
176
|
+
### Submitting for Approval from Flow
|
|
177
|
+
|
|
178
|
+
Use the **Submit for Approval** action element: specify the record ID, optionally the approval process name, submitter, and comments.
|
|
179
|
+
|
|
180
|
+
### Spring '26 — Integrated Approval Screen Component
|
|
181
|
+
|
|
182
|
+
Screen Flows can include an Integrated Approval component for in-flow approve/reject:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
Screen Flow:
|
|
186
|
+
1. Show Record Details
|
|
187
|
+
2. Integrated Approval Component (history, Approve/Reject buttons, comments)
|
|
188
|
+
3. Decision: Check outcome
|
|
189
|
+
4. Update Records based on outcome
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Dynamic Approvers via Flow
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
Autolaunched Flow (invoked by Approval Process):
|
|
196
|
+
1. Get Records: record's Region__c and Amount__c
|
|
197
|
+
2. Decision: Route by amount and region
|
|
198
|
+
- > 500K → VP Finance
|
|
199
|
+
- > 100K → Regional Manager
|
|
200
|
+
- Otherwise → Direct Manager
|
|
201
|
+
3. Return approver User ID
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Design Patterns
|
|
207
|
+
|
|
208
|
+
### Delegation and Backup Approvers
|
|
209
|
+
|
|
210
|
+
- Configure Delegated Approvers in user settings for vacation coverage
|
|
211
|
+
- Use Queues as approvers so any queue member can approve
|
|
212
|
+
- Set approval step timeout for auto-escalation
|
|
213
|
+
|
|
214
|
+
### Approval History Tracking
|
|
215
|
+
|
|
216
|
+
```apex
|
|
217
|
+
public static List<Map<String, Object>> getApprovalHistory(Id recordId) {
|
|
218
|
+
List<Map<String, Object>> trail = new List<Map<String, Object>>();
|
|
219
|
+
for (ProcessInstance pi : [
|
|
220
|
+
SELECT Id, Status, CreatedDate,
|
|
221
|
+
(SELECT StepStatus, Comments, Actor.Name, CreatedDate
|
|
222
|
+
FROM StepsAndWorkitems ORDER BY CreatedDate)
|
|
223
|
+
FROM ProcessInstance
|
|
224
|
+
WHERE TargetObjectId = :recordId
|
|
225
|
+
ORDER BY CreatedDate DESC
|
|
226
|
+
]) {
|
|
227
|
+
for (ProcessInstanceHistory step : pi.StepsAndWorkitems) {
|
|
228
|
+
trail.add(new Map<String, Object>{
|
|
229
|
+
'status' => step.StepStatus,
|
|
230
|
+
'approver' => step.Actor.Name,
|
|
231
|
+
'comments' => step.Comments,
|
|
232
|
+
'date' => step.CreatedDate
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return trail;
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Testing Approval Processes
|
|
243
|
+
|
|
244
|
+
These tests require an approval process to be deployed in the org's metadata. Approval processes cannot be created programmatically in tests.
|
|
245
|
+
|
|
246
|
+
```apex
|
|
247
|
+
@isTest
|
|
248
|
+
static void testApprovalSubmission() {
|
|
249
|
+
Account testAccount = new Account(Name = 'Test Account', AnnualRevenue = 50000);
|
|
250
|
+
insert testAccount;
|
|
251
|
+
|
|
252
|
+
Test.startTest();
|
|
253
|
+
Approval.ProcessSubmitRequest request = new Approval.ProcessSubmitRequest();
|
|
254
|
+
request.setObjectId(testAccount.Id);
|
|
255
|
+
request.setSubmitterId(UserInfo.getUserId());
|
|
256
|
+
Approval.ProcessResult result = Approval.process(request);
|
|
257
|
+
Test.stopTest();
|
|
258
|
+
|
|
259
|
+
System.assert(result.isSuccess(), 'Approval submission should succeed');
|
|
260
|
+
System.assertEquals('Pending', result.getInstanceStatus());
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
@isTest
|
|
264
|
+
static void testApprovalProcess() {
|
|
265
|
+
Account testAccount = new Account(Name = 'Test', AnnualRevenue = 50000);
|
|
266
|
+
insert testAccount;
|
|
267
|
+
|
|
268
|
+
Approval.ProcessSubmitRequest submitReq = new Approval.ProcessSubmitRequest();
|
|
269
|
+
submitReq.setObjectId(testAccount.Id);
|
|
270
|
+
Approval.ProcessResult submitResult = Approval.process(submitReq);
|
|
271
|
+
|
|
272
|
+
Id workItemId = submitResult.getNewWorkitemIds()[0];
|
|
273
|
+
|
|
274
|
+
Approval.ProcessWorkitemRequest approveReq = new Approval.ProcessWorkitemRequest();
|
|
275
|
+
approveReq.setWorkitemId(workItemId);
|
|
276
|
+
approveReq.setAction('Approve');
|
|
277
|
+
approveReq.setComments('Looks good');
|
|
278
|
+
|
|
279
|
+
Test.startTest();
|
|
280
|
+
Approval.ProcessResult approveResult = Approval.process(approveReq);
|
|
281
|
+
Test.stopTest();
|
|
282
|
+
|
|
283
|
+
System.assert(approveResult.isSuccess());
|
|
284
|
+
System.assertEquals('Approved', approveResult.getInstanceStatus());
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Metadata Deployment
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
approvalProcesses/
|
|
294
|
+
Discount_Approval.approvalProcess-meta.xml
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Include in `package.xml`:
|
|
298
|
+
|
|
299
|
+
```xml
|
|
300
|
+
<types>
|
|
301
|
+
<members>Opportunity.Discount_Approval</members>
|
|
302
|
+
<name>ApprovalProcess</name>
|
|
303
|
+
</types>
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Approval processes reference users, queues, and email templates. Ensure dependencies exist in the target org before deployment.
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Related
|
|
311
|
+
|
|
312
|
+
- **Constraints**: `sf-apex-constraints` — Governor limits and Apex safety rules
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sf-aura-development
|
|
3
|
+
description: >-
|
|
4
|
+
Salesforce Aura component development — bundles, events, server-side actions, Locker Service, and LWC migration. Use when maintaining or migrating Aura.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Aura Component Development
|
|
8
|
+
|
|
9
|
+
Aura is Salesforce's original Lightning component framework (introduced 2014). While LWC is the modern standard, thousands of production orgs still run Aura components. This skill covers authoring, maintaining, and migrating Aura components.
|
|
10
|
+
|
|
11
|
+
**Note:** Aura is in maintenance mode. For new development, use LWC (see sf-lwc-development).
|
|
12
|
+
|
|
13
|
+
## When to Use
|
|
14
|
+
|
|
15
|
+
- When maintaining or extending existing Aura components that cannot be rewritten immediately
|
|
16
|
+
- When migrating Aura components to LWC and needing to understand the source patterns
|
|
17
|
+
- When building interoperability layers between LWC and Aura
|
|
18
|
+
- When debugging Aura event propagation, server-side action callbacks, or Locker Service errors
|
|
19
|
+
- When working with features that still require Aura wrappers (Lightning Out, legacy AppExchange)
|
|
20
|
+
|
|
21
|
+
@../_reference/AURA_COMPONENTS.md
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Component Creation Procedure
|
|
26
|
+
|
|
27
|
+
An Aura component is a folder (bundle) containing up to eight files. Only the `.cmp` file is required.
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
force-app/main/default/aura/AccountManager/
|
|
31
|
+
AccountManager.cmp <- Component markup (required)
|
|
32
|
+
AccountManagerController.js <- Client-side controller (action handlers)
|
|
33
|
+
AccountManagerHelper.js <- Reusable logic (called by controller)
|
|
34
|
+
AccountManagerRenderer.js <- Custom rendering overrides (rare)
|
|
35
|
+
AccountManager.css <- Component-scoped styles
|
|
36
|
+
AccountManager.design <- App Builder property editor config
|
|
37
|
+
AccountManager.cmp-meta.xml <- Metadata (apiVersion, description)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Component Markup (.cmp)
|
|
41
|
+
|
|
42
|
+
```xml
|
|
43
|
+
<aura:component controller="AccountController"
|
|
44
|
+
implements="force:appHostable,flexipage:availableForAllPageTypes"
|
|
45
|
+
access="global">
|
|
46
|
+
<aura:attribute name="accounts" type="Account[]" default="[]" />
|
|
47
|
+
<aura:attribute name="isLoading" type="Boolean" default="true" />
|
|
48
|
+
<aura:attribute name="errorMessage" type="String" />
|
|
49
|
+
|
|
50
|
+
<aura:registerEvent name="accountSelected" type="c:AccountSelectedEvent" />
|
|
51
|
+
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
|
|
52
|
+
|
|
53
|
+
<lightning:card title="Account Manager" iconName="standard:account">
|
|
54
|
+
<aura:if isTrue="{!v.isLoading}">
|
|
55
|
+
<lightning:spinner alternativeText="Loading" size="small" />
|
|
56
|
+
<aura:set attribute="else">
|
|
57
|
+
<aura:iteration items="{!v.accounts}" var="acct">
|
|
58
|
+
<lightning:tile label="{!acct.Name}">
|
|
59
|
+
<dl class="slds-list_horizontal slds-wrap">
|
|
60
|
+
<dt class="slds-item_label">Type:</dt>
|
|
61
|
+
<dd class="slds-item_detail">{!acct.Type}</dd>
|
|
62
|
+
</dl>
|
|
63
|
+
</lightning:tile>
|
|
64
|
+
</aura:iteration>
|
|
65
|
+
</aura:set>
|
|
66
|
+
</aura:if>
|
|
67
|
+
</lightning:card>
|
|
68
|
+
</aura:component>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Event Handling
|
|
74
|
+
|
|
75
|
+
### Component Events (Parent-Child)
|
|
76
|
+
|
|
77
|
+
```xml
|
|
78
|
+
<!-- AccountSelectedEvent.evt -->
|
|
79
|
+
<aura:event type="COMPONENT" description="Fired when an account is selected">
|
|
80
|
+
<aura:attribute name="accountId" type="String" />
|
|
81
|
+
</aura:event>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
// Child controller — firing
|
|
86
|
+
handleAccountClick: function(component, event, helper) {
|
|
87
|
+
var compEvent = component.getEvent("accountSelected");
|
|
88
|
+
compEvent.setParams({ accountId: event.currentTarget.dataset.accountId });
|
|
89
|
+
compEvent.fire();
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```xml
|
|
94
|
+
<!-- Parent — handling -->
|
|
95
|
+
<c:AccountTile onaccountSelected="{!c.handleAccountSelected}" />
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Application Events (Cross-Component)
|
|
99
|
+
|
|
100
|
+
```xml
|
|
101
|
+
<aura:event type="APPLICATION" description="Broadcast notification">
|
|
102
|
+
<aura:attribute name="message" type="String" />
|
|
103
|
+
</aura:event>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
// Firing
|
|
108
|
+
var appEvent = $A.get("e.c:GlobalNotificationEvent");
|
|
109
|
+
appEvent.setParams({ message: "Record saved" });
|
|
110
|
+
appEvent.fire();
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```xml
|
|
114
|
+
<!-- Any component can handle -->
|
|
115
|
+
<aura:handler event="c:GlobalNotificationEvent" action="{!c.handleNotification}" />
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Prefer component events over application events. For new cross-component communication, use Lightning Message Service instead.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Controller and Helper Patterns
|
|
123
|
+
|
|
124
|
+
Keep controllers thin; helpers do the work.
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
// AccountManagerController.js
|
|
128
|
+
({
|
|
129
|
+
doInit: function(component, event, helper) {
|
|
130
|
+
helper.loadAccounts(component);
|
|
131
|
+
},
|
|
132
|
+
handleSearch: function(component, event, helper) {
|
|
133
|
+
helper.loadAccounts(component);
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
// AccountManagerHelper.js
|
|
140
|
+
({
|
|
141
|
+
loadAccounts: function(component) {
|
|
142
|
+
component.set("v.isLoading", true);
|
|
143
|
+
var action = component.get("c.getAccounts");
|
|
144
|
+
action.setParams({
|
|
145
|
+
searchTerm: component.get("v.searchTerm") || ""
|
|
146
|
+
});
|
|
147
|
+
action.setCallback(this, function(response) {
|
|
148
|
+
var state = response.getState();
|
|
149
|
+
if (state === "SUCCESS") {
|
|
150
|
+
component.set("v.accounts", response.getReturnValue());
|
|
151
|
+
} else if (state === "ERROR") {
|
|
152
|
+
this.handleErrors(component, response.getError());
|
|
153
|
+
} else if (state === "INCOMPLETE") {
|
|
154
|
+
component.set("v.errorMessage", "Server unreachable.");
|
|
155
|
+
}
|
|
156
|
+
component.set("v.isLoading", false);
|
|
157
|
+
});
|
|
158
|
+
$A.enqueueAction(action);
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
handleErrors: function(component, errors) {
|
|
162
|
+
var message = "Unknown error";
|
|
163
|
+
if (errors && errors[0] && errors[0].message) {
|
|
164
|
+
message = errors[0].message;
|
|
165
|
+
}
|
|
166
|
+
component.set("v.errorMessage", message);
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Server-Side Communication
|
|
174
|
+
|
|
175
|
+
### $A.enqueueAction() Pattern
|
|
176
|
+
|
|
177
|
+
All Apex calls in Aura go through the action queue. Handle all three states: SUCCESS, ERROR, INCOMPLETE.
|
|
178
|
+
|
|
179
|
+
### Storable Actions (Client-Side Caching)
|
|
180
|
+
|
|
181
|
+
```javascript
|
|
182
|
+
var action = component.get("c.getPicklistValues");
|
|
183
|
+
action.setStorable(); // Only for @AuraEnabled(cacheable=true) methods
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Callback may fire twice: once from cache, once from server. Do not use for DML operations.
|
|
187
|
+
|
|
188
|
+
### $A.getCallback() for Async Code
|
|
189
|
+
|
|
190
|
+
Any code executing outside the Aura lifecycle (setTimeout, Promises, third-party callbacks) must use `$A.getCallback()`:
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
setTimeout($A.getCallback(function() {
|
|
194
|
+
if (component.isValid()) {
|
|
195
|
+
component.set("v.status", "Complete");
|
|
196
|
+
}
|
|
197
|
+
}), 2000);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Interoperability with LWC
|
|
203
|
+
|
|
204
|
+
### Embedding LWC Inside Aura
|
|
205
|
+
|
|
206
|
+
```xml
|
|
207
|
+
<!-- AuraWrapper.cmp -->
|
|
208
|
+
<aura:component>
|
|
209
|
+
<c:lwcRecordDetail
|
|
210
|
+
record-id="{!v.selectedRecordId}"
|
|
211
|
+
onrecordupdate="{!c.handleRecordUpdate}" />
|
|
212
|
+
</aura:component>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Aura to LWC** — pass data via attributes mapped to `@api` properties.
|
|
216
|
+
**LWC to Aura** — dispatch `CustomEvent`; Aura receives via `on{eventname}` handler, access detail via `event.getParam("detail")`.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Migration to LWC
|
|
221
|
+
|
|
222
|
+
### Strategy
|
|
223
|
+
|
|
224
|
+
1. **Inventory** — list all Aura components, dependencies, usage locations
|
|
225
|
+
2. **Prioritize** — start with leaf components (no child Aura dependencies)
|
|
226
|
+
3. **Wrap** — replace Aura parents with LWC, keeping Aura children via interop
|
|
227
|
+
4. **Convert** — rewrite using LWC patterns
|
|
228
|
+
5. **Test** — validate behavior parity
|
|
229
|
+
6. **Deploy** — replace references on pages/apps
|
|
230
|
+
|
|
231
|
+
### Key Mappings
|
|
232
|
+
|
|
233
|
+
| Aura | LWC |
|
|
234
|
+
|------|-----|
|
|
235
|
+
| `aura:handler name="init"` | `connectedCallback()` |
|
|
236
|
+
| `aura:handler name="destroy"` | `disconnectedCallback()` |
|
|
237
|
+
| `aura:attribute` | `@api` properties |
|
|
238
|
+
| `aura:if` / `aura:set` | `lwc:if` / `lwc:elseif` / `lwc:else` |
|
|
239
|
+
| `aura:iteration` | `for:each` with `key` |
|
|
240
|
+
| `$A.enqueueAction()` | `@wire` or imperative `await` |
|
|
241
|
+
| `component.get("v.attr")` | `this.propertyName` |
|
|
242
|
+
| `component.set("v.attr", val)` | `this.propertyName = val` |
|
|
243
|
+
| `component.find("auraId")` | `this.template.querySelector()` |
|
|
244
|
+
| Component events | `CustomEvent` |
|
|
245
|
+
| Application events | Lightning Message Service |
|
|
246
|
+
| `$A.getCallback()` | Not needed (LWC handles async natively) |
|
|
247
|
+
| Helper.js (separate file) | Class methods (single JS file) |
|
|
248
|
+
| `$A.createComponent()` | `lwc:component` with `lwc:is` |
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Related
|
|
253
|
+
|
|
254
|
+
### Guardrails
|
|
255
|
+
|
|
256
|
+
- **sf-lwc-constraints** — Enforced rules for LWC (relevant for interop and migration targets)
|
|
257
|
+
|
|
258
|
+
### Agents
|
|
259
|
+
|
|
260
|
+
- **sf-aura-reviewer** — For interactive, in-depth Aura review guidance
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sf-build-fix
|
|
3
|
+
description: >-
|
|
4
|
+
Auto-fix Salesforce build errors — Apex compilation, metadata conflicts, dependencies, test failures. Use when build errors block deployment. Do NOT use for writing new features or refactoring.
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Build Fix — Salesforce Build and Deployment Error Resolution
|
|
9
|
+
|
|
10
|
+
Fix build and deployment errors incrementally. Parse error output, classify issues, fix one at a time, re-validate.
|
|
11
|
+
|
|
12
|
+
Reference: @../_reference/DEPLOYMENT_CHECKLIST.md
|
|
13
|
+
|
|
14
|
+
## When to Use
|
|
15
|
+
|
|
16
|
+
- When Apex compilation errors are blocking a deployment
|
|
17
|
+
- When metadata conflicts prevent deploying to a target org
|
|
18
|
+
- When test failures need to be resolved before deployment validation passes
|
|
19
|
+
- When dependency resolution is needed (missing objects, fields, or class references)
|
|
20
|
+
- When you receive build errors from `sf project deploy` and need systematic resolution
|
|
21
|
+
|
|
22
|
+
## Workflow
|
|
23
|
+
|
|
24
|
+
### Step 1 — Capture Errors
|
|
25
|
+
|
|
26
|
+
Run a dry-run deployment or check compiler output:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
sf project deploy validate --target-org <alias> --json 2>&1
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
If the user pasted error output directly, use that instead.
|
|
33
|
+
|
|
34
|
+
### Step 2 — Parse and Classify
|
|
35
|
+
|
|
36
|
+
Group errors by type and fix in this dependency order:
|
|
37
|
+
|
|
38
|
+
| Priority | Error Type | Fix Strategy |
|
|
39
|
+
|----------|-----------|--------------|
|
|
40
|
+
| 1 | Missing object/field metadata | Deploy metadata first -- objects before classes |
|
|
41
|
+
| 2 | Missing class/interface reference | Check spelling, verify class exists, check API version |
|
|
42
|
+
| 3 | Type mismatch | Cast explicitly, check null handling, verify generic types |
|
|
43
|
+
| 4 | Method signature changed | Update all callers, check for overloaded methods |
|
|
44
|
+
| 5 | Metadata conflict | Retrieve latest from org with `sf project retrieve start`, merge |
|
|
45
|
+
| 6 | Test failure | Fix test data setup, update assertions, check @TestSetup |
|
|
46
|
+
| 7 | Governor limit in test | Add Test.startTest()/stopTest(), reduce data volume |
|
|
47
|
+
|
|
48
|
+
### Step 3 — Fix One at a Time
|
|
49
|
+
|
|
50
|
+
For each error:
|
|
51
|
+
|
|
52
|
+
1. Read the file at the reported line number
|
|
53
|
+
2. Understand the context (class, method, trigger)
|
|
54
|
+
3. Apply the minimal fix
|
|
55
|
+
4. Verify it compiles: `sf project deploy validate --metadata "ApexClass:<ClassName>" --target-org <org>`
|
|
56
|
+
|
|
57
|
+
### Step 4 — Re-validate
|
|
58
|
+
|
|
59
|
+
After all fixes:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
sf project deploy validate --target-org <alias> --test-level RunLocalTests
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Common Apex Compilation Errors
|
|
66
|
+
|
|
67
|
+
| Error Message Pattern | Root Cause | Fix |
|
|
68
|
+
|----------------------|------------|-----|
|
|
69
|
+
| `Variable does not exist: X` | Undeclared variable or field removed | Declare variable or check field API name |
|
|
70
|
+
| `Method does not exist or incorrect signature` | Wrong parameter types or method renamed | Check method signature in target class |
|
|
71
|
+
| `Illegal assignment from X to Y` | Type mismatch | Add explicit cast or fix generic type |
|
|
72
|
+
| `Non-void method might not return a value` | Missing return in a branch | Add return statement to all code paths |
|
|
73
|
+
| `Compile Error: unexpected token` | Syntax error | Check line above the reported line |
|
|
74
|
+
| `System.NullPointerException` (test) | Null reference in test setup | Add null checks or fix @TestSetup |
|
|
75
|
+
| `Duplicate value found` (test) | Test data collision | Use unique identifiers, avoid SeeAllData |
|
|
76
|
+
| `FIELD_CUSTOM_VALIDATION_EXCEPTION` (test) | Validation rule blocking test DML | Populate all required fields in test data |
|
|
77
|
+
| `MIXED_DML_OPERATION` (test) | Setup + non-setup DML in same transaction | Use `System.runAs()` in tests or `@future` in production |
|
|
78
|
+
| `UNABLE_TO_LOCK_ROW` (test) | Concurrent test data conflicts | Use unique records per test method |
|
|
79
|
+
|
|
80
|
+
## Dependency Resolution Order
|
|
81
|
+
|
|
82
|
+
When deploying multiple metadata types, follow this order:
|
|
83
|
+
|
|
84
|
+
1. Custom Objects and Fields
|
|
85
|
+
2. Record Types and Page Layouts
|
|
86
|
+
3. Apex Classes (utilities and base classes first)
|
|
87
|
+
4. Apex Triggers
|
|
88
|
+
5. Lightning Web Components
|
|
89
|
+
6. Flows (Process Builder is deprecated since Winter '23 -- migrate to Flows)
|
|
90
|
+
7. Permission Sets and Profiles
|
|
91
|
+
8. Apex Test Classes (verify at end)
|
|
92
|
+
|
|
93
|
+
## Metadata Conflict Resolution
|
|
94
|
+
|
|
95
|
+
When `sf project deploy` reports conflicts:
|
|
96
|
+
|
|
97
|
+
1. **Retrieve current org state**: `sf project retrieve start --metadata <type>:<name>`
|
|
98
|
+
2. **Compare**: `diff force-app/main/default/<path> <retrieved-path>`
|
|
99
|
+
3. **Merge**: Keep production changes, layer your modifications on top
|
|
100
|
+
4. **Do not force-overwrite** production metadata without understanding the diff
|
|
101
|
+
|
|
102
|
+
## Rules
|
|
103
|
+
|
|
104
|
+
- Fix one error at a time -- cascade fixes often resolve multiple issues
|
|
105
|
+
- Do NOT refactor while fixing builds
|
|
106
|
+
- Do NOT change architecture
|
|
107
|
+
- If a fix introduces new errors, revert and try a different approach
|
|
108
|
+
|
|
109
|
+
## Examples
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
sf-build-fix
|
|
113
|
+
sf-build-fix Fix the Apex compile errors from this deployment output: <paste errors>
|
|
114
|
+
sf-build-fix The AccountService.cls has a type mismatch on line 47
|
|
115
|
+
sf-build-fix Resolve the metadata conflicts blocking our deployment to UAT
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Related
|
|
119
|
+
|
|
120
|
+
- **Constraints**: `sf-deployment-constraints` -- deployment safety rules and validation gates
|