@salesforce/afv-skills 1.1.0 → 1.2.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 +4 -4
- package/skills/agentforce-development/SKILL.md +427 -0
- package/skills/agentforce-development/assets/README-legacy.md +89 -0
- package/skills/agentforce-development/assets/agent-spec-template.md +90 -0
- package/skills/agentforce-development/assets/agents/README.md +45 -0
- package/skills/agentforce-development/assets/agents/hello-world.agent +60 -0
- package/skills/agentforce-development/assets/agents/multi-topic.agent +105 -0
- package/skills/agentforce-development/assets/agents/production-faq.agent +101 -0
- package/skills/agentforce-development/assets/agents/production-faq.bundle-meta.xml +4 -0
- package/skills/agentforce-development/assets/agents/simple-qa.agent +72 -0
- package/skills/agentforce-development/assets/apex/models-api-queueable.cls +225 -0
- package/skills/agentforce-development/assets/bundle-meta.xml +23 -0
- package/skills/agentforce-development/assets/components/apex-action.agent +52 -0
- package/skills/agentforce-development/assets/components/error-handling.agent +58 -0
- package/skills/agentforce-development/assets/components/escalation-setup.agent +169 -0
- package/skills/agentforce-development/assets/components/flow-action.agent +66 -0
- package/skills/agentforce-development/assets/components/n-ary-conditions.agent +110 -0
- package/skills/agentforce-development/assets/components/topic-with-actions.agent +40 -0
- package/skills/agentforce-development/assets/deterministic-routing.agent +166 -0
- package/skills/agentforce-development/assets/escalation-pattern.agent +209 -0
- package/skills/agentforce-development/assets/flow-action-lookup.agent +115 -0
- package/skills/agentforce-development/assets/hub-and-spoke.agent +104 -0
- package/skills/agentforce-development/assets/invocable-apex-template.cls +187 -0
- package/skills/agentforce-development/assets/local-info-agent-annotated.agent +355 -0
- package/skills/agentforce-development/assets/metadata/basic-prompt-template.promptTemplate-meta.xml +109 -0
- package/skills/agentforce-development/assets/metadata/genai-function-apex.xml +92 -0
- package/skills/agentforce-development/assets/metadata/genai-function-flow.xml +57 -0
- package/skills/agentforce-development/assets/metadata/genai-plugin.xml +72 -0
- package/skills/agentforce-development/assets/metadata/http-callout-flow.flow-meta.xml +348 -0
- package/skills/agentforce-development/assets/metadata/record-grounded-prompt.promptTemplate-meta.xml +136 -0
- package/skills/agentforce-development/assets/minimal-starter.agent +42 -0
- package/skills/agentforce-development/assets/patterns/README.md +254 -0
- package/skills/agentforce-development/assets/patterns/action-callbacks.agent +178 -0
- package/skills/agentforce-development/assets/patterns/advanced-input-bindings.agent +141 -0
- package/skills/agentforce-development/assets/patterns/bidirectional-routing.agent +156 -0
- package/skills/agentforce-development/assets/patterns/critical-input-collection.agent +244 -0
- package/skills/agentforce-development/assets/patterns/delegation-routing.agent +89 -0
- package/skills/agentforce-development/assets/patterns/lifecycle-events.agent +127 -0
- package/skills/agentforce-development/assets/patterns/llm-controlled-actions.agent +184 -0
- package/skills/agentforce-development/assets/patterns/multi-step-workflow.agent +282 -0
- package/skills/agentforce-development/assets/patterns/open-gate-routing.agent +286 -0
- package/skills/agentforce-development/assets/patterns/procedural-instructions.agent +273 -0
- package/skills/agentforce-development/assets/patterns/prompt-template-action.agent +188 -0
- package/skills/agentforce-development/assets/patterns/system-instruction-overrides.agent +293 -0
- package/skills/agentforce-development/assets/prompt-rag-search.agent +131 -0
- package/skills/agentforce-development/assets/template-multi-topic.agent +160 -0
- package/skills/agentforce-development/assets/template-single-topic.agent +81 -0
- package/skills/agentforce-development/assets/verification-gate.agent +208 -0
- package/skills/agentforce-development/references/action-prompt-templates.md +164 -0
- package/skills/agentforce-development/references/actions-reference.md +592 -0
- package/skills/agentforce-development/references/agent-access-guide.md +72 -0
- package/skills/agentforce-development/references/agent-design-and-spec-creation.md +1010 -0
- package/skills/agentforce-development/references/agent-metadata-and-lifecycle.md +575 -0
- package/skills/agentforce-development/references/agent-script-core-language.md +1218 -0
- package/skills/agentforce-development/references/agent-topic-map-diagrams.md +323 -0
- package/skills/agentforce-development/references/agent-user-setup.md +526 -0
- package/skills/agentforce-development/references/agent-validation-and-debugging.md +803 -0
- package/skills/agentforce-development/references/known-issues.md +353 -0
- package/skills/agentforce-development/references/minimal-examples.md +67 -0
- package/skills/agentforce-development/references/production-gotchas.md +279 -0
- package/skills/agentforce-development/references/salesforce-cli-for-agents.md +393 -0
- package/skills/agentforce-development/references/version-history.md +23 -0
- package/skills/generate-permission-set/SKILL.md +174 -0
- package/skills/salesforce-custom-application/SKILL.md +1 -2
- package/skills/salesforce-custom-field/SKILL.md +0 -4
- package/skills/salesforce-custom-tab/SKILL.md +84 -8
- package/skills/salesforce-experience-lwr-site/SKILL.md +196 -0
- package/skills/salesforce-experience-lwr-site/docs/bootstrap-template-byo-lwr.md +224 -0
- package/skills/salesforce-experience-lwr-site/docs/configure-content-brandingSet.md +131 -0
- package/skills/salesforce-experience-lwr-site/docs/configure-content-route.md +232 -0
- package/skills/salesforce-experience-lwr-site/docs/configure-content-themeLayout.md +141 -0
- package/skills/salesforce-experience-lwr-site/docs/configure-content-view.md +233 -0
- package/skills/salesforce-experience-lwr-site/docs/configure-guest-sharing-rules.md +42 -0
- package/skills/salesforce-experience-lwr-site/docs/handle-component-and-region-ids.md +27 -0
- package/skills/salesforce-experience-lwr-site/docs/handle-ui-components.md +215 -0
- package/skills/salesforce-flow/SKILL.md +2 -2
- package/skills/salesforce-fragment/SKILL.md +85 -10
- package/skills/salesforce-lightning-app-build/SKILL.md +102 -10
- package/skills/apex-class/SKILL.md +0 -253
- package/skills/apex-class/examples/AccountDeduplicationBatch.cls +0 -148
- package/skills/apex-class/examples/AccountSelector.cls +0 -193
- package/skills/apex-class/examples/AccountService.cls +0 -201
- package/skills/apex-class/templates/abstract.cls +0 -128
- package/skills/apex-class/templates/batch.cls +0 -125
- package/skills/apex-class/templates/domain.cls +0 -102
- package/skills/apex-class/templates/dto.cls +0 -108
- package/skills/apex-class/templates/exception.cls +0 -51
- package/skills/apex-class/templates/interface.cls +0 -25
- package/skills/apex-class/templates/queueable.cls +0 -92
- package/skills/apex-class/templates/schedulable.cls +0 -75
- package/skills/apex-class/templates/selector.cls +0 -92
- package/skills/apex-class/templates/service.cls +0 -69
- package/skills/apex-class/templates/utility.cls +0 -97
- package/skills/apex-test-class/SKILL.md +0 -101
- package/skills/apex-test-class/references/assertion-patterns.md +0 -209
- package/skills/apex-test-class/references/async-testing.md +0 -276
- package/skills/apex-test-class/references/mocking-patterns.md +0 -219
- package/skills/apex-test-class/references/test-data-factory.md +0 -176
- package/skills/deployment-readiness-check/SKILL.md +0 -257
- package/skills/deployment-readiness-check/assets/deployment_checklist.md +0 -286
- package/skills/deployment-readiness-check/references/rollback_procedures.md +0 -308
- package/skills/deployment-readiness-check/scripts/check_metadata.sh +0 -207
- package/skills/salesforce-experience-site/SKILL.md +0 -178
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Domain class for {SObject}.
|
|
3
|
-
* Encapsulates field-level defaults, derivations, and validations.
|
|
4
|
-
* Operates only on in-memory SObject data — no SOQL or DML.
|
|
5
|
-
* @author Generated by Apex Class Writer Skill
|
|
6
|
-
*/
|
|
7
|
-
public with sharing class {SObject}Domain {
|
|
8
|
-
|
|
9
|
-
// ─── Constants ───────────────────────────────────────────────────────
|
|
10
|
-
// TODO: Add constants for default values, statuses, etc.
|
|
11
|
-
|
|
12
|
-
// ─── Field Defaults ──────────────────────────────────────────────────
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @description Applies default field values to new {SObject} records.
|
|
16
|
-
* Call this before insert to ensure consistent defaults.
|
|
17
|
-
* @param records List of {SObject} records to apply defaults to
|
|
18
|
-
*/
|
|
19
|
-
public static void applyDefaults(List<{SObject}> records) {
|
|
20
|
-
if (records == null || records.isEmpty()) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
for ({SObject} record : records) {
|
|
25
|
-
// TODO: Set default field values
|
|
26
|
-
// Example:
|
|
27
|
-
// if (record.Status__c == null) {
|
|
28
|
-
// record.Status__c = DEFAULT_STATUS;
|
|
29
|
-
// }
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// ─── Derivations ────────────────────────────────────────────────────
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @description Derives calculated field values based on other fields.
|
|
37
|
-
* Call this before insert and before update.
|
|
38
|
-
* @param records List of {SObject} records to derive values for
|
|
39
|
-
*/
|
|
40
|
-
public static void deriveFields(List<{SObject}> records) {
|
|
41
|
-
if (records == null || records.isEmpty()) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
for ({SObject} record : records) {
|
|
46
|
-
// TODO: Derive calculated field values
|
|
47
|
-
// Example:
|
|
48
|
-
// record.FullAddress__c = buildFullAddress(record);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// ─── Validations ────────────────────────────────────────────────────
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* @description Validates {SObject} records and adds errors for any violations.
|
|
56
|
-
* Call this before insert and before update.
|
|
57
|
-
* @param records List of {SObject} records to validate
|
|
58
|
-
*/
|
|
59
|
-
public static void validate(List<{SObject}> records) {
|
|
60
|
-
if (records == null || records.isEmpty()) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
for ({SObject} record : records) {
|
|
65
|
-
// TODO: Add validation rules
|
|
66
|
-
// Example:
|
|
67
|
-
// if (String.isBlank(record.Name)) {
|
|
68
|
-
// record.addError('Name is required.');
|
|
69
|
-
// }
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// ─── Comparisons ────────────────────────────────────────────────────
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* @description Determines which fields have changed between old and new record versions.
|
|
77
|
-
* Useful in before update context.
|
|
78
|
-
* @param oldRecord The previous version of the record
|
|
79
|
-
* @param newRecord The current version of the record
|
|
80
|
-
* @return Set of field API names that have changed
|
|
81
|
-
*/
|
|
82
|
-
public static Set<String> getChangedFields({SObject} oldRecord, {SObject} newRecord) {
|
|
83
|
-
Set<String> changedFields = new Set<String>();
|
|
84
|
-
|
|
85
|
-
if (oldRecord == null || newRecord == null) {
|
|
86
|
-
return changedFields;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
Map<String, Schema.SObjectField> fieldMap = Schema.SObjectType.{SObject}.fields.getMap();
|
|
90
|
-
for (String fieldName : fieldMap.keySet()) {
|
|
91
|
-
if (oldRecord.get(fieldName) != newRecord.get(fieldName)) {
|
|
92
|
-
changedFields.add(fieldName);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return changedFields;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// ─── Private Helpers ─────────────────────────────────────────────────
|
|
100
|
-
|
|
101
|
-
// TODO: Add private helper methods as needed
|
|
102
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Data Transfer Object for {describe the data this DTO represents}.
|
|
3
|
-
* Used to pass structured data between layers without exposing SObjects.
|
|
4
|
-
* Serialization-friendly for use with JSON.serialize/deserialize and API responses.
|
|
5
|
-
* @author Generated by Apex Class Writer Skill
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* // Create from constructor
|
|
9
|
-
* {ClassName} dto = new {ClassName}('value1', 42);
|
|
10
|
-
*
|
|
11
|
-
* // Deserialize from JSON
|
|
12
|
-
* {ClassName} dto = ({ClassName}) JSON.deserialize(jsonString, {ClassName}.class);
|
|
13
|
-
*/
|
|
14
|
-
public with sharing class {ClassName} {
|
|
15
|
-
|
|
16
|
-
// ─── Properties ──────────────────────────────────────────────────────
|
|
17
|
-
|
|
18
|
-
/** @description {Describe this property} */
|
|
19
|
-
public String name { get; set; }
|
|
20
|
-
|
|
21
|
-
/** @description {Describe this property} */
|
|
22
|
-
public Id recordId { get; set; }
|
|
23
|
-
|
|
24
|
-
/** @description {Describe this property} */
|
|
25
|
-
public Boolean isActive { get; set; }
|
|
26
|
-
|
|
27
|
-
/** @description {Describe this property} */
|
|
28
|
-
public List<String> tags { get; set; }
|
|
29
|
-
|
|
30
|
-
// TODO: Add additional properties as needed
|
|
31
|
-
|
|
32
|
-
// ─── Constructors ────────────────────────────────────────────────────
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @description No-arg constructor for deserialization compatibility
|
|
36
|
-
*/
|
|
37
|
-
public {ClassName}() {
|
|
38
|
-
this.tags = new List<String>();
|
|
39
|
-
this.isActive = false;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @description Parameterized constructor for convenience
|
|
44
|
-
* @param name The name value
|
|
45
|
-
* @param recordId The associated record Id
|
|
46
|
-
*/
|
|
47
|
-
public {ClassName}(String name, Id recordId) {
|
|
48
|
-
this();
|
|
49
|
-
this.name = name;
|
|
50
|
-
this.recordId = recordId;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// ─── Factory Methods ─────────────────────────────────────────────────
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @description Creates a DTO instance from an SObject record
|
|
57
|
-
* @param record The source {SObject} record
|
|
58
|
-
* @return A populated {ClassName} instance
|
|
59
|
-
*/
|
|
60
|
-
public static {ClassName} fromSObject(SObject record) {
|
|
61
|
-
if (record == null) {
|
|
62
|
-
return new {ClassName}();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
{ClassName} dto = new {ClassName}();
|
|
66
|
-
dto.recordId = record.Id;
|
|
67
|
-
dto.name = (String) record.get('Name');
|
|
68
|
-
// TODO: Map additional fields
|
|
69
|
-
|
|
70
|
-
return dto;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* @description Creates a list of DTOs from a list of SObject records
|
|
75
|
-
* @param records The source records
|
|
76
|
-
* @return List of populated {ClassName} instances
|
|
77
|
-
*/
|
|
78
|
-
public static List<{ClassName}> fromSObjects(List<SObject> records) {
|
|
79
|
-
List<{ClassName}> dtos = new List<{ClassName}>();
|
|
80
|
-
if (records == null) {
|
|
81
|
-
return dtos;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
for (SObject record : records) {
|
|
85
|
-
dtos.add(fromSObject(record));
|
|
86
|
-
}
|
|
87
|
-
return dtos;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// ─── Utility Methods ─────────────────────────────────────────────────
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* @description Serializes this DTO to a JSON string
|
|
94
|
-
* @return JSON representation of this DTO
|
|
95
|
-
*/
|
|
96
|
-
public String toJson() {
|
|
97
|
-
return JSON.serialize(this);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* @description Deserializes a JSON string into a {ClassName} instance
|
|
102
|
-
* @param jsonString The JSON string to deserialize
|
|
103
|
-
* @return A {ClassName} instance
|
|
104
|
-
*/
|
|
105
|
-
public static {ClassName} fromJson(String jsonString) {
|
|
106
|
-
return ({ClassName}) JSON.deserialize(jsonString, {ClassName}.class);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Custom exception for {describe when this exception is thrown}.
|
|
3
|
-
* Use this exception to signal domain-specific errors that callers
|
|
4
|
-
* can catch and handle distinctly from system exceptions.
|
|
5
|
-
* @author Generated by Apex Class Writer Skill
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* throw new {ClassName}('Account merge failed: duplicate detected.');
|
|
9
|
-
*
|
|
10
|
-
* // Wrap a caught exception
|
|
11
|
-
* try {
|
|
12
|
-
* // ... risky operation
|
|
13
|
-
* } catch (DmlException e) {
|
|
14
|
-
* throw new {ClassName}('DML failed during account merge: ' + e.getMessage());
|
|
15
|
-
* }
|
|
16
|
-
*/
|
|
17
|
-
public with sharing class {ClassName} extends Exception {
|
|
18
|
-
// Apex custom exceptions automatically inherit:
|
|
19
|
-
// - getMessage()
|
|
20
|
-
// - getCause()
|
|
21
|
-
// - getStackTraceString()
|
|
22
|
-
// - setMessage(String)
|
|
23
|
-
// - initCause(Exception)
|
|
24
|
-
//
|
|
25
|
-
// And support these constructor patterns:
|
|
26
|
-
// - new {ClassName}()
|
|
27
|
-
// - new {ClassName}('message')
|
|
28
|
-
// - new {ClassName}(causeException)
|
|
29
|
-
// - new {ClassName}('message', causeException)
|
|
30
|
-
//
|
|
31
|
-
// Note: Apex does NOT support custom constructors on Exception subclasses.
|
|
32
|
-
// To add context, use the message string or create a wrapper pattern:
|
|
33
|
-
//
|
|
34
|
-
// Example wrapper pattern (if you need structured error data):
|
|
35
|
-
//
|
|
36
|
-
// public class {ClassName}Detail {
|
|
37
|
-
// public String errorCode;
|
|
38
|
-
// public List<Id> failedRecordIds;
|
|
39
|
-
// public String detail;
|
|
40
|
-
//
|
|
41
|
-
// public {ClassName}Detail(String errorCode, List<Id> failedRecordIds, String detail) {
|
|
42
|
-
// this.errorCode = errorCode;
|
|
43
|
-
// this.failedRecordIds = failedRecordIds;
|
|
44
|
-
// this.detail = detail;
|
|
45
|
-
// }
|
|
46
|
-
//
|
|
47
|
-
// public override String toString() {
|
|
48
|
-
// return '[' + errorCode + '] ' + detail + ' (Records: ' + failedRecordIds + ')';
|
|
49
|
-
// }
|
|
50
|
-
// }
|
|
51
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Interface for {describe the capability or contract this interface defines}.
|
|
3
|
-
* Implement this interface to provide {describe what implementations do}.
|
|
4
|
-
* @author Generated by Apex Class Writer Skill
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* public class EmailNotificationService implements {InterfaceName} {
|
|
8
|
-
* public void execute(Map<String, Object> params) {
|
|
9
|
-
* // Implementation
|
|
10
|
-
* }
|
|
11
|
-
* }
|
|
12
|
-
*/
|
|
13
|
-
public interface {InterfaceName} {
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @description {Describe what this method should do}
|
|
17
|
-
* @param params {Describe the parameter}
|
|
18
|
-
* @return {Describe the return value}
|
|
19
|
-
*/
|
|
20
|
-
// TODO: Define interface methods
|
|
21
|
-
// Example:
|
|
22
|
-
// void execute(Map<String, Object> params);
|
|
23
|
-
// Boolean isEligible(SObject record);
|
|
24
|
-
// List<SObject> process(List<SObject> records);
|
|
25
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Queueable Apex class for {describe the async operation}.
|
|
3
|
-
* Accepts data through the constructor for stateful processing.
|
|
4
|
-
* Optionally implements Database.AllowsCallouts for external integrations.
|
|
5
|
-
* @author Generated by Apex Class Writer Skill
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* // Enqueue the job
|
|
9
|
-
* Id jobId = System.enqueueJob(new {ClassName}(recordIds));
|
|
10
|
-
*/
|
|
11
|
-
public with sharing class {ClassName} implements Queueable /*, Database.AllowsCallouts */ {
|
|
12
|
-
|
|
13
|
-
// ─── Constants ───────────────────────────────────────────────────────
|
|
14
|
-
private static final Integer MAX_CHAIN_DEPTH = 5;
|
|
15
|
-
|
|
16
|
-
// ─── Instance Variables (Stateful) ───────────────────────────────────
|
|
17
|
-
private Set<Id> recordIds;
|
|
18
|
-
private Integer chainDepth;
|
|
19
|
-
|
|
20
|
-
// ─── Constructors ────────────────────────────────────────────────────
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @description Creates a new queueable job to process the specified records
|
|
24
|
-
* @param recordIds Set of record Ids to process
|
|
25
|
-
*/
|
|
26
|
-
public {ClassName}(Set<Id> recordIds) {
|
|
27
|
-
this(recordIds, 0);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @description Creates a new queueable job with chain depth tracking
|
|
32
|
-
* @param recordIds Set of record Ids to process
|
|
33
|
-
* @param chainDepth Current depth in the queueable chain
|
|
34
|
-
*/
|
|
35
|
-
public {ClassName}(Set<Id> recordIds, Integer chainDepth) {
|
|
36
|
-
this.recordIds = recordIds ?? new Set<Id>();
|
|
37
|
-
this.chainDepth = chainDepth;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// ─── Queueable Interface ─────────────────────────────────────────────
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @description Executes the asynchronous work
|
|
44
|
-
* @param context The queueable context
|
|
45
|
-
*/
|
|
46
|
-
public void execute(QueueableContext context) {
|
|
47
|
-
if (this.recordIds.isEmpty()) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
// TODO: Implement the async processing logic
|
|
53
|
-
// List<{SObject}> records = {SObject}Selector.selectByIds(this.recordIds);
|
|
54
|
-
// ... process records ...
|
|
55
|
-
|
|
56
|
-
// Chain to next job if there's more work and we haven't hit the depth limit
|
|
57
|
-
chainIfNeeded();
|
|
58
|
-
|
|
59
|
-
} catch (Exception e) {
|
|
60
|
-
handleError(context.getJobId(), e);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// ─── Private Helpers ─────────────────────────────────────────────────
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @description Chains to the next queueable job if needed, with depth guard
|
|
68
|
-
*/
|
|
69
|
-
private void chainIfNeeded() {
|
|
70
|
-
// TODO: Determine if chaining is needed (e.g., remaining records to process)
|
|
71
|
-
Set<Id> remainingIds = new Set<Id>();
|
|
72
|
-
|
|
73
|
-
if (!remainingIds.isEmpty() && this.chainDepth < MAX_CHAIN_DEPTH) {
|
|
74
|
-
if (!Test.isRunningTest()) {
|
|
75
|
-
System.enqueueJob(new {ClassName}(remainingIds, this.chainDepth + 1));
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* @description Handles errors during execution
|
|
82
|
-
* @param jobId The async job Id
|
|
83
|
-
* @param e The exception that occurred
|
|
84
|
-
*/
|
|
85
|
-
private void handleError(Id jobId, Exception e) {
|
|
86
|
-
System.debug(LoggingLevel.ERROR,
|
|
87
|
-
'{ClassName} failed (Job: ' + jobId + '): ' +
|
|
88
|
-
e.getMessage() + '\n' + e.getStackTraceString()
|
|
89
|
-
);
|
|
90
|
-
// TODO: Persist error to a log object or send notification
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Schedulable Apex class for {describe the scheduled operation}.
|
|
3
|
-
* Delegates heavy processing to a Batch or Queueable job.
|
|
4
|
-
* Keep execute() lightweight — it should only launch other jobs.
|
|
5
|
-
* @author Generated by Apex Class Writer Skill
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* // Schedule to run daily at 2 AM
|
|
9
|
-
* String jobId = System.schedule(
|
|
10
|
-
* '{ClassName} - Daily',
|
|
11
|
-
* {ClassName}.CRON_DAILY_2AM,
|
|
12
|
-
* new {ClassName}()
|
|
13
|
-
* );
|
|
14
|
-
*
|
|
15
|
-
* // Or use the convenience method
|
|
16
|
-
* String jobId = {ClassName}.scheduleDaily();
|
|
17
|
-
*/
|
|
18
|
-
public with sharing class {ClassName} implements Schedulable {
|
|
19
|
-
|
|
20
|
-
// ─── CRON Expressions ────────────────────────────────────────────────
|
|
21
|
-
// Seconds Minutes Hours Day_of_month Month Day_of_week Optional_year
|
|
22
|
-
|
|
23
|
-
/** @description Runs daily at 2:00 AM */
|
|
24
|
-
public static final String CRON_DAILY_2AM = '0 0 2 * * ?';
|
|
25
|
-
|
|
26
|
-
/** @description Runs every weekday at 6:00 AM */
|
|
27
|
-
public static final String CRON_WEEKDAYS_6AM = '0 0 6 ? * MON-FRI';
|
|
28
|
-
|
|
29
|
-
/** @description Runs hourly at the top of the hour */
|
|
30
|
-
public static final String CRON_HOURLY = '0 0 * * * ?';
|
|
31
|
-
|
|
32
|
-
// ─── Schedulable Interface ───────────────────────────────────────────
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @description Entry point for the scheduled execution.
|
|
36
|
-
* Delegates to a Batch or Queueable for the actual work.
|
|
37
|
-
* @param sc The schedulable context
|
|
38
|
-
*/
|
|
39
|
-
public void execute(SchedulableContext sc) {
|
|
40
|
-
// Option A: Launch a Batch job
|
|
41
|
-
// Database.executeBatch(new {BatchClassName}(), 200);
|
|
42
|
-
|
|
43
|
-
// Option B: Launch a Queueable job
|
|
44
|
-
// System.enqueueJob(new {QueueableClassName}(params));
|
|
45
|
-
|
|
46
|
-
// TODO: Implement delegation to appropriate async job
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// ─── Convenience Scheduling Methods ──────────────────────────────────
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @description Schedules this job to run daily at 2 AM
|
|
53
|
-
* @return The scheduled job Id
|
|
54
|
-
*/
|
|
55
|
-
public static String scheduleDaily() {
|
|
56
|
-
return System.schedule(
|
|
57
|
-
'{ClassName} - Daily 2AM',
|
|
58
|
-
CRON_DAILY_2AM,
|
|
59
|
-
new {ClassName}()
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @description Aborts this scheduled job by name
|
|
65
|
-
* @param jobName The name used when scheduling
|
|
66
|
-
*/
|
|
67
|
-
public static void abort(String jobName) {
|
|
68
|
-
for (CronTrigger ct : [
|
|
69
|
-
SELECT Id FROM CronTrigger
|
|
70
|
-
WHERE CronJobDetail.Name = :jobName
|
|
71
|
-
]) {
|
|
72
|
-
System.abortJob(ct.Id);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Selector class for {SObject} queries.
|
|
3
|
-
* Encapsulates all SOQL for {SObject} records.
|
|
4
|
-
* All methods return bulkified results (Lists or Maps).
|
|
5
|
-
* @author Generated by Apex Class Writer Skill
|
|
6
|
-
*/
|
|
7
|
-
public with sharing class {SObject}Selector {
|
|
8
|
-
|
|
9
|
-
// ─── Field Lists ─────────────────────────────────────────────────────
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @description Returns the default set of fields to query for {SObject}.
|
|
13
|
-
* Centralizes field references to keep queries DRY.
|
|
14
|
-
* @return Comma-separated field list as a String
|
|
15
|
-
*/
|
|
16
|
-
private static String getDefaultFields() {
|
|
17
|
-
return String.join(
|
|
18
|
-
new List<String>{
|
|
19
|
-
'Id',
|
|
20
|
-
'Name',
|
|
21
|
-
'CreatedDate',
|
|
22
|
-
'LastModifiedDate'
|
|
23
|
-
// TODO: Add additional fields here
|
|
24
|
-
},
|
|
25
|
-
', '
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// ─── Query Methods ───────────────────────────────────────────────────
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* @description Selects {SObject} records by their Ids
|
|
33
|
-
* @param recordIds Set of {SObject} Ids to query
|
|
34
|
-
* @return List of {SObject} records matching the provided Ids
|
|
35
|
-
* @example
|
|
36
|
-
* Set<Id> ids = new Set<Id>{ '001xx000003DGbY' };
|
|
37
|
-
* List<{SObject}> results = {SObject}Selector.selectByIds(ids);
|
|
38
|
-
*/
|
|
39
|
-
public static List<{SObject}> selectByIds(Set<Id> recordIds) {
|
|
40
|
-
if (recordIds == null || recordIds.isEmpty()) {
|
|
41
|
-
return new List<{SObject}>();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return Database.query(
|
|
45
|
-
'SELECT ' + getDefaultFields() +
|
|
46
|
-
' FROM {SObject}' +
|
|
47
|
-
' WHERE Id IN :recordIds'
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @description Selects {SObject} records as a Map keyed by Id
|
|
53
|
-
* @param recordIds Set of {SObject} Ids to query
|
|
54
|
-
* @return Map of Id to {SObject}
|
|
55
|
-
*/
|
|
56
|
-
public static Map<Id, {SObject}> selectMapByIds(Set<Id> recordIds) {
|
|
57
|
-
return new Map<Id, {SObject}>(selectByIds(recordIds));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* @description Selects {SObject} records by a specific field value
|
|
62
|
-
* @param fieldName API name of the field to filter on
|
|
63
|
-
* @param values Set of values to match
|
|
64
|
-
* @return List of matching {SObject} records
|
|
65
|
-
* @example
|
|
66
|
-
* List<{SObject}> results = {SObject}Selector.selectByField('Status__c', new Set<String>{ 'Active' });
|
|
67
|
-
*/
|
|
68
|
-
public static List<{SObject}> selectByField(String fieldName, Set<String> values) {
|
|
69
|
-
if (String.isBlank(fieldName) || values == null || values.isEmpty()) {
|
|
70
|
-
return new List<{SObject}>();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Validate field name to prevent SOQL injection
|
|
74
|
-
Schema.SObjectField field = Schema.SObjectType.{SObject}.fields.getMap().get(fieldName);
|
|
75
|
-
if (field == null) {
|
|
76
|
-
throw new QueryException('Invalid field name: ' + fieldName);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return Database.query(
|
|
80
|
-
'SELECT ' + getDefaultFields() +
|
|
81
|
-
' FROM {SObject}' +
|
|
82
|
-
' WHERE ' + String.escapeSingleQuotes(fieldName) + ' IN :values'
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// ─── Exception ───────────────────────────────────────────────────────
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* @description Custom exception for query errors
|
|
90
|
-
*/
|
|
91
|
-
public class QueryException extends Exception {}
|
|
92
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Service class for {SObject} business logic.
|
|
3
|
-
* Follows separation of concerns: delegates queries to {SObject}Selector
|
|
4
|
-
* and SObject manipulation to {SObject}Domain where applicable.
|
|
5
|
-
* @author Generated by Apex Class Writer Skill
|
|
6
|
-
*/
|
|
7
|
-
public with sharing class {SObject}Service {
|
|
8
|
-
|
|
9
|
-
// ─── Constants ───────────────────────────────────────────────────────
|
|
10
|
-
private static final String ERROR_NULL_INPUT = 'Input cannot be null or empty.';
|
|
11
|
-
|
|
12
|
-
// ─── Public API ──────────────────────────────────────────────────────
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @description {Describe the primary operation}
|
|
16
|
-
* @param recordIds Set of {SObject} Ids to process
|
|
17
|
-
* @return List of processed {SObject} records
|
|
18
|
-
* @throws {SObject}ServiceException if processing fails
|
|
19
|
-
* @example
|
|
20
|
-
* Set<Id> ids = new Set<Id>{ '001xx000003DGbY' };
|
|
21
|
-
* List<{SObject}> results = {SObject}Service.process{SObject}s(ids);
|
|
22
|
-
*/
|
|
23
|
-
public static List<{SObject}> process{SObject}s(Set<Id> recordIds) {
|
|
24
|
-
// Guard clause
|
|
25
|
-
if (recordIds == null || recordIds.isEmpty()) {
|
|
26
|
-
throw new {SObject}ServiceException(ERROR_NULL_INPUT);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Query via Selector
|
|
30
|
-
List<{SObject}> records = {SObject}Selector.selectByIds(recordIds);
|
|
31
|
-
|
|
32
|
-
// Apply business logic
|
|
33
|
-
// TODO: Implement business logic here
|
|
34
|
-
|
|
35
|
-
// DML
|
|
36
|
-
try {
|
|
37
|
-
update records;
|
|
38
|
-
} catch (DmlException e) {
|
|
39
|
-
throw new {SObject}ServiceException(
|
|
40
|
-
'Failed to update {SObject} records: ' + e.getMessage()
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return records;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// ─── Convenience Overloads ───────────────────────────────────────────
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @description Single-record convenience overload
|
|
51
|
-
* @param recordId The {SObject} Id to process
|
|
52
|
-
* @return The processed {SObject} record
|
|
53
|
-
*/
|
|
54
|
-
public static {SObject} process{SObject}(Id recordId) {
|
|
55
|
-
List<{SObject}> results = process{SObject}s(new Set<Id>{ recordId });
|
|
56
|
-
return results.isEmpty() ? null : results[0];
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// ─── Private Helpers ─────────────────────────────────────────────────
|
|
60
|
-
|
|
61
|
-
// TODO: Add private helper methods as needed
|
|
62
|
-
|
|
63
|
-
// ─── Exception ───────────────────────────────────────────────────────
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* @description Custom exception for {SObject}Service errors
|
|
67
|
-
*/
|
|
68
|
-
public class {SObject}ServiceException extends Exception {}
|
|
69
|
-
}
|