学習・技術検証用デモ — 本システムは実際の銀行サービスではありません。

公開情報をもとに構築した教育目的のシステムです。実在する個人情報・口座情報・機密情報・認証情報等を入力しないでください。

ミニ銀行ACADEMY SYSTEM LEARNING
教材メニュー
学習進捗0 / 134
あと134項目
ADVANCED · 発展COURSE 05 · JAVA / ENTERPRISE DEVELOPMENT

Minibank Architecture:Javaサービスを全体へ置く

最後に、Next.js、Spring Boot Payment Service、PostgREST、PostgreSQL RPC、Ledgerの責任を1本の処理としてつなぎます。現在の実装範囲と、まだ保証されていない部分も区別します。

11 / 11
JAVA / ENTERPRISE DEVELOPMENT · Java・エンタープライズ開発

Java / Spring Bootを入口に、金融システムのService・Repository・Transaction設計を読む。

先に学ぶ内容 — Prerequisite: ソフトウェア工学 / 銀行システム

学ぶこと — LEARNING GOALS

このページで学ぶこと

  • Payment Serviceの全体位置
  • 1件の振込依頼とOTP確認の流れ
  • 現在の実装範囲と次に必要な検証

体験19 · JAVA MINIBANK ARCHITECTURE(全体への位置づけ)

Javaが失敗したとき、自動で別経路に切り替わるか確かめよう

まずは予想をひと言。本文を読んだ後、教材内の参照元で実際のJavaコードを確認します。

体験学習 · STEP 1 / 5
  1. 01
    まず予想する — PREDICT

    まずここだけ:思ったことをひと言書く

    新しく追加されたJavaのサービスが動かなくなったら、既存の仕組み(Next.js)は自動的にそちらを迂回してくれるでしょうか?

    正解でなくて大丈夫です。「〜だと思う」から始めてみましょう。

    ヒント1を見る

    処理が本当に成功したか分からないとき、別の経路でもう一度実行してよいでしょうか?

    ヒント2を見る

    JavaがLedgerや残高を直接管理していたら、既存の仕組みとの責任分担はどうなっていたでしょうか?

    もっと詳しく:この問いで使う専門用語
    • 段階的移行は、既存機能を保ちながら新しい経路を小さく追加することです。
    • fail-closedは、結果が不明なときに処理を続けず失敗として止める考え方です。
    • 責任境界は、各部品が決めることと決めないことを分けることです。
まずはひと言だけで大丈夫です。

この後の本文を最後まで読んでから、実際に操作して確かめるステップへ進みます。

日常語で理解する — PLAIN LANGUAGE

まず、ここだけつかむ

1

Payment Serviceは既存Minibankを置き換えず、振込処理を段階的にJava化する追加のAPI境界です。

2

Next.jsは設定で入口を選び、Javaがうまく動かないときも、確認できない結果を「動いたことにしない」よう自動では別経路へ切り替えません。

3

Spring BootはHTTPと型付きユースケースを担当し、正式な認可・残高・冪等性・Ledgerは既存PostgreSQL RPCへ残します。

4

コードが存在することと運用可能であることは別です。統合・競合・障害・監視・デプロイの検証が必要です。

5

振込を実際に処理する仕組みは2種類のうちどちらかが設定で選ばれており、途中で自動的に切り替わることはありません。どちらが使われているかは、この教材だけでは確認できません。

順番に理解する — DIFFICULT PARTS, STEP BY STEP

難しいポイントを、順番にほどく

専門用語を覚えることより、「なぜ必要か」「このシステムのどこで使うか」を理解することが目標です。

01

段階的移行

やさしく言うと

既存機能を保ちながら新しい経路を小さく追加します。

なぜ必要?

一括置換の障害範囲と戻しにくさを抑えるためです。

Minibankでは

PAYMENT_BACKENDで既存経路とJava Payment Serviceを明示的に切り替えます。

02

fail-closed

やさしく言うと

結果が不明な時に、別経路で処理を続けず失敗として止めます。

なぜ必要?

DB commit後の通信断で自動fallbackすると二重送金になり得るためです。

Minibankでは

Java障害をlegacy処理へ自動fallbackしません。

03

責任境界

やさしく言うと

各部品が決めることと決めないことを分けます。

なぜ必要?

同じ規則の重複と迂回経路を防ぐためです。

Minibankでは

JavaはHTTP、DB RPCは金融判断を担当します。

04

End-to-End検証

やさしく言うと

入口から正式記録まで一連の経路を試すことです。

なぜ必要?

各部品単体が動いてもtokenや変換の接続で失敗するためです。

Minibankでは

Java APIからPostgREST、RPC、Ledgerまで確認が必要です。

発展 — ADVANCEDもっと詳しく確認する最初の学習では読まなくても問題ありません。仕組みをもっと深く理解したい場合に開いてください。

Java経路の実装と稼働確認を分ける

request/confirmはPAYMENT_BACKENDで選択します。未設定・空文字・legacyはNext.js→PostgREST RPC、javaはNext.js→Java Payment Service→PostgREST RPCです。不正な値はエラー、Javaのtimeout・5xx・通信断でもlegacyへ自動fallbackしません。旧OTP再発行はこの切替の対象外で、v7のRPCは常に42501で拒否します。TOTPの認可準備はNext.jsの/api/v1/transfers/mfaが担います。コードの存在は確認済みですが、本番・PreviewでJavaが選択されているかはUNKNOWNです。

  1. 01Next.jsがPAYMENT_BACKENDを読む
  2. 02legacy:呼出者tokenでPostgRESTへ / java:Java Payment ServiceへHTTP
  3. 03request_transfer / confirm_transfer_otpでDB処理
  4. 04Javaの@TransactionalではHTTP先のcommitを取り消せない
  5. 05応答消失時は結果不明。別backendへ自動fallbackしない

追加されたJavaサービスは、既存システムを置き換えない

Payment Serviceは既存Next.js API、Supabase RPC、PostgreSQL関数と並行する段階的な追加です。正式な金融ルールとLedgerは既存DB側に残します。

JavaはHTTP APIの別入口、型付きのユースケース層、PostgRESTへのGatewayを提供します。既存Web教材や既存実装を統合・削除するものではありません。

構成要素主な責任持たない責任
Next.js画面・既存API・利用者体験Javaプロセスの実行
Spring BootPayment HTTP契約・型・オーケストレーション残高lock・Ledger直接更新
PostgRESTHTTP RPCとtoken文脈の橋渡しUI表示
PostgreSQL RPC認可・状態・lock・transaction・idempotencyHTTP DTO
Ledger資金移動の正式な会計記録OTP画面

PAYMENT_BACKENDで入口を段階的に切り替える

Next.jsのTransferServiceはPAYMENT_BACKENDを読み、未設定または空ならlegacy、javaならJavaPaymentBackendへ振込依頼とOTP確認を委譲します。javaを選ぶ場合はPAYMENT_SERVICE_URLが必須で、未知の値は起動時設定エラーとして閉じます。

これは既存経路を残しながら新経路を選択可能にする、strangler fig patternの実践例です。切り戻しは設定をlegacyへ明示的に戻して行い、1件の処理途中で経路を混ぜません。

設定・結果Next.jsの動作
未設定 / legacy既存TypeScript経路を使用
javaJava Payment ServiceへBearer token、requestId、Idempotency-Keyを転送
不正な設定値設定エラーとしてfail-closed
Javaのtimeout・5xx・通信断呼出元へ失敗を返し、legacyへ自動fallbackしない

振込依頼を作る経路

  1. 01呼出元がBearer token・Idempotency-Key・振込入力を送る
  2. 02PaymentControllerが形式を検証しCommandを作る
  3. 03PaymentApplicationServiceがMoneyを生成
  4. 04PaymentRpcGatewayがrequest_transfer引数へ変換
  5. 05SupabaseRpcClientがtoken付きでPostgREST RPCを呼ぶ
  6. 06PostgreSQLが本人・KYC・口座・残高・冪等性を検査
  7. 07PendingPaymentを201 responseへ変換

認可を消費して振込を完了する経路

  1. 01paymentIdを受け取る(6桁OTP欄は互換用で、v7のDBは検証に使わない)
  2. 02Controllerが形式を検証
  3. 03ServiceがconfirmOtpを呼ぶ
  4. 04Gatewayがconfirm_transfer_otp RPCを呼ぶ
  5. 05DBが所有者・依頼期限と、TOTPで認可済みのintent(同じsession・60秒以内・未消費・内容一致)を検査
  6. 06成功時に振込・Ledger・残高・監査を原子的に確定
  7. 07completedまたは期待される業務outcomeを200 responseへ変換

現在の境界と未実装を混同しない

  • Payment作成とOTP確認のController・Service・Gatewayは存在する
  • Next.jsからJava APIへ切り替えるTransferServiceとJavaPaymentBackendが存在する
  • reverse操作とGET系Payment APIは現在の対象外
  • JavaはJPA/JDBCでDBへ直接接続しない
  • Java側とNext.js adapter側には自動テストがある
  • Actuator healthやadapter単体テストは業務処理のend-to-end保証ではない

コードリーディング演習

演習確認する証拠
小数の円を送るDTOの@DigitsとMoney.ofYen
同じキーで金額を変えて再送TR009とRpcErrorMapper
期限切れOTPを確認PaymentOtpConfirmationのoutcome
DBが未知のSQLSTATEを返すINTERNAL_ERRORへの閉じ方
同時に残高を使うJavaのステートレス性とDB RPCのlock

体験学習の続き · LEARNING LOOP

ここまで読めましたか?続けて確認してみましょう

Javaサービスの全体位置を読んだところで、教材内の参照元で実際のコードを確認し、自分の言葉で説明してみます。

STEP 2〜5 / 5
  1. 02
    仕組みを確かめる — CONCEPT CHECK

    画面操作なしで、仕組みを確かめる

    この仕組みは、Mini Bankの画面には現れません。次のEvidenceとCode Trail、教材本文だけで理解を進めます。

  2. 03
    証拠を確認する — EVIDENCE

    何を見たか、1つずつ確かめる

    Evidence(判断の根拠となる記録)を確認したらチェックします。各項目の「何を見るか」を手がかりにしてください。

    画面を開けない項目は、Source Trail(教材の参照元)と教材の説明で確認できます。失敗を実際に起こす必要はありません。

  3. 04
    コードの処理経路を追う — CODE TRAIL

    コードを書く必要はありません

    ここでは「説明されている仕組みが、実際のMini Bankのどこに実装されているか」を確認します。まずは日本語の役割説明を読み、入力した依頼がどこへ渡るかをつかみましょう。コードの全文を読む必要はありません。

    まずJavaの入口となるユースケース層を見て、次に既存RPCへどう委譲しているかを見ます。

    Javaの入口となるユースケース層。既存経路を置き換えず追加する構造を探します。

    services/payment-service/src/main/java/com/minibank/payment/application/PaymentApplicationService.java

    既存PostgreSQL RPCへそのまま委譲する境界。Javaが持たない責任を探します。

    services/payment-service/src/main/java/com/minibank/payment/repository/PaymentRpcGateway.java
    教材の参照元を確認する — Source Trail ↓
  4. 05
    自分の言葉で説明する — EXPLAIN

    LEVEL 1 — やさしい説明(まずここだけ)

    なぜJavaの処理が失敗したとき、自動的に別経路(legacy)へ切り替えないのでしょうか? 短い2文を目安に説明してください。

    日常語だけで完了できます。専門用語の数や正誤を自動採点するものではありません。

    ヒント1を見る

    「fail-closed」と「自動fallback」という2つの言葉を使って書いてみましょう。

    ヒント2を見る

    結果が不明なまま処理を続けると何が起こり得るか考えてみましょう。

    もっと詳しく:LEVEL 2 — 専門用語を使った説明(任意)

    段階的移行、fail-closed、責任境界、End-to-End検証の4つを使って、Javaサービスの追加方針を説明してみましょう。

    挑戦する場合は、上の説明欄に追記できます。追加しなくても完了できます。

    説明の確認ポイント — Checkpoint
    • Javaが既存経路を置き換えるものではないと説明できる
    • 結果不明な失敗を自動で回避しない設計だと説明できる
予想5文字以上・証拠2項目・説明20文字以上で完了できます。

証拠の確認:0 / 2。LEVEL 2(専門用語での説明)は任意です。

入力はこのブラウザに保存されます。Academy教材の進捗とは別の学習メモです。

理解を確かめる — CHECK YOUR UNDERSTANDING

4問で理解チェック

答えを頭の中で考えてから、各項目を開いて確認してください。

Q1Javaのコードがあれば本番で稼働中ですか?
答え

request/confirmはPAYMENT_BACKENDで選択します。未設定・空文字・legacyはNext.js→PostgREST RPC、javaはNext.js→Java Payment Service→PostgREST RPCです。不正な値はエラー、Javaのtimeout・5xx・通信断でもlegacyへ自動fallbackしません。旧OTP再発行はこの切替の対象外で、v7のRPCは常に42501で拒否します。TOTPの認可準備はNext.jsの/api/v1/transfers/mfaが担います。コードの存在は確認済みですが、本番・PreviewでJavaが選択されているかはUNKNOWNです。

Q2Javaサービスは既存Next.js APIを削除しますか?
答え

いいえ。現在は並行して追加する段階です。

Q3JavaがLedgerを直接管理しますか?
答え

いいえ。既存PostgreSQL RPC内のLedger処理を利用します。

Q4Java呼出しがtimeoutしたらlegacyへ自動fallbackしますか?
答え

しません。Java側でcommit済みか判別できないためfail-closedとし、同じIdempotency-Keyを使う明示的な再試行として扱います。

ここまで読めましたか?

完全に暗記する必要はありません。大切な考え方を説明できそうなら押してください。

教材の参照元 — SOURCE TRAIL

根拠と関連教材

CURRENT IMPLEMENTATIONは確認したrepository内の実装です。HISTORICAL IMPLEMENTATIONは導入・修正の履歴で、後続migrationによる再定義があり得ます。RELATED LESSONは教材への案内で、実装の一次Sourceではありません。ASSUMPTIONは仮定、UNKNOWNは未確認を表します。

確認基点: d02eae8914f39cbf06bfe422dc39c71886f82b3e / 2026-09-11。稼働環境への適用確認: UNKNOWN。パス実在の自動検査と、記述した技術的事実の確認は別です。

Implementation Status: IMPLEMENTED IN MINIBANK(この教材が扱うコードの範囲)

Runtime Verification Status: UNKNOWN(本番・Previewでの経路選択)

  • 現在の実装 — CURRENT IMPLEMENTATION — Primary Sourcesrc/lib/config/paymentBackend.tsgetPaymentBackend切替の許容値・default・不正値拒否。稼働環境の値はUNKNOWN。
  • 現在の実装 — CURRENT IMPLEMENTATION — Primary Sourcesrc/services/TransferService.tsrequestTransfer / confirmTransferOtp / reissueTransferOtprequest/confirmのみbackend切替。残存createTransfer関数のコメントは現ACLの根拠にしない。
  • 現在の実装 — CURRENT IMPLEMENTATIONsrc/services/JavaPaymentBackend.tsJavaへのHTTP adapterとエラー処理。自動fallbackなし。
  • 未確認 — UNKNOWNservices/payment-service/README.md仕様資料。現行実装との一致は未確認。Payment Serviceの目的と起動方法
  • 現在の実装 — CURRENT IMPLEMENTATIONservices/payment-service/src/main/java/com/minibank/payment/controller/PaymentController.javaJava APIの入口
  • 現在の実装 — CURRENT IMPLEMENTATIONservices/payment-service/src/main/java/com/minibank/payment/application/PaymentApplicationService.javaユースケース層
  • 現在の実装 — CURRENT IMPLEMENTATIONservices/payment-service/src/main/java/com/minibank/payment/repository/PaymentRpcGateway.java既存PostgreSQL RPCとの接続
  • 現在の実装 — CURRENT IMPLEMENTATIONsrc/lib/config/paymentBackend.tslegacy / javaを検証する設定境界
  • 現在の実装 — CURRENT IMPLEMENTATIONsrc/services/JavaPaymentBackend.tsNext.jsからJavaへ渡すadapter
  • 現在の実装 — CURRENT IMPLEMENTATIONsrc/services/TransferService.test.ts経路選択とfail-closedの自動テスト
  • 現在の実装 — CURRENT IMPLEMENTATIONsrc/app/api/v1/transfers/既存Next.js側の振込API