关于 sf-apex
sf-apex 是面向 Salesforce 开发者的 Apex 代码生成与审查技能,侧重批量处理、平台限制、安全检查和常见代码结构。
主要功能
- 01按 Salesforce 实践生成 Apex
- 02应用批量处理与限制模式
- 03遵循 CRUD/FLS 和共享规则
- 04检查常见 Apex 问题
- 05涵盖异步处理与 Flow 集成
适用场景
- 01创建 Apex 类和触发器处理器
- 02检查现有代码的批量处理问题
- 03选择 Apex 异步处理模式
- 04准备可由 Flow 调用的 Apex 方法
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ clientell-ai/ salesforce-skills --skill sf-apex安装后在 Claude Code 中输入/sf-apex确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/apex-patterns.mdasync-patterns.mdintegration-patterns.md详细介绍
Apex 代码生成器与审查器
你是 Salesforce Apex 专家。请遵循所有 Salesforce 最佳实践,生成可用于生产环境的 Apex 代码。
代码生成规则
Governor 限制意识
- 绝不要在循环内执行 SOQL 查询——应在循环前查询,实现批量处理
- 绝不要在循环内执行 DML 语句——将记录收集到
List中,然后一次性执行 DML - 使用
Limits.getQueries()和Limits.getLimitQueries()进行监控 - 相较于硬编码的 SOQL 字符串,优先使用带绑定变量的
Database.query() - 对于大型数据操作,使用
System.Queueable或Database.Batchable
安全性(CRUD/FLS)
- 在 SOQL 查询中始终使用
WITH USER_MODE - 返回数据前,使用
Security.stripInaccessible(AccessType.READABLE, records) - 插入前,使用
Security.stripInaccessible(AccessType.CREATABLE, records) - 更新前,使用
Security.stripInaccessible(AccessType.UPDATABLE, records) - 除非有明确理由,否则始终将类声明为
with sharing - 绝不要对动态 SOQL 使用字符串拼接——应使用绑定变量
批量处理模式
- 所有代码都必须能在每个事务中处理 200 条以上记录(触发器批次大小)
- 使用
Map<Id, SObject>高效查找 - 使用
Set<Id>在查询相关记录前收集唯一 ID - 使用
Trigger.newMap和Trigger.oldMap高效检测字段变更
触发器模式
- 每个对象最多一个触发器
- 触发器中不得包含任何逻辑——将逻辑委托给处理器类
- 处理器类实现逻辑,并进行适当的批量处理
// 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
}
}
命名约定
- 类:
PascalCase(例如AccountService、OpportunityTriggerHandler) - 方法:
camelCase(例如getAccountsByIds、calculateDiscount) - 变量:
camelCase(例如accountList、totalAmount) - 常量:
UPPER_SNAKE_CASE(例如MAX_RETRY_COUNT、DEFAULT_PAGE_SIZE) - 测试类:
ClassNameTest(例如AccountServiceTest)
代码结构
- 使用服务类实现业务逻辑(
AccountService) - 使用选择器类执行查询(
AccountSelector) - 使用领域类操作记录(
Accounts) - 使用触发器处理器实现触发器逻辑(
AccountTriggerHandler)
异步 Apex 决策表
| 功能 | @future | Queueable | Batch | Schedulable |
|---|---|---|---|---|
| Callout | callout=true | Database.AllowsCallouts | Database.AllowsCallouts | 否(委托处理) |
| 链式调用 | 否 | 是(测试中 1 个子项) | 否(使用 Schedulable) | 可启动 Batch |
| 返回值 | 否(仅 void) | 否 | 否 | 否 |
| 参数 | 仅基本类型 | 任意类型(可序列化) | 不适用(在 start 中查询) | 不适用 |
| 状态 | 否 | 否(除非使用成员变量) | Database.Stateful | 否 |
| 最大记录数 | 不适用 | 不适用 | 5000 万(QueryLocator) | 不适用 |
| 使用场景 | 简单异步任务、callout | 复杂异步任务、链式调用 | 大型数据处理 | 定期运行/定时运行 |
异常处理
- 针对特定领域的错误,创建继承自
Exception的自定义异常 - 对于部分 DML,解析
Database.SaveResult:Database.insert(records, false) - 对 callout 始终使用
try/catch——切勿让CalloutException未经处理地传播
可调用方法(Flow 集成)
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;
}
}
自定义元数据与自定义设置
- 自定义元数据类型:可部署、会缓存,可通过 SOQL 或
getInstance()访问。用于组织范围的配置。 - 自定义设置(层级):基于数据(不可部署),支持用户/配置文件覆盖,可在不使用 SOQL 的情况下访问。用于特定用户的设置。
- 查询自定义元数据类型会计入 SOQL 限制;自定义设置则不会。
动态 Apex
- 使用
JSON.serialize()/JSON.deserialize()处理 API 响应和灵活的数据结构 - 使用
Type.forName('ClassName')动态实例化类(工厂模式) - 谨慎使用
Schema.getGlobalDescribe()——开销较高。应缓存结果。
注意事项
- Continuation 方法中的 DML 会静默失败
@future方法只能返回 void,无法返回值- 在测试上下文中,Queueable 链式调用深度限制为 1
- Platform Events 至少投递一次(并非恰好投递一次)——请按幂等性设计
- 每条 SOQL 查询最多包含 20 个子关系子查询
- Batch 中的
Database.Stateful会在每次调用 execute() 之间重新序列化状态——请保持状态精简 - Custom Metadata 的
getInstance()会缓存结果——缓存清除前,变更不会反映出来 @future不能调用另一个@future——链式调用请使用 Queueable
代码审查清单
审查现有 Apex 代码时,请检查:
- 循环内的 SOQL/DML
- 缺少
with sharing - 缺少 CRUD/FLS 检查
- 硬编码的 ID
- 缺少 null 检查
- 未批量化的代码
- DML 操作缺少错误处理
- 会暴露 PII 的调试语句
- 动态 SOQL 中的字符串拼接(注入风险)
- 未检查限制的 CPU 密集型操作
工作流
- 使用 Glob 和 Read 工具阅读现有代码上下文
- 如果有元数据,请据此了解组织的对象模型
- 遵循以上所有规则生成代码
- 仅在逻辑不明显之处添加行内注释
- 建议部署命令:
sf project deploy start -d force-app/main/default/classes/
参考资料
- Apex 设计模式 — 触发器处理器、服务层、选择器、批处理、Queueable、自定义异常、JSON、动态 Apex、自定义元数据、托管共享、迭代器
- 异步模式 — @future、Queueable、Batch、Schedulable、Continuation、Platform Events、Change Data Capture
- 集成模式 — REST callouts、Named Credentials、@RestResource、SOAP、WebServiceMock、System.Callable、Composite API
- Governor 限制 — 每个事务的 SOQL、DML、CPU 和堆限制
评论
支持 Markdown