
Salesforce Apex Quality Guardrails
OfficialFreeEnsure high-quality Apex code with safety checks.
Free · Opens the source repo
What Salesforce Apex Quality Guardrails does
The Salesforce Apex Quality Guardrails skill provides a comprehensive framework for maintaining high standards in Apex code development. It is designed for Salesforce developers who want to enforce best practices and avoid common pitfalls that can lead to performance issues or security vulnerabilities. This skill focuses on crucial aspects such as governor limit safety, sharing model requirements, CRUD/FLS security, SOQL injection prevention, and modern Apex idioms. By integrating these guardrails into your development workflow, you can significantly reduce the risk of deploying flawed code.
When using this skill, developers can systematically apply a series of checks to their Apex classes, triggers, and test files. For instance, it emphasizes the importance of avoiding SOQL and DML operations within loops, which can lead to governor limit exceptions. The skill instructs users to refactor such patterns and adopt bulk-safe practices. Additionally, it mandates that all classes explicitly declare their sharing intent to prevent unpredictable behavior, ensuring that security and access control are appropriately managed.
The skill also addresses security concerns by enforcing CRUD and FLS checks. Developers are guided on how to verify object and field access before performing operations on behalf of users, thus preventing unauthorized data access. Furthermore, it promotes modern Apex idioms, encouraging the use of updated language features to write cleaner and more efficient code.
Lastly, the skill includes a checklist for Positive/Negative/Bulk (PNB) test coverage, ensuring that all code paths are adequately tested. This thorough approach not only enhances code quality but also fosters a culture of accountability and excellence within development teams. Ideal for both new and experienced Salesforce developers, this skill is a valuable addition to any Apex development toolkit.
When to use it
Use this skill when reviewing or generating Apex classes, trigger handlers, batch jobs, or test classes to ensure compliance with best practices.
When not to use it
This skill may not be suitable for projects that do not require strict adherence to Apex best practices or for teams that prefer a more flexible coding approach.
What you can build with it
Reviewing Apex Classes
Use this skill to systematically check Apex classes for compliance with best practices before deployment.
Refactoring Legacy Code
Apply the guardrails to existing Apex code to identify and fix potential issues related to governor limits and security.
Training New Developers
Leverage this skill as a teaching tool to introduce new developers to essential Apex coding standards and practices.
How to install Salesforce Apex Quality Guardrails
View source1. Install with the skills CLI
npx skills add github/awesome-copilot/salesforce-apex-quality --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by githubSalesforce Apex Quality Guardrails
Apply these checks to every Apex class, trigger, and test file you write or review.
Step 1 — Governor Limit Safety Check
Scan for these patterns before declaring any Apex file acceptable:
SOQL and DML in Loops — Automatic Fail
// ❌ NEVER — causes LimitException at scale
for (Account a : accounts) {
List<Contact> contacts = [SELECT Id FROM Contact WHERE AccountId = :a.Id]; // SOQL in loop
update a; // DML in loop
}
// ✅ ALWAYS — collect, then query/update once
Set<Id> accountIds = new Map<Id, Account>(accounts).keySet();
Map<Id, List<Contact>> contactsByAccount = new Map<Id, List<Contact>>();
for (Contact c : [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds]) {
if (!contactsByAccount.containsKey(c.AccountId)) {
contactsByAccount.put(c.AccountId, new List<Contact>());
}
contactsByAccount.get(c.AccountId).add(c);
}
update accounts; // DML once, outside the loop
Rule: if you see [SELECT or Database.query, insert, update, delete, upsert, merge inside a for loop body — stop and refactor before proceeding.
Step 2 — Sharing Model Verification
Every class must declare its sharing intent explicitly. Undeclared sharing inherits from the caller — unpredictable behaviour.
| Declaration | When to use |
|---|---|
public with sharing class Foo | Default for all service, handler, selector, and controller classes |
public without sharing class Foo | Only when the class must run elevated (e.g. system-level logging, trigger bypass). Requires a code comment explaining why. |
public inherited sharing class Foo | Framework entry points that should respect the caller's sharing context |
If a class does not have one of these three declarations, add it before writing anything else.
Step 3 — CRUD / FLS Enforcement
Apex code that reads or writes records on behalf of a user must verify object and field access. The platform does not enforce FLS or CRUD automatically in Apex.
// Check before querying a field
if (!Schema.sObjectType.Contact.fields.Email.isAccessible()) {
throw new System.NoAccessException();
}
// Or use WITH USER_MODE in SOQL (API 56.0+)
List<Contact> contacts = [SELECT Id, Email FROM Contact WHERE AccountId = :accId WITH USER_MODE];
// Or use Database.query with AccessLevel
List<Contact> contacts = Database.query('SELECT Id, Email FROM Contact', AccessLevel.USER_MODE);
Rule: any Apex method callable from a UI component, REST endpoint, or @InvocableMethod must enforce CRUD/FLS. Internal service methods called only from trusted contexts may use with sharing instead.
Step 4 — SOQL Injection Prevention
// ❌ NEVER — concatenates user input into SOQL string
String soql = 'SELECT Id FROM Account WHERE Name = \'' + userInput + '\'';
// ✅ ALWAYS — bind variable
String soql = [SELECT Id FROM Account WHERE Name = :userInput];
// ✅ For dynamic SOQL with user-controlled field names — validate against a whitelist
Set<String> allowedFields = new Set<String>{'Name', 'Industry', 'AnnualRevenue'};
if (!allowedFields.contains(userInput)) {
throw new IllegalArgumentException('Field not permitted: ' + userInput);
}
Step 5 — Modern Apex Idioms
Prefer current language features (API 62.0 / Winter '25+):
| Old pattern | Modern replacement |
|---|---|
if (obj != null) { x = obj.Field__c; } | x = obj?.Field__c; |
x = (y != null) ? y : defaultVal; | x = y ?? defaultVal; |
System.assertEquals(expected, actual) | Assert.areEqual(expected, actual) |
System.assert(condition) | Assert.isTrue(condition) |
[SELECT ... WHERE ...] with no sharing context | [SELECT ... WHERE ... WITH USER_MODE] |
Step 6 — PNB Test Coverage Checklist
Every feature must be tested across all three paths. Missing any one of these is a quality failure:
Positive Path
- Expected input → expected output.
- Assert the exact field values, record counts, or return values — not just that no exception was thrown.
Negative Path
- Invalid input, null values, empty collections, and error conditions.
- Assert that exceptions are thrown with the correct type and message.
- Assert that no records were mutated when the operation should have failed cleanly.
Bulk Path
- Insert/update/delete 200–251 records in a single test transaction.
- Assert that all records processed correctly — no partial failures from governor limits.
- Use
Test.startTest()/Test.stopTest()to isolate governor limit counters for async work.
Test Class Rules
@isTest(SeeAllData=false) // Required — no exceptions without a documented reason
private class AccountServiceTest {
@TestSetup
static void makeData() {
// Create all test data here — use a factory if one exists in the project
}
@isTest
static void givenValidInput_whenProcessAccounts_thenFieldsUpdated() {
// Positive path
List<Account> accounts = [SELECT Id FROM Account LIMIT 10];
Test.startTest();
AccountService.processAccounts(accounts);
Test.stopTest();
// Assert meaningful outcomes — not just no exception
List<Account> updated = [SELECT Status__c FROM Account WHERE Id IN :accounts];
Assert.areEqual('Processed', updated[0].Status__c, 'Status should be Processed');
}
}
Step 7 — Trigger Architecture Checklist
- One trigger per object. If a second trigger exists, consolidate into the handler.
- Trigger body contains only: context checks, handler invocation, and routing logic.
- No business logic, SOQL, or DML directly in the trigger body.
- If a trigger framework (Trigger Actions Framework, ff-apex-common, custom base class) is already in use — extend it. Do not create a parallel pattern.
- Handler class is
with sharingunless the trigger requires elevated access.
Quick Reference — Hardcoded Anti-Patterns Summary
| Pattern | Action |
|---|---|
SOQL inside for loop | Refactor: query before the loop, operate on collections |
DML inside for loop | Refactor: collect mutations, DML once after the loop |
| Class missing sharing declaration | Add with sharing (or document why without sharing) |
escape="false" on user data (VF) | Remove — auto-escaping enforces XSS prevention |
Empty catch block | Add logging and appropriate re-throw or error handling |
| String-concatenated SOQL with user input | Replace with bind variable or whitelist validation |
| Test with no assertion | Add a meaningful Assert.* call |
System.assert / System.assertEquals style | Upgrade to Assert.isTrue / Assert.areEqual |
Hardcoded record ID ('001...') | Replace with queried or inserted test record ID |
Frequently asked questions about Salesforce Apex Quality Guardrails
Similar skills
Quality Playbook Generator
Run comprehensive quality audits on any codebase.
PR Draft Summary
Automate PR summary generation for openai-agents-python.
Final Release Review
Streamline your release candidate audits with ease.
Unit Test Vue Pinia
Efficiently write and review unit tests for Vue 3 applications.
Slang Shader Expert
Optimize and integrate Slang shaders with ease.
Telemetry Standards
Ensure consistent event tracking in Supabase Studio.
