@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.
Files changed (103) hide show
  1. package/package.json +4 -4
  2. package/skills/agentforce-development/SKILL.md +427 -0
  3. package/skills/agentforce-development/assets/README-legacy.md +89 -0
  4. package/skills/agentforce-development/assets/agent-spec-template.md +90 -0
  5. package/skills/agentforce-development/assets/agents/README.md +45 -0
  6. package/skills/agentforce-development/assets/agents/hello-world.agent +60 -0
  7. package/skills/agentforce-development/assets/agents/multi-topic.agent +105 -0
  8. package/skills/agentforce-development/assets/agents/production-faq.agent +101 -0
  9. package/skills/agentforce-development/assets/agents/production-faq.bundle-meta.xml +4 -0
  10. package/skills/agentforce-development/assets/agents/simple-qa.agent +72 -0
  11. package/skills/agentforce-development/assets/apex/models-api-queueable.cls +225 -0
  12. package/skills/agentforce-development/assets/bundle-meta.xml +23 -0
  13. package/skills/agentforce-development/assets/components/apex-action.agent +52 -0
  14. package/skills/agentforce-development/assets/components/error-handling.agent +58 -0
  15. package/skills/agentforce-development/assets/components/escalation-setup.agent +169 -0
  16. package/skills/agentforce-development/assets/components/flow-action.agent +66 -0
  17. package/skills/agentforce-development/assets/components/n-ary-conditions.agent +110 -0
  18. package/skills/agentforce-development/assets/components/topic-with-actions.agent +40 -0
  19. package/skills/agentforce-development/assets/deterministic-routing.agent +166 -0
  20. package/skills/agentforce-development/assets/escalation-pattern.agent +209 -0
  21. package/skills/agentforce-development/assets/flow-action-lookup.agent +115 -0
  22. package/skills/agentforce-development/assets/hub-and-spoke.agent +104 -0
  23. package/skills/agentforce-development/assets/invocable-apex-template.cls +187 -0
  24. package/skills/agentforce-development/assets/local-info-agent-annotated.agent +355 -0
  25. package/skills/agentforce-development/assets/metadata/basic-prompt-template.promptTemplate-meta.xml +109 -0
  26. package/skills/agentforce-development/assets/metadata/genai-function-apex.xml +92 -0
  27. package/skills/agentforce-development/assets/metadata/genai-function-flow.xml +57 -0
  28. package/skills/agentforce-development/assets/metadata/genai-plugin.xml +72 -0
  29. package/skills/agentforce-development/assets/metadata/http-callout-flow.flow-meta.xml +348 -0
  30. package/skills/agentforce-development/assets/metadata/record-grounded-prompt.promptTemplate-meta.xml +136 -0
  31. package/skills/agentforce-development/assets/minimal-starter.agent +42 -0
  32. package/skills/agentforce-development/assets/patterns/README.md +254 -0
  33. package/skills/agentforce-development/assets/patterns/action-callbacks.agent +178 -0
  34. package/skills/agentforce-development/assets/patterns/advanced-input-bindings.agent +141 -0
  35. package/skills/agentforce-development/assets/patterns/bidirectional-routing.agent +156 -0
  36. package/skills/agentforce-development/assets/patterns/critical-input-collection.agent +244 -0
  37. package/skills/agentforce-development/assets/patterns/delegation-routing.agent +89 -0
  38. package/skills/agentforce-development/assets/patterns/lifecycle-events.agent +127 -0
  39. package/skills/agentforce-development/assets/patterns/llm-controlled-actions.agent +184 -0
  40. package/skills/agentforce-development/assets/patterns/multi-step-workflow.agent +282 -0
  41. package/skills/agentforce-development/assets/patterns/open-gate-routing.agent +286 -0
  42. package/skills/agentforce-development/assets/patterns/procedural-instructions.agent +273 -0
  43. package/skills/agentforce-development/assets/patterns/prompt-template-action.agent +188 -0
  44. package/skills/agentforce-development/assets/patterns/system-instruction-overrides.agent +293 -0
  45. package/skills/agentforce-development/assets/prompt-rag-search.agent +131 -0
  46. package/skills/agentforce-development/assets/template-multi-topic.agent +160 -0
  47. package/skills/agentforce-development/assets/template-single-topic.agent +81 -0
  48. package/skills/agentforce-development/assets/verification-gate.agent +208 -0
  49. package/skills/agentforce-development/references/action-prompt-templates.md +164 -0
  50. package/skills/agentforce-development/references/actions-reference.md +592 -0
  51. package/skills/agentforce-development/references/agent-access-guide.md +72 -0
  52. package/skills/agentforce-development/references/agent-design-and-spec-creation.md +1010 -0
  53. package/skills/agentforce-development/references/agent-metadata-and-lifecycle.md +575 -0
  54. package/skills/agentforce-development/references/agent-script-core-language.md +1218 -0
  55. package/skills/agentforce-development/references/agent-topic-map-diagrams.md +323 -0
  56. package/skills/agentforce-development/references/agent-user-setup.md +526 -0
  57. package/skills/agentforce-development/references/agent-validation-and-debugging.md +803 -0
  58. package/skills/agentforce-development/references/known-issues.md +353 -0
  59. package/skills/agentforce-development/references/minimal-examples.md +67 -0
  60. package/skills/agentforce-development/references/production-gotchas.md +279 -0
  61. package/skills/agentforce-development/references/salesforce-cli-for-agents.md +393 -0
  62. package/skills/agentforce-development/references/version-history.md +23 -0
  63. package/skills/generate-permission-set/SKILL.md +174 -0
  64. package/skills/salesforce-custom-application/SKILL.md +1 -2
  65. package/skills/salesforce-custom-field/SKILL.md +0 -4
  66. package/skills/salesforce-custom-tab/SKILL.md +84 -8
  67. package/skills/salesforce-experience-lwr-site/SKILL.md +196 -0
  68. package/skills/salesforce-experience-lwr-site/docs/bootstrap-template-byo-lwr.md +224 -0
  69. package/skills/salesforce-experience-lwr-site/docs/configure-content-brandingSet.md +131 -0
  70. package/skills/salesforce-experience-lwr-site/docs/configure-content-route.md +232 -0
  71. package/skills/salesforce-experience-lwr-site/docs/configure-content-themeLayout.md +141 -0
  72. package/skills/salesforce-experience-lwr-site/docs/configure-content-view.md +233 -0
  73. package/skills/salesforce-experience-lwr-site/docs/configure-guest-sharing-rules.md +42 -0
  74. package/skills/salesforce-experience-lwr-site/docs/handle-component-and-region-ids.md +27 -0
  75. package/skills/salesforce-experience-lwr-site/docs/handle-ui-components.md +215 -0
  76. package/skills/salesforce-flow/SKILL.md +2 -2
  77. package/skills/salesforce-fragment/SKILL.md +85 -10
  78. package/skills/salesforce-lightning-app-build/SKILL.md +102 -10
  79. package/skills/apex-class/SKILL.md +0 -253
  80. package/skills/apex-class/examples/AccountDeduplicationBatch.cls +0 -148
  81. package/skills/apex-class/examples/AccountSelector.cls +0 -193
  82. package/skills/apex-class/examples/AccountService.cls +0 -201
  83. package/skills/apex-class/templates/abstract.cls +0 -128
  84. package/skills/apex-class/templates/batch.cls +0 -125
  85. package/skills/apex-class/templates/domain.cls +0 -102
  86. package/skills/apex-class/templates/dto.cls +0 -108
  87. package/skills/apex-class/templates/exception.cls +0 -51
  88. package/skills/apex-class/templates/interface.cls +0 -25
  89. package/skills/apex-class/templates/queueable.cls +0 -92
  90. package/skills/apex-class/templates/schedulable.cls +0 -75
  91. package/skills/apex-class/templates/selector.cls +0 -92
  92. package/skills/apex-class/templates/service.cls +0 -69
  93. package/skills/apex-class/templates/utility.cls +0 -97
  94. package/skills/apex-test-class/SKILL.md +0 -101
  95. package/skills/apex-test-class/references/assertion-patterns.md +0 -209
  96. package/skills/apex-test-class/references/async-testing.md +0 -276
  97. package/skills/apex-test-class/references/mocking-patterns.md +0 -219
  98. package/skills/apex-test-class/references/test-data-factory.md +0 -176
  99. package/skills/deployment-readiness-check/SKILL.md +0 -257
  100. package/skills/deployment-readiness-check/assets/deployment_checklist.md +0 -286
  101. package/skills/deployment-readiness-check/references/rollback_procedures.md +0 -308
  102. package/skills/deployment-readiness-check/scripts/check_metadata.sh +0 -207
  103. 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
- }