銀行エンジニアリング 02:Business EventとPosting Rule
「何が起きたか(業務)」と「どう記帳するか(会計)」を分けると、仕訳のルールを変えても業務処理を書き換えずに済みます。MiniBank v8のPosting Engineで確かめます。
v8以降に実装した台帳・記帳エンジンなどを実際に動かし、正常時と異常時の両方から銀行システムの構造を学ぶ。
Prerequisite: BANKING SYSTEMLEARNING GOALS
このページで学ぶこと
- Business Event と Posting Rule の役割分担
- ルールの版管理と、仕訳への適用ルールの固定
- 顧客ごとの勘定(補助元帳)と試算表(総勘定元帳への入口)の関係
PLAIN LANGUAGE
まず、ここだけつかむ
出来事(Business Event)と記帳方法(Posting Rule)を分けて管理します。
ルールは版付きのデータで、仕訳には適用したルールが固定されます。
顧客ごとの預金勘定は補助元帳の役割を持ち、試算表では合算して表示します。
DIFFICULT PARTS, STEP BY STEP
難しいポイントを、順番にほどく
専門用語を覚えることより、「なぜ必要か」「このシステムのどこで使うか」を理解することが目標です。
Business Event
業務上の出来事1件の記録です。
何が起きたかを会計から独立して残すためです。
posting.business_events。1イベントに1仕訳が対応します。
Posting Rule
出来事を仕訳へ変換する決まりです。
記帳方法を業務処理と分けて管理・監査するためです。
accounting.rule_definitions / rule_lines。有効化は accounting.activate_rule だけ。
Sub Ledger(補助元帳)
総勘定の内訳を顧客や契約単位で持つ帳簿です。
合計だけでなく、誰の分かを説明するためです。
顧客ごとの預金勘定(DEP-口座番号)がこの役割です。
Level 1 基礎:出来事と記帳方法を分ける
「預金に利息を払った」「口座手数料をいただいた」は業務上の出来事(Business Event)です。それを「どの勘定の借方・貸方にいくら書くか」に変換する決まりが記帳ルール(Posting Rule)で、変換して台帳に書く作業を記帳(Posting)と呼びます。
- 01Business Event(出来事)
- 02Posting Rule(記帳ルール)
- 03Journal Entry(仕訳)
- 04Journal Lines(明細)
- 05Ledger Account(勘定)
- 06Balance(残高)
Level 2 銀行業務:利息支払と手数料徴収
顧客ごとの預金勘定は、銀行全体の「預金」の内訳を顧客単位で持つ補助元帳(Sub Ledger)の役割を果たしています。試算表ではこれらを「顧客普通預金(合算)」にまとめて表示しており、これが総勘定元帳(General Ledger)側から見た預金の姿です。
| Business Event | Posting Rule | 借方 | 貸方 | 銀行にとっての意味 |
|---|---|---|---|---|
| DEPOSIT_INTEREST_PAYMENT | DEPOSIT_INTEREST_PAYMENT_STANDARD | INTEREST_EXPENSE(費用) | 顧客の預金勘定(負債) | 利息という費用が発生し、顧客へ返す義務が増える |
| SERVICE_FEE_CHARGE | SERVICE_FEE_CHARGE_STANDARD | 顧客の預金勘定(負債) | FEE_REVENUE(収益) | 顧客へ返す義務が減り、手数料収益になる |
Level 3 システム:MiniBankでの実装(正常時)
- posting.event_types がイベント種別と会計上の transaction_type、手動記帳の可否を持つ
- Posting Rule は v7 からある accounting.rule_definitions / rule_lines に登録する。v8では勘定の指定に「LEDGER:勘定コード」を使えるようにした
- posting.evaluate() がルールと文脈(口座・金額)から明細を作り、ledger.post_journal_entry() が記帳する
- 仕訳には適用したルールのIDが固定され、後でルールが新しい版に変わっても「当時どのルールで記帳したか」が残る
- 記帳のたびに posting.business_events へ1行追加し、イベント⇔仕訳が1対1で結びつく
異常時:ルールが勘定を見つけられない
| 段階 | 内容 |
|---|---|
| 症状 | 記帳が AR015(勘定を解決できない)で失敗する |
| 調査 | ルールの明細が指す勘定コードが ledger.ledger_accounts に存在するか確認する |
| 真因(実例) | v8の開発中、空のDBでは INTEREST_EXPENSE 勘定がまだ作られていなかった。v7では定期預金の初回満期時に作られる遅延作成だったため |
| 対応 | v8のmigrationで既存の作成関数を呼び、勘定を先に用意した |
| 再発防止 | 登録済みのすべてのイベントについて、ルールが勘定を解決でき借方=貸方になることを確認するテストを追加した |
Level 4 アーキテクチャ:ルールをデータとして持つ理由
記帳ルールをコードではなくデータ(版付き)で持つと、会計方針の変更を「新しい版の登録と有効化」として記録でき、過去の仕訳は当時の版で説明できます。一方で、ルールの誤りはすべての記帳に波及するため、有効化は専用関数(accounting.activate_rule)に限定され、有効化後の明細は変更できません。
どこを確認すればよいか
- 管理画面「会計・Ledger」→ 会計ルール:全ルールと版
- 管理画面「Ledger・Posting」→ 各イベントのトレース:イベント→ルール→仕訳→残高
CHECK YOUR UNDERSTANDING
3問で理解チェック
答えを頭の中で考えてから、各項目を開いて確認してください。
Q1ルールを改訂したら、過去の仕訳はどうなりますか?
変わりません。仕訳には当時のルールIDが固定されています。
Q2勘定が見つからないルールで記帳するとどうなりますか?
AR015で失敗し、何も書き込まれません。
Q3利息支払イベントの借方は何ですか?
INTEREST_EXPENSE(費用)です。
完全に暗記する必要はありません。大切な考え方を説明できそうなら押してください。
SOURCE TRAIL
根拠と関連教材
CURRENT IMPLEMENTATIONは確認したrepository内の実装です。HISTORICAL IMPLEMENTATIONは導入・修正の履歴で、後続migrationによる再定義があり得ます。RELATED LESSONは教材への案内で、実装の一次Sourceではありません。ASSUMPTIONは仮定、UNKNOWNは未確認を表します。
確認基点: d02eae8914f39cbf06bfe422dc39c71886f82b3e / 2026-09-11。稼働環境への適用確認: UNKNOWN。パス実在の自動検査と、記述した技術的事実の確認は別です。
Implementation Status: IMPLEMENTED IN MINIBANK(この教材が扱うコードの範囲)
- RELATED LESSON/docs/accounting銀行取引と会計
- RELATED LESSON/docs/be-ledger-foundation台帳と借方・貸方
- CURRENT IMPLEMENTATION
supabase/migrations/20260924100000_v8_posting_engine.sqlposting.evaluate / posting.register_rulePosting Ruleの評価と登録 - CURRENT IMPLEMENTATION
supabase/migrations/20260924100000_v8_posting_engine.sqlposting.post_event / posting.find_idempotentBusiness Eventの記帳と冪等性 - CURRENT IMPLEMENTATION
src/app/admin/(protected)/ledger/events/[id]/page.tsxEventTracePage()EventからBalanceまでのトレース画面