元帳は、出来事を説明できる数字へ変える
複式簿記の二つの側面から、v8の計上ルール、取消しと訂正、v10の銀行全体の会計までをつなぐ。
本文の説明・図・掲載コードだけで読み進められます。出典リンクは、権限のある人向け(非公開GitHub)です。GitHubで閲覧権限がある方だけ開けます。
この記事でわかること
- 借方・貸方の意味は勘定の種類と銀行側の視点で読む
- v8は新しい業務事象を、版を固定したルールと仕訳へ結び付ける
- v10のGLは既存元帳の集計であり、もう一つの独立した正本ではない
この記事の目次
二つの行は、同じ出来事の違う側面を表す
元帳は、残高の答えだけでなく、その数字になった理由を積み重ねる記録です。架空の山田さんが十万円を預けると、銀行の現金は十万円増え、山田さんに返す義務も十万円増えます。借方に現金十万円、貸方に顧客預金十万円を記録すると、同じ出来事の二つの側面が残ります。借方と貸方は、良い・悪い、支払う・受け取るを表す言葉ではありません。
MiniBankの顧客預金は銀行側の負債なので貸方で増えます。資産や費用は通常借方で増え、負債・資本・収益は通常貸方で増える区分です。したがって、行内振込で送り手の預金勘定を借方に記録するのは、銀行が送り手へ返す義務を減らす意味になります。受け手の預金勘定の貸方は、受け手へ返す義務を増やします。
左右の合計が同じなら、片側だけを書いた誤りを検知できます。ただし、間違った相手へ同額を振り込んでも左右は一致します。複式簿記は万能な正しさの証明ではなく、整合性を確かめる重要な一つの軸です。本人、宛先、許可、重複、業務状態の確認を別に持つ必要があります。
元帳の入口が、仕訳と残高の約束を守る
基盤のledger.post_journal_entryは、仕訳を書き込むための内部処理です。最低二行があること、通貨が円であること、勘定が実在すること、借方と貸方の合計が同じであることなどを確かめます。仕訳行自体にも、片側だけを正の金額にする制約があります。入口と表の両方に防御を置き、一か所の判断だけに依存しない形です。
固定ソースでは、この処理が対象の顧客口座を順番にロックし、計上前のキャッシュと元帳の差を確認します。仕訳を書いた後には、派生残高を同じ取引内で再計算します。結果として返すのは仕訳を識別するUUIDです。ただし、この内部関数を呼べば、本人確認や業務の重複防止まですべて完了する、という意味ではありません。元帳の書込みと銀行業務の実行は、責任の範囲が違います。
読み解く際は「一回の関数呼出し」「一回の仕訳」「一回の業務依頼」を区別してください。内部部品を直接使っても、業務の依頼キーや対応する商品記録を飛ばしてしまえば、貸借だけが合った説明不足の記録が生まれ得ます。元帳の関数を実行用の練習コマンドとして扱わず、どの業務処理から呼ばれるかまで追うのが大切です。
v8は「何が起きたか」と「どう記帳したか」を結ぶ
v8のPosting Engineは、業務事象を仕訳へ変える共通機構です。業務事象とは、預金利息を支払う、口座サービス手数料を取る、といった意味を持つ出来事です。posting.event_typesで出来事の種類を登録し、会計ルールから借方・貸方の行を作り、既存の元帳へ書きます。新しい事象の記録には、使用したルールのIDと仕訳IDを残します。
たとえば十万円を預けている山田さんへ、説明用に百円の利息を支払うとします。利息費用の借方百円と、山田さんの預金の貸方百円が作られ、預金残高は十万百円になります。銀行の費用が増えたことと、顧客への支払義務が増えたことを、一つの出来事としてつなげます。この百円は本章の架空例で、自動計算された実際の利率を意味しません。
重要な範囲の注意があります。v8より前の振込・入金・出金などは、すべてこの事象表へ移し替えられたわけではありません。既存の業務記録と経路を保ち、同じ元帳の基盤を使います。「現在の全取引が必ずbusiness_eventsから始まる」と説明するのは不正確です。
同じ出来事を、同じ一回として扱う
v8の事象表では、source_system、event_type、idempotency_keyの組を一意にします。つまり、どの業務から来た何の出来事かと、同じ依頼を示すキーを組み合わせます。内容の指紋も保存し、同じキーで金額や内容を変えた場合は衝突として拒否します。同じ百円の利息支払を通信都合で再送しても、百円を二回足さないための土台です。
constraint business_events_idempotency
unique (source_system, event_type, idempotency_key)これは実際の表制約の抜粋です。さらに処理中には、同じ組の呼出しを同時に進めないためのアドバイザリロックを取ります。こちらは「このキーの作業は一つずつ」とDB内で待ち合わせる仕組みです。保存時の一意性と、保存前の順序付けが補い合います。
ルールの版を仕訳と結び付ける理由も、後からの説明にあります。今日のルールが変わっていても、昨日の百円がどの定義から作られたかを追える必要があります。ただし、ルールが固定されているだけでそのルールの経済的妥当性まで保証されるわけではありません。入力、適用ルール、結果を分けて検証できる構造を作っているのです。
取消しと訂正は、履歴へ新しい説明を足す
百円の利息が誤りで、正しくは八十円だったとします。元の百円を直接八十円へ書き換えると、誤りがいつ見つかり誰が直したかが消えます。v8の訂正は、元の百円を打ち消す逆仕訳と、正しい八十円の新しい事象を一つのトランザクションで作ります。山田さんの残高への純影響は八十円ですが、履歴には百円、マイナス百円に相当する逆向きの記録、八十円の経過が残ります。
取消しの事象には元の事象への参照があり、理由を求めます。同じ元事象を二回取り消すことや、取消しをさらに取り消すことも制限します。訂正の前半だけ成功して後半が失敗したら、顧客に戻すべき八十円が欠けるため、一組として扱うことに意味があります。
ただし汎用の取消し画面が、すべての商品を自由に戻せるわけではありません。後の版では、他行送金や融資・価格・資金取引など、業務側が持つ状態との整合を守るため、領域に属する事象の操作を制限しています。仕訳だけ戻して契約や送金状態をそのままにすれば、新しい不整合を作るからです。逆仕訳の数学と、業務上その操作を許可することは別です。
v10のGLは、同じ元帳を銀行全体の言葉へまとめる
顧客ごとの勘定を読むと、山田さんはいくら、佐藤さんはいくらと分かります。しかし銀行全体では、普通預金の総額や、現金・貸出・資金調達の残高を見たい場面があります。GLはGeneral Ledger、総勘定元帳という銀行全体の科目へ集計する層です。MiniBankのv10は既存の仕訳を集計し、別の独立した金融の正本を新しく作る設計ではありません。
すべての顧客預金勘定はGL2100の普通預金へまとめます。山田さんが十万百円、佐藤さんが五万円なら、二人だけの架空例で普通預金合計は十五万百円です。個人の内訳を失わず、銀行全体の同じ科目へ足し上げられます。SYSTEM_FUNDINGは現金GL1000、手数料収益はGL4200というように対応表を使います。
試算表では勘定科目ごとの残高と貸借の一致を、貸借対照表では資産・負債・純資産を、損益計算書では期間の収益と費用を見ます。また、GLの普通預金額と口座側の残高合計、定期預金額と有効な契約の元本合計などを照合します。左右が合う仕訳でも、商品台帳とのつながりが壊れていないかを別に確かめるためです。
締めは、数字を検査し、その時点の証拠を残す
v10の日次締めは、試算表、貸借対照表、補助元帳、勘定の対応、計上の整合性を確認し、結果と集計の写しをclosing_runsへ残します。重大な照合不一致があればBLOCKEDです。一方、結果不明の他行送金や未解消の仮受金は、基盤定義では警告として区別されます。すべての注意を同じ「失敗」にすると、何が締めを止める条件なのか分からなくなるためです。
この会計の締めと、v7の営業日の終了・開始は別の仕組みです。またv10の限界として、損益を振り替える決算仕訳は作らず、利益剰余金は収益と費用の累計から表示上計算します。過去日の締めを見ても、補助元帳の照合には現在の状態を使う部分があります。保存された写しがいつのどの範囲を示すかを、日付だけで早合点しないことが必要です。
元帳を読む力は、数字が合うことだけに安心せず、「どの業務事象か」「どのルールか」「どの記録と照合したか」「いつの状態か」を尋ねる力です。この章で確認したのは固定ソースと版ごとの契約です。実行中の銀行サービスの完全性、実際の決算対応、監査適合性を保証するものではありません。
出典と、確認できた範囲
以下のリンクは非公開GitHubへの出典で、閲覧権限が必要です。本文はリンク先を開かなくても読める構成です。固定コード・設計資料を参照していますが、今回、この読み物のために銀行の取引やDB操作、本番試験は実行していません。実装や資料にある検査と、こちらで実施した検証を混同しないようにしています。
- 仕訳の表定義 ↗(非公開GitHub・要権限)
見出し・明細と金額制約 - 元帳の計上基盤 ↗(非公開GitHub・要権限)
貸借・差異・ロック・派生残高 - v8計上機構 ↗(非公開GitHub・要権限)
事象、ルール、冪等性、取消しと訂正 - v8の範囲 ↗(非公開GitHub・要権限)
旧顧客経路の維持 - v10銀行会計 ↗(非公開GitHub・要権限)
科目対応、集計、照合、締め - v10の限界 ↗(非公開GitHub・要権限)
損益振替なし、営業日と締めの区別 - 後期の操作境界 ↗(非公開GitHub・要権限)
業務領域の事象を汎用取消しから保護
MiniBankは学習・検証用の銀行アプリです。架空の金額や人物は、仕組みを説明するための例です。
つながる読み物
ここまで読んだ記録を、ひとつ。
自分のペースで。あとから取り消すこともできます。