generating-apex
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGenerating Apex
生成Apex代码
Use this skill for production-grade Apex: new classes, selectors, services, async jobs,
invocable methods, and triggers; and for evidence-based review of existing OR .
.cls.trigger本技能适用于生产级Apex代码开发:新类、选择器、服务、异步作业、可调用方法和触发器;也适用于对现有或文件的基于证据的评审。
.cls.triggerRequired Inputs
必要输入
Gather or infer before authoring:
- Class type (service, selector, domain, batch, queueable, schedulable, invocable, trigger, trigger action, DTO, utility, interface, abstract, exception, REST resource)
- Target object(s) and business goal
- Class name (derive using the naming table below)
- Net-new vs refactor/fix; any org/API constraints
- Deployment targets (default to runSpecifiedTests and use generated tests where applicable)
Defaults unless specified:
- Sharing: (see sharing rules per type below)
with sharing - Access: (use
publiconly when required by managed packages orglobal)@RestResource - API version: (minimum version)
66.0 - ApexDoc comments: yes
If the user provides a clear, complete request, generate immediately without unnecessary back-and-forth.
在开始编写代码前,需收集或推断以下信息:
- 类类型(服务类、选择器类、领域类、批处理类、可队列类、可调度类、可调用类、触发器、触发器动作、DTO、工具类、接口、抽象类、异常类、REST资源类)
- 目标对象及业务目标
- 类名(根据下方命名规则表生成)
- 是新建代码还是重构/修复;是否有组织/API限制
- 部署目标(默认使用runSpecifiedTests,适用时使用生成的测试用例)
未指定时的默认规则:
- 共享模式:(详见下方各类型的共享规则)
with sharing - 访问权限:(仅在托管包或
public要求时使用@RestResource)global - API版本:(最低版本)
66.0 - ApexDoc注释:必须添加
如果用户提供了清晰完整的请求,请直接生成代码,无需多余沟通。
Workflow
工作流程
All steps are sequential. Do not skip, merge, or reorder. If blocked, stop and ask for missing context. If not applicable, mark with a one-line justification in the report.
N/A所有步骤需按顺序执行,不得跳过、合并或重新排序。若因缺少上下文受阻,请停止并询问用户。若某步骤不适用,请在报告中标记并附上一行说明。
N/APhase 1 — Author
阶段1 — 编写代码
-
Discover project conventions
- Service-Selector-Domain layering, logging utilities
- Existing classes/triggers and current trigger framework or handler pattern
- Whether Trigger Actions Framework (TAF) is already in use
-
Choose the smallest correct pattern (see Type-Specific Guidance below)
-
Review templates and assets
- Read the matching template from before authoring (see Type-Specific Guidance for the file mapping)
assets/ - When a example exists for the type, read it as a concrete style guide
references/ - For any test class work, always read and use skill
generating-apex-test
- Read the matching template from
-
Author with guardrails -- apply every rule in the Rules section below
- Generate with ApexDoc
{ClassName}.cls - Generate
{ClassName}.cls-meta.xml
- Generate
-
Generate test classes -- Load the skillto create
generating-apex-testand{ClassName}Test.cls. Apex tests are always required to be generated to deploy. No test file creation or edits can occur without loading the{ClassName}Test.cls-meta.xmlskill to generate tests.generating-apex-test
-
了解项目约定
- 服务-选择器-领域分层架构、日志工具
- 现有类/触发器及当前使用的触发器框架或处理器模式
- 是否已使用触发器动作框架(TAF)
-
选择最简合适的模式(详见下方各类型专属指南)
-
查阅模板和资源
- 编写前先阅读目录下的对应模板(详见各类型专属指南中的文件映射)
assets/ - 若该类型存在示例,请将其作为具体风格指南参考
references/ - 所有测试类相关工作,务必使用技能
generating-apex-test
- 编写前先阅读
-
遵循约束编写代码 — 严格执行下方规则部分的所有要求
- 生成带ApexDoc注释的文件
{ClassName}.cls - 生成文件
{ClassName}.cls-meta.xml
- 生成带ApexDoc注释的
-
生成测试类 — 调用技能创建
generating-apex-test和{ClassName}Test.cls。Apex测试用例是部署的必要条件,未经{ClassName}Test.cls-meta.xml技能生成的测试文件不得创建或编辑。generating-apex-test
Phase 2 — Validate (required before reporting)
阶段2 — 验证(报告前必须完成)
Writing files is the midpoint, not the finish line. Steps 6 and 7 each require a tool invocation and produce output that must appear in the Step 8 report. Do not summarize or present the report until both steps have run and their output is captured.
-
Run code analyzer
- Invoke MCP on all generated/updated
run_code_analyzerfiles..cls - Remediate all ,
sev0, andsev1violations; re-run until clean.sev2 - Capture the final tool output verbatim for the report.
- Fallback: . If both are unavailable, record
sf code-analyzer run --target <target>in the report.run_code_analyzer=unavailable: <error>
- Invoke MCP
-
Execute Apex tests
- Run org tests including via
{ClassName}Testor MCP.sf apex run test - Delegate all test generation/fixes/coverage work to ; iterate until the tests pass.
generating-apex-test - Capture pass/fail counts and coverage percentage for the report.
- If unavailable, record in the report.
test_execution=unavailable: <error>
- Run org tests including
编写文件仅为中间步骤,并非最终完成。步骤6和7均需调用工具,并将输出结果纳入步骤8的报告中。在完成这两个步骤并获取输出前,不得总结或提交报告。
-
运行代码分析器
- 对所有生成/更新的文件调用MCP
.cls工具。run_code_analyzer - 修复所有、
sev0和sev1级别的问题;重新运行直至无问题。sev2 - 如实记录工具的最终输出用于报告。
- 备选方案:使用。若两种工具均不可用,请在报告中记录
sf code-analyzer run --target <target>。run_code_analyzer=unavailable: <error>
- 对所有生成/更新的
-
执行Apex测试用例
- 通过或MCP运行包含
sf apex run test的组织测试用例。{ClassName}Test - 所有测试用例生成/修复/覆盖率优化工作均委托给技能;反复迭代直至测试通过。
generating-apex-test - 记录测试通过/失败数量及覆盖率百分比用于报告。
- 若工具不可用,请在报告中记录。
test_execution=unavailable: <error>
- 通过
Phase 3 — Report
阶段3 — 提交报告
- Report -- use the output format at the bottom of this file.
- The line must contain the actual Step 6 tool output (or
Analyzerafter attempting invocation).run_code_analyzer=unavailable: <reason> - The line must contain the actual Step 7 results (or
Testingafter attempting invocation).test_execution=unavailable: <reason> - A report missing either line is incomplete. Always attempt the tool invocation before recording unavailable.
- The
- 提交报告 — 使用本文件底部的输出格式。
- 行必须包含步骤6的实际工具输出(或尝试调用后记录
Analyzer)。run_code_analyzer=unavailable: <reason> - 行必须包含步骤7的实际结果(或尝试调用后记录
Testing)。test_execution=unavailable: <reason> - 缺少任意一行的报告均视为不完整,在记录不可用情况前务必先尝试调用工具。
Rules
规则
Hard-Stop Constraints (Must Enforce)
强制约束(必须执行)
If any constraint would be violated in generated code, stop and explain the problem before proceeding:
| Constraint | Rationale |
|---|---|
| Place all SOQL outside loops | Avoid query governor limits (100 queries) |
| Place all DML outside loops | Avoid DML governor limits (150 statements) |
| Declare a sharing keyword on every class | Prevent unintended |
| Use Custom Metadata/Labels/describe calls instead of hardcoded IDs | Ensure portability across orgs |
| Always handle exceptions (log, rethrow, or recover) | Prevent silent failures |
| Use bind variables for all dynamic SOQL with user input | Prevent SOQL injection |
Use Apex-native collections ( | Prevent compile errors |
| Verify methods exist in Apex before use | Prevent reliance on non-existent APIs |
Avoid | Debug statements evaluate even when loggign is not active and consume CPU. Use a logging framework if required on main code paths |
Never use | Use Queueable with |
若生成的代码违反以下任一约束,请停止并向用户说明问题后再继续:
| 约束 | 理由 |
|---|---|
| 所有SOQL语句必须置于循环外 | 避免查询Governor限制(最多100次查询) |
| 所有DML操作必须置于循环外 | 避免DML Governor限制(最多150次操作) |
| 每个类必须声明共享关键字 | 防止意外使用 |
| 使用自定义元数据/标签/describe调用替代硬编码ID | 确保代码在不同组织间的可移植性 |
| 始终处理异常(日志记录、重新抛出或恢复) | 防止静默失败 |
| 所有含用户输入的动态SOQL必须使用绑定变量 | 防止SOQL注入攻击 |
使用Apex原生集合( | 避免编译错误 |
| 使用前验证Apex方法是否存在 | 防止依赖不存在的API |
主代码路径中避免使用 | 调试语句即使在未启用日志时也会执行,消耗CPU资源。若主代码路径需要日志,请使用日志框架 |
禁止使用 | 使用带 |
Bulkification & Governor Limits
批量处理与Governor限制
- All public APIs accept and process collections; single-record overloads delegate to the bulk method
- In batch/bulk flows, prefer partial-success DML () and process
Database.update(records, false)for errorsSaveResult - Use constructor for efficient ID-based lookups from query results
Map<Id, SObject> - Use to group child records by parent; build the map in a single loop before processing
Map<Id, List<SObject>> - Use for deduplication and membership checks; prefer
Set<Id>overSet.contains()List.contains() - Use relationship subqueries to fetch parent + child records in a single SOQL when both are needed
- Use with
AggregateResultfor rollup calculations instead of querying and counting in ApexGROUP BY - Only DML records that actually changed — compare against or prior state before adding to the update list
Trigger.oldMap - Use ,
Limits.getQueries(),Limits.getDmlStatements()to monitor consumption in complex transactionsLimits.getCpuTime()
- 所有公共API需支持集合输入和处理;单记录重载需委托给批量方法
- 在批处理/批量流程中,优先使用部分成功的DML操作()并处理
Database.update(records, false)中的错误SaveResult - 使用构造函数从查询结果中高效获取基于ID的查找
Map<Id, SObject> - 使用按父记录分组子记录;在处理前通过单次循环构建映射
Map<Id, List<SObject> - 使用进行去重和成员检查;优先使用
Set<Id>而非Set.contains()List.contains() - 当同时需要父记录和子记录时,使用关系子查询通过单次SOQL获取
- 使用带的
GROUP BY进行汇总计算,而非在Apex中查询后计数AggregateResult - 仅对实际变更的记录执行DML操作 — 在添加到更新列表前,与或先前状态进行比较
Trigger.oldMap - 在复杂事务中使用、
Limits.getQueries()、Limits.getDmlStatements()监控资源消耗Limits.getCpuTime()
SOQL Optimization
SOQL优化
- Use selective queries with proper clauses; use indexed fields (
WHERE,Id,Name, lookup/master-detail fields,OwnerIdfields, custom indexes) in filters when possibleExternalId - does not exist in SOQL -- always specify the exact fields needed
SELECT * - Apply clauses to bound result sets; use
LIMITfor deterministic resultsORDER BY - When querying Custom Metadata Types (objects ending with ), do NOT use SOQL — use the built-in methods (
__mdt,{CustomMdt__mdt}.getAll().values(), etc.)getInstance()
- 使用带合适子句的选择性查询;尽可能在筛选条件中使用索引字段(
WHERE、Id、Name、查找/主明细字段、OwnerId字段、自定义索引)ExternalId - SOQL中不存在— 始终指定所需的具体字段
SELECT * - 应用子句限制结果集大小;使用
LIMIT确保结果确定性ORDER BY - 查询自定义元数据类型(以结尾的对象)时,请勿使用SOQL — 使用内置方法(
__mdt、{CustomMdt__mdt}.getAll().values()等)getInstance()
Caching
缓存
- Use Platform Cache (/
Cache.Org) for frequently accessed, rarely changed data; set a TTL and always handle cache misses — cache can be evicted at any timeCache.Session - Use fields as transaction-scoped caches to prevent duplicate queries within the same execution context; lazy-initialize on first access
private static Map
- 使用平台缓存(/
Cache.Org)存储频繁访问、极少变更的数据;设置TTL并始终处理缓存未命中情况 — 缓存可能随时被清除Cache.Session - 使用字段作为事务范围的缓存,防止同一执行上下文中的重复查询;首次访问时延迟初始化
private static Map
Security
安全
- Default to ; document justification for
with sharingorwithout sharinginherited sharing - in SOQL and
WITH USER_MODEforAccessLevel.USER_MODEDML for CRUD/FLS enforcementDatabase - Validate dynamic field/operator names via allowlist or
Schema.describe - Named Credentials for all external credentials/API keys
- for
AuraHandledExceptionuser-facing errors (no internal details)@AuraEnabled - requires a Custom Permission check
without sharing - Isolate logic in dedicated helper classes; call from
without sharingentry points to limit elevated-access scopewith sharing - Encrypt PII/sensitive data at rest via Platform Encryption; never expose PII in debug statements, error messages, or API responses
- 默认使用;若使用
with sharing或without sharing需记录理由inherited sharing - 在SOQL中使用,在
WITH USER_MODEDML中使用Database以强制执行CRUD/FLS权限AccessLevel.USER_MODE - 通过白名单或验证动态字段/操作符名称
Schema.describe - 所有外部凭证/API密钥使用命名凭证
- 方法的用户可见错误使用
@AuraEnabled(不包含内部细节)AuraHandledException - 使用需检查自定义权限
without sharing - 将逻辑隔离在专用辅助类中;从
without sharing入口点调用以限制高权限范围with sharing - 通过平台加密对PII/敏感数据进行静态加密;绝不在调试语句、错误消息或API响应中暴露PII
Security Verification
安全验证
Before finalizing, verify: CRUD/FLS enforced (SOQL + DML) · explicit sharing keyword on every class · no hardcoded secrets or Record IDs · PII excluded from logs and error messages · error messages sanitized for end users.
最终定稿前,需验证:CRUD/FLS权限已强制执行(SOQL + DML)· 每个类都有明确的共享关键字 · 无硬编码密钥或记录ID · 日志和错误消息中不含PII · 错误消息已为终端用户清理
Error Handling
错误处理
- Catch specific exceptions before generic ; include context in messages
Exception - Use only around code that can throw (DML, callouts, JSON parsing, casts); avoid defensive wrapping of simple assignments/collection ops/arithmetic
try/catch - Preserve exception cause chains: (do not replace stack trace with concatenated messages)
new CustomException('message', cause) - Provide a custom exception class per service domain when meaningful
- In methods, catch exceptions and rethrow as
@AuraEnabledAuraHandledException - Fallback option: when no meaningful domain exception exists, catch generic and either rethrow it or wrap it in a minimal custom exception that preserves the original cause.
Exception
- 先捕获特定异常,再捕获通用;消息中需包含上下文信息
Exception - 仅在可能抛出异常的代码(DML、外部调用、JSON解析、类型转换)周围使用;避免对简单赋值/集合操作/算术运算进行防御性包裹
try/catch - 保留异常原因链:(不要用拼接消息替换堆栈跟踪)
new CustomException('message', cause) - 每个服务领域需提供自定义异常类(如有意义)
- 在方法中捕获异常并重新抛出为
@AuraEnabledAuraHandledException - 备选方案:若没有有意义的领域异常,捕获通用并重新抛出,或包裹在保留原始原因的最小自定义异常中
Exception
Null Safety
空值安全
- Add guard clauses for null/empty inputs at the top of every public method; match style to context: early in private/trigger-handler methods,
returnexceptions in public APIs,throwin validation servicesrecord.addError() - Return empty collections instead of
null - Use safe navigation () for chained property access
?. - Never dereference inline unless presence is guaranteed; use
map.get(key), assignment+null check, or safe navigation firstcontainsKey - Use null coalescing () for default values
?? - Prefer over manual checks like
String.isBlank(value)value == null || value.trim().isEmpty()
- 每个公共方法顶部需添加空值/空输入的守卫语句;根据上下文选择风格:私有/触发器处理器方法中提前,公共API中抛出异常,验证服务中使用
returnrecord.addError() - 返回空集合而非
null - 链式属性访问使用安全导航操作符()
?. - 除非确保键存在,否则不要直接引用;先使用
map.get(key)、赋值+空值检查或安全导航操作符containsKey - 使用空值合并操作符()设置默认值
?? - 优先使用而非手动检查(如
String.isBlank(value))value == null || value.trim().isEmpty()
Constants & Literals
常量与字面量
- Use enums over string constants whenever possible; enum values follow
UPPER_SNAKE_CASE - Extract repeated literal strings/numbers into constants or a constants class
private static final - Use custom labels for user-facing strings
Label. - Use Custom Metadata for configurable values (thresholds, mappings, feature flags)
- Never output HTML-escaped entities in code (e.g., ); use literal single quotes
'in Apex string literals'
- 尽可能使用枚举而非字符串常量;枚举值遵循命名法
UPPER_SNAKE_CASE - 将重复出现的字面量字符串/数字提取为常量或常量类
private static final - 用户可见字符串使用自定义标签
Label. - 可配置值(阈值、映射、功能开关)使用自定义元数据
- 代码中禁止输出HTML转义实体(如);Apex字符串字面量中使用单引号
''
Naming Conventions
命名约定
| Type | Pattern | Example |
|---|---|---|
| Service | | |
| Selector | | |
| Domain | | |
| Batch | | |
| Queueable | | |
| Schedulable | | |
| DTO | | |
| Wrapper | | |
| Utility | | |
| Interface | | |
| Abstract | | |
| Exception | | |
| REST Resource | | |
| Trigger | | |
| Trigger Action | | |
Additional naming rules:
- Classes:
PascalCase - Methods: , start with a verb (
camelCase,get,create,process,validate,is,has)can - Variables: , descriptive nouns; Lists as plural nouns (e.g.,
camelCase,accounts); Maps asrelatedContacts(e.g.,{value}By{key}); Sets asaccountsById{noun}Ids - Constants:
UPPER_SNAKE_CASE - Use full descriptive names instead of abbreviations (,
acc,tks)rec
| 类型 | 命名模式 | 示例 |
|---|---|---|
| 服务类 | | |
| 选择器类 | | |
| 领域类 | | |
| 批处理类 | | |
| 可队列类 | | |
| 可调度类 | | |
| DTO | | |
| 包装类 | | |
| 工具类 | | |
| 接口 | | |
| 抽象类 | | |
| 异常类 | | |
| REST资源类 | | |
| 触发器 | | |
| 触发器动作 | | |
额外命名规则:
- 类名:(大驼峰)
PascalCase - 方法名:(小驼峰),以动词开头(
camelCase、get、create、process、validate、is、has)can - 变量名:(小驼峰),使用描述性名词;列表用复数名词(如
camelCase、accounts);映射用relatedContacts格式(如{value}By{key});集合用accountsById格式{noun}Ids - 常量:(大写蛇形)
UPPER_SNAKE_CASE - 使用完整描述性名称而非缩写(如避免、
acc、tks)rec
ApexDoc
ApexDoc注释
- Required on the class header and every /
publicmethodglobal - Include: brief description, ,
@param,@return,@throwswhere helpful@example
Class-level format:
apex
/**
* Provides services for geolocation and address conversion.
*/
public with sharing class GeolocationService { }Method-level format:
apex
/**
* @param paramName Description of the parameter
* @return Description of the return value
* @example
* List<Account> results = AccountService.deduplicateAccounts(accountIds);
*/- 类头部和每个/
public方法必须添加ApexDoc注释global - 内容需包含:简要描述、、
@param、@return、必要时添加@throws@example
类级注释格式:
apex
/**
* 提供地理位置和地址转换服务。
*/
public with sharing class GeolocationService { }方法级注释格式:
apex
/**
* @param paramName 参数描述
* @return 返回值描述
* @example
* List<Account> results = AccountService.deduplicateAccounts(accountIds);
*/Code Structure & Architecture
代码结构与架构
- Single responsibility per class; max 500 lines -- split when exceeded
- Return Early: validate preconditions at method top, return/throw immediately
- Extract private helpers for methods over ~40 lines
- Use Dependency Injection (constructor/method params) for testability
- Prefer composition and narrow interfaces over deep inheritance; extend via new implementations, not modifications
- Enforce single-level abstraction per method across layer boundaries:
| Layer | Owns | Must NOT contain |
|---|---|---|
| Trigger | Event routing only | Business logic, orchestration |
| Handler/Service | Flow control, coordination | Inline SOQL/DML/HTTP/parsing |
| Domain | Business rules, validation | Queries, callouts, persistence details |
| Data/Integration | SOQL, DML, HTTP | Business decisions |
- Disallowed: methods mixing orchestration with inline SOQL/DML/HTTP; business rules mixed with parsing internals; validation + persistence + cross-system plumbing in one method
- 每个类遵循单一职责原则;最多500行代码 — 超过时需拆分
- 提前返回:方法顶部验证前置条件,立即返回或抛出异常
- 将超过40行的方法提取为私有辅助方法
- 使用依赖注入(构造函数/方法参数)提高可测试性
- 优先使用组合和窄接口而非深层继承;通过新实现扩展功能,而非修改现有代码
- 跨层边界的方法需遵循单一抽象层级:
| 层级 | 负责内容 | 禁止包含 |
|---|---|---|
| 触发器 | 仅事件路由 | 业务逻辑、编排 |
| 处理器/服务 | 流程控制、协调 | 内联SOQL/DML/HTTP/解析 |
| 领域 | 业务规则、验证 | 查询、外部调用、持久化细节 |
| 数据/集成 | SOQL、DML、HTTP | 业务决策 |
- 禁止:方法混合编排与内联SOQL/DML/HTTP;业务规则与解析逻辑混合;验证+持久化+跨系统 plumbing 混合在一个方法中
Async Decision Matrix
异步决策矩阵
| Scenario | Default | Key Traits |
|---|---|---|
| Standard async work | Queueable | Job ID, chaining, non-primitive types, configurable delay (up to 10 min via |
| Very large datasets | Batch Apex | Chunked processing, max 5 concurrent; use |
| Modern batch alternative | CursorStep ( | 2000-record chunks, higher throughput, no 5-job limit |
| Recurring schedule | Scheduled Flow (preferred) or Schedulable | Schedulable has 100-job limit; use only when chaining to Batch or needing complex Apex logic |
| Post-job cleanup | Finalizer ( | Runs regardless of Queueable success/failure |
| Long-running callouts | Continuation | Up to 3 per transaction, 3 parallel |
| Delays > 10 minutes | | Schedule a Batch job at a specific future time |
| Legacy fire-and-forget | | Do not use in new code — see Hard-Stop Constraints; replace with Queueable + Finalizer |
| 场景 | 默认选择 | 核心特性 |
|---|---|---|
| 标准异步工作 | Queueable | 作业ID、链式调用、支持非基本类型、可配置延迟(通过 |
| 超大数据集 | Batch Apex | 分块处理,最多5个并发作业;大范围内使用 |
| 现代批处理替代方案 | CursorStep ( | 2000记录分块,更高吞吐量,无5个作业限制 |
| 定期调度 | Scheduled Flow(优先选择)或 Schedulable | Schedulable有100个作业限制;仅在需要链式调用Batch或复杂Apex逻辑时使用 |
| 作业后清理 | Finalizer ( | 无论Queueable成功或失败都会运行 |
| 长时间外部调用 | Continuation | 每个事务最多3个,支持3个并行调用 |
| 延迟超过10分钟 | | 在特定未来时间调度Batch作业 |
| 遗留即发即弃 | | 新代码中禁止使用 — 详见强制约束;替换为Queueable + Finalizer |
Type-Specific Guidance
各类型专属指南
Service
服务类
- Template: · Reference:
assets/service.clsreferences/AccountService.cls - ; stateless — no
with sharingfields or mutable instance state; keep public APIs focused andpublicwhere reasonablestatic - Delegate all SOQL to Selectors and SObject behavior to Domains
- Wrap business errors in a custom exception (e.g., )
AccountServiceException
- 模板:· 参考示例:
assets/service.clsreferences/AccountService.cls - 使用;无状态 — 无
with sharing字段或可变实例状态;公共API需聚焦,合理使用publicstatic - 所有SOQL操作委托给选择器类,SObject行为委托给领域类
- 业务错误使用自定义异常包裹(如)
AccountServiceException
Selector
选择器类
- Template: · Reference:
assets/selector.clsreferences/AccountSelector.cls - ; one per SObject or query domain
inherited sharing - Return or
List<SObject>; use a shared base field list constant (no inline duplication)Map<Id, SObject> - Accept filter parameters; always include
WITH USER_MODE
- 模板:· 参考示例:
assets/selector.clsreferences/AccountSelector.cls - 使用;每个SObject或查询领域对应一个选择器类
inherited sharing - 返回或
List<SObject>;使用共享的基础字段列表常量(避免内重复)Map<Id, SObject> - 接受筛选参数;始终包含
WITH USER_MODE
Domain
领域类
- Template:
assets/domain.cls - ; encapsulate field defaults, derivations, and validations
with sharing - Operate on in-memory lists only; no SOQL/DML (belongs in Services/Selectors)
- 模板:
assets/domain.cls - 使用;封装字段默认值、派生逻辑和验证规则
with sharing - 仅操作内存中的列表;禁止SOQL/DML(属于服务类/选择器类职责)
Batch
批处理类
- Template: · Reference:
assets/batch.clsreferences/AccountDeduplicationBatch.cls - ; implement
with sharing(addDatabase.Batchable<SObject>when tracking across chunks)Database.Stateful - = query definition;
start()= business logic;execute()= logging/notificationfinish() - Use for large datasets; handle partial failures via
QueryLocatorDatabase.SaveResult - Accept filter parameters via constructor for reusability
- 模板:· 参考示例:
assets/batch.clsreferences/AccountDeduplicationBatch.cls - 使用;实现
with sharing(跨分块跟踪状态时添加Database.Batchable<SObject>)Database.Stateful - = 查询定义;
start()= 业务逻辑;execute()= 日志记录/通知finish() - 大数据集使用;通过
QueryLocator处理部分失败Database.SaveResult - 通过构造函数接受筛选参数以提高复用性
Queueable
可队列类
- Template:
assets/queueable.cls - ; implement
with sharingand optionallyQueueablewhen HTTP callouts are neededDatabase.AllowsCallouts - Accept data via constructor
- Add chain-depth guards to prevent infinite chains
- Optionally implement for recovery/cleanup
Finalizer - Use for configurable delay (up to 10 min) and dedup signatures
AsyncOptions
- 模板:
assets/queueable.cls - 使用;实现
with sharing,需要HTTP外部调用时可选实现QueueableDatabase.AllowsCallouts - 通过构造函数接受数据
- 添加链式调用深度防护以防止无限循环
- 可选实现用于恢复/清理
Finalizer - 使用配置延迟(最多10分钟)和去重签名
AsyncOptions
Schedulable
可调度类
- Template:
assets/schedulable.cls - ;
with sharingdelegates to Queueable or Batchexecute() - Provide CRON constants and a convenience helper
scheduleDaily()
- 模板:
assets/schedulable.cls - 使用;
with sharing方法委托给Queueable或Batchexecute() - 提供CRON常量和便捷的辅助方法
scheduleDaily()
DTO / Wrapper
DTO / 包装类
- Template:
assets/dto.cls - No sharing keyword needed (pure data containers)
- Simple public properties; no-arg + parameterized constructors; when ordering matters
Comparable - Use on private/protected inner DTOs that are serialized/deserialized
@JsonAccess
- 模板:
assets/dto.cls - 无需共享关键字(纯数据容器)
- 简单公共属性;无参+带参构造函数;排序需要时实现
Comparable - 序列化/反序列化的私有/保护内部DTO使用
@JsonAccess
Utility
工具类
- Template:
assets/utility.cls - No sharing keyword needed; all methods ;
public staticconstructorprivate - Pure, side-effect-free; no SOQL/DML
- 模板:
assets/utility.cls - 无需共享关键字;所有方法为;构造函数为
public staticprivate - 纯函数,无副作用;禁止SOQL/DML
Interface
接口
- Template:
assets/interface.cls - Define clear contracts with ApexDoc on each method signature
- 模板:
assets/interface.cls - 定义清晰的契约,每个方法签名需添加ApexDoc注释
Abstract
抽象类
- Template:
assets/abstract.cls - ; offer default behavior via
with sharingmethodsvirtual - Mark extension points or
protected virtualprotected abstract - Include a concrete example in the ApexDoc showing how to extend the class
- 模板:
assets/abstract.cls - 使用;通过
with sharing方法提供默认行为virtual - 扩展点标记为或
protected virtualprotected abstract - ApexDoc中需包含具体示例,说明如何扩展该类
Custom Exception
自定义异常
- Template:
assets/exception.cls - No sharing keyword; extend with descriptive names
Exception - Supported constructors: ,
(),('msg'),(cause)('msg', cause)
- 模板:
assets/exception.cls - 无需共享关键字;继承并使用描述性名称
Exception - 支持的构造函数:、
()、('msg')、(cause)('msg', cause)
Trigger
触发器
- Template:
assets/trigger.cls - One trigger per object; delegate all logic to handler/TAF action classes
- Include all relevant DML contexts; if TAF:
new MetadataTriggerHandler().run();
- 模板:
assets/trigger.cls - 每个对象对应一个触发器;所有逻辑委托给处理器/TAF动作类
- 包含所有相关DML上下文;若使用TAF:
new MetadataTriggerHandler().run();
Trigger Action (TAF)
触发器动作(TAF)
- One class per concern per context; implement
TriggerAction.{Context} - Register via (actions are inactive without registration)
Trigger_Action__mdt - Name: ; prefer field-value comparison over static booleans for recursion
TA_{SObject}_{ActionName}
- 每个对象的每个关注点对应一个类;实现
TriggerAction.{Context} - 通过注册(未注册的动作处于非激活状态)
Trigger_Action__mdt - 命名格式:;优先使用字段值比较而非静态布尔值防止递归
TA_{SObject}_{ActionName}
Invocable Method (@InvocableMethod
)
@InvocableMethod可调用方法(@InvocableMethod
)
@InvocableMethod- Template:
assets/invocable.cls - ; inner
with sharing/RequestwithResponse@InvocableVariable - Method must be ; non-static or single-object signatures will not compile
public static - Accept , return
List<Request>; bulkify (SOQL/DML outside loops)List<Response> - Decorator parameters: (required — Flow Builder display name),
label,description(groups actions in Builder),category(required when method makes HTTP callouts)callout=true - parameters:
@InvocableVariable(required),label,descriptionrequired=true/false - supports: primitives,
@InvocableVariable,Id,SObjectonly (noList<T>/Map/Set); useBloborList<Id>fields for Flow collection I/OList<SObject> - Always include ,
isSuccess, anderrorMessage(errorType) in Responsee.getTypeName() - Return errors in Response (recommended); throwing an exception triggers the Flow Fault path — reserve for unrecoverable failures only
- 模板:
assets/invocable.cls - 使用;内部
with sharing/Request类带Response@InvocableVariable - 方法必须为;非静态或单对象签名无法编译
public static - 接受,返回
List<Request>;支持批量处理(SOQL/DML置于循环外)List<Response> - 装饰器参数:(必填 — Flow Builder显示名称)、
label、description(在Builder中分组动作)、category(方法涉及HTTP外部调用时必填)callout=true - 参数:
@InvocableVariable(必填)、label、descriptionrequired=true/false - 支持:基本类型、
@InvocableVariable、Id、SObject(不支持List<T>/Map/Set);Flow集合输入输出使用Blob或List<Id>字段List<SObject> - Response中必须包含、
isSuccess和errorMessage(errorType)e.getTypeName() - 推荐在Response中返回错误;抛出异常会触发Flow错误路径 — 仅在不可恢复失败时使用
REST Resource (@RestResource
)
@RestResourceREST资源(@RestResource
)
@RestResource- Template:
assets/rest-resource.cls - ; both class and methods must be
global with sharingglobal - Versioned URL:
@RestResource(urlMapping='/{resource}/v1/*') - Use proper HTTP status codes per branch (/
200/201/400/404/422); never default all errors to500500 - Validate inputs (Id format: ); bind all user input in SOQL
Pattern.matches('[a-zA-Z0-9]{15,18}', value) - Include /
LIMITin queries; implement pagination (ORDER BY/pageSize)offset - Standardized wrapper (
ApiResponse,success,message/data); inner request/response DTOsrecords - Thin controller: delegate business logic to Service classes
- 模板:
assets/rest-resource.cls - 使用;类和方法必须为
global with sharingglobal - 版本化URL:
@RestResource(urlMapping='/{resource}/v1/*') - 根据分支使用正确的HTTP状态码(/
200/201/400/404/422);禁止所有错误默认返回500500 - 验证输入(ID格式:);所有用户输入在SOQL中使用绑定变量
Pattern.matches('[a-zA-Z0-9]{15,18}', value) - 查询中包含/
LIMIT;实现分页(ORDER BY/pageSize)offset - 标准化包装类(
ApiResponse、success、message/data);内部请求/响应DTOrecords - 轻量级控制器:业务逻辑委托给服务类
@AuraEnabled
Controller
@AuraEnabled@AuraEnabled
控制器
@AuraEnabled- ; use
with sharingin all SOQLWITH USER_MODE - Use only for read-only queries; leave
@AuraEnabled(cacheable=true)unset for DML operationscacheable - Catch exceptions and rethrow as with user-friendly messages
AuraHandledException
- 使用;所有SOQL使用
with sharingWITH USER_MODE - 仅对只读查询使用;DML操作不设置
@AuraEnabled(cacheable=true)cacheable - 捕获异常并重新抛出为带用户友好消息的
AuraHandledException
Output Expectations
输出要求
Deliverables per class:
{ClassName}.cls- (default API version
{ClassName}.cls-meta.xmlor higher unless specified)66.0 - (generated via
{ClassName}Test.clsskill)generating-apex-test - (generated via
{ClassName}Test.cls-meta.xmlskill)generating-apex-test
Deliverables per trigger:
{TriggerName}.trigger- (default API version
{TriggerName}.trigger-meta.xmlor higher unless specified)66.0
Meta XML template:
xml
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>{API_VERSION}</apiVersion>
<status>Active</status>
</ApexClass>Report in this order:
text
Apex work: <summary>
Files: <paths>
Design: <pattern / framework choices>
Workflow: all steps completed (1-8); any N/A justified
Risks: <security, bulkification, async, dependency notes>
Analyzer: <REQUIRED -- paste actual run_code_analyzer output or state "run_code_analyzer=unavailable: <reason>">
Testing: <REQUIRED -- paste actual test execution results (pass/fail, coverage) or state "test_execution=unavailable: <reason>">
Deploy: <dry-run or next step>每个类的交付物:
{ClassName}.cls- (默认API版本
{ClassName}.cls-meta.xml或更高,除非指定)66.0 - (通过
{ClassName}Test.cls技能生成)generating-apex-test - (通过
{ClassName}Test.cls-meta.xml技能生成)generating-apex-test
每个触发器的交付物:
{TriggerName}.trigger- (默认API版本
{TriggerName}.trigger-meta.xml或更高,除非指定)66.0
Meta XML模板:
xml
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>{API_VERSION}</apiVersion>
<status>Active</status>
</ApexClass>报告需按以下顺序:
text
Apex工作内容: <摘要>
文件路径: <路径列表>
设计方案: <模式/框架选择>
工作流程: 所有步骤已完成(1-8); 不适用步骤已说明
风险提示: <安全、批量处理、异步、依赖相关说明>
分析器结果: <必填 -- 粘贴run_code_analyzer的实际输出或记录"run_code_analyzer=unavailable: <原因>">
测试结果: <必填 -- 粘贴实际测试执行结果(通过/失败数量、覆盖率)或记录"test_execution=unavailable: <原因>">
部署建议: <预检查或下一步操作>Cross-Skill Integration
跨技能集成
| Need | Delegate to |
|---|---|
| Apex tests / fix failures | |
| Describe objects/fields | metadata skill (if available) |
| Deploy to org | deploy skill (if available) |
| Flow calling Apex | Flow skill (if available) |
| LWC calling Apex | LWC skill (if available) |
| 需求 | 委托给 |
|---|---|
| Apex测试用例/修复失败 | |
| 描述对象/字段 | 元数据技能(若可用) |
| 部署到组织 | 部署技能(若可用) |
| 调用Apex的Flow | Flow技能(若可用) |
| 调用Apex的LWC | LWC技能(若可用) |
Troubleshooting Boundary
故障处理边界
This skill handles production // issues only: compile/parse failures, deployment dependency errors, runtime governor-limit failures. For test execution, assertions, coverage, or failures, delegate to .
.cls.trigger.apexsf apex run testgenerating-apex-test本技能仅处理生产环境//文件的问题:编译/解析失败、部署依赖错误、运行时Governor限制失败。测试执行、断言、覆盖率或失败相关问题,需委托给技能。
.cls.trigger.apexsf apex run testgenerating-apex-test