platform-apex-generate
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:新类、selector、service、异步任务、invocable方法和trigger;以及对现有或进行基于证据的评审。
.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.
在编写前收集或推断:
- 类类型(service、selector、domain、batch、queueable、schedulable、invocable、trigger、trigger action、DTO、utility、interface、abstract、exception、REST resource)
- 目标对象及业务目标
- 类名(使用下方命名表推导)
- 新建还是重构/修复;任何组织/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
platform-apex-test-generate
- 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
platform-apex-test-generateand{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.platform-apex-test-generate
-
发现项目约定
- Service-Selector-Domain分层、日志工具
- 现有类/trigger以及当前的trigger框架或处理程序模式
- 是否已使用Trigger Actions Framework(TAF)
-
选择最小的正确模式(见下方特定类型指南)
-
查看模板和资源
- 编写前读取中的匹配模板(见特定类型指南的文件映射)
assets/ - 如果该类型存在示例,将其作为具体风格指南阅读
references/ - 对于任何测试类工作,务必读取并使用技能
platform-apex-test-generate
- 编写前读取
-
在约束下编写 -- 应用下方规则部分的所有规则
- 生成带ApexDoc的
{ClassName}.cls - 生成
{ClassName}.cls-meta.xml
- 生成带ApexDoc的
-
生成测试类 -- 加载技能以创建
platform-apex-test-generate和{ClassName}Test.cls。部署必须生成Apex测试。不加载{ClassName}Test.cls-meta.xml技能就无法创建或编辑测试文件。platform-apex-test-generate
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.
platform-apex-test-generate - 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 - 将所有测试生成/修复/覆盖率工作委托给;迭代直至测试通过。
platform-apex-test-generate - 捕获通过/失败计数和覆盖率百分比用于报告。
- 如果不可用,在报告中记录。
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 Limits(100次查询) |
| 将所有DML置于循环外 | 避免DML Governor Limits(150条语句) |
| 为每个类声明共享关键字 | 防止意外的 |
| 使用自定义元数据/标签/describe调用而非硬编码ID | 确保跨组织的可移植性 |
| 始终处理异常(记录、重新抛出或恢复) | 防止静默失败 |
| 对所有含用户输入的动态SOQL使用绑定变量 | 防止SOQL注入 |
使用Apex原生集合( | 防止编译错误 |
| 使用前验证方法在Apex中存在 | 防止依赖不存在的API |
避免在主代码路径中使用 | 即使未启用日志,调试语句也会执行并消耗CPU。如果主代码路径需要日志,使用日志框架 |
绝不使用 | 使用带 |
Bulkification & Governor Limits
批量处理与Governor Limits
- 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
- 使用Platform Cache(/
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 - 通过Platform Encryption在静态时加密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()
- 在每个公共方法顶部添加针对空/空输入的保护子句;匹配上下文风格:私有/trigger处理程序方法中提前,公共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
| 类型 | 模式 | 示例 |
|---|---|---|
| Service | | |
| Selector | | |
| Domain | | |
| Batch | | |
| Queueable | | |
| Schedulable | | |
| DTO | | |
| Wrapper | | |
| Utility | | |
| Interface | | |
| Abstract | | |
| Exception | | |
| REST Resource | | |
| Trigger | | |
| Trigger Action | | |
额外命名规则:
- 类:
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方法都需要global - 包含:简要描述、、
@param、@return、@throws(如有帮助)@example
类级格式:
apex
/**
* Provides services for geolocation and address conversion.
*/
public with sharing class GeolocationService { }方法级格式:
apex
/**
* @param paramName Description of the parameter
* @return Description of the return value
* @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行的方法为私有辅助方法
- 使用依赖注入(构造函数/方法参数)提高可测试性
- 优先使用组合和窄接口而非深层继承;通过新实现扩展,而非修改
- 跨层边界强制执行方法的单级抽象:
| 层 | 负责内容 | 不得包含 |
|---|---|---|
| Trigger | 仅事件路由 | 业务逻辑、编排 |
| Handler/Service | 流程控制、协调 | 内联SOQL/DML/HTTP/解析 |
| Domain | 业务规则、验证 | 查询、调用、持久化细节 |
| Data/Integration | SOQL、DML、HTTP | 业务决策 |
- 禁止:将编排与内联SOQL/DML/HTTP混合的方法;将业务规则与解析内部细节混合;将验证+持久化+跨系统管道放在一个方法中
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
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委托给Selector,将SObject行为委托给Domain
- 将业务错误包装在自定义异常中(如)
AccountServiceException
Selector
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
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(属于Service/Selector)
Batch
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
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
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 / Wrapper
- 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
Utility
- Template:
assets/utility.cls - No sharing keyword needed; all methods ;
public staticconstructorprivate - Pure, side-effect-free; no SOQL/DML
- 模板:
assets/utility.cls - 无需共享关键字;所有方法为;
public static构造函数private - 纯函数,无副作用;无SOQL/DML
Interface
Interface
- Template:
assets/interface.cls - Define clear contracts with ApexDoc on each method signature
- 模板:
assets/interface.cls - 定义清晰的契约,每个方法签名带ApexDoc
Abstract
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
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
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 - 每个对象一个trigger;将所有逻辑委托给处理程序/TAF操作类
- 包含所有相关DML上下文;如果使用TAF:
new MetadataTriggerHandler().run();
Trigger Action (TAF)
Trigger Action (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
)
@InvocableMethodInvocable Method (@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);使用Blob或List<Id>字段进行Flow集合I/OList<SObject> - 始终在Response中包含、
isSuccess和errorMessage(errorType)e.getTypeName() - 在Response中返回错误(推荐);抛出异常会触发Flow错误路径 — 仅为不可恢复的故障保留
REST Resource (@RestResource
)
@RestResourceREST Resource (@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 - 轻量级控制器:将业务逻辑委托给Service类
@AuraEnabled
Controller
@AuraEnabled@AuraEnabled
Controller
@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)platform-apex-test-generate - (generated via
{ClassName}Test.cls-meta.xmlskill)platform-apex-test-generate
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技能生成)platform-apex-test-generate - (通过
{ClassName}Test.cls-meta.xml技能生成)platform-apex-test-generate
每个trigger的交付物:
{TriggerName}.trigger- (默认API版本
{TriggerName}.trigger-meta.xml或更高,除非指定)66.0
元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 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>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测试 / 修复失败 | |
| 描述对象/字段 | 元数据技能(如可用) |
| 部署到组织 | 部署技能(如可用) |
| Flow调用Apex | Flow技能(如可用) |
| LWC调用Apex | 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 testplatform-apex-test-generate此技能仅处理生产级//问题:编译/解析失败、部署依赖错误、运行时Governor Limit失败。对于测试执行、断言、覆盖率或失败,委托给。
.cls.trigger.apexsf apex run testplatform-apex-test-generate