銀行エンジニアリング 38:グループ内の資金移動と照合
2つの法人をまたぐ資金の移動を、なぜ1つの仕訳にせず『送る → 受け取る』の2段階にするのか。片側だけ確定したときに何が起き、どう見つけて、どう解消するのかを学びます。
v8以降に実装した台帳・記帳エンジンなどを実際に動かし、正常時と異常時の両方から銀行システムの構造を学ぶ。
Prerequisite: BANKING SYSTEMLEARNING GOALS
このページで学ぶこと
- 2段階の移動と、片側だけ確定した状態
- 相互勘定(グループ内債権・債務)
- 照合で『説明がつく差』と『説明のつかない差』を分ける
PLAIN LANGUAGE
まず、ここだけつかむ
entity 間の資金移動は『送る → 受け取る』の2段階で、それぞれの entity が自分の仕訳を確定します。
片側だけ確定した移動は『照合待ち』で、完了とは表示せず、人が解消するまで残ります。
照合では、移動中で説明がつく差と、説明のつかない差を分けます。
DIFFICULT PARTS, STEP BY STEP
難しいポイントを、順番にほどく
専門用語を覚えることより、「なぜ必要か」「このシステムのどこで使うか」を理解することが目標です。
相互勘定
グループ内の貸し借りの、両側の帳簿の科目です。
2つの帳簿の数字が一致していることを確かめるためです。
1500 と 2500、4300 と 5400。
照合待ち
片側だけ記帳が確定した移動の状態です。
成功とも失敗とも偽らず、解消まで見えるようにするためです。
PENDING_RECONCILIATION。retry_receive か cancel_send で解消。
説明のつかない差
移動中の金額でも説明できない、相互勘定の差です。
誤記帳や不正の兆候を見つけるためです。
reconcile の unexplained。ゼロでなければ all_matched は false。
Level 1 基礎:貸し借りは、両側の帳簿に残る
A社がB社に100円を貸すと、A社の帳簿には『Bへの債権』、B社の帳簿には『Aへの債務』が載ります。同じ取引を2つの帳簿が別々に記録するので、2つの数字は必ず一致していなければなりません。
| 種類 | 送り手 | 受け手 |
|---|---|---|
| 資金の貸出 | 現金が減り、グループ内債権(1500)が増える | 現金が増え、グループ内債務(2500)が増える |
| 返済 | 借り手が送る。債務が減る | 貸し手が受け取る。債権が減る |
| 役務の対価 | グループ内支払手数料(5400) | グループ内受取手数料(4300) |
Level 2 銀行業務:2段階にする理由
- 送り手と受け手は別の法人で、別の責任者が確定する。1つの仕訳で両側を一度に記帳すると、権限が分けられない
- 送る:送り手の仕訳を確定し、移動は『受取り待ち』になる。受け手の帳簿はまだ変わらない
- 受け取る:受け手の責任者が受け取ると、受け手の仕訳が確定して『完了』になる
- 停止中の entity は送れず、受け取れない。現金が足りなければ送れない(GR008)。返済は借りている残高を超えられない(GR009)
Level 3 システム:片側だけ確定したとき
- 送ったのに受け取れなかった移動は、そのままでは『受取り待ち』のまま残る。sweep が、受取りに失敗して残った移動を『照合待ち(PENDING_RECONCILIATION)』にする。完了とは表示しない
- 解消は2通り:retry_receive(受け手が復旧したので受け取り直す)、または cancel_send(送り手の記帳を逆仕訳で取り消す)。どちらも理由が必要で、記録に残る
- 完了・取消済みの移動は変えられない(GR007)。冪等キーは送り手ごとで、同じキー・別内容は GR005
- bankgroup.reconcile は、相手ごとに 送り手の債権と受け手の債務の差を計算し、移動中で説明がつく分と、説明のつかない分を分ける。説明のつかない差があれば all_matched は false
異常時:グループの照合が合わない
| 段階 | 内容 |
|---|---|
| 症状 | 運用センターに『片側だけ確定した移動』または『説明のつかない相互勘定の差』が出る |
| 確認1 | 差は、移動中(受取り待ち・照合待ち)の金額で説明がつくか。つくなら、移動を受け取るか取り消す |
| 確認2 | 説明がつかない差は、手仕訳などで相互勘定を直接動かしていないか(グループ内の科目は移動でだけ記帳できる。GR006) |
| 確認3 | 基準の銀行の補助元帳(1500・2500・4300・5400)が、移動の記録の合計と一致するか |
Level 4 アーキテクチャ:『成功』を偽らない
2つのシステムをまたぐ処理は、片側だけ成功した状態が必ず起きえます。それを『成功』とも『失敗』とも呼ばず、独立した状態として持ち、人が解消するまで運用センターに出し続けます。ここで大切なのは、完了の表示を、両側の記帳が揃った時にだけ出すことです。
どこを確認すればよいか
- 管理画面『グループ・連結』:移動の一覧と状態、グループの照合、照合待ちの警告
- テスト:2段階、片側だけ確定、停止、権限、冪等(scripts/banking/v19-group.test.mjs)
CHECK YOUR UNDERSTANDING
3問で理解チェック
答えを頭の中で考えてから、各項目を開いて確認してください。
Q1受け取れるのは誰ですか?
受け手の責任者だけです。送り手の役割では受け取れません。
Q2片側だけ確定した移動は、画面ではどう見えますか?
『照合待ち(片側だけ確定)』です。完了とは表示されません。
Q3手仕訳でグループ内の科目を動かせますか?
できません(GR006)。移動だけが記帳できます。
完全に暗記する必要はありません。大切な考え方を説明できそうなら押してください。
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/be-group-entity-ledgerentity と権限
- RELATED LESSON/docs/be-result-unknown結果が分からないとき
- CURRENT IMPLEMENTATION
supabase/migrations/20260930150000_v19_group.sqlbankgroup.send送り手の entity の仕訳を確定し、移動を「受取り待ち」にする(現金が足りなければ GR008、冪等キーは送り手ごと) - CURRENT IMPLEMENTATION
supabase/migrations/20260930150000_v19_group.sqlbankgroup.receive受け手の entity の仕訳を確定して「完了」にする。送り手の役割では受け取れない - CURRENT IMPLEMENTATION
supabase/migrations/20260930150000_v19_group.sqlbankgroup.sweep / bankgroup.retry_receive / bankgroup.cancel_send片側だけ確定した移動を「照合待ち」にし、受け取り直すか送り手の記帳を逆仕訳で取り消して解消する - CURRENT IMPLEMENTATION
supabase/migrations/20260930150000_v19_group.sqlbankgroup.reconcileentity ごとの借貸・相互勘定・基準の銀行の補助元帳・adapter を別々に照合し、移動中で説明がつく差と説明のつかない差を分ける - CURRENT IMPLEMENTATION
scripts/banking/v19-group.test.mjs権限の分離・2段階の移動・片側だけ確定した場合・停止・照合・連結と元帳の不変のDBテスト