salesforce-apex-quality
Helps your agent ensure the quality and security of Apex code in Salesforce. It checks important rules to prevent limit and security issues.
What it does
This tool helps ensure that code written for the Salesforce platform is secure and efficient. It checks for common mistakes that can cause performance or security issues, like performing too many database operations at once or not checking if the user has permission to access certain data.
When to use it
- ✓When writing or reviewing Apex code for Salesforce.
- ✓When you want to avoid Salesforce governor limit errors.
- ✓To ensure code respects user permissions (security).
Example of what to ask your AI
“Review this Apex code to ensure it follows Salesforce security and limit best practices.”
Want more? Open the sections below.
How to use
The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.
Skill link
Ready-to-paste message
How it works
The tool analyzes your code for known patterns that cause problems. For example, it checks if you are querying the database or updating information inside a loop, which is inefficient and can crash the system. It also checks if the code is set up to respect the permissions of whoever is running it.
Installation
Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.
In the terminal (Claude Code, Codex, Cursor), in your project folder:
npx skills add github/awesome-copilot --skill salesforce-apex-qualityOr download just the file:
curl -L https://raw.githubusercontent.com/github/awesome-copilot/main/skills/salesforce-apex-quality/SKILL.md -o SKILL.mdTechnical content (original SKILL.md)
Original text by the author, straight from GitHub.
Salesforce 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.
…
FAQ
What are 'governor limits'?
These are Salesforce rules that limit the amount of processing code can do to ensure the platform runs smoothly for all users.
What is 'SOQL/DML in loops'?
This is when you perform a database query (SOQL) or a write operation (DML like insert, update, delete) repeatedly inside a loop. This consumes a lot of resources and is generally forbidden.
What does 'CRUD/FLS security' mean?
CRUD (Create, Read, Update, Delete) is about permission to create, read, update, or delete records. FLS (Field-Level Security) is about permission to access specific fields within a record. Code must check if the user has these permissions.
Details
Original description by the author
Apex code quality guardrails for Salesforce development. Enforces bulk-safety rules (no SOQL/DML in loops), sharing model requirements, CRUD/FLS security, SOQL injection prevention, PNB test coverage (Positive / Negative / Bulk), and modern Apex idioms. Use this skill when reviewing or generating Apex classes, trigger handlers, batch jobs, or test classes to catch governor limit risks, security ga
repo: github/awesome-copilot
Popularity
- GitHub stars
- 40k
- Ranking position
- #5355
- License
- MIT
- Updated
- 10/15/2026
Comments
- …
More skills from this repository
acquire-codebase-knowledge
Helps your agent understand and document an existing code project. It's useful for onboarding new people or getting an overview of the architecture.
github/awesome-copilot
acreadiness-assess
Enables your agent to assess a project's readiness for AI and generate a report. It's useful for understanding how well a project is prepared to use AI tools.
github/awesome-copilot
acreadiness-generate-instructions
Helps your agent create instructions for AI tools based on an assessment. It's useful for improving how AI interacts with code and closing identified gaps.
github/awesome-copilot
acreadiness-policy
Enables your agent to help define or apply policies for AI project assessment. It's useful for standardizing how projects are evaluated and ensuring compliance.
github/awesome-copilot
Similar skills
api-connector-builder
Has your agent build new API connections following the existing pattern. Use when you need to add one more integration without creating a new way of doing things.
affaan-m/ECC
api-design
Helps your agent design REST APIs following best practices. It's useful for defining how APIs communicate, how errors are shown, and how to organize data.
affaan-m/ECC
backend-patterns
Helps your agent with server-side architecture patterns and database optimization. It's useful for building or reviewing code that runs on the server.
affaan-m/ECC