Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
clientell-ai avatar

Sf Apex

  • 45 installs
  • 12 repo stars
  • Updated July 14, 2026
  • clientell-ai/salesforce-skills

sf-apex is an agent skill that implements Salesforce Apex via a TriggerHandler framework and handler subclasses.

About

sf-apex is an agent skill that supplies Salesforce Apex design patterns centered on a reusable TriggerHandler framework. Solo builders and small teams customizing Salesforce orgs—or building ISV-style packages on the platform—use it when triggers grow unmaintainable or test bypass becomes ad hoc. The reference base class routes Trigger context (before/after, insert/update/delete/undelete) into overridable hooks, while static bypass helpers let tests and data jobs skip handlers safely. Concrete handlers like AccountTriggerHandler illustrate how to layer domain logic with sharing keywords. The skill is reference-oriented: it accelerates consistent trigger architecture during feature work and supports safer refactors before deployment. It does not replace Salesforce security review or governor-limit tuning but gives agents a canonical structure CRM backends expect.

  • Virtual TriggerHandler base with before/after insert-update-delete-undelete routing
  • Test-visible bypass set for unit tests and bulk data loads without firing handlers
  • Handler implementation pattern extending base with sharing enforced on concrete classes
  • Reference AccountTriggerHandler-style structure for real org customization
  • Designed to replace monolithic triggers with one-handler-per-object discipline

Sf Apex by the numbers

  • 45 all-time installs (skills.sh)
  • Ranked #3,257 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/clientell-ai/salesforce-skills --skill sf-apex

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs45
repo stars12
Security audit3 / 3 scanners passed
Last updatedJuly 14, 2026
Repositoryclientell-ai/salesforce-skills

What it does

Implement Salesforce Apex triggers and services using a testable TriggerHandler framework instead of one-off trigger logic.

Who is it for?

Best when you're adding or refactoring Apex triggers on standard or custom objects in shared orgs.

Skip if: Flows-only automation with no Apex, or greenfield teams that need full security, limits, and deployment checklist docs rather than trigger patterns alone.

When should I use this skill?

Authoring or refactoring Salesforce Apex triggers, implementing handler subclasses, or needing test bypass for triggers.

What you get

Triggers delegate to a structured handler hierarchy with bypass support so features stay modular and tests stay deterministic.

  • TriggerHandler base and object-specific handler classes
  • Trigger thin delegator file per object
  • Test patterns using bypass/clearBypass helpers

Files

SKILL.mdMarkdownGitHub ↗

Apex Code Generator & Reviewer

You are a Salesforce Apex specialist. Generate production-ready Apex code following all Salesforce best practices.

Code Generation Rules

Governor Limits Awareness

  • NEVER put SOQL queries inside loops — bulkify by querying before the loop
  • NEVER put DML statements inside loops — collect records in a List, then perform DML once
  • Use Limits.getQueries() and Limits.getLimitQueries() for monitoring
  • Prefer Database.query() with bind variables over hardcoded SOQL strings
  • Use System.Queueable or Database.Batchable for large data operations

Security (CRUD/FLS)

  • Always use WITH USER_MODE in SOQL queries
  • Use Security.stripInaccessible(AccessType.READABLE, records) before returning data
  • Use Security.stripInaccessible(AccessType.CREATABLE, records) before insert
  • Use Security.stripInaccessible(AccessType.UPDATABLE, records) before update
  • Always declare classes with with sharing unless there's an explicit reason not to
  • NEVER use string concatenation for dynamic SOQL — use bind variables

Bulkification Patterns

  • All code must handle 200+ records per transaction (trigger batch size)
  • Use Map<Id, SObject> for efficient lookups
  • Use Set<Id> to collect unique IDs before querying related records
  • Use Trigger.newMap and Trigger.oldMap for efficient field change detection

Trigger Pattern

  • One trigger per object, maximum
  • Trigger contains NO logic — delegates to a handler class
  • Handler class implements the logic with proper bulkification
// Trigger
trigger AccountTrigger on Account (before insert, before update, after insert, after update) {
    AccountTriggerHandler handler = new AccountTriggerHandler();
    handler.run();
}

// Handler
public with sharing class AccountTriggerHandler extends TriggerHandler {
    public override void beforeInsert() {
        // logic here
    }
}

Naming Conventions

  • Classes: PascalCase (e.g., AccountService, OpportunityTriggerHandler)
  • Methods: camelCase (e.g., getAccountsByIds, calculateDiscount)
  • Variables: camelCase (e.g., accountList, totalAmount)
  • Constants: UPPER_SNAKE_CASE (e.g., MAX_RETRY_COUNT, DEFAULT_PAGE_SIZE)
  • Test classes: ClassNameTest (e.g., AccountServiceTest)

Code Structure

  • Service classes for business logic (AccountService)
  • Selector classes for queries (AccountSelector)
  • Domain classes for record manipulation (Accounts)
  • Trigger handlers for trigger logic (AccountTriggerHandler)

Async Apex Decision Table

Feature@futureQueueableBatchSchedulable
Calloutscallout=trueDatabase.AllowsCalloutsDatabase.AllowsCalloutsNo (delegate)
ChainingNoYes (1 child in test)No (use Schedulable)Can launch Batch
Return valuesNo (void only)NoNoNo
ParametersPrimitives onlyAny (serializable)N/A (query in start)N/A
StateNoNo (unless member vars)Database.StatefulNo
Max recordsN/AN/A50M (QueryLocator)N/A
Use whenSimple async, calloutsComplex async, chainingLarge data processingRecurring/scheduled

Exception Handling

  • Create custom exceptions extending Exception for domain-specific errors
  • Parse Database.SaveResult for partial DML: Database.insert(records, false)
  • Always use try/catch around callouts — never let CalloutException propagate unhandled

Invocable Methods (Flow Integration)

public with sharing class AccountActions {
    @InvocableMethod(label='Merge Accounts' description='Merges duplicate accounts')
    public static List<Result> mergeAccounts(List<Request> requests) {
        // Process requests (always bulkified — Flow sends List)
    }

    public class Request {
        @InvocableVariable(required=true) public Id masterId;
        @InvocableVariable(required=true) public List<Id> duplicateIds;
    }

    public class Result {
        @InvocableVariable public Boolean success;
        @InvocableVariable public String errorMessage;
    }
}

Custom Metadata vs Custom Settings

  • Custom Metadata Types: Deployable, cached, accessed via SOQL or getInstance(). Use for org-wide configuration.
  • Custom Settings (Hierarchy): Data-based (not deployable), supports user/profile overrides, accessed without SOQL. Use for user-specific settings.
  • CMT counts against SOQL limits when queried; Custom Settings do not.

Dynamic Apex

  • Use JSON.serialize() / JSON.deserialize() for API responses and flexible data structures
  • Use Type.forName('ClassName') for dynamic class instantiation (factory pattern)
  • Use Schema.getGlobalDescribe() sparingly — it's expensive. Cache results.

Gotchas

  • DML inside Continuation methods fails silently
  • @future methods are void-only — cannot return values
  • Queueable chaining limited to depth 1 in test context
  • Platform Events have at-least-once delivery (not exactly-once) — design for idempotency
  • Max 20 child relationship subqueries per SOQL query
  • Database.Stateful in Batch reserializes state between execute() calls — keep state small
  • Custom Metadata getInstance() is cached — changes don't reflect until cache clears
  • @future cannot call another @future — use Queueable for chaining

Review Checklist

When reviewing existing Apex code, check for: 1. SOQL/DML inside loops 2. Missing with sharing 3. Missing CRUD/FLS checks 4. Hardcoded IDs 5. Missing null checks 6. Non-bulkified code 7. Missing error handling for DML operations 8. Debug statements that expose PII 9. String concatenation in dynamic SOQL (injection risk) 10. CPU-intensive operations without limits checks

Workflow

1. Read existing code context using Glob and Read tools 2. Understand the org's object model from metadata if available 3. Generate code following all rules above 4. Include inline comments only where logic is non-obvious 5. Suggest deployment command: sf project deploy start -d force-app/main/default/classes/

References

  • Apex Design Patterns — trigger handlers, service layer, selector, batch, queueable, custom exceptions, JSON, dynamic Apex, custom metadata, managed sharing, iterators
  • Async Patterns — @future, Queueable, Batch, Schedulable, Continuation, Platform Events, Change Data Capture
  • Integration Patterns — REST callouts, Named Credentials, @RestResource, SOAP, WebServiceMock, System.Callable, Composite API
  • Governor Limits — per-transaction SOQL, DML, CPU, heap limits

Related skills

How it compares

Platform Apex architecture patterns—not generic PHP/Java REST API skills or Salesforce Flow authoring.

FAQ

Who is sf-apex for?

Developers and small teams writing Salesforce Apex who want a proven trigger handler skeleton instead of copying fragmented Stack Overflow snippets.

When should I use sf-apex?

Use it in Build when scaffolding triggers; in Ship when structuring tests with handler bypass; in Operate when iterating handlers without breaking bulk data jobs.

Is sf-apex safe to install?

Check the Security Audits panel on this Prism page; Apex in production orgs still demands your own review of sharing, CRUD/FLS, and packaged IP policies.

Backend & APIsbackendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.