REGEN* DELIVERABLE SAMPLES

約20万行のマーケットプレイスを、
読める仕様書と移行計画へ。

Regen*のフェーズ0で、ソースコードのリバースエンジニアリングから「仕様書」と「移行計画」の成果物に落とし込んだサンプルです。

66機能仕様
182画面仕様
897業務用語
3解析対象言語

REGEN* DELIVERABLE SAMPLES

仕様書いま、何がどう動いているのか

コードと実際の動作を照合し、移行判断に使える仕様書へ再構成した成果物です。

EXECUTIVE SUMMARY

コードを「読める仕様」に変換する

得られる成果

暗黙の分岐や例外処理を、根拠となるソース参照とともに整理する

仕様書が残っていないシステムでも、コードのリバースエンジニアリングにより、業務ルール、画面遷移、外部連携、未解決事項を移行可能な単位で可視化します。

01

業務ルール

条件分岐、計算、権限、状態遷移を整理します。

02

画面と利用者の動き

画面構成、操作、入力チェック、エラー時の挙動を復元します。

03

根拠と未解決事項

参照コードと、追加確認が必要な論点を明示します。

出力構成

リバースエンジニアリングで復元される仕様書の全体像

ソースコードと実際の動作から、システム全体、機能、画面、業務フローを段階的に復元します。用途ごとに情報を分け、更新しやすい仕様書として整理します。

ソースコード 約1,500ファイル rebuild-spec エンジン 5パス処理 system/ generated/ features/ flows/ screens/ 担当者向けの概要 解析結果の一覧 機能ごとに4ファイル 業務フロー 182件の画面仕様
rebuild-spec/jp/
    • overview.mdシステム概要(散文)
    • architecture.mdアーキテクチャ図(Mermaid)+技術スタック
    • glossary.md業務用語集(用語解析を有効にした場合)
    • permissions.md権限 — わかりやすい解説
    • business-rules.md業務ルール — わかりやすい解説
    • entities.mdデータモデル/エンティティ
    • user-stories.mdユーザーストーリー(US### コード)
    • api-map.mdルート+バックグラウンドジョブ
    • permissions-matrix.md権限マトリクス(PERM### コード)
    • feature-list.md機能カタログ(F### コード)
    • screen-list.md画面一覧(SCR### コード)
    • screen-flow.md画面間ナビゲーションフロー
    • route-list.md全ルート/エンドポイント
    • behavior-logic.mdバックグラウンドロジック(BL### コード)
    • api-contracts.mdREST/JSON の request-response 仕様
    • community-membership-lifecycle.mdコミュニティ参加・退会の流れ
    • export-task-lifecycle.mdデータ書き出しの処理状態
    • paypal-commission-lifecycle.mdPayPal 手数料の確定まで
    • sender-email-verification.md送信元メールの認証手順
    • system-flow.mdシステム全体の処理の流れ
    • transaction-lifecycle.md取引の状態遷移
    • technical-spec.md技術仕様 — 実装者向け
    • business-context.md業務背景 — 企画・BA向け
    • screens.md関連画面と操作
    • edge-cases.md例外・境界条件
    • spec.md13セクション構成(画面構成・操作・入力チェック・エラー時の挙動ほか)

※ features/ は F001_Auth 〜 F066_AdminTransactionConfig、screens/ は SCR001_Homepage 〜 SCR272_TopbarProps。各フォルダ内のファイル構成は共通です。

各ネームスペース概要
ネームスペース 目的 ライフサイクル 対象読者
system/ 担当者が読むシステム概要 AIが初稿を作成し、担当者が確認・編集 全員
generated/ ルート・データ・機能・要件の解析結果一覧 再生成可能(手動編集はしない) rebuild-spec 内部
flows/ 複数機能にまたがるビジネスフロー AIが初稿を作成し、担当者が確認・承認 BA / アーキテクト
features/ 機能ごとの詳細仕様(4ファイル、読者別) F### 単位で生成 Dev / BA / QA
screens/ 画面ごとの仕様(13セクション構成) SCR### 単位で生成 Dev UI / QA
generated/ — 各ファイルの mini-preview
entities.mdデータモデル / エンティティ定義
属性型制約説明
idintPK, NOT NULL, AUTO_INCREMENTサロゲートPK
uuidbinary(16)NOT NULL, UNIQUEグローバルUUID
identvarchar(255)UNIQUEサブドメイン識別子
domainvarchar(255)—カスタムドメイン

MODEL001(Community)を筆頭に50以上のエンティティを収録。ERD は Mermaid 形式で掲載。

user-stories.mdユーザーストーリー(US### コード)
要件ID利用者が実現したいこと種別優先度関連画面
US001_BrowseListings出品の検索結果を閲覧するui 画面P1SCR001, SCR060
US002_FilterListingsカテゴリ・価格・場所で絞り込むui 画面P1SCR001, SCR060
US003_ViewListingDetail出品の詳細を確認するui 画面P1SCR061

124件の US### コードを収録。ui 型(画面あり)と system 型(バックグラウンド)に分類。

api-map.mdルート+バックグラウンドジョブのマッピング
処理ID処理名役割
BL046MarketplaceLookupホスト/サブドメインからコミュニティを特定
BL047MarketplaceHostFromCustomHeaderカスタムヘッダーがある場合にホスト情報を上書き
BL048EnforceSsl本番環境でHTTPをHTTPSへ転送
BL050CustomCookieRenamerテナント分離のためCookie名を変更
BL052SessionContextMiddlewareセッション情報をリクエストへ追加

全ルートにミドルウェア BL046〜BL052 が適用される。Handler/Indirect BL### で直接・間接トリガーを記録。

screen-list.md画面一覧(SCR### コード)
画面ID画面名認証処理URL
SCR001_Homepageホーム/検索pub(公開)homepage#indexGET /
SCR060_ListingsBrowse出品一覧pub(公開)listings#indexGET /listings
SCR061_ListingDetail出品詳細pub(公開)listings#showGET /listings/:id
SCR091_PreauthorizeCheckout決済の事前承認auth(ログイン必須)preauthorize_transactions#newGET /listings/:id/initiate

182画面を収録。pub / auth / admin / super の4認証レベル。

screen-flow.md画面間ナビゲーションフロー
Mermaid 抜粋: ENTRY → A{Landing page enabled?} A → Yes → SCR002_LandingPage → SCR001_Homepage A → No → SCR001_Homepage SCR001 → SCR061_ListingDetail → AUTH_GATE → SCR091_PreauthorizeCheckout SCR061 → AUTH_GATE → SCR020_LoginPage (未ログイン時)

Mermaid フローチャートで全主要ナビゲーションパスを図示。ガード条件付き。

permissions-matrix.md権限マトリクス(PERM### コード)
権限ID権限方式適用箇所
PERM001_ViewPublicScreens公開画面の閲覧route-guard(ルート制御)ApplicationController#before_action
PERM002_LoginRequiredログイン必須route-guard(ルート制御)ApplicationController#ensure_logged_in
PERM003_AdminRequired管理者権限必須route-guard(ルート制御)EnsureAdmin#ensure_is_admin
PERM004_SuperAdminRequired全体管理者権限必須route-guard(ルート制御)EnsureAdmin#ensure_is_superadmin
PERM005_BannedUserBlocked利用停止ユーザーを拒否route-guard(ルート制御)ApplicationController#cannot_access_if_banned

53件の PERM### コードを収録。4ロール(visitor / member / admin / global_admin)の権限マトリクス。

feature-list.md機能カタログ(F### コード)
機能ID機能名種別優先度関連画面
F001Auth
認証
ui 画面P0SCR020, SCR021…
F018TransactionInitiate
取引開始
ui 画面P0SCR090, SCR091…
F019TransactionLifecycle
取引ライフサイクル
mixed 複合P0SCR093, SCR125…
F020TransactionPayPalFlow
PayPal決済フロー
mixed 複合P2SCR095〜SCR101
F051TransactionStateMachine
取引状態管理
background バックグラウンドP0—

66機能を収録。優先度はP0(最重要)〜P3(低)の4段階、種別は画面/バックグラウンド/複合の3種類です。

route-list.md全ルート(約390件)
HTTPパス処理認証説明
GET/homepage#indexpub(公開)ホームページ
GET/listings/:id/initiatepreauthorize_transactions#newauth(ログイン必須)決済の事前承認を開始
POST/webhooks/paypal_ipnpaypal_ipn#ipn_hookpub(公開)PayPal IPN Webhookを受信
POST/bouncesamazon_bounces#notificationpub(公開)Amazon SESのバウンス通知

全ルートに (/:locale) オプションスコープ付き。pub / auth / admin / super 凡例。

behavior-logic.mdバックグラウンドロジック(BL### コード)
分類件数主な処理
queue-worker(キューワーカー)43メール送信、画像処理、Sphinx差分更新、決済コールバック
mail(メール)5取引、会話、会員管理、ニュースレター
integration(外部連携)6Stripe、PayPal、SES、S3、Google Maps、Intercom
middleware (Rack)(ミドルウェア)7MarketplaceLookup、HSTS、ロケール、robots
state-machine(状態管理)1TransactionProcessStateMachine(Statesman)
webhook(Webhook)2PayPal IPN、Amazon SESバウンス

scheduled-job / queue-worker / event-listener 等の10種類の BL タイプを定義。

api-contracts.mdREST/JSON リクエスト-レスポンス仕様
レスポンス型定義元説明
FlashRedirectResponseapp/controllers/application_controller.rbRails標準リダイレクトと通知/エラー表示
HTMLPageResponseapp/views/サーバー側で描画するHAML/ERBテンプレート
JSONResponseapp/controllers/int_api/int_api/でJSONを直接返す
TopbarPropsJSONapp/controllers/topbar_api_controller.rbReactトップバーへ渡すJSONデータ

opt-in 生成(--api-contracts)。int_api/ と ui_api/ のみ JSON を返す。

識別コード体系
コード意味定義元
F###Feature(機能)generated/feature-list.md
US###User storygenerated/user-stories.md
SCR### / REG###画面 / 画面内リージョンgenerated/screen-list.md
PERM###権限generated/permissions-matrix.md
BL###Behavior Logic(バックグラウンド)generated/behavior-logic.md
FR/BR/SM/ALG/INT/DEC機能仕様内のロジック種別features/*/technical-spec.md
サンプル 1 — system/overview.md

システム全体をつかむ

解析の第1段階で生成する、140行のシステム概要です。何をする事業のシステムなのか、どんな決まりで動いているのかを先に示し、その後に技術構成を並べます。

system/overview.md system
対象システム10年以上にわたり開発されてきたオープンソースのマーケットプレイス基盤
生成日2026-06-04
構成マルチテナント型マーケットプレイス(Railsモノリス+一部React)

業務概要

事業者が自社のマーケットプレイスを開設・運営するための基盤です。事業者はサブドメイン(例:example-market.example.com)ごとに独立したマーケットプレイスを持ち、扱う商材に合わせて出品フォームの項目、カテゴリ、決済手段、手数料を設定します。出品者は商品やサービスを登録し、購入者はそれを検索して予約・購入します。代金は Stripe または PayPal で決済され、運営者は取引額に応じた手数料を受け取ります。

出品と取引の状態は、検索インデックス、取引メール、運営管理画面、外部連携(PayPal IPN、SES バウンス通知)へ波及します。取引の状態遷移と決済の整合が崩れると、売上と入金の記録がずれるため、刷新時はこの2点の新旧一致確認が要点になります。

本書の対象範囲は、受領したソース約1,478ファイルをリバースエンジニアリングして復元した66機能/182画面です。記述はすべてソースコード(source of truth)から抽出しており、コードだけでは確定できない点は各仕様書の「追加確認が必要な事項」に列挙しています。

業務上の共通原則

個々の機能を読む前に押さえておく、全体に共通する決まりです。

共通原則業務内容
事業者単位のデータ分離リクエストのサブドメイン/ドメインから Rack ミドルウェア MarketplaceLookup が事業者(Community)を特定し、ApplicationController の fetch_community が以降のクエリをその事業者に限定する。別の事業者のデータは参照できない。
取引は状態遷移で管理取引の進行は TransactionProcessStateMachine(Statesman)が管理し、initiated → preauthorized → paid → confirmed と進む。rejected/canceled/refunded/disputed への分岐も状態として持つ。変更は TransactionTransition に履歴として残り、いつ何が起きたか追跡できる。
決済は事前承認してから確定購入の時点では決済を確定させず事前承認(preauthorize)にとどめ、取引が成立した時点で確定(キャプチャ)する。決済手段は TransactionService::Gateway が Transaction#payment_gateway を見て Stripe/PayPal/フリー(決済不要)に振り分ける。
出品項目は事業者が定義出品の型(ListingShape)、カテゴリ(Category)、任意項目(CustomField)を事業者ごとに設定できる。同じ基盤でも、扱う商材によって入力項目が変わる。
権限は所属で決まる利用者の役割は CommunityMembership(メンバー/管理者/バン)として事業者ごとに持つ。運営管理画面は EnsureAdmin が管理者に限定する。同じ人物が、ある事業者では購入者、別の事業者では運営者になり得る。
時間のかかる処理は非同期メール送信、出品画像の変換、検索インデックスの更新、決済コールバックは delayed_job(43ジョブ)で画面処理から切り離す。画面はすぐに応答を返し、結果は通知や再読込で反映される。

技術構成の要点

対象は、Ruby on Rails のモノリスとして長年運用されてきたマルチテナント型のマーケットプレイス基盤です。備える機能は、出品、検索、予約、売買、メッセージ、Stripe/PayPal決済、運営管理、ランディングページ編集。

基本構成は Rails モノリスです。検索や空き状況カレンダーなど、操作性が求められる一部の画面だけに React 16 を組み込み、react_on_rails で連携しています。各リクエストのサブドメインから Rack ミドルウェアが事業者(Community)を特定し、その事業者に属するデータだけを扱います。

スケール指標:ソースファイル約1,478件、コントローラ136件、モデル100件、サービス176件、バックグラウンドジョブ43件、マイグレーション897件、ビュー1,018件。

中核となるデータ構造

Community(テナント=事業者ごとの区画)
    • CommunityMembershipPerson と Community を結ぶ所属情報
    • ListingShape取引の型(売買/レンタル/無償/リクエスト)
    • Categoryカテゴリ(階層構造)
    • CustomField事業者ごとに設定できる任意項目
    • Booking日付範囲の予約
    • TransactionTransition状態遷移のログ(Statesman)
    • Conversation / Messageスレッド形式のメッセージ
    • Payment決済記録(Stripe または PayPal)
  • LandingPageVersionCMS で編集したランディングページの版

取引の状態遷移(Statesman): initiated → preauthorized → payment_intent_requires_action → paid → confirmed | rejected | canceled | refunded | errored | disputed

Community Person user Listing item / service Transaction deal LandingPageVersion CMS snapshot CommunityMembership ListingShape Category CustomField Booking TransactionTransition Conversation/Message Payment

※ overview.md のコアドメインモデルを図示

設計上の重要な判断

判断1:Rackミドルウェアによるサブドメイン単位のマルチテナント

背景複数の独立したマーケットプレイスが、厳格なデータ分離を維持しながら一つの Rails プロセスを共有する必要があります。
採用方針MarketplaceLookup Rack ミドルウェアが、すべてのリクエストに対してリクエストのサブドメイン/ドメインから Community を解決し、request.env[:current_marketplace] に注入します。ApplicationController は fetch_community before_action を介してこれを読み取り、すべてのクエリをスコープします。
理由Rails スタックの前でテナント解決を一元化できます。
トレードオフすべてのリクエストにミドルウェアのオーバーヘッドが生じます。ただしコミュニティの参照は Rails キャッシュを経由します。

判断2:決済サービスを切り替えるアダプターパターン

背景異なる API 仕様を持つ2つの商用ゲートウェイ(Stripe、PayPal)と、決済不要の出品向けの「フリー」モードが存在します。
採用方針TransactionService::Gateway が Transaction#payment_gateway を参照し、StripeService、PaypalService、FreeService のいずれかに処理を振り分けます。
理由ゲートウェイ固有のロジックを共通インターフェースの背後に閉じ込められます。
トレードオフアダプター層のぶん処理の追跡が一段深くなります。また PayPal はレガシーの Classic API を使っています。

判断3:全面SPAではなく、必要な画面だけReact化

背景画面の大半は HAML/ERB によるサーバーサイドレンダリングです。検索、トップバー、空き状況カレンダー、初期設定など、操作性が必要な部分だけに React を使っています。
採用方針6つの react_on_rails エントリーポイントを、サーバーサイドレンダリングとクライアント側のハイドレーションの両方に登録しています。
理由React のコストを負担するのは操作性が必要な部分だけで済みます。
トレードオフWebpack バンドルがクライアント用とサーバー用の2系統になり、ビルド手順が複雑になります。また React 16 はサポートが終了しています。

判断4:2つの管理画面を段階的に統合

採用方針admin/(29コントローラー)がコミュニティの基本設定を扱い、admin2/(57コントローラー)がダッシュボード、デザイン、SEO、アナリティクス、詳細設定を扱います。
理由段階的に移していくことで、管理画面の大規模な作り直しを避けられました。
トレードオフどの管理機能がどちらにあるのか分かりにくく、一部の設定が両方の画面に重複しています。

判断5:delayed_jobによるバックグラウンド処理

採用方針delayed_job を ActiveRecord バックエンド(MySQL のキューテーブル)で運用しています。非同期処理は43のジョブでカバーされています。
理由キュー専用のインフラを別に用意する必要がありません。
トレードオフ処理量が増えると、MySQL をキューとして使う構成が性能上の頭打ちになります。

セキュリティ上の確認事項

認証Devise 5(bcrypt によるメール/パスワード)+ Facebook、Google OAuth2、LinkedIn OpenID への OmniAuth。
権限管理CommunityMembership(メンバー/管理者/バン)によるロールベース。EnsureAdmin コンサーンが管理者専用ルートを適用。
データ保護パスワードは bcrypt でハッシュ化。Stripe/PayPal シークレットはコミュニティ設定に保存。
API保護Rails の protect_from_forgery による CSRF 保護。レート制限に rack-attack gem。
コンテンツ保護disarm_custom_head_script before_action が管理者が注入した JS をサニタイズ。

拡張性

現在の構成単一の Rails モノリス。ロードバランサー配下の複数 Passenger ワーカーによる水平スケーリング。
拡張方針ステートレスなアプリ層。ファイルアップロードは S3 にオフロード。フラグメントキャッシングに Redis。
性能上の懸念書き込みが多い負荷下での MySQL 支援ジョブキュー。React 16 の SSR バンドルがリクエストごとに CPU コストを追加。

バックグラウンド処理

分類件数例
キューワーカー(delayed_job)43ジョブメール送信、画像処理、Sphinx差分更新、決済コールバック
メール配信5メーラー取引、会話、コミュニティ参加、ニュースレター
外部API連携6ラッパーStripe、PayPal、SES、S3、Google Maps、Intercom
ミドルウェア(Rack)7件MarketplaceLookup、HSTS、ロケール、robots
状態管理1件TransactionProcessStateMachine(Statesman)
受信Webhook2件PayPal IPN、Amazon SESバウンス
定期実行ジョブcronで実行Sphinx全件再インデックス、プラン有効期限の確認

Reactで構築された主な画面

画面アプリ使用箇所
SearchPageApp出品の閲覧・検索ページ
TopbarAppサイト共通ナビゲーション
ManageAvailabilityAppカレンダー形式の空き状況管理
ListingWorkingHoursApp出品ごとの営業時間設定
OnboardingGuideAppマーケットプレイス開設ウィザード
OnboardingTopBarAppオンボーディング進捗表示

これらの画面は内部 JSON API(/int_api/)からデータを取得し、トップバーには /ui_api/topbar_props が表示データを返します。

サンプル 2 — features/F020_TransactionPayPalFlow/

機能仕様の例:決済フロー

機能仕様の4ファイル構成。読者別に分離 — BA向けのビジネスコンテキストから開発者向けの技術仕様まで。

features/F020_TransactionPayPalFlow/ features

業務上の位置づけ — F020_TransactionPayPalFlow

この機能が重要な理由

PayPal決済では、購入者がいったんマーケットプレイスを離れ、PayPal上で支払いを承認してから戻ります。そのため、承認結果が届くまでの待機状態と、失敗・キャンセル時の戻り先を明確に扱う必要があります。この仕様では、処理中画面、エラー時の再試行、キャンセル時の復帰、出品者によるPayPal受取設定までを一つの流れとして整理しています。

チェックアウトで PayPal 選択 PayPal サイト PayPal 認証・承認 ログイン & 支払い承認 キャンセル → 出品ページへ マーケットプレイスへ戻る 処理中スピナー・ポーリング エラー → エラー表示・再試行 取引詳細ページへ 決済完了 ✓

※ business-context.md の購入者フローを図示

利用者

  • PayPal 支払いを完了する購入者 — PayPal にリダイレクトされ、承認し、トランザクション確認に着地する前の短い待機画面を経てマーケットプレイスに戻る
  • PayPal 支払いをキャンセルする購入者 — PayPal でキャンセルをクリックし、閲覧していたリスティングにクリーンに戻る
  • PayPal をセットアップする売り手 — マーケットプレイスで PayPal 支払いを受け取れるようになる前に、2段階の PayPal アカウント接続プロセス(注文権限の付与、次に課金契約のセットアップ)を経る

主な操作

購入者の支払いフロー

  1. チェックアウトで PayPal を選択した後、購入者は PayPal のウェブサイトに移動してログインし、支払いを承認する。
  2. 承認時、購入者はマーケットプレイスに戻り、支払いが記録される間の短い「処理中」画面を確認する。
  3. 確認されると、購入者は完了した予約を表示するトランザクション詳細ページに遷移する。
  4. 購入者が承認の代わりに PayPal で「キャンセル」をクリックした場合、支払いがキャンセルされた旨の通知とともにリスティングページに戻る。
  5. PayPal がエラーを報告した場合(例:残高不足や制限されたアカウント)、購入者には具体的な説明が表示され、リトライやマーケットプレイスへの連絡が案内される。

売り手のセットアップフロー

  1. 売り手が支払い設定にアクセスし、PayPal 接続を開始する。
  2. マーケットプレイスが売り手に代わって PayPal に権限をリクエストする — 売り手は PayPal にリダイレクトされ、注文処理権限を付与する。
  3. 権限付与後、売り手はマーケットプレイスに戻り、2番目のステップを完了する:マーケットプレイスが将来の支払いを処理できるようにする課金契約のセットアップ。
  4. 両方のステップが完了すると、売り手のアカウントは PayPal 対応となり、支払いを受け取れるようになる。

追加確認が必要な事項

課金契約の要件すべての PayPal 売り手が課金契約ステップを完了する必要があるか、特定の支払いタイプにのみ必要かは完全に確認されていない。
ポーリング時間「処理中」待機画面にかかる時間と、購入者に表示されるタイムアウトがあるかどうかはソースコードから確認されていない。
サンプル 3 — screens/screen-list.md

画面の全体像をつかむ

個々の画面仕様に入る前に、どんな画面が何のためにあるのかを一覧で確認できます。全182画面のうち代表10画面を抜粋しています。

screens/screen-list.md screens
収録画面数182画面(pub/auth/admin/super の4認証レベル)
画面IDの付け方SCR###_PascalCaseName。ルーティングと画面の対応をコードから抽出して採番。
ステータスの意味確定=ソースから読み取れた内容のみで記述。要確認=コードだけでは判断できず、各仕様書の「追加確認が必要な事項」に記載。

画面一覧(抜粋)

※ 表は横にスクロールできます。

画面ID画面名種別利用者ステータス目的・概要
SCR001
Homepage
ホーム/検索画面購入者 確定 事業者のトップページ。ランディングページが有効な場合はそちらを表示し、無効なら検索画面を表示する。未ログインでも閲覧可(pub)。homepage#index/GET /
SCR060
ListingsBrowse
出品一覧画面購入者 確定 キーワード・カテゴリ・価格・場所で絞り込み、結果を一覧表示。未ログインでも閲覧可(pub)。SearchPageApp(React)で描画。listings#index/GET /listings
SCR061
ListingDetail
出品詳細画面購入者 確定 出品内容と事業者が定義した任意項目、空き状況カレンダーを表示し、予約または問い合わせへ進む。未ログインでも閲覧可(pub)。listings#show/GET /listings/:id
SCR091
PreauthorizeCheckout
決済の事前承認画面購入者 確定 予約内容と料金内訳を確認し、Stripeカードまたは PayPal で事前承認を開始する。取引成立までは決済を確定させない。ログイン必須(auth)。GET /listings/:id/initiate
SCR095
OperationStatus
操作ステータスサブ画面購入者 要確認 非同期処理の完了待ちを表示する汎用のスピナー画面。SCR098との使い分けがソースから確定できない。
SCR096
PayPalSuccess
PayPal 決済成功画面購入者 確定 PayPal 認可後の成功処理。エラーコード(10486/13113/10417/10425)ごとに再試行・出品へ戻すなどへ分岐する。
SCR098
PayPalOpStatus
PayPal 操作ステータスサブ画面購入者 要確認 PayPal 操作の完了をポーリングして待つ画面。ポーリング間隔とタイムアウトがソースから確定できない。
SCR118
TransactionThread
取引のやりとり画面購入者
出品者
確定 取引の状態表示とスレッド形式のメッセージ送受信。取引の完了・キャンセル申請もこの画面から行う。
SCR140
AdminCommunitySettings
運営:基本設定画面運営者 確定 admin/(29コントローラー)側のコミュニティ基本設定。EnsureAdmin により管理者に限定。
SCR201
AdminTransactions
運営:取引管理画面運営者 確定 admin2/(57コントローラー)側の取引一覧・手数料設定・返金処理。同じ設定がSCR140側と重複する箇所がある。

※ 認証レベル・コントローラー・URLは全182画面ぶん同じ形式で出力されます。

サンプル 4 — screens/SCR091_PreauthorizeCheckout/spec.md

画面仕様の例:決済の事前承認

13セクション構成の画面仕様。認証済み購入者が事前承認トランザクションを開始する画面。
URL: GET /listings/:listing_id/initiate

screens/SCR091_PreauthorizeCheckout/spec.md screens
画面IDSCR091_PreauthorizeCheckout
種別単体画面
URLGET /listings/:listing_id/initiate
生成日2026-06-04

画面の目的

認証済みの購入者が出品物の詳細と価格を確認し、任意でメッセージを入力し、Stripe カードまたは PayPal で支払いを送信して出品物の事前承認トランザクションを開始する。

画面構成

画面上部に出品タイトルを表示し、その下に予約内容・料金内訳と支払いフォームを並べます。フォームでは、出品者へのメッセージ入力、取引条件への同意、StripeカードまたはPayPalの選択を行います。実装上は #new_message_form.centered-section にまとめられています。

market.example.com/listings/245/initiate
MARKETPLACE
R1 タイトル

予約内容とお支払いの確認

海辺のコテージ・2泊3日

R2 出品・料金

予約内容

海辺のコテージ

出品者:Sample Host
神奈川県・海まで徒歩3分

チェックイン
8月24日
チェックアウト
8月26日
¥18,000 × 2泊¥36,000
サービス料¥3,600
合計¥39,600
R3 取引フォーム

お支払い方法

4242 4242 4242 424212 / 28123

コードから復元した画面イメージです。実際の決済操作はできません。

IDリージョン名スクロール主な構成要素
R1タイトルなしcontent_for :title_header経由の見出し
R2出品・料金情報なし_price_break_downによる料金内訳
R3取引フォームあり_stripe_payment、同意欄、PayPalボタン

画面項目定義

凡例:必須=入力必須/任意=省略可/—=表示のみ(入力なし)。「表示条件」が空欄の項目は常時表示。

※ 表は横にスクロールできます。

No.項目名(表示名)コントロール入力表示条件制約・業務ルール(根拠)
R1 タイトル
1出品タイトル見出しリンク— listing.title を表示し、出品詳細(SCR061)へ遷移。見出しの操作ラベルは action_button_label で切り替わる。
R2 出品・料金情報
2出品者名ラベル— コントローラーから受け取る author の表示名。
3予約日(開始/終了)ラベル—予約型の出品のみ start_on/end_on はルートパラメーター(非表示)で受け取り、duration は両者から算出。
4料金内訳(小計・配送料・サービス料・合計)ラベル—各金額が設定されている場合のみ行を表示 いずれも算出値。表示は MoneyViewUtils.to_humanized を通す。購入者サービス料は buyer_fee、運営手数料は fee。
R3 取引フォーム
5出品者へのメッセージテキストエリア任意 未入力でも送信可。#new_message_form 内の textarea。桁数制限はソースから確定できない(要確認)。
6キャンセルポリシーと取引条件への同意チェックボックス必須transaction_agreement_in_use が true のとき 未チェックで送信すると transaction_agreement.required_error を表示して送信を中止。「Read more」で同意文をライトボックス表示。
7決済手段の選択ボタン(クレジットカード/PayPal)必須stripe_in_use/paypal_in_use の設定により表示が変化 両方無効なら決済不可。片方のみ有効ならその手段に固定。両方有効ならカードを既定にし PayPal を併記。
8カード番号Stripe Elements必須カード決済を選択したとき カード情報は画面上でトークン化し、stripe_payment_method_id をフォームに挿入してから送信。カード番号自体は自社サーバーへ送らない。
9有効期限 / セキュリティコードStripe Elements必須カード決済を選択したとき 不正・期限切れは stripe.card_declined/stripe.expired_card を #card-errors(role="alert")に表示。
10支払いボタン(合計額を表示)ボタン— 押下でフォームを AJAX 送信。送信中は submitInProgress/inProgress ガードにより再クリックを受け付けない。
11配送方法ラジオボタン必須配送を扱う出品のみ 未選択で送信すると select_delivery_method を表示。<label> 要素は付与済み。

操作フロー

基本フロー

01

内容を確認

購入者は、出品内容、予約日、料金内訳、合計金額を確認します。

R2_price_break_down
02

メッセージと取引条件を確認

必要に応じて出品者へメッセージを入力し、キャンセルポリシーと取引条件に同意します。

R3transaction_agreement_in_use
03

支払い方法を選択

利用可能な決済方法から、カードまたはPayPalを選びます。

Stripe

カード情報をトークン化して送信します。

createPaymentMethod
PayPal

PayPal決済としてフォームを送信します。

payment_type=paypal
04

送信・結果確認

送信中は処理状態を表示し、結果に応じて次の画面へ進みます。

画面遷移
redirect_url
処理状況を確認
op_status_url
本人認証
stripe_payment_intent.requires_action
confirm_intent_path

分岐

判断箇所条件画面上の結果根拠
Step 4stripe_in_use == false && paypal_in_use == false支払いボタンが描画されない;フォームを送信できないinitiate.haml:58-82
Step 4stripe_in_use && !paypal_in_useStripe カード要素のみ表示initiate.haml:58-63
Step 5paypal_in_use && !stripe_in_usePayPal ボタンのみ表示initiate.haml:65-69
Step 5paypal_in_use && stripe_in_useStripe と「or pay with PayPal」の両方が表示initiate.haml:71-79
Step 3transaction_agreement_in_use同意チェックボックスが描画される;バリデーションでチェックが必要initiate.haml:47-48
Step 9Stripe 3DS 失敗 / カードエラーエラーメッセージがフラッシュで表示;スピナー非表示stripe_payment.js:99-104
Step 7サーバーが error_msg を返すST.utils.showError でエラー表示;フォームが再有効化transaction.js:29
フォーム送信 transaction_agreement _in_use? YES 同意チェックボックスを表示 NO JS 有効? 無効 noscript 通知表示 有効 stripe_in_use && paypal_in_use? Stripe のみ Stripe カード要素のみ PayPal のみ PayPal ボタンのみ 両方 両方表示 → 送信

※ SCR091 spec.md に復元した条件分岐と画面状態から、主要な流れを抜粋して図示

使用データ

項目表示ラベル根拠形式未設定時
listing.title出品タイトル(見出しリンク+詳細)URLパラメーター → DB文字列該当なし(画面表示に必須)
author 表示名出品者名コントローラーから受け取る値文字列該当なし
listing_price1日/夜/時間/単位あたりの価格コントローラーローカルMoneyViewUtils.to_humanizednil の場合は非表示
start_on / end_on予約日ルートパラメーター(非表示フィールド)l date, format: :long_with_abbr_day_namenil の場合は非表示
duration予約日数/夜数/時間数開始/終了から算出整数+複数形化されたラベルnil の場合は非表示
subtotal小計算出MoneyViewUtils.to_humanizednil の場合は非表示
shipping_price配送料算出MoneyViewUtils.to_humanizednil の場合は非表示
total合計算出MoneyViewUtils.to_humanizednil の場合は非表示
feeサービス料算出-MoneyViewUtils.to_humanized(fee)ゼロの場合は非表示
buyer_fee購入者サービス料算出MoneyViewUtils.to_humanizedゼロ/nil の場合は非表示
paypal_expiration_period「You will be charged」通知コントローラーローカル整数(日数)支払いなしの場合は非表示
action_button_label見出しの操作ラベルコントローラーから受け取る値(i18n)文字列該当なし

UIの状態

状態発生条件画面表示可能な操作根拠
submitting (PayPal)PayPal ボタンクリック / フォーム送信.paypal-button-loading-img スピナー表示、再送信ブロックなしtransaction.js:94
submitting (Stripe)「Pay with card」クリックスピナー表示、inProgress=trueなしstripe_payment.js:146
errorサーバーまたは Stripe エラーレスポンスST.utils.showError フラッシュメッセージ;スピナー非表示;フォーム再有効化再試行stripe_payment.js:99-104
stripe card errorエラーを含む Stripe カード要素の変更イベント#card-errors ラベルにインラインエラーテキストカード入力を修正stripe_payment.js:28-37
3DS action requiredstripe_payment_intent.requires_actionStripe.js が 3DS モーダルを開く(外部)3DS チャレンジを完了stripe_payment.js:56-93
success/redirectredirect_url を受信JS がブラウザをリダイレクトなしtransaction.js:55-56
処理状況の確認中op_status_url を受信要確認 ポーリング中もスピナーを表示なしtransaction.js:8-15

入力チェックとエラー表示

A)ブラウザ側

項目種別必須制約エラー表示
contract_agreedcheckboxyes (if transaction_agreement_in_use)チェック必須t("error_messages.transaction_agreement.required_error")
shipping_address[name]テキストstripe_shipping_required の場合は必須stripe-shipping-address 属性により必須チェックを実行要確認 標準の必須エラー
shipping_address[street1]テキストstripe_shipping_required の場合は必須同上要確認
shipping_address[postal_code]テキストstripe_shipping_required の場合は必須同上要確認
カード入力欄Stripe.js要素stripe_in_use の場合は必須Stripeがカード情報を検証#card-errors にエラーを表示

B)サーバー側

Initiated (preauthorize form POST)

エンドポイントPOST /listings/:listing_id/initiated
成功時200 → JSON {redirect_url} または {op_status_url, op_error_msg} または {stripe_payment_intent: {...}}
エラー時200 JSON {error_msg} → ST.utils.showError で表示。具体的には: invalid_parameters、select_delivery_method、dates_not_available、transaction_agreement.required_error、double_booking_payment_voided、stripe.card_declined、stripe.expired_card
根拠ソースapp/controllers/preauthorize_transactions_controller.rb:40-64

Stripe Confirm Intent

エンドポイントPOST /listings/:listing_id/preauthorize_transactions/:id/stripe_confirm_intent
成功時200 → JSON {success: true, redirect_url} → JS がリダイレクト
エラー時200 JSON {error: t("error_messages.stripe.generic_error")} → showError で表示
根拠ソースapp/controllers/preauthorize_transactions_controller.rb:66-97

操作パターン

操作したときの挙動根拠ソース
PayPal ボタンをクリックすると payment_type が "paypal" に設定され、AJAX 経由でフォームが送信されるinitiate.haml:93-108
「Pay with card」(Stripe)をクリックするとカードをトークン化し、stripe_payment_method_id を挿入してからフォームの AJAX 送信をトリガーするstripe_payment.js:135-168
AJAX 送信中は、支払いボタンの再クリックがブロックされる(submitInProgress / inProgress ガード)transaction.js:75, stripe_payment.js:137
「Read more」リンクをクリックするとトランザクション同意コンテンツがライトボックスモーダルで開く_transaction_agreement_checkbox.haml:7

アクセシビリティ

確認項目状況備考
ARIA roles/labelspartial#card-errors に role="alert" あり;フォームの他の要素には明示的な ARIA なし
Keyboard navigationnot implemented明示的な tabindex や keydown ハンドラーなし;標準的なブラウザタブ順序
Focus managementunmanagedモーダル/ライトボックスに autofocus やフォーカストラップなし
Screen reader compatibilitypartial配送フィールドに <label> 要素あり;カードエラーに role="alert" あり
[NO_A11Y_DETECTED] — 本番リリース前にアクセシビリティ監査が必要。

条件による表示切り替え

条件種別表示内容備考
stripe_in_useauth/featureStripe カード要素、配送先住所フィールド迂回した場合の影響:Stripe 支払いパスが利用不可
paypal_in_use && !stripe_in_useauth/featurePayPal のみのボタン行迂回した場合の影響:PayPal のみの支払いパスが利用不可
paypal_in_use && stripe_in_useauth/feature「Or pay with PayPal」行+PayPal 画像ボタン迂回した場合の影響:二重支払い選択が非表示
@current_community.transaction_agreement_in_useauth_transaction_agreement_checkbox パーシャル迂回した場合の影響:同意が得られない可能性、法的リスク
stripe_shipping_requiredauth/featureStripe パーシャル内の配送先住所フィールド迂回した場合の影響:配送先住所が収集されない
quantity が存在するfeaturehidden_field_tag :quantityユーザーへの影響なし
per_hour が truefeaturestart_time、end_time、per_hour 非表示フィールドユーザーへの影響なし

セキュリティ上の注意点

条件種別未適用時の影響
before_action :ensure_logged_inauthログイン通知とともにリダイレクト
before_action :ensure_listing_is_openpermission出品物がクローズ済みの場合、フラッシュエラーとともにリダイレクト
before_action :ensure_listing_author_is_not_current_userpermissionリダイレクト;自己トランザクションを防ぐ
before_action :ensure_authorized_to_replypermission出品物がユーザーに見えない場合、検索にリダイレクト
before_action :ensure_can_receive_paymentpermission売り手の支払いが設定されていない場合、出品物にリダイレクト

参照ソース

  • Page/View: app/views/listing_conversations/initiate.haml:1-109
  • Price breakdown partial: app/views/transactions/_price_break_down.haml:1-102
  • Stripe payment partial: app/views/listing_conversations/_stripe_payment.haml:1-68
  • Transaction agreement partial: app/views/listing_conversations/_transaction_agreement_checkbox.haml:1-14
  • Controller: app/controllers/preauthorize_transactions_controller.rb:1-439
  • Client JS (PayPal/polling): app/assets/javascripts/transaction.js:1-130
  • Client JS (Stripe): app/assets/javascripts/stripe_payment.js:1-173
  • Routes: config/routes.rb:117-135

TECHNICAL DETAILS

技術者向け詳細

ここからは、業務用語、状態遷移、全機能の一覧を確認できます。移行設計や追加ヒアリングの論点を洗い出す際に使用する情報です。

F 機能SCR 画面US 利用者視点の要件BL バックグラウンド処理MOD 移行モジュール
サンプル 5 — system/glossary.md(抜粋)

業務用語集

解析の第4段階(--glossary)で生成します。全760行・76語のうち、決済フローと事前承認画面に関係する20語を掲載しています。

system/glossary.md system

全760行収録 — 下記は他サンプル(F020、SCR091)との関連度が高い20語を選定した抜粋。

用語定義技術上の別名関連機能
Auto-Confirmation買い手が手動で受領確認を行わなかった場合、設定された日数経過後にシステムがトランザクションを完了済みとし、売り手への支払いを自動的にリリースするアクション。Community.automatic_confirmation_after_daysF019, F051, F052, F066
Billing Agreement (PayPal)マーケットプレイスが将来のトランザクションにおいて売り手の PayPal アカウントから手数料を徴収することを許可する PayPal の同意。PayPal 売り手設定の第2ステップとして必要。billing_agreements table; PaypalAccountF020, F027, F060
Bookingトランザクションに紐付けられた日付または時間帯の予約レコード。MODEL014F014, F018, F019, F051
Communityプラットフォーム上で動作する単一のマーケットプレイスインスタンス。各コミュニティは独自のサブドメイン、メンバー、リスティング、カテゴリ、決済設定を持つ。MODEL001F001, F004, F005, F031, F034, F058
Community Membershipユーザーとコミュニティの関係を表し、ステータス(承認済み、保留中、利用禁止)と権限(投稿権限、管理者ロール)を保持する。MODEL003; status (DISC-005)F001, F003, F004, F017, F028, F039
Confirmation (Transaction)買い手が商品またはサービスを受け取ったことを確認する操作。これにより売り手への支払いが実行される。Transaction.current_state = 'confirmed' (DISC-011)F019, F042, F051, F052, F066
Conversation2人以上の参加者間のメッセージスレッド。リスティングやトランザクションに任意で紐付けられる。MODEL015F022, F023, F043
Listingマーケットプレイスメンバーが投稿する商品またはサービス。マーケットプレイスの主要コンテンツ単位。MODEL005F011, F012, F013, F014, F015, F016, F017, F018, F041
Listing Shape / Order Typeリスティングのトランザクションモデルを定義するテンプレート — 販売、レンタル、サービス予約、無料交換のいずれかを指定する。MODEL006 (ListingShape)F011, F037
Listing Stateapproved = 検索に表示され取引可能 / approval_pending = 管理者レビュー待ち / approval_rejected = 却下済みListing.state (DISC-006)F011, F017, F041
Order Permission (PayPal)マーケットプレイスが売り手に代わって注文を処理することを許可する PayPal の同意。PayPal 売り手アカウント設定の第1ステップ。order_permissions table; PaypalAccountF020, F027, F060
Payment Gatewayマーケットプレイスが使用する外部決済処理業者 — Stripe または PayPal。PaymentSettings.payment_gateway (DISC-020)F025, F045, F059, F060
Payment Process決済のキャプチャタイミング。preauthorize(資金を保留し売り手が承認した時点でキャプチャ)または postpay(配送後に課金)。TransactionProcess.process (DISC-015)F018, F019, F051, F059, F066
Personシステムに登録されたユーザー。コミュニティごとに一意のユーザー名で識別される。MODEL002F001, F006, F007, F008
Preauthorization買い手の決済カードまたは PayPal 残高に対して、即座に課金せずに資金を確保するホールド。Transaction.current_state = 'preauthorized' (DISC-011)F018, F019, F051, F059
Review / Testimonialトランザクション後に一方の当事者がもう一方に対して残す評価と任意のコメント。受け手のプロフィールに公開表示される。MODEL023 (Testimonial); grade (0.0–1.0)F024, F044
Transaction特定のリスティングに対する買い手と売り手の間の取引。開始から決済、完了またはキャンセルまでのライフサイクル全体を包含する。MODEL011F018, F019, F021, F042, F051
Transaction Agreementトランザクション確定前に買い手が同意する必要のある任意のテキスト。マーケットプレイス管理者が法的条件を設定するために使用する。Community.transaction_agreement_in_useF018, F066
Transaction Processリスティングシェイプに対して利用可能な決済タイミングモデル(なし、事前認可、後払い)のコミュニティレベル定義。MODEL013; process (DISC-015)F037, F051
Transaction Statesinitiated / preauthorized / paid / confirmed / canceled / rejected / refunded / disputed / errored / free — ステートマシンによって制御されるライフサイクル状態。Transaction.current_state (DISC-011)F019, F042, F051
トランザクションライフサイクル

状態遷移

Statesman gem を使ったトランザクション状態遷移。10ノード、12エッジ。confirmed が唯一の成功終端ノード。

initiated 支払い注文作成済み preauthorized 支払い承認済み paid キャプチャ済み confirmed 取引完了 ✓ …requires_action 3DS 完了 pending_ext PayPal外部クリアリング PayPal IPN 完了 rejected errored disputed 紛争提起 refunded 返金済み
機能インベントリ

復元した66機能の一覧

generated/feature-list.md より自動抽出。各機能はさらに4つのドキュメントに展開されます。

認証・会員(Auth & Membership)
F001認証 F002OAuthログイン F003メール確認 F004利用規約同意 F006公開プロフィール F007プロフィール編集 F008アカウント設定 F009メール管理 F010フォロー機能 F028招待 F029メール停止
出品(Listings)
F011リスティング作成 F012リスティング編集 F013画像アップロード F014空き状況設定 F015検索・発見 F016詳細表示 F017認証ゲート F030静的ページ
取引・決済(Transactions & Payments)
F018取引開始 F019取引ライフサイクル F020PayPalフロー F021取引履歴 F024レビュー F025支払い設定 F026Stripe接続 F027PayPal接続 F051状態遷移 F055PayPal IPN F059Stripe連携 F060PayPal連携
メッセージ(Messaging)
F022メッセージング F023ダイレクトメッセ
管理(Administration)
F031管理ダッシュボード F032ブランディング F033ランディングページ F034基本設定 F035カテゴリ管理 F036リスティングフィールド F037注文タイプ F038ユーザーフィールド F039ユーザー管理 F040招待管理 F041リスティング監視 F042取引管理 F043会話監視 F044レビュー管理 F045決済ゲートウェイ F046メール管理 F047検索・位置情報 F048SEO設定 F049アナリティクス F050詳細設定 F064プラン・フラグ F065ログイン設定 F066取引設定
基盤・インフラ(Platform & Infra)
F005マーケット作成 F052メール通知ジョブ F053画像処理ジョブ F054データエクスポート F056SES Webhook F057プランWebhook F058リクエスト処理 F061メールサービス F062アナリティクス連携 F063メンテナンス
生成される仕様ドキュメント:76,000行超。66機能分の264ドキュメントと、182件の画面仕様を1つのコードベースから生成する見本です。

REGEN* DELIVERABLE SAMPLES

移行計画これから、どの順番でどう移すか

上の仕様書で可視化した依存関係とリスクをもとに、段階的な移行計画へ落とし込みます。

EXECUTIVE SUMMARY

このロードマップで判断できること

推奨方針

高リスク領域を先に可視化し、依存の少ないモジュールから段階移行する

一括移行は行わず、3つのウェーブに分けます。各ウェーブの終了時に品質ゲートを設け、次へ進むかを判断します。

01

移行対象と優先順位

依存関係、技術リスク、事業価値から順序を決めます。

02

期間と停止条件

ウェーブごとの期間と、次へ進むための判定基準を示します。

03

主要リスクと対策

決済、検索、非同期処理など、移行前に検証すべき領域を明確にします。

現状分析

現状と、移行後の構成

現状アーキテクチャ Rails 8 モノリス(86 controllers) React 16 Islands + react_on_rails 13 jQuery(asset pipeline / HAML・ERB) Sphinx + ts-delayed-delta(全文検索) delayed_job / MySQL(43ジョブ) PayPal Classic IPN + Stripe 5.55 管理画面 2系統(admin/ + admin2/) MySQL + Redis(キャッシュのみ) 移行 ターゲットアーキテクチャ Next.js App Router + TypeScript(BFF統合) React 最新世代・jQuery 全廃 Auth.js(devise-jwt ブリッジ経由) Meilisearch(JP tokenizer、v1.x stable) BullMQ / Redis(非同期ジョブ・タイマー) PayPal Orders v2 REST / Stripe 最新SDK 管理画面統合(単一 Next.js Admin) MySQL 据え置き + Prisma(dual-write 禁止)

S1 — 現状 vs ターゲットスタック対応図(見本値)

原則 1
DB 単一ソース・dual-write 禁止
MySQL は既存スキーマのまま据え置き。Next.js 側は Prisma イントロスペクションで同一 DB を参照。データ同期エージェント不要。
原則 2
ルート単位ストラングラー
Next.js rewrites をプロキシとして利用。パス単位で段階的に新系へ切替え、旧 Rails は残パスを引き続き処理。
原則 3
旧系は移行完了まで稼働継続
各モジュール完了時点でそのルートのみ旧系から切り離す。全モジュール完了まで旧系をシャットダウンしない(孤立モノリス防止)。

※ 最終選定はアセスメントで確定。

Regen* コアプロセス

新旧の動作が一致することを、段階ごとに確認する

このプロセスがRegen*の中核です。「新システムが動く」だけでは十分ではありません。事前に定義したテストケースで、新旧の結果がすべて一致したことを確認してからリリースします。本ページでは、この新旧の動作一致を「パリティ」と呼び、「パリティ100%」は定義済みテストケースがすべて一致した状態を指します。

準備フェーズ(W0・1回限り) 既存スペックライブラリ 66機能・182画面仕様 既存テスト資産 Rails Unit/Integration テスト 振る舞いテストスイート構築 結合・振る舞いテスト/主要フローを網羅 旧バックエンドの基準値を測定 全テスト通過・スナップショット保存 モジュールごとループ(全10モジュール共通) ① spec スペック参照 ② AI プラン Takumi 実装プラン策定 ③ TDD 新しい単体テストを生成 ※ 実装より先 ④ 実装 UT 全通過まで繰り返し ⑤ 品質ゲート コードレビュー セキュリティ監査 linter / typecheck ⑥ 最終関門 新旧一致 100% フラグ付 リリース ✕ 不一致 → ③ に戻る(マージ不可) ↺ 次モジュールへ

S7 — 新旧の動作が一致することを段階ごとに確認する流れ(見本)。TDDによる単体テスト生成(③)は実装(④)より先に行います。すべての品質確認を通過した後、新旧一致の最終確認(⑥)と担当者による受け入れテストを経てリリースします。

機能・画面単位の開発では、TDDと標準の品質確認を繰り返します。一定数の機能が完成した段階で新旧比較テストを実行し、担当者による受け入れテストへ進めるかを判断します。

仕様から生成した単体テストだけでは、現行システムの暗黙的な動作をすべて捉え切れない場合があります。新旧比較テストを追加することで、移行後の見落としを減らします。

2層テストの役割分担

層目的タイミング合格基準
TDDによる単体テスト(新系) 新実装の正しさ(仕様への準拠) 実装前に生成、実装と同時進行 すべての単体テストが成功 = 実装完了条件
新旧比較テスト(新旧両系) 新旧の振る舞い同等性 品質ゲート通過後・リリース直前 100% 一致 = マージ・リリース条件
  • 既存テスト資産を捨てない — 現行のRailsテストを基盤に、振る舞いテストを構築
  • 受け入れ基準が客観的 — 仕様を起点にすることで、主観的な「動いていそう」ではなく測定結果で判断
  • 新旧不一致なら変更を統合しない — 気づきにくいビジネスロジックの劣化を構造的に防止
リスク分析

先に対処すべき高リスク領域

移行前に解決必須の技術負債・リスク集中点。6件を特定し、影響モジュールと対応方針を確定。

#ホットスポット根拠(エビデンス)影響モジュール対応方針
H-01 React 16.1.1 EOL + react_on_rails 13 6 entry points、2バンドル Webpack 構成 MOD-04, 03, 08 App Router RSC へ段階移行、Webpack → Next.js bundler 統合
H-02 Sphinx + ts-delayed-delta 全文検索 別デーモン、delta 再インデックス delayed_job 経由 MOD-04 Meilisearch(JP tokenizer)へ置換、インデックス再構築 parity 検証
H-03 MySQL上のdelayed_job(ActiveRecord) 43 ジョブ、タイマー 3本(BL001/002/003) MOD-05, 10, 08, 03 BullMQ/Redisへ移行し、ジョブ種別ごとに比較テスト基盤を構築
H-04 PayPal Classic API(IPN + legacy REST) IPN webhook、BillingAgreement、OrderPermission MOD-05, 07 非推奨 → PayPal Orders v2 REST + Webhooks 移行
H-05 管理画面 2系統(admin/ 29 + admin2/ 57 controllers) SCR140–SCR177 + SCR180–SCR242、同一設定の重複 MOD-08, 09, 10 MOD-08 移行時に単一 Next.js Admin UI へ統合
H-06 kt-paperclip + ActiveStorage 共存 出品画像 Paperclip、landing ページ資産 ActiveStorage MOD-03, 09 S3 パス監査後に ActiveStorage 一本化

現状アーキテクチャ(§2)の主要データはシステムソースファイル・設計ドキュメント・実コードから確認済み。

モジュール設計

機能を10の移行単位に分ける

66機能を、共通して使うデータ、認証範囲、取引フローのつながりを基準に整理し、10の移行モジュールに分けます。

移行ID名称対象機能ID画面数サイズ
MOD-01 認証・テナント基盤
Auth & Tenant Foundation
F001F002F003F004F058
11 M
MOD-02 プロフィール・ソーシャル
User Profile & Social
F006–F010F029
11 M
MOD-03 リスティング管理
Listing Management
F011–F014F017
6 L
MOD-04 リスティング発見・検索
Listing Discovery & Search
F015F016F030
20 L
MOD-05 トランザクション・決済
Transactions & Payments
F018–F021F051F055F059F060
12 XL
MOD-06 メッセージング・レビュー
Messaging & Reviews
F022F023F024
9 M
MOD-07 決済設定
Payment Account Settings
F025F026F027
3 S
MOD-08 マーケットプレイス設定
Marketplace Setup & Admin Config
F005F028F031F034–F038F047F064–F066
~35 XL
MOD-09 ブランディング・CMS・SEO
Branding, CMS & SEO
F032F033F048F049F062
~22 L
MOD-10 管理オペレーション
Admin Operations & Platform
F039–F046F050F052–F054F056F057F061F063
~28 XL

画面数は SCR 番号ベース集計。サンプル#1「182画面仕様」はスペック登録数(計上方法が異なる)。

依存関係・リスク分析

依存関係と、移行優先順位の決め方

A → B = A は B に依存(B が先に移行済みである必要がある)

基盤(依存ゼロ) 第1層 第2層 第3層 最終 MOD-01 認証・テナント基盤 MOD-08 MP 設定 MOD-02 プロフィール MOD-07 決済設定 MOD-03 リスティング管理 MOD-06 メッセージング MOD-04 発見・検索 MOD-05 トランザクション MOD-09 CMS・SEO MOD-10 管理オペレーション ← MOD-08 も参照 ← MOD-01 / MOD-08 も参照 直接依存 層をまたぐ依存 ルート(依存ゼロ・先に着手) ※ 交差を避けるため、遠距離の依存は注記で表示

S2 — 依存関係グラフ(見本)。MOD-05 ↔ MOD-06 の準循環はデータ層では真の循環なし(MOD-05 先行で解消可能)。

リスクと事業価値から優先順位を決める

移行リスク(1–5) 事業重要度(1–5) 1 2 3 4 5 1 2 3 4 5 パイロット適地 早期着手 後回し可 慎重・並行稼働 MOD-01 MOD-02 MOD-03 MOD-04 MOD-05 MOD-06 MOD-07 MOD-08 MOD-09 MOD-10 S / M サイズ L サイズ XL サイズ

S3 — リスク×価値散布図(見本値)。円サイズ = モジュール規模。

移行シーケンス

3つのウェーブで段階的に移行する

まず、他機能への依存が少ない基盤モジュールを選びます。次に、技術リスクと事業価値を比較して順序を調整し、決済領域は並行稼働、運用系は最終ウェーブに配置します。

W0 〜3週 W1 4–8週 W2 〜4週 W3 〜6週 W4 〜8週 W5 〜4週 基盤・テスト パイロット 低リスク展開 コア機能 決済並行稼働 管理系完了 振る舞いテスト スイート構築 MOD-01 認証・テナント基盤 MOD-02 プロフィール(パイロット) MOD-07 決済設定 MOD-06 メッセージング MOD-04 発見・検索 MOD-03 リスティング管理 MOD-08 MP 設定 MOD-05 並行稼働→本番切り替え MOD-09 MOD-10 振る舞いテスト(新旧比較の準備) 並行稼働(MOD-05) ウェーブゲート

S4 — ウェーブ計画スイムレーン(見本値)。黄帯 = MOD-05 並行稼働期間。◆ = ゲート(通過条件は下表参照)。

ウェーブ◆ ゲート完了条件(要約)
W0旧バックエンドで定義済み振る舞いテストがすべて成功・ベースライン記録済み・rewrites 全ルート転送確認
W1定義済みテストが100%一致・重大障害0件・本番相当の通信で新旧を7日間比較
※新旧比較を強化する方法の一例です。適用範囲は、体制やシステムの複雑さに応じて決定します。
W2各モジュールの定義済みテストが100%一致・認証領域の移行完了・PayPal Orders v2への移行計画を確定
W3検索結果が事前に定めた許容範囲内で一致・対象モジュールの定義済みテストが100%一致・管理画面の機能を統合
W4全取引フローの定義済みテストが100%一致・本番相当の通信で14日以上比較・重大障害0件・切り戻し手順を確認
W5全10モジュールの定義済みテストが100%一致・旧システムの全URLを新システムで処理・旧システムを停止して保管

ロールバック共通: Next.js rewrites の当該パスを Rails origin へ切り戻すだけで即時ロールバック可能。

TECHNICAL DETAILS

技術者向け詳細

ここからは、モジュールごとの移行方針、新旧システムを共存させる構成、品質ゲートの運用、後続ウェーブを効率化する仕組みを詳しく確認できます。

MOD 移行モジュールF 機能SCR 画面US 利用者視点の要件BL バックグラウンド処理
モジュール詳細

モジュールごとの移行方針

※工数は Takumi による AI コード生成(仕様を起点)を前提とした、レビュー・テスト中心の見本値です。

MOD-01 認証・テナント基盤 / Auth & Tenant Foundation M
対象機能IDF001, F002, F003, F004, F058
移行対応Devise+OmniAuth → Auth.js(devise-jwt ブリッジ経由)/RackAttack → Next.js middleware rate-limit/MarketplaceLookup → middleware.ts テナントリゾルバー/legacy_encrypted_password → SHA256→bcrypt 段階移行
新旧比較の方法標準の品質確認サイクル+固有対応:統一Cookieドメイン下でのセッション継続テスト、テナントリゾルバーのサブドメイン別レスポンス比較
ロールバックrewrites で Auth.js ルートを Rails Devise origin へ切戻し(1行変更)
サイズ / 工数M / 3–4人週(見本値)
MOD-02 プロフィール・ソーシャル / User Profile & Social パイロット M
対象機能IDF006, F007, F008, F009, F010, F029
移行対応HAML server-render → Next.js App Router RSC/FollowerRelationship CRUD → API Route Handler/CustomFieldValue polymorphic → Prisma @map アノテーション//:username バニティ URL → catch-all + generateStaticParams
新旧比較の方法標準確認+個別対応: バニティ URL ルーティング一致確認、CustomFieldValue 多態的読取比較
ロールバック/:username, /profile/* パスを Rails origin へ rewrite 切戻し
サイズ / 工数M / 3–4人週(見本値)
MOD-03 リスティング管理 / Listing Management L
対象機能IDF011, F012, F013, F014, F017
移行対応ManageAvailabilityApp(React 16 island)→ App Router RSC+Client Component/ListingWorkingHoursApp → 同上/int_api blocked-dates → API Route Handler/kt-paperclip ListingImage → S3 パス監査後 ActiveStorage 相当
新旧比較の方法標準確認+個別対応: カレンダー UI 操作後の blocked-dates API 結果比較、ListingImage S3 URL 一致確認
ロールバック/listings/* 管理パスを Rails origin へ切戻し
サイズ / 工数L / 5–7人週(見本値)
MOD-04 リスティング発見・検索 / Listing Discovery & Search L
対象機能IDF015, F016, F030
移行対応SearchPageApp(React 16 + Redux)→ App Router RSC+Client Component/Sphinx + ts-delayed-delta → Meilisearch(JP tokenizer)/マップピン JSON → API Route Handler/静的エラーページ → Next.js 静的ページ
新旧比較の方法標準確認+個別対応:検索順位の差と関連度の許容範囲を事前に定めて比較します。地図ピンの座標とまとめ方も確認します。
ロールバック/s/* /listings/* 検索パスを Rails origin へ切戻し
サイズ / 工数L / 5–7人週(見本値)
MOD-05 トランザクション・決済 / Transactions & Payments XL
対象機能IDF018, F019, F020, F021, F051, F055, F059, F060
移行対応Statesman 10状態ステートマシン → TypeScript 状態マシン(XState 等)+新旧比較/PayPal Classic IPN → PayPal Orders v2 REST Webhooks/delayed_job タイマー(BL001/002/003)→ BullMQ delayed jobs/Stripe 5.55 → Stripe 最新 SDK
新旧比較の方法標準確認+個別対応:非同期IPN Webhookと自動タイマー(BL001/002/003)には、同期処理とは別の比較テスト基盤を構築。取引の状態遷移(10状態)を全経路で比較し、14日以上のシャドートラフィックで決済金額・ステータスの一致を確認してから本番へ切り替える。
ロールバック/transactions/* /checkout/* パスを Rails origin へ即時切戻し(フラグ付リリースで追加粒度)
サイズ / 工数XL / 10–14人週(見本値)
MOD-06 メッセージング・レビュー / Messaging & Reviews M
対象機能IDF022, F023, F024
移行対応Conversation/Message CRUD → API Route Handler+RSC/Testimonial → Server Action/スレッドメッセージング UI → Client Component(WebSocket or polling)
新旧比較の方法標準確認+個別対応:メッセージの読み書きと、取引開始時のConversation初期化を新旧で比較します。
ロールバック/messages/* /reviews/* パスを Rails origin へ切戻し
サイズ / 工数M / 3–4人週(見本値)
MOD-07 決済設定 / Payment Account Settings S
対象機能IDF025, F026, F027
移行対応Stripe Connect OAuth → API Route Handler+OAuth redirect/PayPal BillingAgreement → PayPal Orders v2 出品者オンボーディング(Classic API 非推奨対応)/PaymentSettings CRUD → Prisma
新旧比較の方法標準確認+個別対応: OAuth redirect コールバック URL の state/code 検証一致。PayPal フローは Orders v2 に変更されるため「旧 IPN 流入なし」をルーティングレベルで遮断後に新旧比較。
ロールバック/payment_accounts/* パスを Rails origin へ切戻し
サイズ / 工数S / 2–3人週(見本値)
MOD-08 マーケットプレイス設定 / Marketplace Setup & Admin Config XL
対象機能IDF005, F028, F031, F034–F038, F047, F064–F066
移行対応OnboardingGuideApp(React 16 island)→ App Router RSC/admin/ 29 controllers + admin2/ 57 controllers → 単一 Next.js Admin UI(統合)/Category/CustomField/ListingShape 管理 API → API Route Handler/MarketplaceConfigurations → Prisma
新旧比較の方法標準確認+個別対応: admin/ と admin2/ で重複する設定画面の機能等価性確認(旧系2パスの合計が新系1パスで網羅されていること)。FeatureFlag 書込みの即時反映確認。
ロールバック/admin/* /admin2/* パスを Rails origin へ切戻し
サイズ / 工数XL / 10–14人週(見本値)
MOD-09 ブランディング・CMS・SEO / Branding, CMS & SEO L
対象機能IDF032, F033, F048, F049, F062
移行対応Mercury in-place editor → ヘッドレス CMS(またはカスタムブロックエディタ)/LandingPageVersion JSON renderer → Next.js ISR/SSG ランディングページ/SEO メタタグ → Next.js Metadata API/GTM/GA → next/script
新旧比較の方法標準確認+個別対応: ランディングページ HTML のメタタグ/OG タグ一致確認(SEO 回帰防止)。Lighthouse スコア差分を閾値以内に収める。kt-paperclip LandingPage assets → S3 パス統一後に新旧比較。
ロールバック/landing/* /p/* ブランドパスを Rails origin へ切戻し
サイズ / 工数L / 5–7人週(見本値)
MOD-10 管理オペレーション / Admin Operations & Platform XL
対象機能IDF039–F046, F050, F052–F054, F056, F057, F061, F063
移行対応管理モデレーション(Listing/Transaction/Conversation/Review)→ Next.js Admin API Route Handler/一括メール/ニュースレター → BullMQ email job/データエクスポート → BullMQ export job + S3/SES bounce webhook → API Route Handler/delayed_job 20+種 → BullMQ 移行
新旧比較の方法標準確認+個別対応:20種以上のバックグラウンドジョブに対し、ジョブ種別ごとの比較テスト基盤を構築。一括メールの送信件数とバウンスイベント処理件数の一致を確認する。
ロールバック/admin/* 管理オペレーションパスを Rails origin へ切戻し
サイズ / 工数XL / 10–14人週(見本値)
移行中アーキテクチャ

新旧システムを安全に共存させる

移行完了前のある時点における共存アーキテクチャ。Next.js rewrites がプロキシ層として機能し、移行済みパスは新系、未移行パスは旧系で処理する。

入口 アプリケーション 共通基盤 データ・外部 ブラウザ クライアント Next.js App rewrites = プロキシ 移行済みパスを処理 Rails モノリス 未移行パス処理 Redis cache + BullMQ Auth Bridge devise-jwt ↔ Auth.js Meilisearch MOD-04 移行後に有効 MySQL(単一 DB) dual-write 禁止 Stripe API 最新 SDK PayPal Orders v2 REST + Webhooks 全リクエスト 未移行パス転送 Prisma ActiveRecord Shadow Comparator 並行トラフィック比較 現在の経路 移行後に有効/比較用

S5 — 移行中共存アーキテクチャ(見本)。赤ノード = Next.js proxy(全リクエストの入口)。点線 = 移行後に有効化。dual-write 禁止。

移行前に避けるべき4つの落とし穴

  • PF-01セッション転送 — middleware.ts で Authorization/Cookie ヘッダーを明示転送。統一 cookie ドメインで phantom ログアウト防止。
  • PF-02SEO 301 — rewrites 切替時に 301 リダイレクト確認。302 を使わない。Screaming Frog 等で切替前後の監査必須。
  • PF-03フラグ負債に sunset 期限 — 各 feature flag に TTL 設定。1スプリント以内に削除(issue tracker で追跡)。
  • PF-04非同期処理の比較漏れ — delayed_job/BullMQのジョブには、同期処理とは別の比較テスト基盤を用意。シャドー実行で新旧ジョブの動作を比較する。
ガバナンス

品質ゲートを支える5つの運用ルール

ここでは、品質ゲートで必ず守る5つの運用ルールを示します。具体的な確認手順は、「新旧の動作が一致することを、段階ごとに確認する」で説明しています。

  1. 1
    仕様を起点にテストする
    テストはスペックライブラリから生成。仕様外の実装は受け入れない。スペックに書いていない振る舞いはテストも通過しない。
  2. 2
    旧システムの基準値を測定する
    移行前に旧システムで振る舞いテストを実行し、結果を基準値として記録します。比較できる状態になるまで移行を始めません。
  3. 3
    基準値の再現を統合条件にする
    新システムが定義済みテストの基準値をすべて再現した場合にだけ、変更を統合します。1件でも不一致があれば先へ進めません。
  4. 4
    シニアレビュー拒否権
    シニアエンジニアがコードレビューを行い、仕様から外れた実装や新旧比較が完了していない変更は統合しません。
  5. 5
    シャドートラフィック検証
    本番相当の通信を新旧両方へ流し、結果に差がないことを確認してから切り替えます。
    ※適用範囲は、ご要望、体制、システムの複雑さに応じて決定します。

ウェーブ別ゲート ◆ 一覧

ウェーブ◆ ゲート条件(要約)
W0旧バックエンドで定義済み振る舞いテストがすべて成功・ベースライン記録済み
W1定義済みテストが100%一致・重大障害0件・本番相当の通信で7日間比較
W2各モジュールの定義済みテストが100%一致・認証領域の移行完了
W3検索結果が許容範囲内で一致・対象モジュールの定義済みテストが100%一致・管理画面を統合
W4全取引フローの定義済みテストが100%一致・本番相当の通信で14日以上比較・重大障害0件・切り戻し手順を確認
W5全10モジュールの定義済みテストが100%一致・旧システムの全URLを新システムで処理・旧システムを停止
速度複利

移行を重ねるほど、次のウェーブが進めやすくなる

モジュール移行が進むにつれ、Takumiエンジンと比較テスト基盤への投資が蓄積し、後続モジュールの移行を効率化できます。

1.0 1.5 2.0 2.5 3.0 MOD-01 MOD-02 MOD-07 MOD-06 MOD-03 MOD-04 MOD-08 MOD-05 MOD-09 MOD-10 最大約3倍(見本) モジュール移行順序 相対移行速度インデックス

S6 — 移行を重ねるほど、次のウェーブが進めやすくなる(見本値)。MOD-05 は高リスク並行稼働のため一時減速。最大約3倍(見本値)。

後続ウェーブを進めやすくする3つの要因

要因 1
エンジニアリングメモリ
Takumi が過去モジュールの移行パターン・決定履歴を学習し、新モジュールのプラン生成が高速化。
要因 2
比較テスト基盤の再利用
振る舞いテストスイートの共通部分(認証・テナント・DB 接続)を後続モジュールがそのまま流用。
要因 3
並行化
後半ウェーブでは複数モジュールを同時並行で移行可能(依存解消済みのため)。

本ページは実案件を参考に構成した成果物サンプルです。

NEXT STEP

自社システムの移行順序を、可視化しませんか。

対象システムの概要を伺い、アセスメントで確認する項目と進め方をご提案します。初回のご相談・ご提案は無料です。