利用者の操作がどこを通り、どこに記録されるかを一枚の図でつかみます。

このページでわかること

  • MiniBank v1の全体構成
  • 画面・API・データベースの役割
  • データを安全に更新する境界

画面からデータまで

ブラウザに表示される画面はNext.jsで作られています。利用者が操作すると、Next.jsのAPIが入力を受け、必要な処理を呼び出します。データの保存先はSupabase上のPostgreSQLです。

認証もSupabaseを利用します。ただし「ログインできた」だけで送金を許すわけではありません。本人確認状態、口座の所有者や状態などを処理の中で確認します。

送金はデータベース内で一つにまとめる

送金は、送金元の残高を減らし、送金先を増やし、帳簿と監査ログを残す一連の処理です。途中で失敗すると一部だけ反映される危険があります。

v1では送金の核心をPostgreSQLの execute_transfer 関数にまとめ、ひとつのトランザクションとして実行します。成功なら全部確定し、失敗なら全部取り消します。

役割を分ける理由

画面は見せ方、APIは入口、データベースは整合性を守る場所です。責任の分担を決めておくと、どこにルールを書くべきかが明確になります。とくにお金を動かす不変条件は、画面の都合だけに任せません。

矢印のどこが信頼の境界か

ブラウザから届く金額や口座番号は、画面で検証していても信用できません。APIは入力の形を確認し、データベース側は口座の所有、本人確認、残高など現在の事実を確認します。境界を越えるたびに「前の層で調べたから大丈夫」と考えないことが重要です。

逆方向では、データベースの内部IDやエラー詳細をそのままブラウザへ返さず、公開してよい形に変換します。

送金ボタンを押した後の往復

山田さんが佐藤さんへ1万円を送るとします。ブラウザは入力をAPIへ渡し、APIは送金処理へ渡します。データベースは山田さんの口座が使えるか、残高が足りるかを確認し、取引と仕訳を同時に保存します。その結果がAPIから画面へ戻り、画面は完了または失敗を示します。

この往復を理解すると、画面の表示と取引の確定が別の出来事だと分かります。画面が「送信中」の間も、データベースでは検証やロックが行われています。

更新するデータと読むデータを分ける

残高表示や履歴一覧は読み取りです。一方、送金は複数の記録を変える更新です。読み取りは少し古い表示でも再取得できますが、送金では片側だけ更新された状態を許せません。二つを同じ「API呼び出し」としてまとめて考えると、必要な安全策の違いが見えにくくなります。

v1では金銭移動の核心をPostgreSQL関数に置き、送金の成立条件をデータと同じ場所で確認します。

認証と業務ルールは別の問い

ログイン済みの利用者であっても、他人の口座から送金できてはいけません。また自分の口座でも凍結中なら送金できません。「本人か」「その口座を使えるか」「今この金額を送れるか」は別々の問いです。

この区別は管理画面にも当てはまります。管理者としてログインできることと、特定の操作を実行する権限を持つことは同義ではありません。

障害はどの矢印でも起こる

ブラウザとAPIの通信が切れる、APIがデータベースへ到達できない、処理中の条件に合わず拒否されるなど、失敗の位置によって対処が違います。特に「返事が届かなかった」は、処理自体が失敗したことを意味しません。

利用者が再試行するときは同じ依頼を識別できるキーを保ち、取引履歴でも結果を確認できるようにします。構成図は正常な流れだけでなく、どこで結果が不明になり得るかを見る道具です。

どのデータがどこにあるか

ログインを管理する情報と、顧客プロフィールや口座の業務データは同じ役割ではありません。認証で得た利用者IDを業務上の顧客へ結び、そこから口座の所有を確認します。画面はその結果を表示しますが、所有関係の正解そのものを持ちません。

送金では取引、仕訳、監査という目的の違う記録が生まれます。一つの成功画面にまとめて見えても、後で調査するときに別々の視点から同じ一件をたどれることが大切です。

エラーが通る逆向きの経路

データベースが残高不足を検知しても、その内部エラー文をそのまま画面へ出しません。APIは公開してよいエラーコードと説明へ変換し、画面は利用者が次に取れる行動を示します。内部のSQLや秘密情報を漏らさないためです。

一方で調査用にはリクエストIDを使い、利用者の報告とサーバー側の記録を結びつけます。成功時だけでなく、失敗がどの層を逆向きに戻るかも構成図の一部です。

← 前の記事次の記事 →