generating-apex

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Generating 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
.cls
OR
.trigger
.
此技能适用于生产级Apex开发:新类、选择器、服务、异步任务、可调用方法和触发器;以及对现有
.cls
.trigger
文件的基于证据的评审。

Required 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:
    with sharing
    (see sharing rules per type below)
  • Access:
    public
    (use
    global
    only when required by managed packages or
    @RestResource
    )
  • API version:
    66.0
    (minimum version)
  • 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
N/A
with a one-line justification in the report.
所有步骤按顺序执行,不得跳过、合并或重新排序。若受阻,停止并询问缺失的上下文。若某步骤不适用,在报告中标记
N/A
并附上一行理由。

Phase 1 — Author

阶段1 — 编写

  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
  2. Choose the smallest correct pattern (see Type-Specific Guidance below)
  3. Review templates and assets
    • Read the matching template from
      assets/
      before authoring (see Type-Specific Guidance for the file mapping)
    • When a
      references/
      example exists for the type, read it as a concrete style guide
    • For any test class work, always read and use
      generating-apex-test
      skill
  4. Author with guardrails -- apply every rule in the Rules section below
    • Generate
      {ClassName}.cls
      with ApexDoc
    • Generate
      {ClassName}.cls-meta.xml
  5. Generate test classes -- Load the skill
    generating-apex-test
    to create
    {ClassName}Test.cls
    and
    {ClassName}Test.cls-meta.xml
    . Apex tests are always required to be generated to deploy. No test file creation or edits can occur without loading the
    generating-apex-test
    skill to generate tests.
  1. 发现项目约定
    • Service-Selector-Domain分层结构、日志工具
    • 现有类/触发器及当前使用的触发器框架或处理器模式
    • 是否已使用Trigger Actions Framework (TAF)
  2. 选择最小且正确的模式(详见下方类型特定指南)
  3. 查看模板和资源
    • 编写前读取
      assets/
      中的匹配模板(详见类型特定指南中的文件映射)
    • 若该类型存在
      references/
      示例,将其作为具体风格指南阅读
    • 任何测试类工作,务必读取并使用
      generating-apex-test
      技能
  4. 遵循约束编写 -- 应用下方规则部分的所有规则
    • 生成带ApexDoc注释的
      {ClassName}.cls
      文件
    • 生成
      {ClassName}.cls-meta.xml
      文件
  5. 生成测试类 -- 加载
    generating-apex-test
    技能创建
    {ClassName}Test.cls
    {ClassName}Test.cls-meta.xml
    。部署必须生成Apex测试用例,未加载
    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.
  1. Run code analyzer
    • Invoke MCP
      run_code_analyzer
      on all generated/updated
      .cls
      files.
    • Remediate all
      sev0
      ,
      sev1
      , and
      sev2
      violations; re-run until clean.
    • Capture the final tool output verbatim for the report.
    • Fallback:
      sf code-analyzer run --target <target>
      . If both are unavailable, record
      run_code_analyzer=unavailable: <error>
      in the report.
  2. Execute Apex tests
    • Run org tests including
      {ClassName}Test
      via
      sf apex run test
      or MCP.
    • Delegate all test generation/fixes/coverage work to
      generating-apex-test
      ; iterate until the tests pass.
    • Capture pass/fail counts and coverage percentage for the report.
    • If unavailable, record
      test_execution=unavailable: <error>
      in the report.
编写文件仅为中间步骤,而非终点。步骤6和7均需调用工具,其输出必须包含在步骤8的报告中。在完成两个步骤并捕获输出前,不得总结或提交报告。
  1. 运行代码分析器
    • 对所有生成/更新的
      .cls
      文件调用MCP
      run_code_analyzer
    • 修复所有
      sev0
      sev1
      sev2
      级别的违规问题;重新运行直至无违规。
    • 完整捕获最终工具输出用于报告。
    • 备选方案:
      sf code-analyzer run --target <target>
      。若两者均不可用,在报告中记录
      run_code_analyzer=unavailable: <error>
  2. 执行Apex测试
    • 通过
      sf apex run test
      或MCP运行包含
      {ClassName}Test
      的组织测试。
    • 将所有测试生成/修复/覆盖率工作委托给
      generating-apex-test
      技能;迭代直至测试通过。
    • 捕获通过/失败计数及覆盖率百分比用于报告。
    • 若不可用,在报告中记录
      test_execution=unavailable: <error>

Phase 3 — Report

阶段3 — 报告

  1. Report -- use the output format at the bottom of this file.
    • The
      Analyzer
      line must contain the actual Step 6 tool output (or
      run_code_analyzer=unavailable: <reason>
      after attempting invocation).
    • The
      Testing
      line must contain the actual Step 7 results (or
      test_execution=unavailable: <reason>
      after attempting invocation).
    • A report missing either line is incomplete. Always attempt the tool invocation before recording unavailable.

  1. 报告 -- 使用本文件底部的输出格式。
    • Analyzer
      行必须包含步骤6的实际工具输出(或尝试调用后记录
      run_code_analyzer=unavailable: <reason>
      )。
    • Testing
      行必须包含步骤7的实际结果(或尝试调用后记录
      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:
ConstraintRationale
Place all SOQL outside loopsAvoid query governor limits (100 queries)
Place all DML outside loopsAvoid DML governor limits (150 statements)
Declare a sharing keyword on every classPrevent unintended
without sharing
defaults and data exposure
Use Custom Metadata/Labels/describe calls instead of hardcoded IDsEnsure portability across orgs
Always handle exceptions (log, rethrow, or recover)Prevent silent failures
Use bind variables for all dynamic SOQL with user inputPrevent SOQL injection
Use Apex-native collections (
List
,
Map
,
Set
) rather than Java types
Prevent compile errors
Verify methods exist in Apex before usePrevent reliance on non-existent APIs
Avoid
System.debug()
in main code paths
Debug statements evaluate even when loggign is not active and consume CPU. Use a logging framework if required on main code paths
Never use
@future
methods
Use Queueable with
System.Finalizer
;
@future
cannot chain, cannot be called from Batch, and cannot accept non-primitive types
若生成的代码违反任何约束,停止并说明问题后再继续:
约束理由
将所有SOQL置于循环外避免查询 governor 限制(100次查询)
将所有DML置于循环外避免DML governor 限制(150次操作)
为每个类声明共享关键字防止意外的
without sharing
默认值和数据泄露
使用自定义元数据/标签/describe调用而非硬编码ID确保跨组织的可移植性
始终处理异常(日志、重新抛出或恢复)防止静默失败
对所有含用户输入的动态SOQL使用绑定变量防止SOQL注入
使用Apex原生集合(
List
Map
Set
)而非Java类型
防止编译错误
使用前验证方法在Apex中是否存在避免依赖不存在的API
主代码路径中避免使用
System.debug()
调试语句即使在日志未激活时也会执行,消耗CPU。若主代码路径需要日志,使用日志框架
禁止使用
@future
方法
使用带
System.Finalizer
的Queueable;
@future
无法链式调用、无法从Batch调用、无法接受非原始类型

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 (
    Database.update(records, false)
    ) and process
    SaveResult
    for errors
  • Use
    Map<Id, SObject>
    constructor for efficient ID-based lookups from query results
  • Use
    Map<Id, List<SObject>>
    to group child records by parent; build the map in a single loop before processing
  • Use
    Set<Id>
    for deduplication and membership checks; prefer
    Set.contains()
    over
    List.contains()
  • Use relationship subqueries to fetch parent + child records in a single SOQL when both are needed
  • Use
    AggregateResult
    with
    GROUP BY
    for rollup calculations instead of querying and counting in Apex
  • Only DML records that actually changed — compare against
    Trigger.oldMap
    or prior state before adding to the update list
  • Use
    Limits.getQueries()
    ,
    Limits.getDmlStatements()
    ,
    Limits.getCpuTime()
    to monitor consumption in complex transactions
  • 所有公共API接受并处理集合;单记录重载委托给批量方法
  • 在批处理/批量流程中,优先使用部分成功DML(
    Database.update(records, false)
    )并处理
    SaveResult
    错误
  • 使用
    Map<Id, SObject>
    构造函数从查询结果中高效进行基于ID的查找
  • 使用
    Map<Id, List<SObject>
    按父记录分组子记录;处理前在单个循环中构建映射
  • 使用
    Set<Id>
    进行去重和成员检查;优先使用
    Set.contains()
    而非
    List.contains()
  • 当同时需要父记录和子记录时,使用关系子查询在单个SOQL中获取
  • 使用带
    GROUP BY
    AggregateResult
    进行汇总计算,而非在Apex中查询并计数
  • 仅DML实际变更的记录 — 更新前与
    Trigger.oldMap
    或先前状态对比
  • 在复杂事务中使用
    Limits.getQueries()
    Limits.getDmlStatements()
    Limits.getCpuTime()
    监控资源消耗

SOQL Optimization

SOQL优化

  • Use selective queries with proper
    WHERE
    clauses; use indexed fields (
    Id
    ,
    Name
    ,
    OwnerId
    , lookup/master-detail fields,
    ExternalId
    fields, custom indexes) in filters when possible
  • SELECT *
    does not exist in SOQL -- always specify the exact fields needed
  • Apply
    LIMIT
    clauses to bound result sets; use
    ORDER BY
    for deterministic results
  • When querying Custom Metadata Types (objects ending with
    __mdt
    ), do NOT use SOQL — use the built-in methods (
    {CustomMdt__mdt}.getAll().values()
    ,
    getInstance()
    , etc.)
  • 使用带适当
    WHERE
    子句的选择性查询;尽可能在过滤器中使用索引字段(
    Id
    Name
    OwnerId
    、查找/主明细字段、
    ExternalId
    字段、自定义索引)
  • SOQL中不存在
    SELECT *
    — 始终指定所需的精确字段
  • 应用
    LIMIT
    子句限制结果集;使用
    ORDER BY
    确保结果确定性
  • 查询自定义元数据类型(以
    __mdt
    结尾的对象)时,请勿使用SOQL — 使用内置方法(
    {CustomMdt__mdt}.getAll().values()
    getInstance()
    等)

Caching

缓存

  • Use Platform Cache (
    Cache.Org
    /
    Cache.Session
    ) for frequently accessed, rarely changed data; set a TTL and always handle cache misses — cache can be evicted at any time
  • Use
    private static Map
    fields as transaction-scoped caches to prevent duplicate queries within the same execution context; lazy-initialize on first access
  • 使用平台缓存(
    Cache.Org
    /
    Cache.Session
    )存储频繁访问、极少变更的数据;设置TTL并始终处理缓存未命中 — 缓存可能随时被清除
  • 使用
    private static Map
    字段作为事务范围缓存,防止同一执行上下文中的重复查询;首次访问时延迟初始化

Security

安全

  • Default to
    with sharing
    ; document justification for
    without sharing
    or
    inherited sharing
  • WITH USER_MODE
    in SOQL and
    AccessLevel.USER_MODE
    for
    Database
    DML for CRUD/FLS enforcement
  • Validate dynamic field/operator names via allowlist or
    Schema.describe
  • Named Credentials for all external credentials/API keys
  • AuraHandledException
    for
    @AuraEnabled
    user-facing errors (no internal details)
  • without sharing
    requires a Custom Permission check
  • Isolate
    without sharing
    logic in dedicated helper classes; call from
    with sharing
    entry points to limit elevated-access scope
  • 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_MODE
    ,在
    Database
    DML中使用
    AccessLevel.USER_MODE
    以执行CRUD/FLS检查
  • 通过允许列表或
    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
    Exception
    ; include context in messages
  • Use
    try/catch
    only around code that can throw (DML, callouts, JSON parsing, casts); avoid defensive wrapping of simple assignments/collection ops/arithmetic
  • Preserve exception cause chains:
    new CustomException('message', cause)
    (do not replace stack trace with concatenated messages)
  • Provide a custom exception class per service domain when meaningful
  • In
    @AuraEnabled
    methods, catch exceptions and rethrow as
    AuraHandledException
  • Fallback option: when no meaningful domain exception exists, catch generic
    Exception
    and either rethrow it or wrap it in a minimal custom exception that preserves the original cause.
  • 在捕获通用
    Exception
    前先捕获特定异常;消息中包含上下文
  • 仅在可能抛出异常的代码(DML、调用、JSON解析、类型转换)周围使用
    try/catch
    ;避免对简单赋值/集合操作/算术进行防御性包裹
  • 保留异常因果链:
    new CustomException('message', cause)
    (不要用拼接消息替换堆栈跟踪)
  • 有意义时为每个服务域提供自定义异常类
  • @AuraEnabled
    方法中捕获异常并重新抛出为
    AuraHandledException
  • 备选方案:当无有意义的域异常时,捕获通用
    Exception
    并重新抛出,或包装在保留原始原因的最小自定义异常中。

Null Safety

空值安全

  • Add guard clauses for null/empty inputs at the top of every public method; match style to context:
    return
    early in private/trigger-handler methods,
    throw
    exceptions in public APIs,
    record.addError()
    in validation services
  • Return empty collections instead of
    null
  • Use safe navigation (
    ?.
    ) for chained property access
  • Never dereference
    map.get(key)
    inline unless presence is guaranteed; use
    containsKey
    , assignment+null check, or safe navigation first
  • Use null coalescing (
    ??
    ) for default values
  • Prefer
    String.isBlank(value)
    over manual checks like
    value == null || value.trim().isEmpty()
  • 在每个公共方法顶部添加空值/空输入的防护语句;根据上下文匹配风格:私有/触发器处理器方法中提前
    return
    ,公共API中抛出异常,验证服务中使用
    record.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
    private static final
    constants or a constants class
  • Use
    Label.
    custom labels for user-facing strings
  • Use Custom Metadata for configurable values (thresholds, mappings, feature flags)
  • Never output HTML-escaped entities in code (e.g.,
    &#39;
    ); use literal single quotes
    '
    in Apex string literals
  • 尽可能使用枚举而非字符串常量;枚举值遵循
    UPPER_SNAKE_CASE
    格式
  • 将重复的字面量字符串/数字提取为
    private static final
    常量或常量类
  • 面向用户的字符串使用
    Label.
    自定义标签
  • 可配置值(阈值、映射、功能标志)使用自定义元数据
  • 代码中切勿输出HTML转义实体(如
    &#39;
    );在Apex字符串字面量中使用单引号
    '

Naming Conventions

命名约定

TypePatternExample
Service
{SObject}Service
AccountService
Selector
{SObject}Selector
AccountSelector
Domain
{SObject}Domain
OpportunityDomain
Batch
{Descriptive}Batch
AccountDeduplicationBatch
Queueable
{Descriptive}Queueable
ExternalSyncQueueable
Schedulable
{Descriptive}Schedulable
DailyCleanupSchedulable
DTO
{Descriptive}DTO
AccountMergeRequestDTO
Wrapper
{Descriptive}Wrapper
OpportunityLineWrapper
Utility
{Descriptive}Util
StringUtil
Interface
I{Descriptive}
INotificationService
Abstract
Abstract{Descriptive}
AbstractIntegrationService
Exception
{Descriptive}Exception
AccountServiceException
REST Resource
{SObject}RestResource
AccountRestResource
Trigger
{SObject}Trigger
AccountTrigger
Trigger Action
TA_{SObject}_{Action}
TA_Account_SetDefaults
Additional naming rules:
  • Classes:
    PascalCase
  • Methods:
    camelCase
    , start with a verb (
    get
    ,
    create
    ,
    process
    ,
    validate
    ,
    is
    ,
    has
    ,
    can
    )
  • Variables:
    camelCase
    , descriptive nouns; Lists as plural nouns (e.g.,
    accounts
    ,
    relatedContacts
    ); Maps as
    {value}By{key}
    (e.g.,
    accountsById
    ); Sets as
    {noun}Ids
  • Constants:
    UPPER_SNAKE_CASE
  • Use full descriptive names instead of abbreviations (
    acc
    ,
    tks
    ,
    rec
    )
类型模式示例
Service
{SObject}Service
AccountService
Selector
{SObject}Selector
AccountSelector
Domain
{SObject}Domain
OpportunityDomain
Batch
{Descriptive}Batch
AccountDeduplicationBatch
Queueable
{Descriptive}Queueable
ExternalSyncQueueable
Schedulable
{Descriptive}Schedulable
DailyCleanupSchedulable
DTO
{Descriptive}DTO
AccountMergeRequestDTO
Wrapper
{Descriptive}Wrapper
OpportunityLineWrapper
Utility
{Descriptive}Util
StringUtil
Interface
I{Descriptive}
INotificationService
Abstract
Abstract{Descriptive}
AbstractIntegrationService
Exception
{Descriptive}Exception
AccountServiceException
REST Resource
{SObject}RestResource
AccountRestResource
Trigger
{SObject}Trigger
AccountTrigger
Trigger Action
TA_{SObject}_{Action}
TA_Account_SetDefaults
额外命名规则:
  • 类:
    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
    public
    /
    global
    method
  • Include: brief description,
    @param
    ,
    @return
    ,
    @throws
    ,
    @example
    where helpful
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
    方法必须添加ApexDoc注释
  • 包含:简要描述、
    @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:
LayerOwnsMust NOT contain
TriggerEvent routing onlyBusiness logic, orchestration
Handler/ServiceFlow control, coordinationInline SOQL/DML/HTTP/parsing
DomainBusiness rules, validationQueries, callouts, persistence details
Data/IntegrationSOQL, DML, HTTPBusiness 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/IntegrationSOQL、DML、HTTP业务决策
  • 禁止:方法混合编排与内联SOQL/DML/HTTP;业务规则与解析内部逻辑混合;验证+持久化+跨系统管道在一个方法中

Async Decision Matrix

异步决策矩阵

ScenarioDefaultKey Traits
Standard async workQueueableJob ID, chaining, non-primitive types, configurable delay (up to 10 min via
AsyncOptions
), dedup signatures
Very large datasetsBatch ApexChunked processing, max 5 concurrent; use
QueryLocator
for large scopes
Modern batch alternativeCursorStep (
Database.Cursor
)
2000-record chunks, higher throughput, no 5-job limit
Recurring scheduleScheduled Flow (preferred) or SchedulableSchedulable has 100-job limit; use only when chaining to Batch or needing complex Apex logic
Post-job cleanupFinalizer (
System.Finalizer
)
Runs regardless of Queueable success/failure
Long-running calloutsContinuationUp to 3 per transaction, 3 parallel
Delays > 10 minutes
System.scheduleBatch()
Schedule a Batch job at a specific future time
Legacy fire-and-forget
@future
Do not use in new code — see Hard-Stop Constraints; replace with Queueable + Finalizer

场景默认选择核心特性
标准异步工作Queueable作业ID、链式调用、非原始类型、可配置延迟(通过
AsyncOptions
最多10分钟)、去重签名
超大数据集Batch Apex分块处理,最多5个并发;大型范围使用
QueryLocator
现代批处理替代方案CursorStep (
Database.Cursor
)
2000记录块,更高吞吐量,无5作业限制
定时重复任务Scheduled Flow(优先)或SchedulableSchedulable有100作业限制;仅在需要链式调用Batch或复杂Apex逻辑时使用
作业后清理Finalizer (
System.Finalizer
)
无论Queueable成功与否都会运行
长时间调用Continuation每个事务最多3个,支持3个并行调用
延迟超过10分钟
System.scheduleBatch()
在特定未来时间调度Batch作业
遗留即发即弃任务
@future
新代码中禁止使用 — 详见强制约束;替换为Queueable + Finalizer

Type-Specific Guidance

类型特定指南

Service

Service

  • Template:
    assets/service.cls
    · Reference:
    references/AccountService.cls
  • with sharing
    ; stateless — no
    public
    fields or mutable instance state; keep public APIs focused and
    static
    where reasonable
  • Delegate all SOQL to Selectors and SObject behavior to Domains
  • Wrap business errors in a custom exception (e.g.,
    AccountServiceException
    )
  • 模板:
    assets/service.cls
    · 参考:
    references/AccountService.cls
  • with sharing
    ;无状态 — 无
    public
    字段或可变实例状态;合理情况下保持公共API为
    static
  • 将所有SOQL委托给Selectors,将SObject行为委托给Domains
  • 将业务错误包装在自定义异常中(如
    AccountServiceException

Selector

Selector

  • Template:
    assets/selector.cls
    · Reference:
    references/AccountSelector.cls
  • inherited sharing
    ; one per SObject or query domain
  • Return
    List<SObject>
    or
    Map<Id, SObject>
    ; use a shared base field list constant (no inline duplication)
  • Accept filter parameters; always include
    WITH USER_MODE
  • 模板:
    assets/selector.cls
    · 参考:
    references/AccountSelector.cls
  • inherited sharing
    ;每个SObject或查询域对应一个Selector
  • 返回
    List<SObject>
    Map<Id, SObject>
    ;使用共享的基础字段列表常量(无内联重复)
  • 接受过滤参数;始终包含
    WITH USER_MODE

Domain

Domain

  • Template:
    assets/domain.cls
  • with sharing
    ; encapsulate field defaults, derivations, and validations
  • Operate on in-memory lists only; no SOQL/DML (belongs in Services/Selectors)
  • 模板:
    assets/domain.cls
  • with sharing
    ;封装字段默认值、派生逻辑和验证规则
  • 仅操作内存中的列表;无SOQL/DML(属于Services/Selectors职责)

Batch

Batch

  • Template:
    assets/batch.cls
    · Reference:
    references/AccountDeduplicationBatch.cls
  • with sharing
    ; implement
    Database.Batchable<SObject>
    (add
    Database.Stateful
    when tracking across chunks)
  • start()
    = query definition;
    execute()
    = business logic;
    finish()
    = logging/notification
  • Use
    QueryLocator
    for large datasets; handle partial failures via
    Database.SaveResult
  • Accept filter parameters via constructor for reusability
  • 模板:
    assets/batch.cls
    · 参考:
    references/AccountDeduplicationBatch.cls
  • with sharing
    ;实现
    Database.Batchable<SObject>
    (跨块跟踪状态时添加
    Database.Stateful
  • start()
    = 查询定义;
    execute()
    = 业务逻辑;
    finish()
    = 日志/通知
  • 大型数据集使用
    QueryLocator
    ;通过
    Database.SaveResult
    处理部分失败
  • 通过构造函数接受过滤参数以提高复用性

Queueable

Queueable

  • Template:
    assets/queueable.cls
  • with sharing
    ; implement
    Queueable
    and optionally
    Database.AllowsCallouts
    when HTTP callouts are needed
  • Accept data via constructor
  • Add chain-depth guards to prevent infinite chains
  • Optionally implement
    Finalizer
    for recovery/cleanup
  • Use
    AsyncOptions
    for configurable delay (up to 10 min) and dedup signatures
  • 模板:
    assets/queueable.cls
  • with sharing
    ;实现
    Queueable
    ,需要HTTP调用时可选实现
    Database.AllowsCallouts
  • 通过构造函数接收数据
  • 添加链深度防护以防止无限链式调用
  • 可选实现
    Finalizer
    用于恢复/清理
  • 使用
    AsyncOptions
    配置延迟(最多10分钟)和去重签名

Schedulable

Schedulable

  • Template:
    assets/schedulable.cls
  • with sharing
    ;
    execute()
    delegates to Queueable or Batch
  • Provide CRON constants and a convenience
    scheduleDaily()
    helper
  • 模板:
    assets/schedulable.cls
  • with sharing
    execute()
    委托给Queueable或Batch
  • 提供CRON常量和便捷的
    scheduleDaily()
    辅助方法

DTO / Wrapper

DTO / Wrapper

  • Template:
    assets/dto.cls
  • No sharing keyword needed (pure data containers)
  • Simple public properties; no-arg + parameterized constructors;
    Comparable
    when ordering matters
  • Use
    @JsonAccess
    on private/protected inner DTOs that are serialized/deserialized
  • 模板:
    assets/dto.cls
  • 无需共享关键字(纯数据容器)
  • 简单公共属性;无参+带参构造函数;需要排序时实现
    Comparable
  • 序列化/反序列化的私有/受保护内部DTO使用
    @JsonAccess

Utility

Utility

  • Template:
    assets/utility.cls
  • No sharing keyword needed; all methods
    public static
    ;
    private
    constructor
  • 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
  • with sharing
    ; offer default behavior via
    virtual
    methods
  • Mark extension points
    protected virtual
    or
    protected abstract
  • Include a concrete example in the ApexDoc showing how to extend the class
  • 模板:
    assets/abstract.cls
  • with sharing
    ;通过
    virtual
    方法提供默认行为
  • 扩展点标记为
    protected virtual
    protected abstract
  • ApexDoc中包含具体示例说明如何扩展类

Custom Exception

Custom Exception

  • Template:
    assets/exception.cls
  • No sharing keyword; extend
    Exception
    with descriptive names
  • 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
  • 每个对象对应一个触发器;将所有逻辑委托给处理器/TAF动作类
  • 包含所有相关DML上下文;若使用TAF:
    new MetadataTriggerHandler().run();

Trigger Action (TAF)

Trigger Action (TAF)

  • One class per concern per context; implement
    TriggerAction.{Context}
  • Register via
    Trigger_Action__mdt
    (actions are inactive without registration)
  • Name:
    TA_{SObject}_{ActionName}
    ; prefer field-value comparison over static booleans for recursion
  • 每个上下文对应一个关注点类;实现
    TriggerAction.{Context}
  • 通过
    Trigger_Action__mdt
    注册(未注册的动作处于非激活状态)
  • 命名:
    TA_{SObject}_{ActionName}
    ;优先使用字段值对比而非静态布尔值处理递归

Invocable Method (
@InvocableMethod
)

Invocable Method (
@InvocableMethod
)

  • Template:
    assets/invocable.cls
  • with sharing
    ; inner
    Request
    /
    Response
    with
    @InvocableVariable
  • Method must be
    public static
    ; non-static or single-object signatures will not compile
  • Accept
    List<Request>
    , return
    List<Response>
    ; bulkify (SOQL/DML outside loops)
  • Decorator parameters:
    label
    (required — Flow Builder display name),
    description
    ,
    category
    (groups actions in Builder),
    callout=true
    (required when method makes HTTP callouts)
  • @InvocableVariable
    parameters:
    label
    (required),
    description
    ,
    required=true/false
  • @InvocableVariable
    supports: primitives,
    Id
    ,
    SObject
    ,
    List<T>
    only (no
    Map
    /
    Set
    /
    Blob
    ); use
    List<Id>
    or
    List<SObject>
    fields for Flow collection I/O
  • Always include
    isSuccess
    ,
    errorMessage
    , and
    errorType
    (
    e.getTypeName()
    ) in Response
  • 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>
    ,返回
    List<Response>
    ;批量处理(SOQL/DML置于循环外)
  • 装饰器参数:
    label
    (必填 — Flow Builder显示名称)、
    description
    category
    (在Builder中分组动作)、
    callout=true
    (方法发起HTTP调用时必填)
  • @InvocableVariable
    参数:
    label
    (必填)、
    description
    required=true/false
  • @InvocableVariable
    支持:原始类型、
    Id
    SObject
    List<T>
    (不支持
    Map
    /
    Set
    /
    Blob
    );Flow集合输入输出使用
    List<Id>
    List<SObject>
    字段
  • Response中始终包含
    isSuccess
    errorMessage
    errorType
    e.getTypeName()
  • 在Response中返回错误(推荐);抛出异常会触发Flow错误路径 — 仅用于不可恢复的失败

REST Resource (
@RestResource
)

REST Resource (
@RestResource
)

  • Template:
    assets/rest-resource.cls
  • global with sharing
    ; both class and methods must be
    global
  • Versioned URL:
    @RestResource(urlMapping='/{resource}/v1/*')
  • Use proper HTTP status codes per branch (
    200
    /
    201
    /
    400
    /
    404
    /
    422
    /
    500
    ); never default all errors to
    500
  • Validate inputs (Id format:
    Pattern.matches('[a-zA-Z0-9]{15,18}', value)
    ); bind all user input in SOQL
  • Include
    LIMIT
    /
    ORDER BY
    in queries; implement pagination (
    pageSize
    /
    offset
    )
  • Standardized
    ApiResponse
    wrapper (
    success
    ,
    message
    ,
    data
    /
    records
    ); inner request/response DTOs
  • Thin controller: delegate business logic to Service classes
  • 模板:
    assets/rest-resource.cls
  • global with sharing
    ;类和方法必须为
    global
  • 版本化URL:
    @RestResource(urlMapping='/{resource}/v1/*')
  • 根据分支使用正确的HTTP状态码(
    200
    /
    201
    /
    400
    /
    404
    /
    422
    /
    500
    );切勿将所有错误默认设为
    500
  • 验证输入(Id格式:
    Pattern.matches('[a-zA-Z0-9]{15,18}', value)
    );SOQL中绑定所有用户输入
  • 查询中包含
    LIMIT
    /
    ORDER BY
    ;实现分页(
    pageSize
    /
    offset
  • 标准化
    ApiResponse
    包装器(
    success
    message
    data
    /
    records
    );内部请求/响应DTO
  • 轻量级控制器:将业务逻辑委托给Service类

@AuraEnabled
Controller

@AuraEnabled
Controller

  • with sharing
    ; use
    WITH USER_MODE
    in all SOQL
  • Use
    @AuraEnabled(cacheable=true)
    only for read-only queries; leave
    cacheable
    unset for DML operations
  • Catch exceptions and rethrow as
    AuraHandledException
    with user-friendly messages

  • with sharing
    ;所有SOQL使用
    WITH USER_MODE
  • 仅对只读查询使用
    @AuraEnabled(cacheable=true)
    ;DML操作不设置
    cacheable
  • 捕获异常并重新抛出为带用户友好消息的
    AuraHandledException

Output Expectations

输出预期

Deliverables per class:
  • {ClassName}.cls
  • {ClassName}.cls-meta.xml
    (default API version
    66.0
    or higher unless specified)
  • {ClassName}Test.cls
    (generated via
    generating-apex-test
    skill)
  • {ClassName}Test.cls-meta.xml
    (generated via
    generating-apex-test
    skill)
Deliverables per trigger:
  • {TriggerName}.trigger
  • {TriggerName}.trigger-meta.xml
    (default API version
    66.0
    or higher unless specified)
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
  • {ClassName}.cls-meta.xml
    (默认API版本
    66.0
    或更高,除非指定)
  • {ClassName}Test.cls
    (通过
    generating-apex-test
    技能生成)
  • {ClassName}Test.cls-meta.xml
    (通过
    generating-apex-test
    技能生成)
每个触发器的交付物:
  • {TriggerName}.trigger
  • {TriggerName}.trigger-meta.xml
    (默认API版本
    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工作:<摘要>
文件:<路径>
设计:<模式/框架选择>
工作流程:所有步骤已完成(1-8);任何N/A已说明理由
风险:<安全、批量处理、异步、依赖项说明>
Analyzer:<必填 -- 粘贴实际run_code_analyzer输出或记录"run_code_analyzer=unavailable: <理由>">
Testing:<必填 -- 粘贴实际测试执行结果(通过/失败、覆盖率)或记录"test_execution=unavailable: <理由>">
部署:<试运行或下一步>

Cross-Skill Integration

跨技能集成

NeedDelegate to
Apex tests / fix failures
generating-apex-test
skill
Describe objects/fieldsmetadata skill (if available)
Deploy to orgdeploy skill (if available)
Flow calling ApexFlow skill (if available)
LWC calling ApexLWC skill (if available)

需求委托给
Apex测试 / 修复失败
generating-apex-test
技能
描述对象/字段metadata技能(若可用)
部署到组织deploy技能(若可用)
Flow调用ApexFlow技能(若可用)
LWC调用ApexLWC技能(若可用)

Troubleshooting Boundary

故障排除边界

This skill handles production
.cls
/
.trigger
/
.apex
issues only: compile/parse failures, deployment dependency errors, runtime governor-limit failures. For test execution, assertions, coverage, or
sf apex run test
failures, delegate to
generating-apex-test
.
此技能仅处理生产级
.cls
/
.trigger
/
.apex
问题:编译/解析失败、部署依赖错误、运行时governor限制失败。测试执行、断言、覆盖率或
sf apex run test
失败问题,委托给
generating-apex-test
技能。