salesforce-apex-generator-skill
T0 static code generation for production-grade Apex. This skill is a forge, not a flashlight — it authors correct, deployable Apex with the right sharing model, governor-limit safety, and security defaults for each class type. No org connection required.
When This Skill Owns the Task
Use salesforce-apex-generator-skill when the work requires authoring new Apex code:
- "Write an AccountService class that queries all Accounts by owner"
- "Generate a Queueable that sends platform events for Order updates"
- "Create a Schedulable wrapper for a batch job"
- "Scaffold the Selector layer for the Contact object"
- "Implement a Domain class with trigger logic for Opportunity"
- "Write a REST resource endpoint for an external integration"
- "Create a .cls file for our deduplication logic"
Delegate elsewhere when:
| Situation | Skill to use | |---|---| | User needs test classes specifically | salesforce-apex-test-generator-skill | | User wants to run tests against a live org | salesforce-apex-test-runner-skill | | User is debugging a log file or stack trace | salesforce-apex-log-analyzer-skill | | User needs to deploy and validate | salesforce-deployment-validator-skill | | Static code review of existing Apex | salesforce-apex-lwc-code-review-skill |
Required Context to Gather First
Before generating, confirm:
- Class type — service, selector, domain, batch, queueable, schedulable, invocable,
trigger, trigger-handler, REST resource, DTO, utility, interface, exception
- Target object(s) — the SObject API names involved (e.g.,
Account,Opportunity__c) - Business goal — what the class must accomplish
- Class name — derive from naming conventions if not provided
- Existing patterns — does the project use a trigger framework (TAF, MetadataTriggerHandler)?
Service-Selector-Domain already in place?
- API version — default
62.0minimum - Test class expected? — always recommend pairing with
salesforce-apex-test-generator-skill
If the user provides a clear, complete request, generate immediately without unnecessary back-and-forth. Apply defaults (see Rules section) for anything not specified.
Recommended Workflow
Step 1 — Identify class type and infer defaults
Map the request to a class type using the type table below. Set defaults:
- Sharing:
with sharingunless type-specific exception applies - Access modifier:
publicunlessglobalis required - ApexDoc: always include
- API version meta XML: always generate
Step 2 — Choose the minimal correct pattern
Consult references/apex-patterns.md for Service-Selector-Domain conventions, async patterns, and type-specific templates.
Step 3 — Apply all hard-stop constraints
Before writing a single line, verify every constraint in the Rules section would be satisfied. If a constraint would be violated by the user's request, explain the problem and propose the correct approach.
Step 4 — Generate the class file
Produce {ClassName}.cls with:
- Correct
with sharing/without sharing/inherited sharingdeclaration - ApexDoc comment block (purpose, author placeholder, version)
- All SOQL outside loops
- All DML outside loops
- No
@futuremethods — use Queueable - Bind variables for any dynamic SOQL
- Proper exception handling
- No hardcoded Ids or credentials
Step 5 — Generate the metadata XML
Produce {ClassName}.cls-meta.xml using the correct apiVersion and status: Active.
Step 6 — Score against the quality rubric
Run the 100-point scoring rubric (see below). If the score is below 80, revise before presenting. Document score and notes in the output.
Step 7 — Recommend test class pairing
Always end with an explicit recommendation to generate a companion test class using salesforce-apex-test-generator-skill, noting the class name and key scenarios to cover.
Class Type Reference
| Class Type | Sharing Model | Access | Key Rules | |---|---|---|---| | Service | with sharing | public | No SOQL/DML in loops; inject Selector | | Selector | with sharing | public | Returns typed lists; no business logic | | Domain | with sharing | public | Trigger-context aware; delegates to Service | | Trigger | N/A (handler delegates) | — | One trigger per object; delegates to Domain/handler | | Batchable | without sharing or with sharing | public | Implements Database.Batchable; Database.Stateful only if required | | Queueable | with sharing | public | Implements Queueable; use System.Finalizer for chaining; replaces @future | | Schedulable | with sharing | public | Implements Schedulable; delegates to Queueable or Batch | | Invocable | with sharing | public | @InvocableMethod; typed inner request/result classes | | REST Resource | without sharing (framework handles sharing) | global | @RestResource; @HttpGet/@HttpPost etc. | | DTO / Wrapper | N/A | public | No methods with side effects; serializable | | Utility | with sharing | public | Static methods only; no instance state | | Exception | N/A | public | Extends Exception; no override of getMessage |
Rules
Hard-Stop Constraints (Must Enforce)
| Constraint | Rationale | |---|---| | Place all SOQL outside loops | Avoid query governor limit (100 queries per transaction) | | Place all DML outside loops | Avoid DML statement governor limit (150 per transaction) | | Declare sharing keyword on every class | Prevent unintended without sharing defaults and data leakage | | Use Custom Metadata / Labels / describe calls instead of hardcoded Ids | Portability across orgs | | Always handle exceptions (log, rethrow, or recover) | Prevent silent failures | | Use bind variables for all dynamic SOQL accepting user input | Prevent SOQL injection | | Use Apex-native collection types | Prevent compile errors from Java-style types | | Never use @future methods | Use Queueable with System.Finalizer; @future cannot chain or accept non-primitive types | | No System.debug in main code paths | Debug statements consume CPU; use a logging framework | | Security: use WITH USER_MODE on SOQL in classes that touch user-controlled data | Enforces FLS/CRUD at query time | | Apply Security.stripInaccessible when constructing SObjects from user input | Strips fields the user cannot access |
Naming Conventions
| Type | Pattern | Example | |---|---|---| | Service | {SObject}Service | AccountService | | Selector | {SObject}Selector | AccountSelector | | Domain | {SObject}Domain | AccountDomain | | Handler | {SObject}TriggerHandler | AccountTriggerHandler | | Batch | {Purpose}Batch | AccountDeduplicationBatch | | Queueable | {Purpose}Queueable | OrderEventQueueable | | Schedulable | {Purpose}Scheduler | NightlyCleanupScheduler | | DTO | {Purpose}Dto or {Purpose}Wrapper | OrderResponseDto |
Quality Scoring Rubric (100-point)
Score the generated class before presenting. Threshold: 80+ pass, 60–79 caveat with explanation, below 60 revise before presenting.
| Dimension | Points | What earns full marks | |---|---|---| | Sharing model correctness | 25 | Every class has an explicit sharing declaration; with sharing is used wherever FLS/CRUD enforcement is appropriate; without sharing is justified with a comment | | Governor-limit safety | 25 | No SOQL in loops; no DML in loops; bulkified with List/Map patterns; Collections used correctly | | Security defaults | 20 | WITH USER_MODE or Security.stripInaccessible applied where appropriate; no hardcoded Ids or credentials; no SOQL injection vectors | | Naming conventions | 15 | Class and method names follow conventions table; ApexDoc present; XML meta generated | | Test class recommendation | 15 | Companion test class explicitly recommended with key scenarios listed |
Scoring penalties:
- SOQL inside a loop: -20 (immedi