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.

在开始编写代码前,需收集或推断以下信息:
  • 类类型(服务类、选择器类、领域类、批处理类、可队列类、可调度类、可调用类、触发器、触发器动作、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
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. 了解项目约定
    • 服务-选择器-领域分层架构、日志工具
    • 现有类/触发器及当前使用的触发器框架或处理器模式
    • 是否已使用触发器动作框架(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
    )
类型命名模式示例
服务类
{SObject}Service
AccountService
选择器类
{SObject}Selector
AccountSelector
领域类
{SObject}Domain
OpportunityDomain
批处理类
{Descriptive}Batch
AccountDeduplicationBatch
可队列类
{Descriptive}Queueable
ExternalSyncQueueable
可调度类
{Descriptive}Schedulable
DailyCleanupSchedulable
DTO
{Descriptive}DTO
AccountMergeRequestDTO
包装类
{Descriptive}Wrapper
OpportunityLineWrapper
工具类
{Descriptive}Util
StringUtil
接口
I{Descriptive}
INotificationService
抽象类
Abstract{Descriptive}
AbstractIntegrationService
异常类
{Descriptive}Exception
AccountServiceException
REST资源类
{SObject}RestResource
AccountRestResource
触发器
{SObject}Trigger
AccountTrigger
触发器动作
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行的方法提取为私有辅助方法
  • 使用依赖注入(构造函数/方法参数)提高可测试性
  • 优先使用组合和窄接口而非深层继承;通过新实现扩展功能,而非修改现有代码
  • 跨层边界的方法需遵循单一抽象层级:
层级负责内容禁止包含
触发器仅事件路由业务逻辑、编排
处理器/服务流程控制、协调内联SOQL/DML/HTTP/解析
领域业务规则、验证查询、外部调用、持久化细节
数据/集成SOQL、DML、HTTP业务决策
  • 禁止:方法混合编排与内联SOQL/DML/HTTP;业务规则与解析逻辑混合;验证+持久化+跨系统 plumbing 混合在一个方法中

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

服务类

  • 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操作委托给选择器类,SObject行为委托给领域类
  • 业务错误使用自定义异常包裹(如
    AccountServiceException

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或查询领域对应一个选择器类
  • 返回
    List<SObject>
    Map<Id, SObject>
    ;使用共享的基础字段列表常量(避免内重复)
  • 接受筛选参数;始终包含
    WITH USER_MODE

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(属于服务类/选择器类职责)

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

可队列类

  • 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

可调度类

  • 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 / 包装类

  • 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

工具类

  • 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

接口

  • Template:
    assets/interface.cls
  • Define clear contracts with ApexDoc on each method signature
  • 模板:
    assets/interface.cls
  • 定义清晰的契约,每个方法签名需添加ApexDoc注释

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

自定义异常

  • 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

触发器

  • 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
    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
)

可调用方法(
@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资源(
@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
  • 轻量级控制器:业务逻辑委托给服务类

@AuraEnabled
Controller

@AuraEnabled
控制器

  • 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
    或更高,除非指定)
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

跨技能集成

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
技能
描述对象/字段元数据技能(若可用)
部署到组织部署技能(若可用)
调用Apex的FlowFlow技能(若可用)
调用Apex的LWCLWC技能(若可用)

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
技能。