WAGBY11 MANUAL / 27
登録・更新・削除に合わせて業務処理を追加する
実行する契機・条件・処理内容をruleとして整理し、保存前後のSPIへJava実装を追加する進め方を説明します。
最終更新日:
1. このページで伝える機能
データの登録・更新・削除に合わせて、関連する履歴の作成や別モデルの更新などを行えます。実行する契機、条件、処理内容をAppSchemaのrulesへ整理し、目的に合うSPIへJavaで実装します。
このページでは、受注の登録後に履歴を作る例を使います。標準の初期値・計算・入力チェックで実現できる部分を確認し、それだけでは表せない処理をカスタマイズします。ルールの文章を記述しただけで、処理が実装されるわけではありません。
2. Wagby11で実現できること
2.1 いつ・どの条件で・何を行うかを決める
例えば「受注を登録したら、その受注IDと件名を受注履歴へ記録する」「承認済みの場合だけ関連処理を行う」「削除前に関連データを確認する」といった要件を整理します。
| 決める内容 | AppSchemaでの指定 | 受注履歴の例 |
|---|---|---|
| 識別子 | id | 登録後の履歴作成を識別する固定のルールID |
| 契機 | trigger.operation | 受注の登録(INSERT) |
| 保存の前後 | trigger.timing | 受注の保存処理後(AFTER_SAVE) |
| 実行する条件 | trigger.condition | 条件を省略し、対象の登録時に処理する |
| 処理内容 | actions | 受注ID・件名・記録日時・イベント種別を履歴へ保存する |
ルールは、更新先ではなく処理の契機となるモデルへ記述します。この例では、履歴を作る処理でも受注側のモデルモジュールへ置きます。画面ボタンを定義するui.actionsとは別の設定です。
条件を指定した場合、その判定もJava側へ実装します。条件が成立しないときは対象の処理を行いません。「状態が承認済み」なのか「今回、承認済みに変わった」なのかでは対象が変わるため、更新前の値との比較が必要かも明示します。
2.2 保存前と保存後を使い分ける
| 契機 | BEFORE_SAVE(省略時) | AFTER_SAVE |
|---|---|---|
登録 INSERT | beforeCreate | afterCreate |
更新 UPDATE | beforeUpdate | afterUpdate |
削除 DELETE | beforeDelete | afterDelete |
表はLifecycleRuleHandlerで処理する場合の対応です。timingはJava実装との約束であり、指定しただけで処理を呼び分けたり、実装したりする設定ではありません。保存前の計算や業務検証には、それぞれの役割に合うSPIを使います。
登録・更新では、基本認可・追加認可、標準のルックアップと計算、追加計算、業務検証、保存前のライフサイクル処理、保存、保存後のライフサイクル処理という順序で進みます。複数の業務処理を連続して行う場合は、必要な順序を仕様と実装で明確にし、テストします。
2.3 同じモデルの値や関連レコードを扱う
同じモデルの項目へ値を設定する場合は、まず標準の初期値やcalcで表せるかを確認します。独自の計算にはCalculationCustomizer、保存を拒否する業務判断にはカスタム検証を使い分けます。
保存前後に別モデルのレコードを作成・更新する場合は、LifecycleRuleHandlerを使います。受注登録後の履歴作成なら、afterCreateへ処理を実装します。Java実装が参照する履歴モデルは、追加の依存モデルとして定義にも記録します。
関連レコードの処理では、権限・検証・計算と整合する保存方法を選びます。別モデルのルールがさらに元のモデルを更新する場合は、繰り返し起動や循環が起きない条件を決めます。同じ要求の再送や処理の再実行で、履歴や外部連携要求が重複しないことも確認します。
2.4 失敗したときに取り消す範囲を決める
保存前後のライフサイクル処理は、生成された保存処理のトランザクション内で実行します。同じトランザクションで受注と履歴を保存する例では、履歴の作成や後続処理が失敗すると受注側の変更も取り消されます。
一方、直接実行したメール送信や外部APIへの依頼は、DBのロールバックでは取り消せません。コミット成功後だけ行いたい外部処理は、同じトランザクションで送信・実行要求をOutboxへ登録し、確定後に別処理で実行する構成にします。Outboxは、後で実行する要求をDBに残す仕組みです。メールには製品のOutbox用サービスを使えます。
AFTER_COMMITというトリガーは提供しません。外部処理の失敗・再試行・重複防止も含めて設計します。保存後に利用者へメッセージを出すだけなら、保存完了通知で実現できるかを先に確認してください。
2.5 定義とJava実装を分けて依頼する
- 1回目はAppSchemaへ設計を定義します。実行契機・タイミング・条件・処理内容・依存モデルを整理し、Java実装は作らずに仕様を確認します。
- 2回目はJava実装を依頼します。AIが最新の定義から必要なコードを生成し、生成された型とRule Catalogを確認して、対応するSPIのメソッドへ実装します。
Java本体は再生成で上書きされないrestapi/src/main/customize/javaへ置きます。生成コードは直接変更しません。ルールIDと実装の未対応・重複・変更の有無に加え、条件の成立・不成立、失敗時の取り消し、重複実行をテストします。
Rule Catalogの対応検査は、業務処理の内容が正しいことをすべて保証するものではありません。AFTER_SAVEでは適切なライフサイクルSPIと対応メソッドの実装も検査しますが、そのメソッド内で条件と処理を正しく実装したかはテストで確かめます。
3. AIへの指示例
最小限の指示例
1回目:ルールの設計を用意する
受注を登録したときに、受注履歴も作りたいです。既存モデルと標準機能を確認し、まずAppSchemaのruleと必要な定義だけを用意してください。処理のタイミングと、失敗時に取り消す範囲を説明してください。Java実装はまだ作らないでください。AIは対象モデル、履歴に残す項目、条件、ルールID、関連モデルの構成を類推して補います。例えば、登録時だけの履歴か更新時にも必要か、履歴の作成に失敗したとき受注も取り消すかを整理します。この短い指示だけで、次の詳細例と同じ定義になるとは限りません。
2回目:ruleをJavaで実装する
確認したruleに対応するJava実装を、Javaカスタマイズガイドに従って作ってください。保存後処理に合うSPIを使い、生成コードを直接変更しないでください。履歴の作成、失敗時の取り消し、要求の再送時に重複しないことと、ルール・実装の対応をテストしてください。より詳細な指示例
1回目:受注登録後の履歴作成を定義する
Wagby11の業務ルールguideとrulesのreferenceを確認してください。
発火元を受注Order、関連モデルをOrderHistoryとする例です。実際の既存モデル名・主キー・項目・型を確認し、異なる場合は対応を整理してください。
受注の新規登録後に、受注ID、登録時の件名、記録日時、イベント種別CREATEDを履歴へ保存します。更新・削除ではこのルールを実行しません。履歴の保存も同じトランザクションに含め、失敗時は受注登録も取り消します。外部送信は行いません。
Orderのモデルモジュールへ、id RULE_ORDER_CREATED_HISTORY、name 受注登録履歴作成、trigger.operation INSERT、trigger.timing AFTER_SAVEを定義してください。conditionは省略し、対象の登録時に処理します。actionsへ上記の仕様を具体的に記述し、contract.entitiesにOrderHistoryを指定してください。
履歴モデルがなければ、必要な項目・参照・権限・重複を防ぐ条件を設計してください。既存の主キー・固定ID・項目・データ・権限は保持します。
今回はAppSchemaの定義と仕様確認までとし、Java実装・アプリのビルドは行わないでください。次の指示で実装すべきSPIと処理を説明してください。2回目:保存後のSPIへ実装する
確認済みのRULE_ORDER_CREATED_HISTORYを実装してください。
製品同梱のJavaカスタマイズコード作成ガイドと、業務ルールのカスタマイズの説明を確認してください。最新のAppSchemaから必要なコードを生成し、生成されたOrder・OrderHistoryの型、保存処理、Rule Catalogと既存カスタマイズを確認してください。
LifecycleRuleHandlerのafterCreateへ、受注登録後の履歴作成を実装します。beforeCreateやafterUpdateへ置き換えないでください。受注と同じトランザクションで履歴を保存し、履歴側の権限・検証・計算と整合する保存経路を使ってください。
実装はrestapi/src/main/customize/javaへ置き、生成コードは直接変更しません。ruleIdsには生成Rule Catalogの定数を使い、implementationFingerprintsへ実装時点の生成値を確認してリテラルで記録してください。同じルールIDを複数のクラスやSPIへ重複登録しないでください。
新規登録で履歴が作られること、更新ではこの登録履歴を追加しないこと、履歴作成を失敗させると受注も残らないこと、同じ冪等キーで要求を再送しても履歴が増えないことをテストしてください。Rule Catalogによる対応・タイミング・fingerprintの検査も用意してください。
実装後は必要なテストとビルドを行い、ルールと実装先の対応、検証結果を説明してください。2回目の指示例は、実装を依頼する段階で使います。ルールの定義だけを検討する段階では、Java実装やアプリのビルドへ進む必要はありません。
4. 編集されるAppSchemaの例
受注のモデルモジュールへ置く、登録後の履歴作成の例です。受注・履歴の項目、参照、権限は別に定義されている前提です。
# appschema/Order.yaml
rules:
- id: RULE_ORDER_CREATED_HISTORY
name: 受注登録履歴作成
trigger:
operation: INSERT
timing: AFTER_SAVE
actions: >-
LifecycleRuleHandler.afterCreateで、登録した受注ID、件名、
記録日時、イベント種別CREATEDをOrderHistoryへ保存する。
同じトランザクションに含め、履歴保存に失敗した場合は受注登録も取り消す。
同じ冪等キーでの要求再送によって履歴を重複作成しない。
contract:
entities: [OrderHistory]
contract.entitiesは、実装が参照する追加モデルを示します。発火元のOrderは自動で対象になるため、重ねて記述しません。actionsはAIが実装するための仕様であり、文章そのものが実行されるわけではありません。
更新時に承認済みの受注だけを対象にするなら、条件はtriggerの内側へ指定します。次は条件とタイミングの記述例です。
trigger:
operation: UPDATE
timing: AFTER_SAVE
condition: status == "APPROVED"
この条件の判定もJavaへ実装します。「承認済みへ変更されたときだけ」にしたい場合は、変更前の状態との比較と、関連処理を重複させない条件を別に仕様化します。trigger.conditionに書いた文字列を、そのまま実行する仕組みではありません。
ルールID、操作、タイミング、依存モデルなどを変更したときは、実装とテストを確認してfingerprintの記録も更新します。値だけを更新して確認を省略しないこと、進捗をrules[].noteへ書かないことは、定義と実装の対応を確認するも参照してください。
5. 参考資料
- guide:業務ルール
designer/docs/appschema/html/guide/08-rules/01-business-rules.html- guide:トリガー
designer/docs/appschema/html/guide/08-rules/02-triggers.html- guide:業務ルールの条件
designer/docs/appschema/html/guide/08-rules/03-conditions.html- guide:業務ルールのアクション
designer/docs/appschema/html/guide/08-rules/04-actions.html- reference:rules(業務ルール)
designer/docs/appschema/html/reference/08-rules.html- Javaカスタマイズコード作成ガイド
designer/docs/java/html/java-customization/index.html- 業務ルールのカスタマイズ
designer/docs/java/html/11_business_rule_customization.html