diff --git a/skills/generating-apex-test/assets/test-class-template.cls b/skills/generating-apex-test/assets/test-class-template.cls index 1cee33e..f02ae8e 100644 --- a/skills/generating-apex-test/assets/test-class-template.cls +++ b/skills/generating-apex-test/assets/test-class-template.cls @@ -1,7 +1,7 @@ /** - * @description Test class for {ClassUnderTest}. - * Tests bulk operations (251+ records), positive/negative paths, - * and exception handling. + * Test class for {ClassUnderTest}. + * Tests bulk operations (251+ records), positive/negative paths, + * and exception handling. */ @isTest private class {ClassUnderTest}Test { diff --git a/skills/generating-apex-test/references/assertion-patterns.md b/skills/generating-apex-test/references/assertion-patterns.md index 90ba4a5..229642a 100644 --- a/skills/generating-apex-test/references/assertion-patterns.md +++ b/skills/generating-apex-test/references/assertion-patterns.md @@ -26,7 +26,7 @@ Assert.isTrue(accounts.size() > 0); // vague — use areEqual with exact count ### Good: Descriptive message, tests specific behavior ```apex -Assert.areEqual(true, result, 'Service should return true for valid input'); +Assert.isTrue(result, 'Service should return true for valid input'); Assert.areEqual(200, accounts.size(), 'All 200 accounts should be processed'); ``` diff --git a/skills/generating-apex-test/references/async-testing.md b/skills/generating-apex-test/references/async-testing.md index c16d8c2..70c6021 100644 --- a/skills/generating-apex-test/references/async-testing.md +++ b/skills/generating-apex-test/references/async-testing.md @@ -140,7 +140,7 @@ static void shouldExecuteFutureMethod() { Test.stopTest(); Account updated = [SELECT Id, Processed__c FROM Account WHERE Id = :acc.Id]; - Assert.areEqual(true, updated.Processed__c, 'Future should process record'); + Assert.isTrue(updated.Processed__c, 'Future should process record'); } ``` diff --git a/skills/generating-apex/SKILL.md b/skills/generating-apex/SKILL.md index 44b0a21..b18ba56 100644 --- a/skills/generating-apex/SKILL.md +++ b/skills/generating-apex/SKILL.md @@ -6,7 +6,7 @@ description: Primary Apex authoring skill for class generation, refactoring, and # Generating Apex Use this skill for production-grade Apex: new classes, selectors, services, async jobs, -invocable methods, and triggers; and for evidence-based review of existing `.cls`. +invocable methods, and triggers; and for evidence-based review of existing `.cls` OR `.trigger`. ## Required Inputs @@ -16,11 +16,11 @@ Gather or infer before authoring: - Target object(s) and business goal - Class name (derive using the naming table below) - Net-new vs refactor/fix; any org/API constraints -- Deployment targets +- Deployment targets (default to runSpecifiedTests and use generated tests where applicable) Defaults unless specified: - Sharing: `with sharing` (see sharing rules per type below) -- Access: `public` (use `global` only when required by managed packages or `@InvocableMethod`) +- Access: `public` (use `global` only when required by managed packages or `@RestResource`) - API version: `66.0` (minimum version) - ApexDoc comments: yes @@ -48,9 +48,9 @@ All steps are sequential. Do not skip, merge, or reorder. If blocked, stop and a 4. **Author with guardrails** -- apply every rule in the Rules section below - Generate `{ClassName}.cls` with ApexDoc - - Generate `{ClassName}.cls-meta.xml` + - Generate `{ClassName}.cls-meta.xml` -5. **Generate test classes** -- delegate to `generating-apex-test` to create `{ClassName}Test.cls` and `{ClassName}Test.cls-meta.xml`. Do not write test code in this skill. If the test skill is unavailable, record `test_skill=unavailable: ` in Step 8. +5. **Generate test classes** -- Load the skill `generating-apex-test` to create `{ClassName}Test.cls` and `{ClassName}Test.cls-meta.xml`. Apex tests are always required to be generated to deploy. No test file creation or edits can occur without loading the `generating-apex-test` skill to generate tests. ### Phase 2 — Validate (required before reporting) @@ -64,7 +64,7 @@ Writing files is the midpoint, not the finish line. Steps 6 and 7 each require a 7. **Execute Apex tests** - Run org tests including `{ClassName}Test` via `sf apex run test` or MCP. - - Delegate all test fixes/coverage work to `generating-apex-test`; iterate until green. + - Delegate all test generation/fixes/coverage work to `generating-apex-test`; iterate until the tests pass. - Capture pass/fail counts and coverage percentage for the report. - If unavailable, record `test_execution=unavailable: ` in the report. @@ -93,7 +93,7 @@ If any constraint would be violated in generated code, **stop and explain the pr | Use bind variables for all dynamic SOQL with user input | Prevent SOQL injection | | Use Apex-native collections (`List`, `Map`, `Set`) rather than Java types | Prevent compile errors | | Verify methods exist in Apex before use | Prevent reliance on non-existent APIs | -| Prefer structured logging over `System.debug()` | Debug string concatenation consumes CPU even when not observed | +| Avoid `System.debug()` in main code paths | Debug statements evaluate even when loggign is not active and consume CPU. Use a logging framework if required on main code paths | | Never use `@future` methods | Use Queueable with `System.Finalizer`; `@future` cannot chain, cannot be called from Batch, and cannot accept non-primitive types | ### Bulkification & Governor Limits @@ -142,6 +142,8 @@ Before finalizing, verify: CRUD/FLS enforced (SOQL + DML) · explicit sharing ke - Preserve exception cause chains: `new CustomException('message', cause)` (do not replace stack trace with concatenated messages) - Provide a custom exception class per service domain when meaningful - In `@AuraEnabled` methods, catch exceptions and rethrow as `AuraHandledException` +- Fallback option: when no meaningful domain exception exists, catch generic `Exception` and either rethrow it or wrap it in a minimal custom exception that preserves the original cause. + ### Null Safety @@ -196,8 +198,9 @@ Class-level format: ```apex /** - * @author Generated by Apex Skill + * Provides services for geolocation and address conversion. */ +public with sharing class GeolocationService { } ``` Method-level format: @@ -357,6 +360,10 @@ Deliverables per class: - `{ClassName}Test.cls` (generated via `generating-apex-test` skill) - `{ClassName}Test.cls-meta.xml` (generated via `generating-apex-test` skill) +Deliverables per trigger: +- `{TriggerName}.trigger` +- `{TriggerName}.trigger-meta.xml` (default API version `66.0` or higher unless specified) + Meta XML template: ```xml @@ -396,4 +403,4 @@ Deploy: ## Troubleshooting Boundary -This skill handles production `.cls`/`.trigger` issues only: compile/parse failures, deployment dependency errors, runtime governor-limit failures. For test execution, assertions, coverage, or `sf apex run test` failures, delegate to `generating-apex-test`. +This skill handles production `.cls`/`.trigger`/`.apex` issues only: compile/parse failures, deployment dependency errors, runtime governor-limit failures. For test execution, assertions, coverage, or `sf apex run test` failures, delegate to `generating-apex-test`. \ No newline at end of file diff --git a/skills/generating-apex/assets/abstract.cls b/skills/generating-apex/assets/abstract.cls index 37c9a2f..1aa43fd 100644 --- a/skills/generating-apex/assets/abstract.cls +++ b/skills/generating-apex/assets/abstract.cls @@ -6,7 +6,6 @@ >>>>>>> Stashed changes * Provides common behavior and defines extension points for subclasses. * Subclasses must implement the abstract methods to provide specific behavior. - * @author Generated by Apex Class Writer Skill * * @example * // Extending this abstract class: diff --git a/skills/generating-apex/assets/batch.cls b/skills/generating-apex/assets/batch.cls index 3633ee0..99165ba 100644 --- a/skills/generating-apex/assets/batch.cls +++ b/skills/generating-apex/assets/batch.cls @@ -2,7 +2,6 @@ * Batch Apex class for {describe the batch operation}. * Processes {SObject} records in configurable batch sizes. * Implements Database.Stateful to track cumulative results across chunks. - * @author Generated by Apex Class Writer Skill * * @example * // Execute with default batch size diff --git a/skills/generating-apex/assets/domain.cls b/skills/generating-apex/assets/domain.cls index 6c2dcbd..f4bfd26 100644 --- a/skills/generating-apex/assets/domain.cls +++ b/skills/generating-apex/assets/domain.cls @@ -2,7 +2,6 @@ * Domain class for {SObject}. * Encapsulates field-level defaults, derivations, and validations. * Operates only on in-memory SObject data — no SOQL or DML. - * @author Generated by Apex Class Writer Skill */ public with sharing class {SObject}Domain { diff --git a/skills/generating-apex/assets/dto.cls b/skills/generating-apex/assets/dto.cls index ff1609a..e5cb231 100644 --- a/skills/generating-apex/assets/dto.cls +++ b/skills/generating-apex/assets/dto.cls @@ -2,7 +2,6 @@ * Data Transfer Object for {describe the data this DTO represents}. * Used to pass structured data between layers without exposing SObjects. * Serialization-friendly for use with JSON.serialize/deserialize and API responses. - * @author Generated by Apex Class Writer Skill * * @example * // Create from constructor diff --git a/skills/generating-apex/assets/exception.cls b/skills/generating-apex/assets/exception.cls index a18978a..323281a 100644 --- a/skills/generating-apex/assets/exception.cls +++ b/skills/generating-apex/assets/exception.cls @@ -2,7 +2,6 @@ * Custom exception for {describe when this exception is thrown}. * Use this exception to signal domain-specific errors that callers * can catch and handle distinctly from system exceptions. - * @author Generated by Apex Class Writer Skill * * @example * throw new {ClassName}('Account merge failed: duplicate detected.'); diff --git a/skills/generating-apex/assets/interface.cls b/skills/generating-apex/assets/interface.cls index 15796cd..b35b356 100644 --- a/skills/generating-apex/assets/interface.cls +++ b/skills/generating-apex/assets/interface.cls @@ -1,7 +1,6 @@ /** * Interface for {describe the capability or contract this interface defines}. * Implement this interface to provide {describe what implementations do}. - * @author Generated by Apex Class Writer Skill * * @example * public class EmailNotificationService implements {InterfaceName} { diff --git a/skills/generating-apex/assets/invocable.cls b/skills/generating-apex/assets/invocable.cls index 18193d1..d02fa11 100644 --- a/skills/generating-apex/assets/invocable.cls +++ b/skills/generating-apex/assets/invocable.cls @@ -2,7 +2,6 @@ * Invocable Apex action for {describe the action}. * Callable from Flows, Process Builder, and Agentforce. * Accepts bulkified List, returns List. - * @author Generated by Apex Class Writer Skill */ public with sharing class {ClassName} { diff --git a/skills/generating-apex/assets/queueable.cls b/skills/generating-apex/assets/queueable.cls index 8629b6c..911b56b 100644 --- a/skills/generating-apex/assets/queueable.cls +++ b/skills/generating-apex/assets/queueable.cls @@ -2,7 +2,6 @@ * Queueable Apex class for {describe the async operation}. * Accepts data through the constructor for stateful processing. * Optionally implements Database.AllowsCallouts for external integrations. - * @author Generated by Apex Class Writer Skill * * @example * // Enqueue the job diff --git a/skills/generating-apex/assets/schedulable.cls b/skills/generating-apex/assets/schedulable.cls index fe402db..1eb01f0 100644 --- a/skills/generating-apex/assets/schedulable.cls +++ b/skills/generating-apex/assets/schedulable.cls @@ -2,7 +2,6 @@ * Schedulable Apex class for {describe the scheduled operation}. * Delegates heavy processing to a Batch or Queueable job. * Keep execute() lightweight — it should only launch other jobs. - * @author Generated by Apex Class Writer Skill * * @example * // Schedule to run daily at 2 AM diff --git a/skills/generating-apex/assets/selector.cls b/skills/generating-apex/assets/selector.cls index be24059..29fd609 100644 --- a/skills/generating-apex/assets/selector.cls +++ b/skills/generating-apex/assets/selector.cls @@ -2,7 +2,6 @@ * Selector class for {SObject} queries. * Encapsulates all SOQL for {SObject} records. * All methods return bulkified results (Lists or Maps). - * @author Generated by Apex Class Writer Skill */ public inherited sharing class {SObject}Selector { diff --git a/skills/generating-apex/assets/service.cls b/skills/generating-apex/assets/service.cls index 6f802e6..d1ae58d 100644 --- a/skills/generating-apex/assets/service.cls +++ b/skills/generating-apex/assets/service.cls @@ -2,7 +2,6 @@ * Service class for {SObject} business logic. * Follows separation of concerns: delegates queries to {SObject}Selector * and SObject manipulation to {SObject}Domain where applicable. - * @author Generated by Apex Class Writer Skill */ public with sharing class {SObject}Service { diff --git a/skills/generating-apex/assets/trigger.cls b/skills/generating-apex/assets/trigger.cls index 7fc2d75..5f849ad 100644 --- a/skills/generating-apex/assets/trigger.cls +++ b/skills/generating-apex/assets/trigger.cls @@ -1,5 +1,5 @@ /** - * @author Generated by Apex Class Writer Skill + * {SObject} Trigger */ trigger {SObject}Trigger on {SObject} ( before insert, diff --git a/skills/generating-apex/assets/utility.cls b/skills/generating-apex/assets/utility.cls index 718df49..36ef885 100644 --- a/skills/generating-apex/assets/utility.cls +++ b/skills/generating-apex/assets/utility.cls @@ -2,7 +2,6 @@ * Utility class for {describe the category of utilities: String, Date, Collection, etc.}. * All methods are static and side-effect-free (no SOQL, no DML). * Private constructor prevents instantiation. - * @author Generated by Apex Class Writer Skill */ public with sharing class {ClassName} { diff --git a/skills/generating-apex/references/AccountDeduplicationBatch.cls b/skills/generating-apex/references/AccountDeduplicationBatch.cls index 2d6f005..6671839 100644 --- a/skills/generating-apex/references/AccountDeduplicationBatch.cls +++ b/skills/generating-apex/references/AccountDeduplicationBatch.cls @@ -3,7 +3,6 @@ * Compares Accounts by Name and BillingPostalCode to find potential duplicates. * Flags duplicates by setting the Is_Potential_Duplicate__c checkbox. * Implements Database.Stateful to track results across batch chunks. - * @author Generated by Apex Class Writer Skill * * @example * // Run with default batch size (200) diff --git a/skills/generating-apex/references/AccountSelector.cls b/skills/generating-apex/references/AccountSelector.cls index 1d826a1..57282dd 100644 --- a/skills/generating-apex/references/AccountSelector.cls +++ b/skills/generating-apex/references/AccountSelector.cls @@ -2,7 +2,6 @@ * Selector class for Account queries. * Encapsulates all SOQL for Account records. * All methods return bulkified results (Lists or Maps). - * @author Generated by Apex Class Writer Skill */ public with sharing class AccountSelector { diff --git a/skills/generating-apex/references/AccountService.cls b/skills/generating-apex/references/AccountService.cls index 0ec3cb8..242f5ae 100644 --- a/skills/generating-apex/references/AccountService.cls +++ b/skills/generating-apex/references/AccountService.cls @@ -2,7 +2,6 @@ * Service class for Account business logic. * Provides account deduplication, enrichment, and territory assignment. * Delegates queries to AccountSelector and SObject manipulation to AccountDomain. - * @author Generated by Apex Class Writer Skill */ public with sharing class AccountService {