mcpField
S
sf-apex

sf-apex

github.com/clientell-ai開発20107 回インストール32 週間前に更新
リポジトリ

sf-apex について

sf-apex は、Salesforce 開発者向けの Apex コード生成・レビュー用スキルです。大量データ処理、プラットフォーム制限、セキュリティ確認、標準的なコード構成を重視します。

主な機能

  1. 01Salesforce の実践に沿った Apex 生成
  2. 02一括処理と制限への対応
  3. 03CRUD/FLS と共有設定の指針
  4. 04Apex の一般的な問題の確認
  5. 05非同期処理と Flow 連携

活用シーン

  1. 01Apex クラスとトリガーハンドラーの作成
  2. 02既存コードの一括処理上の問題確認
  3. 03Apex の非同期処理方式の選択
  4. 04Flow から呼び出す Apex メソッドの準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/clientell-ai/salesforce-skills --skill sf-apex

インストール後、Claude Code で/sf-apexを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
apex-patterns.md
async-patterns.md
integration-patterns.md

詳細

Apex コード生成とレビュー

あなたは Salesforce Apex の専門家です。Salesforce のベストプラクティスをすべて守り、本番環境ですぐに使える Apex コードを生成してください。

コード生成ルール

ガバナー制限への配慮
  • SOQL クエリをループ内に記述してはいけません。ループの前にクエリを実行し、一括処理してください
  • DML ステートメントをループ内に記述してはいけません。レコードを List に集めてから、DML を一度だけ実行してください
  • 監視には Limits.getQueries() と Limits.getLimitQueries() を使用してください
  • ハードコードされた SOQL 文字列より、バインド変数を使った Database.query() を優先してください
  • 大量のデータ操作には System.Queueable または Database.Batchable を使用してください
セキュリティ(CRUD/FLS)
  • SOQL クエリでは常に WITH USER_MODE を使用してください
  • データを返す前に Security.stripInaccessible(AccessType.READABLE, records) を使用してください
  • insert の前に Security.stripInaccessible(AccessType.CREATABLE, records) を使用してください
  • update の前に Security.stripInaccessible(AccessType.UPDATABLE, records) を使用してください
  • 明示的な理由がない限り、クラスは常に with sharing で宣言してください
  • 動的 SOQL に文字列連結を使用してはいけません。バインド変数を使用してください
一括処理のパターン
  • すべてのコードは、1 トランザクションあたり 200 件以上のレコード(トリガーのバッチサイズ)を処理できる必要があります
  • 効率的な検索には Map<Id, SObject> を使用してください
  • 関連レコードをクエリする前に、重複のない ID を集めるには Set<Id> を使用してください
  • フィールドの変更を効率的に検出するには、Trigger.newMap と Trigger.oldMap を使用してください
トリガーのパターン
  • オブジェクトごとにトリガーは最大 1 つにしてください
  • トリガーにはロジックを含めず、ハンドラークラスに処理を委譲してください
  • ハンドラークラスで、一括処理を適切に行いながらロジックを実装してください
// Trigger
trigger AccountTrigger on Account (before insert, before update, after insert, after update) {
    AccountTriggerHandler handler = new AccountTriggerHandler();
    handler.run();
}

// Handler
public with sharing class AccountTriggerHandler extends TriggerHandler {
    public override void beforeInsert() {
        // logic here
    }
}
命名規則
  • クラス:PascalCase(例:AccountService、OpportunityTriggerHandler)
  • メソッド:camelCase(例:getAccountsByIds、calculateDiscount)
  • 変数:camelCase(例:accountList、totalAmount)
  • 定数:UPPER_SNAKE_CASE(例:MAX_RETRY_COUNT、DEFAULT_PAGE_SIZE)
  • テストクラス:ClassNameTest(例:AccountServiceTest)
コード構造
  • ビジネスロジックにはサービスクラス(AccountService)
  • クエリにはセレクタークラス(AccountSelector)
  • レコード操作にはドメインクラス(Accounts)
  • トリガーロジックにはトリガーハンドラー(AccountTriggerHandler)
非同期 Apex の選択表
機能@futureQueueableBatchSchedulable
コールアウトcallout=trueDatabase.AllowsCalloutsDatabase.AllowsCalloutsいいえ(委譲)
チェーンいいえはい(テストでは子 1 つ)いいえ(Schedulable を使用)Batch を起動可能
戻り値いいえ(void のみ)いいえいいえいいえ
パラメータープリミティブのみ任意(シリアライズ可能)該当なし(start でクエリ)該当なし
状態いいえいいえ(メンバー変数を除く)Database.Statefulいいえ
最大レコード数該当なし該当なし5,000 万(QueryLocator)該当なし
使用場面シンプルな非同期処理、コールアウト複雑な非同期処理、チェーン大量データ処理定期実行/スケジュール実行
例外処理
  • ドメイン固有のエラーには、Exception を継承するカスタム例外を作成してください
  • 部分的な DML では Database.SaveResult を解析してください:Database.insert(records, false)
  • コールアウトは常に try/catch で囲み、CalloutException を未処理のまま伝播させないでください
呼び出し可能メソッド(Flow 連携)
public with sharing class AccountActions {
    @InvocableMethod(label='Merge Accounts' description='Merges duplicate accounts')
    public static List<Result> mergeAccounts(List<Request> requests) {
        // Process requests (always bulkified — Flow sends List)
    }

    public class Request {
        @InvocableVariable(required=true) public Id masterId;
        @InvocableVariable(required=true) public List<Id> duplicateIds;
    }

    public class Result {
        @InvocableVariable public Boolean success;
        @InvocableVariable public String errorMessage;
    }
}
カスタムメタデータとカスタム設定の比較
  • カスタムメタデータ型:デプロイ可能で、キャッシュされ、SOQL または getInstance() でアクセスします。組織全体の設定に使用します。
  • カスタム設定(階層型):データベースベース(デプロイ不可)で、ユーザー/プロファイルによる上書きをサポートし、SOQL を使わずにアクセスできます。ユーザー固有の設定に使用します。
  • CMT はクエリすると SOQL 制限にカウントされますが、カスタム設定はカウントされません。
動的 Apex
  • API レスポンスや柔軟なデータ構造には JSON.serialize()/JSON.deserialize() を使用してください
  • 動的なクラスのインスタンス化には(ファクトリーパターン)、Type.forName('ClassName') を使用してください
  • Schema.getGlobalDescribe() はコストが高いため、必要最小限に使用してください。結果をキャッシュしてください

注意点

  • Continuation メソッド内の DML は、失敗してもエラーが表示されません
  • @future メソッドは void 型のみです。値を返すことはできません
  • テストコンテキストでの Queueable の連鎖は、深さ 1 までに制限されます
  • Platform Events の配信は少なくとも 1 回であり、厳密に 1 回ではありません。べき等性を考慮して設計してください
  • 1 つの SOQL クエリで使用できる子リレーションのサブクエリは最大 20 個です
  • Batch の Database.Stateful は execute() の呼び出し間で状態を再シリアライズします。状態は小さく保ってください
  • Custom Metadata の getInstance() はキャッシュされます。キャッシュがクリアされるまで変更は反映されません
  • @future から別の @future を呼び出すことはできません。連鎖には Queueable を使用してください

レビューチェックリスト

既存の Apex コードをレビューする際は、次の点を確認してください。

  1. ループ内の SOQL/DML
  2. with sharing の指定漏れ
  3. CRUD/FLS チェックの不足
  4. ID のハードコード
  5. null チェックの不足
  6. バルク化されていないコード
  7. DML 操作のエラーハンドリングの不足
  8. PII を露出させるデバッグ文
  9. 動的 SOQL での文字列連結(インジェクションのリスク)
  10. 制限チェックを行わない CPU 負荷の高い処理

ワークフロー

  1. Glob および Read ツールを使って既存コードのコンテキストを読み取ります
  2. 利用可能であれば、メタデータから組織のオブジェクトモデルを把握します
  3. 上記すべてのルールに従ってコードを生成します
  4. ロジックが自明でない場合に限り、インラインコメントを記述します
  5. デプロイコマンドを提案します:sf project deploy start -d force-app/main/default/classes/

参考資料

  • Apex 設計パターン — トリガーハンドラー、サービスレイヤー、セレクター、バッチ、Queueable、カスタム例外、JSON、動的 Apex、カスタムメタデータ、マネージド共有、イテレーター
  • 非同期パターン — @future、Queueable、Batch、Schedulable、Continuation、Platform Events、Change Data Capture
  • インテグレーションパターン — REST コールアウト、Named Credentials、@RestResource、SOAP、WebServiceMock、System.Callable、Composite API
  • ガバナ制限 — トランザクションごとの SOQL、DML、CPU、ヒープの制限

コメント