scc-universal 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/.claude-plugin/plugin.json +44 -0
  2. package/.cursor/agents/deep-researcher.md +142 -0
  3. package/.cursor/agents/doc-updater.md +219 -0
  4. package/.cursor/agents/eval-runner.md +335 -0
  5. package/.cursor/agents/learning-engine.md +210 -0
  6. package/.cursor/agents/loop-operator.md +245 -0
  7. package/.cursor/agents/refactor-cleaner.md +119 -0
  8. package/.cursor/agents/sf-admin-agent.md +127 -0
  9. package/.cursor/agents/sf-agentforce-agent.md +126 -0
  10. package/.cursor/agents/sf-apex-agent.md +117 -0
  11. package/.cursor/agents/sf-architect.md +426 -0
  12. package/.cursor/agents/sf-aura-reviewer.md +369 -0
  13. package/.cursor/agents/sf-bugfix-agent.md +101 -0
  14. package/.cursor/agents/sf-flow-agent.md +155 -0
  15. package/.cursor/agents/sf-integration-agent.md +141 -0
  16. package/.cursor/agents/sf-lwc-agent.md +123 -0
  17. package/.cursor/agents/sf-review-agent.md +357 -0
  18. package/.cursor/agents/sf-visualforce-reviewer.md +465 -0
  19. package/.cursor/hooks/adapter.js +81 -0
  20. package/.cursor/hooks/after-file-edit.js +26 -0
  21. package/.cursor/hooks/after-mcp-execution.js +12 -0
  22. package/.cursor/hooks/after-shell-execution.js +30 -0
  23. package/.cursor/hooks/after-tab-file-edit.js +12 -0
  24. package/.cursor/hooks/before-mcp-execution.js +11 -0
  25. package/.cursor/hooks/before-read-file.js +13 -0
  26. package/.cursor/hooks/before-shell-execution.js +29 -0
  27. package/.cursor/hooks/before-submit-prompt.js +23 -0
  28. package/.cursor/hooks/pre-compact.js +7 -0
  29. package/.cursor/hooks/session-end.js +10 -0
  30. package/.cursor/hooks/session-start.js +10 -0
  31. package/.cursor/hooks/stop.js +18 -0
  32. package/.cursor/hooks/subagent-start.js +10 -0
  33. package/.cursor/hooks/subagent-stop.js +10 -0
  34. package/.cursor/hooks.json +107 -0
  35. package/.cursor/skills/aside/SKILL.md +115 -0
  36. package/.cursor/skills/checkpoint/SKILL.md +50 -0
  37. package/.cursor/skills/configure-scc/SKILL.md +160 -0
  38. package/.cursor/skills/continuous-agent-loop/SKILL.md +260 -0
  39. package/.cursor/skills/mcp-server-patterns/SKILL.md +142 -0
  40. package/.cursor/skills/model-route/SKILL.md +81 -0
  41. package/.cursor/skills/prompt-optimizer/SKILL.md +366 -0
  42. package/.cursor/skills/refactor-clean/SKILL.md +133 -0
  43. package/.cursor/skills/resume-session/SKILL.md +111 -0
  44. package/.cursor/skills/save-session/SKILL.md +183 -0
  45. package/.cursor/skills/search-first/SKILL.md +140 -0
  46. package/.cursor/skills/security-scan/SKILL.md +142 -0
  47. package/.cursor/skills/sessions/SKILL.md +124 -0
  48. package/.cursor/skills/sf-agentforce-development/SKILL.md +449 -0
  49. package/.cursor/skills/sf-apex-async-patterns/SKILL.md +324 -0
  50. package/.cursor/skills/sf-apex-best-practices/SKILL.md +421 -0
  51. package/.cursor/skills/sf-apex-constraints/SKILL.md +79 -0
  52. package/.cursor/skills/sf-apex-cursor/SKILL.md +336 -0
  53. package/.cursor/skills/sf-apex-enterprise-patterns/SKILL.md +344 -0
  54. package/.cursor/skills/sf-apex-testing/SKILL.md +407 -0
  55. package/.cursor/skills/sf-api-design/SKILL.md +237 -0
  56. package/.cursor/skills/sf-approval-processes/SKILL.md +312 -0
  57. package/.cursor/skills/sf-aura-development/SKILL.md +260 -0
  58. package/.cursor/skills/sf-build-fix/SKILL.md +120 -0
  59. package/.cursor/skills/sf-data-modeling/SKILL.md +274 -0
  60. package/.cursor/skills/sf-debugging/SKILL.md +362 -0
  61. package/.cursor/skills/sf-deployment/SKILL.md +291 -0
  62. package/.cursor/skills/sf-deployment-constraints/SKILL.md +153 -0
  63. package/.cursor/skills/sf-devops-ci-cd/SKILL.md +322 -0
  64. package/.cursor/skills/sf-docs-lookup/SKILL.md +100 -0
  65. package/.cursor/skills/sf-e2e-testing/SKILL.md +321 -0
  66. package/.cursor/skills/sf-experience-cloud/SKILL.md +248 -0
  67. package/.cursor/skills/sf-flow-development/SKILL.md +376 -0
  68. package/.cursor/skills/sf-governor-limits/SKILL.md +319 -0
  69. package/.cursor/skills/sf-harness-audit/SKILL.md +139 -0
  70. package/.cursor/skills/sf-help/SKILL.md +156 -0
  71. package/.cursor/skills/sf-integration/SKILL.md +479 -0
  72. package/.cursor/skills/sf-lwc-constraints/SKILL.md +128 -0
  73. package/.cursor/skills/sf-lwc-development/SKILL.md +302 -0
  74. package/.cursor/skills/sf-lwc-testing/SKILL.md +387 -0
  75. package/.cursor/skills/sf-metadata-management/SKILL.md +285 -0
  76. package/.cursor/skills/sf-platform-events-cdc/SKILL.md +372 -0
  77. package/.cursor/skills/sf-quickstart/SKILL.md +170 -0
  78. package/.cursor/skills/sf-security/SKILL.md +330 -0
  79. package/.cursor/skills/sf-security-constraints/SKILL.md +125 -0
  80. package/.cursor/skills/sf-soql-constraints/SKILL.md +129 -0
  81. package/.cursor/skills/sf-soql-optimization/SKILL.md +353 -0
  82. package/.cursor/skills/sf-tdd-workflow/SKILL.md +332 -0
  83. package/.cursor/skills/sf-testing-constraints/SKILL.md +198 -0
  84. package/.cursor/skills/sf-trigger-constraints/SKILL.md +88 -0
  85. package/.cursor/skills/sf-trigger-frameworks/SKILL.md +343 -0
  86. package/.cursor/skills/sf-visualforce-development/SKILL.md +259 -0
  87. package/.cursor/skills/strategic-compact/SKILL.md +205 -0
  88. package/.cursor/skills/update-docs/SKILL.md +162 -0
  89. package/.cursor/skills/update-platform-docs/SKILL.md +86 -0
  90. package/.cursor-plugin/plugin.json +26 -0
  91. package/LICENSE +21 -0
  92. package/README.md +522 -0
  93. package/agents/deep-researcher.md +145 -0
  94. package/agents/doc-updater.md +222 -0
  95. package/agents/eval-runner.md +340 -0
  96. package/agents/learning-engine.md +211 -0
  97. package/agents/loop-operator.md +247 -0
  98. package/agents/refactor-cleaner.md +122 -0
  99. package/agents/sf-admin-agent.md +131 -0
  100. package/agents/sf-agentforce-agent.md +132 -0
  101. package/agents/sf-apex-agent.md +124 -0
  102. package/agents/sf-architect.md +435 -0
  103. package/agents/sf-aura-reviewer.md +372 -0
  104. package/agents/sf-bugfix-agent.md +105 -0
  105. package/agents/sf-flow-agent.md +159 -0
  106. package/agents/sf-integration-agent.md +146 -0
  107. package/agents/sf-lwc-agent.md +127 -0
  108. package/agents/sf-review-agent.md +366 -0
  109. package/agents/sf-visualforce-reviewer.md +468 -0
  110. package/assets/logo.svg +18 -0
  111. package/docs/ARCHITECTURE.md +133 -0
  112. package/docs/authoring-guide.md +373 -0
  113. package/docs/hook-development.md +578 -0
  114. package/docs/token-optimization.md +139 -0
  115. package/docs/workflow-examples.md +645 -0
  116. package/examples/agentforce-action/README.md +227 -0
  117. package/examples/apex-trigger-handler/README.md +114 -0
  118. package/examples/devops-pipeline/README.md +325 -0
  119. package/examples/flow-automation/README.md +188 -0
  120. package/examples/integration-pattern/README.md +416 -0
  121. package/examples/lwc-component/README.md +180 -0
  122. package/examples/platform-events/README.md +492 -0
  123. package/examples/scratch-org-setup/README.md +138 -0
  124. package/examples/security-audit/README.md +244 -0
  125. package/examples/visualforce-migration/README.md +314 -0
  126. package/hooks/hooks.json +338 -0
  127. package/hooks/memory-persistence/README.md +73 -0
  128. package/manifests/install-modules.json +217 -0
  129. package/manifests/install-profiles.json +17 -0
  130. package/mcp-configs/mcp-servers.json +19 -0
  131. package/package.json +89 -0
  132. package/schemas/hooks.schema.json +123 -0
  133. package/schemas/install-modules.schema.json +76 -0
  134. package/schemas/install-profiles.schema.json +28 -0
  135. package/schemas/install-state.schema.json +73 -0
  136. package/schemas/package-manager.schema.json +18 -0
  137. package/schemas/plugin.schema.json +112 -0
  138. package/schemas/scc-install-config.schema.json +29 -0
  139. package/schemas/state-store.schema.json +111 -0
  140. package/scripts/cli/install-apply.js +170 -0
  141. package/scripts/cli/uninstall.js +193 -0
  142. package/scripts/hooks/check-console-log.js +101 -0
  143. package/scripts/hooks/check-hook-enabled.js +17 -0
  144. package/scripts/hooks/check-platform-docs-age.js +48 -0
  145. package/scripts/hooks/cost-tracker.js +78 -0
  146. package/scripts/hooks/doc-file-warning.js +63 -0
  147. package/scripts/hooks/evaluate-session.js +98 -0
  148. package/scripts/hooks/governor-check.js +220 -0
  149. package/scripts/hooks/learning-observe.sh +206 -0
  150. package/scripts/hooks/mcp-health-check.js +588 -0
  151. package/scripts/hooks/post-bash-build-complete.js +34 -0
  152. package/scripts/hooks/post-bash-pr-created.js +43 -0
  153. package/scripts/hooks/post-edit-console-warn.js +61 -0
  154. package/scripts/hooks/post-edit-format.js +79 -0
  155. package/scripts/hooks/post-edit-typecheck.js +98 -0
  156. package/scripts/hooks/post-write.js +168 -0
  157. package/scripts/hooks/pre-bash-git-push-reminder.js +35 -0
  158. package/scripts/hooks/pre-bash-tmux-reminder.js +47 -0
  159. package/scripts/hooks/pre-compact.js +51 -0
  160. package/scripts/hooks/pre-tool-use.js +163 -0
  161. package/scripts/hooks/pre-write-doc-warn.js +9 -0
  162. package/scripts/hooks/quality-gate.js +251 -0
  163. package/scripts/hooks/run-with-flags-shell.sh +32 -0
  164. package/scripts/hooks/run-with-flags.js +135 -0
  165. package/scripts/hooks/session-end-marker.js +29 -0
  166. package/scripts/hooks/session-end.js +311 -0
  167. package/scripts/hooks/session-start.js +202 -0
  168. package/scripts/hooks/sfdx-scanner-check.js +142 -0
  169. package/scripts/hooks/sfdx-validate.js +119 -0
  170. package/scripts/hooks/stop-hook.js +170 -0
  171. package/scripts/hooks/suggest-compact.js +67 -0
  172. package/scripts/lib/agent-adapter.js +82 -0
  173. package/scripts/lib/apex-analysis.js +194 -0
  174. package/scripts/lib/hook-flags.js +74 -0
  175. package/scripts/lib/install-config.js +73 -0
  176. package/scripts/lib/install-executor.js +363 -0
  177. package/scripts/lib/install-state.js +121 -0
  178. package/scripts/lib/orchestration-session.js +299 -0
  179. package/scripts/lib/package-manager.js +124 -0
  180. package/scripts/lib/project-detect.js +228 -0
  181. package/scripts/lib/schema-validator.js +190 -0
  182. package/scripts/lib/skill-adapter.js +100 -0
  183. package/scripts/lib/state-store.js +376 -0
  184. package/scripts/lib/tmux-worktree-orchestrator.js +598 -0
  185. package/scripts/lib/utils.js +313 -0
  186. package/scripts/scc.js +164 -0
  187. package/skills/_reference/AGENTFORCE_PATTERNS.md +112 -0
  188. package/skills/_reference/APEX_CURSOR.md +159 -0
  189. package/skills/_reference/API_VERSIONS.md +78 -0
  190. package/skills/_reference/APPROVAL_PROCESSES.md +105 -0
  191. package/skills/_reference/ASYNC_PATTERNS.md +163 -0
  192. package/skills/_reference/AURA_COMPONENTS.md +146 -0
  193. package/skills/_reference/DATA_MIGRATION_PATTERNS.md +151 -0
  194. package/skills/_reference/DATA_MODELING.md +124 -0
  195. package/skills/_reference/DEBUGGING_TOOLS.md +140 -0
  196. package/skills/_reference/DEPLOYMENT_CHECKLIST.md +87 -0
  197. package/skills/_reference/DEPRECATIONS.md +79 -0
  198. package/skills/_reference/DOCKER_CI_PATTERNS.md +138 -0
  199. package/skills/_reference/ENTERPRISE_PATTERNS.md +122 -0
  200. package/skills/_reference/EXPERIENCE_CLOUD.md +143 -0
  201. package/skills/_reference/FLOW_PATTERNS.md +113 -0
  202. package/skills/_reference/GOVERNOR_LIMITS.md +77 -0
  203. package/skills/_reference/INTEGRATION_PATTERNS.md +105 -0
  204. package/skills/_reference/LWC_PATTERNS.md +79 -0
  205. package/skills/_reference/METADATA_TYPES.md +115 -0
  206. package/skills/_reference/NAMING_CONVENTIONS.md +84 -0
  207. package/skills/_reference/PACKAGE_DEVELOPMENT.md +150 -0
  208. package/skills/_reference/PLATFORM_EVENTS.md +121 -0
  209. package/skills/_reference/REPORTING_API.md +143 -0
  210. package/skills/_reference/SCRATCH_ORG_PATTERNS.md +126 -0
  211. package/skills/_reference/SECURITY_PATTERNS.md +127 -0
  212. package/skills/_reference/SHARING_MODEL.md +120 -0
  213. package/skills/_reference/SOQL_PATTERNS.md +119 -0
  214. package/skills/_reference/TESTING_STANDARDS.md +96 -0
  215. package/skills/_reference/TRIGGER_PATTERNS.md +114 -0
  216. package/skills/_reference/VISUALFORCE_PATTERNS.md +121 -0
  217. package/skills/aside/SKILL.md +118 -0
  218. package/skills/checkpoint/SKILL.md +53 -0
  219. package/skills/configure-scc/SKILL.md +163 -0
  220. package/skills/continuous-agent-loop/SKILL.md +264 -0
  221. package/skills/mcp-server-patterns/SKILL.md +146 -0
  222. package/skills/model-route/SKILL.md +84 -0
  223. package/skills/prompt-optimizer/SKILL.md +369 -0
  224. package/skills/refactor-clean/SKILL.md +136 -0
  225. package/skills/resume-session/SKILL.md +114 -0
  226. package/skills/save-session/SKILL.md +186 -0
  227. package/skills/search-first/SKILL.md +144 -0
  228. package/skills/security-scan/SKILL.md +146 -0
  229. package/skills/sessions/SKILL.md +127 -0
  230. package/skills/sf-agentforce-development/SKILL.md +450 -0
  231. package/skills/sf-apex-async-patterns/SKILL.md +326 -0
  232. package/skills/sf-apex-best-practices/SKILL.md +425 -0
  233. package/skills/sf-apex-constraints/SKILL.md +81 -0
  234. package/skills/sf-apex-cursor/SKILL.md +338 -0
  235. package/skills/sf-apex-enterprise-patterns/SKILL.md +348 -0
  236. package/skills/sf-apex-testing/SKILL.md +409 -0
  237. package/skills/sf-api-design/SKILL.md +238 -0
  238. package/skills/sf-approval-processes/SKILL.md +315 -0
  239. package/skills/sf-aura-development/SKILL.md +263 -0
  240. package/skills/sf-build-fix/SKILL.md +121 -0
  241. package/skills/sf-data-modeling/SKILL.md +278 -0
  242. package/skills/sf-debugging/SKILL.md +363 -0
  243. package/skills/sf-deployment/SKILL.md +295 -0
  244. package/skills/sf-deployment-constraints/SKILL.md +155 -0
  245. package/skills/sf-devops-ci-cd/SKILL.md +325 -0
  246. package/skills/sf-docs-lookup/SKILL.md +103 -0
  247. package/skills/sf-e2e-testing/SKILL.md +324 -0
  248. package/skills/sf-experience-cloud/SKILL.md +249 -0
  249. package/skills/sf-flow-development/SKILL.md +377 -0
  250. package/skills/sf-governor-limits/SKILL.md +323 -0
  251. package/skills/sf-harness-audit/SKILL.md +142 -0
  252. package/skills/sf-help/SKILL.md +159 -0
  253. package/skills/sf-integration/SKILL.md +483 -0
  254. package/skills/sf-lwc-constraints/SKILL.md +130 -0
  255. package/skills/sf-lwc-development/SKILL.md +303 -0
  256. package/skills/sf-lwc-testing/SKILL.md +388 -0
  257. package/skills/sf-metadata-management/SKILL.md +288 -0
  258. package/skills/sf-platform-events-cdc/SKILL.md +375 -0
  259. package/skills/sf-quickstart/SKILL.md +173 -0
  260. package/skills/sf-security/SKILL.md +334 -0
  261. package/skills/sf-security-constraints/SKILL.md +127 -0
  262. package/skills/sf-soql-constraints/SKILL.md +131 -0
  263. package/skills/sf-soql-optimization/SKILL.md +354 -0
  264. package/skills/sf-tdd-workflow/SKILL.md +336 -0
  265. package/skills/sf-testing-constraints/SKILL.md +200 -0
  266. package/skills/sf-trigger-constraints/SKILL.md +90 -0
  267. package/skills/sf-trigger-frameworks/SKILL.md +347 -0
  268. package/skills/sf-visualforce-development/SKILL.md +260 -0
  269. package/skills/strategic-compact/SKILL.md +208 -0
  270. package/skills/update-docs/SKILL.md +165 -0
  271. package/skills/update-platform-docs/SKILL.md +90 -0
@@ -0,0 +1,324 @@
1
+ ---
2
+ name: sf-e2e-testing
3
+ description: >-
4
+ Use when writing Salesforce Apex end-to-end integration tests, deployment
5
+ verification, or bulk scenario validation. Do NOT use for unit tests or TDD.
6
+ origin: SCC
7
+ user-invocable: false
8
+ ---
9
+
10
+ # Salesforce E2E Testing
11
+
12
+ Comprehensive testing patterns for Salesforce applications including Apex integration tests, LWC component tests, and deployment verification.
13
+
14
+ Reference: @../_reference/TESTING_STANDARDS.md
15
+
16
+ ## When to Use
17
+
18
+ - When writing integration tests that exercise complete business workflows end-to-end
19
+ - When verifying full automation chains including triggers, flows, and queueable jobs
20
+ - When setting up pre-deployment verification test suites for a sandbox or production org
21
+ - When testing bulk scenarios with 200+ records across the full trigger and automation stack
22
+ - When building LWC integration tests with Jest that mock Apex wire adapters and calls
23
+
24
+ ## Apex Integration Tests
25
+
26
+ ```apex
27
+ @IsTest
28
+ private class OpportunityWorkflowTest {
29
+
30
+ @TestSetup
31
+ static void setup() {
32
+ Account acc = new Account(Name = 'E2E Test Account');
33
+ insert acc;
34
+
35
+ Opportunity opp = new Opportunity(
36
+ AccountId = acc.Id,
37
+ Name = 'E2E Test Opp',
38
+ StageName = 'Prospecting',
39
+ CloseDate = Date.today().addDays(30),
40
+ Amount = 50000
41
+ );
42
+ insert opp;
43
+ }
44
+
45
+ @IsTest
46
+ static void shouldProgressThroughFullSalesCycle() {
47
+ Opportunity opp = [SELECT Id, StageName FROM Opportunity LIMIT 1];
48
+
49
+ Test.startTest();
50
+
51
+ opp.StageName = 'Qualification';
52
+ update opp;
53
+
54
+ opp.StageName = 'Proposal/Price Quote';
55
+ update opp;
56
+
57
+ opp.StageName = 'Closed Won';
58
+ update opp;
59
+
60
+ Test.stopTest();
61
+
62
+ Opportunity result = [SELECT StageName, IsClosed, IsWon FROM Opportunity WHERE Id = :opp.Id];
63
+ Assert.areEqual('Closed Won', result.StageName);
64
+ Assert.isTrue(result.IsClosed, 'Should be closed');
65
+ Assert.isTrue(result.IsWon, 'Should be won');
66
+
67
+ // Verify downstream automation fired
68
+ List<Task> followUpTasks = [SELECT Id FROM Task WHERE WhatId = :opp.Id];
69
+ Assert.isTrue(!followUpTasks.isEmpty(), 'Should have created follow-up tasks');
70
+ }
71
+
72
+ @IsTest
73
+ static void shouldHandleBulkStageChanges() {
74
+ List<Opportunity> opps = new List<Opportunity>();
75
+ Account acc = [SELECT Id FROM Account LIMIT 1];
76
+ for (Integer i = 0; i < 200; i++) {
77
+ opps.add(new Opportunity(
78
+ AccountId = acc.Id,
79
+ Name = 'Bulk Opp ' + i,
80
+ StageName = 'Prospecting',
81
+ CloseDate = Date.today().addDays(30)
82
+ ));
83
+ }
84
+ insert opps;
85
+
86
+ Test.startTest();
87
+ for (Opportunity opp : opps) {
88
+ opp.StageName = 'Closed Won';
89
+ }
90
+ update opps;
91
+ Test.stopTest();
92
+
93
+ Integer closedCount = [SELECT COUNT() FROM Opportunity WHERE StageName = 'Closed Won'];
94
+ Assert.isTrue(closedCount >= 200, 'All opportunities should be closed');
95
+ }
96
+ }
97
+ ```
98
+
99
+ ## LWC Integration Tests
100
+
101
+ ```javascript
102
+ import { createElement } from 'lwc';
103
+ import OpportunityPipeline from 'c/opportunityPipeline';
104
+ import getOpportunities from '@salesforce/apex/OpportunityController.getOpportunities';
105
+
106
+ jest.mock('@salesforce/apex/OpportunityController.getOpportunities', () => ({
107
+ default: jest.fn()
108
+ }), { virtual: true });
109
+
110
+ const MOCK_OPPS = [
111
+ { Id: '006xx0001', Name: 'Opp 1', StageName: 'Prospecting', Amount: 10000 },
112
+ { Id: '006xx0002', Name: 'Opp 2', StageName: 'Closed Won', Amount: 50000 },
113
+ ];
114
+
115
+ describe('c-opportunity-pipeline (integration)', () => {
116
+ afterEach(() => { while (document.body.firstChild) document.body.removeChild(document.body.firstChild); });
117
+
118
+ it('renders pipeline with correct stage grouping', async () => {
119
+ getOpportunities.mockResolvedValue(MOCK_OPPS);
120
+ const element = createElement('c-opportunity-pipeline', { is: OpportunityPipeline });
121
+ document.body.appendChild(element);
122
+
123
+ await Promise.resolve();
124
+ await Promise.resolve();
125
+
126
+ const stages = element.shadowRoot.querySelectorAll('.stage-column');
127
+ expect(stages.length).toBeGreaterThan(0);
128
+ });
129
+ });
130
+ ```
131
+
132
+ ## Deployment Verification
133
+
134
+ ```bash
135
+ # Full E2E deployment verification
136
+ sf project deploy validate --test-level RunLocalTests --target-org staging
137
+ sf project deploy start --test-level RunLocalTests --target-org staging
138
+ sf apex run test --test-level RunLocalTests --result-format human --target-org staging
139
+ ```
140
+
141
+ ## Flow Integration Testing
142
+
143
+ ```apex
144
+ @IsTest
145
+ private class CaseEscalationFlowTest {
146
+
147
+ @IsTest
148
+ static void shouldEscalateHighPriorityCases() {
149
+ Account acc = new Account(Name = 'Flow E2E Account');
150
+ insert acc;
151
+
152
+ Case c = new Case(
153
+ AccountId = acc.Id,
154
+ Subject = 'Urgent Issue',
155
+ Priority = 'High',
156
+ Status = 'New'
157
+ );
158
+ insert c;
159
+
160
+ Test.startTest();
161
+ c.Status = 'Escalated';
162
+ update c;
163
+ Test.stopTest();
164
+
165
+ List<Task> tasks = [SELECT Subject, Priority FROM Task WHERE WhatId = :c.Id AND Subject LIKE '%Escalation%'];
166
+ Assert.isTrue(!tasks.isEmpty(), 'Flow should have created escalation task');
167
+ Assert.areEqual('High', tasks[0].Priority, 'Task priority should match case priority');
168
+ }
169
+ }
170
+ ```
171
+
172
+ ## Platform Event Testing
173
+
174
+ ```apex
175
+ @IsTest
176
+ private class OrderEventTest {
177
+
178
+ @IsTest
179
+ static void shouldPublishEventOnOrderCompletion() {
180
+ Order_Complete__e event = new Order_Complete__e(
181
+ Order_Id__c = 'ORD-001',
182
+ Total_Amount__c = 5000.00
183
+ );
184
+
185
+ Test.startTest();
186
+ Database.SaveResult sr = EventBus.publish(event);
187
+ Test.stopTest();
188
+
189
+ Assert.isTrue(sr.isSuccess(), 'Event should publish successfully');
190
+ }
191
+
192
+ @IsTest
193
+ static void shouldProcessEventInSubscriber() {
194
+ Order_Complete__e event = new Order_Complete__e(
195
+ Order_Id__c = 'ORD-002',
196
+ Total_Amount__c = 10000.00
197
+ );
198
+
199
+ Test.startTest();
200
+ EventBus.publish(event);
201
+ Test.getEventBus().deliver(); // Force trigger subscriber to execute
202
+ Test.stopTest();
203
+
204
+ List<Fulfillment__c> fulfillments = [
205
+ SELECT Order_Id__c FROM Fulfillment__c WHERE Order_Id__c = 'ORD-002'
206
+ ];
207
+ Assert.areEqual(1, fulfillments.size(), 'Subscriber should have created fulfillment');
208
+ }
209
+ }
210
+ ```
211
+
212
+ ## Async Job Verification
213
+
214
+ ```apex
215
+ @IsTest
216
+ private class AsyncWorkflowTest {
217
+
218
+ @IsTest
219
+ static void shouldProcessQueueableChain() {
220
+ Account acc = new Account(Name = 'Async E2E');
221
+ insert acc;
222
+
223
+ Test.startTest();
224
+ System.enqueueJob(new AccountEnrichmentJob(acc.Id));
225
+ Test.stopTest();
226
+
227
+ Account result = [SELECT Description, Industry FROM Account WHERE Id = :acc.Id];
228
+ Assert.isNotNull(result.Description, 'Enrichment job should populate description');
229
+ }
230
+ }
231
+ ```
232
+
233
+ ## Multi-User Testing
234
+
235
+ ```apex
236
+ @IsTest
237
+ private class PermissionE2ETest {
238
+
239
+ @IsTest
240
+ static void shouldRestrictAccessForStandardUser() {
241
+ // Note: Profile names are locale-dependent. For non-English orgs,
242
+ // query by Profile.UserType or use a custom permission set.
243
+ Profile stdProfile = [SELECT Id FROM Profile WHERE Name = 'Standard User'];
244
+ User testUser = new User(
245
+ Alias = 'stdu', Email = 'stduser@test.com',
246
+ EmailEncodingKey = 'UTF-8', LastName = 'StdUser',
247
+ LanguageLocaleKey = 'en_US', LocaleSidKey = 'en_US',
248
+ ProfileId = stdProfile.Id, TimeZoneSidKey = 'America/Los_Angeles',
249
+ UserName = 'stduser' + DateTime.now().getTime() + '@test.com'
250
+ );
251
+ insert testUser;
252
+
253
+ System.runAs(testUser) {
254
+ Test.startTest();
255
+ try {
256
+ ConfidentialRecord__c rec = new ConfidentialRecord__c(Name = 'Secret');
257
+ insert rec;
258
+ Assert.fail('Should have thrown insufficient access exception');
259
+ } catch (DmlException e) {
260
+ Assert.isTrue(e.getMessage().contains('INSUFFICIENT_ACCESS') ||
261
+ e.getMessage().contains('access'),
262
+ 'Should get access denied: ' + e.getMessage());
263
+ }
264
+ Test.stopTest();
265
+ }
266
+ }
267
+ }
268
+ ```
269
+
270
+ ## Performance Assertions
271
+
272
+ ```apex
273
+ @IsTest
274
+ private class PerformanceE2ETest {
275
+
276
+ @IsTest
277
+ static void shouldStayWithinGovernorLimits() {
278
+ List<Account> accounts = new List<Account>();
279
+ for (Integer i = 0; i < 200; i++) {
280
+ accounts.add(new Account(Name = 'Perf Test ' + i));
281
+ }
282
+ insert accounts;
283
+
284
+ Test.startTest();
285
+ Integer queriesBefore = Limits.getQueries();
286
+
287
+ AccountService.processAccounts(new Map<Id, Account>(accounts).keySet());
288
+
289
+ Integer queriesUsed = Limits.getQueries() - queriesBefore;
290
+ Test.stopTest();
291
+
292
+ Assert.isTrue(queriesUsed <= 5,
293
+ 'Should use <= 5 SOQL queries for 200 records, used: ' + queriesUsed);
294
+ }
295
+ }
296
+ ```
297
+
298
+ ## Anti-Patterns
299
+
300
+ | Anti-Pattern | Problem | Fix |
301
+ |-------------|---------|-----|
302
+ | Testing with 1 record only | Misses bulkification bugs | Test with 200+ records |
303
+ | No Test.startTest/stopTest | Governor limits from setup count against test | Wrap test logic in startTest/stopTest |
304
+ | Using SeeAllData=true | Tests depend on org data, fail unpredictably | Use @TestSetup with test-specific data |
305
+ | Hardcoded IDs | Break across orgs and sandboxes | Query for IDs or use TestDataFactory |
306
+ | No downstream verification | Trigger fires but automation not verified | Assert on records created by automation |
307
+ | Ignoring async results | Queueable/Batch results not checked | Test.stopTest forces execution, then assert |
308
+
309
+ ## Best Practices
310
+
311
+ - Use @TestSetup for shared test data across methods
312
+ - Test complete workflows, not just individual methods
313
+ - Include bulk tests (200+ records) for all trigger-based automation
314
+ - Test both happy path and error scenarios
315
+ - Verify downstream automation by checking created records
316
+ - Use Test.startTest()/Test.stopTest() to isolate governor limit counting
317
+ - Use Test.getEventBus().deliver() to force Platform Event subscriber execution
318
+ - Use System.runAs() to test permission and sharing model enforcement
319
+ - Assert governor limit consumption for performance-sensitive code
320
+ - For HTTP callout tests, use `Test.setMock(HttpCalloutMock.class, mock)` -- see the sf-integration skill for mock patterns
321
+
322
+ ## Related
323
+
324
+ - **Constraints**: `sf-testing-constraints` -- test isolation rules, assertion requirements, coverage gates
@@ -0,0 +1,249 @@
1
+ ---
2
+ name: sf-experience-cloud
3
+ description: "Salesforce Experience Cloud — site setup, guest users, external sharing, LWC in communities, CMS, auth. Use when building portals or partner communities. Do NOT use for internal Lightning apps."
4
+ origin: SCC
5
+ user-invocable: false
6
+ ---
7
+
8
+ # Salesforce Experience Cloud
9
+
10
+ ## When to Use
11
+
12
+ - When building customer self-service portals, partner communities, or public-facing sites
13
+ - When configuring guest user access and reviewing external user security
14
+ - When developing LWC components for Experience Cloud sites
15
+ - When managing Experience Cloud deployment (Network, ExperienceBundle metadata)
16
+ - When designing sharing models for community/external users
17
+
18
+ @../_reference/EXPERIENCE_CLOUD.md
19
+
20
+ ---
21
+
22
+ ## Site Setup Procedure
23
+
24
+ ### Step 1 — Choose Site Type
25
+
26
+ | Site Type | Use Case |
27
+ |-----------|----------|
28
+ | Customer Service | Self-service portal (Knowledge, Cases) |
29
+ | Partner Central | Channel partner management (Leads, Opps) |
30
+ | Build Your Own (LWR) | Custom branded site, full customization |
31
+ | Help Center | Public knowledge base, no login required |
32
+
33
+ For new sites, use LWR (Lightning Web Runtime) for better performance, SEO, and LWC-only components.
34
+
35
+ ### Step 2 — Configure User Licensing
36
+
37
+ | User Type | License | Access |
38
+ |-----------|---------|--------|
39
+ | Customer Community | Community | Read/create own records |
40
+ | Customer Community Plus | Community Plus | Read/create + sharing rules |
41
+ | Partner Community | Partner Community | Leads, Opps, deal registration |
42
+ | Guest User | None | Public read access only |
43
+
44
+ ### Step 3 — Set Up Sharing Model
45
+
46
+ External users see records based on their Account association:
47
+
48
+ ```
49
+ External User -> Contact -> Account -> Records shared with that Account
50
+ ```
51
+
52
+ Configure Sharing Sets in Setup for account-based access. Each community has automatic share groups: All Customer Portal Users, All Partner Users.
53
+
54
+ ---
55
+
56
+ ## Guest User Configuration
57
+
58
+ Guest users access your site without logging in. This is the highest-risk area for data exposure.
59
+
60
+ ### Profile Permissions
61
+
62
+ - Grant Read only on objects explicitly needed for public display
63
+ - Review: Setup > Digital Experiences > [Site] > Guest User Profile
64
+
65
+ ### Guest User Sharing Rules
66
+
67
+ Configure in Setup > Sharing Settings > Guest User Sharing Rules:
68
+
69
+ ```
70
+ Object: Knowledge__kav
71
+ Criteria: IsPublished__c = TRUE AND Channel__c includes 'Public'
72
+ Access: Read Only
73
+ Shared With: Guest User (site-specific)
74
+ ```
75
+
76
+ ### Securing Apex Controllers for Guest Access
77
+
78
+ ```apex
79
+ // Use "with sharing" to enforce sharing rules
80
+ // Use WITH USER_MODE for CRUD/FLS enforcement
81
+ public with sharing class PublicKnowledgeController {
82
+ @AuraEnabled(cacheable=true)
83
+ public static List<Knowledge__kav> getPublicArticles() {
84
+ return [
85
+ SELECT Title, Summary FROM Knowledge__kav
86
+ WHERE PublishStatus = 'Online' AND IsVisibleInPkb = true
87
+ WITH USER_MODE
88
+ ];
89
+ }
90
+ }
91
+ ```
92
+
93
+ `with sharing` is necessary but not sufficient for guest users. You must also configure Guest User Sharing Rules. Without them, the query returns zero results.
94
+
95
+ ---
96
+
97
+ ## LWC in Experience Cloud
98
+
99
+ ### Component Meta XML
100
+
101
+ ```xml
102
+ <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
103
+ <apiVersion>66.0</apiVersion>
104
+ <isExposed>true</isExposed>
105
+ <targets>
106
+ <target>lightningCommunity__Page</target>
107
+ <target>lightningCommunity__Default</target>
108
+ </targets>
109
+ <targetConfigs>
110
+ <targetConfig targets="lightningCommunity__Default">
111
+ <property name="title" type="String" label="Card Title" default="Welcome"/>
112
+ </targetConfig>
113
+ </targetConfigs>
114
+ </LightningComponentBundle>
115
+ ```
116
+
117
+ ### Accessing Community Context
118
+
119
+ ```javascript
120
+ import communityId from '@salesforce/community/Id';
121
+ import communityBasePath from '@salesforce/community/basePath';
122
+ import isGuest from '@salesforce/user/isGuest';
123
+ ```
124
+
125
+ ### Light DOM for Theming
126
+
127
+ LWR sites support Light DOM, allowing site-level CSS to style component internals:
128
+
129
+ ```javascript
130
+ export default class ThemedComponent extends LightningElement {
131
+ static renderMode = 'light';
132
+ }
133
+ ```
134
+
135
+ ### Navigation
136
+
137
+ ```javascript
138
+ import { NavigationMixin } from 'lightning/navigation';
139
+
140
+ // Navigate to a community named page
141
+ this[NavigationMixin.Navigate]({
142
+ type: 'comm__namedPage',
143
+ attributes: { name: 'Home' }
144
+ });
145
+ ```
146
+
147
+ ---
148
+
149
+ ## CMS Content
150
+
151
+ Manage content via CMS Workspaces, publish to site channels.
152
+
153
+ ```javascript
154
+ import { getContent } from 'experience/cmsDeliveryApi';
155
+
156
+ @wire(getContent, { channelId: '$channelId', contentKeyOrId: '$contentId' })
157
+ content;
158
+
159
+ get title() { return this.content?.data?.title?.value; }
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Custom Authentication
165
+
166
+ ### Self-Registration Handler
167
+
168
+ ```apex
169
+ global class CustomRegistrationHandler implements Auth.RegistrationHandler {
170
+ global User createUser(Id portalId, Auth.UserData data) {
171
+ Account portalAccount = [SELECT Id FROM Account WHERE Name = 'Community Users' LIMIT 1];
172
+ Contact c = new Contact(
173
+ AccountId = portalAccount.Id, FirstName = data.firstName,
174
+ LastName = data.lastName, Email = data.email
175
+ );
176
+ insert c;
177
+
178
+ Profile p = [SELECT Id FROM Profile WHERE Name = 'Customer Community User'];
179
+ return new User(
180
+ ContactId = c.Id, ProfileId = p.Id,
181
+ Username = data.email + '.community',
182
+ FirstName = data.firstName, LastName = data.lastName,
183
+ Email = data.email, Alias = data.firstName != null ? data.firstName.left(8) : 'guest',
184
+ EmailEncodingKey = 'UTF-8', LanguageLocaleKey = 'en_US',
185
+ LocaleSidKey = 'en_US', TimeZoneSidKey = 'America/Los_Angeles'
186
+ );
187
+ }
188
+
189
+ global void updateUser(Id userId, Id portalId, Auth.UserData data) {
190
+ update new User(Id = userId, FirstName = data.firstName,
191
+ LastName = data.lastName, Email = data.email);
192
+ }
193
+ }
194
+ ```
195
+
196
+ Social login: configure in Settings > Login & Registration > Social Sign-On (Google, Facebook, Apple, LinkedIn, or custom OAuth providers).
197
+
198
+ ---
199
+
200
+ ## Deployment Steps
201
+
202
+ ### Metadata Components
203
+
204
+ | Metadata Type | Directory |
205
+ |---------------|-----------|
206
+ | Network | `networks/` |
207
+ | ExperienceBundle | `experiences/` |
208
+ | CustomSite | `sites/` |
209
+ | NavigationMenu | `navigationMenus/` |
210
+
211
+ ### Deploy Procedure
212
+
213
+ ```bash
214
+ sf project deploy start --source-dir force-app/main/default/experiences
215
+ sf project deploy start --source-dir force-app/main/default/networks
216
+ ```
217
+
218
+ Publish via Experience Builder UI or Apex: `ConnectApi.Communities.publishCommunity(null, communityId);`
219
+
220
+ ### Deployment Checklist
221
+
222
+ 1. Deploy Network metadata (site configuration)
223
+ 2. Deploy ExperienceBundle (pages, themes, routes)
224
+ 3. Deploy NavigationMenu and dependent components (LWC, Apex, objects)
225
+ 4. Publish the site
226
+ 5. Verify guest user profile permissions
227
+ 6. Test with community user login
228
+
229
+ ---
230
+
231
+ ## SEO and Performance
232
+
233
+ - Configure sitemap in Settings > SEO (LWR sites only)
234
+ - Use semantic URLs (`/orders/12345` not `/s/detail/a01xx000003ABC`)
235
+ - Enable CDN caching for static assets (default for LWR)
236
+ - Use `@AuraEnabled(cacheable=true)` for read-only data
237
+ - Use Custom Labels for multi-language support
238
+
239
+ ---
240
+
241
+ ## Related
242
+
243
+ ### Guardrails
244
+
245
+ - **sf-security-constraints** — Enforced rules for guest user permissions, sharing, and CRUD/FLS
246
+
247
+ ### Agents
248
+
249
+ - **sf-lwc-agent** — For LWC components used in Experience Cloud sites