# 画面設計書 16-ルーティングFSM可視化画面

## 概要

本ドキュメントは、Ruby on Railsフレームワークにおける「ルーティングFSM可視化画面」の設計仕様を定義する。Railsのルーティングエンジン（Journey）が内部で使用する有限状態マシン（FSM: Finite State Machine）をD3.jsで可視化し、NFAシミュレーションを実行できる開発者向け分析ツール画面である。

### 本画面の処理概要

この画面は、RailsのルーティングエンジンであるJourneyが内部で構築する有限状態マシン（NFA/GTG）をSVGグラフとして可視化し、開発者が入力したルートパスに対してNFAシミュレーションを実行できる開発用ツールである。ルーティングの内部動作を視覚的に理解し、パフォーマンス分析やデバッグに活用できる。

**業務上の目的・背景**：Railsのルーティングシステムは複雑なパターンマッチングを行うため、内部的に有限状態マシンを使用している。大規模なアプリケーションでルーティングのパフォーマンス問題やマッチング挙動の問題が発生した際に、この可視化ツールを使用することで、状態遷移の構造を視覚的に把握し、問題の原因を特定できる。これは主にRailsコア開発者や、ルーティングに関する深い理解が必要な開発者向けの高度なツールである。

**画面へのアクセス方法**：この画面は通常のルーティングでは公開されておらず、`TransitionTable#visualizer`メソッドを直接呼び出すことでHTMLが生成される。開発者がコンソールやスクリプトからこのメソッドを呼び出し、生成されたHTMLをブラウザで開くことでアクセスする。

**主要な操作・処理内容**：
1. FSMグラフの表示 - D3.jsを使用してSVG形式のFSMグラフを描画
2. ルートパス入力 - テキストフィールドにテスト用のルートパスを入力
3. シミュレーション実行 - "simulate"ボタンで入力パスに対するNFA状態遷移をアニメーション表示
4. グラフリセット - "reset"ボタンでハイライトをクリア
5. サンプルルート選択 - "fun routes"リンクでサンプルルートを自動入力
6. 定義済みルート一覧表示 - 現在のアプリケーションで定義されているルートを一覧表示

**画面遷移**：
- 遷移元：コンソールまたはスクリプトからの直接生成
- 遷移先：なし（単独のツール画面）

**権限による表示制御**：
- この画面は内部ツールであり、通常は開発環境でのみ使用される
- 本番環境では使用されない想定

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 15 | Journey | 主機能 | ルーティング有限状態マシンの可視化処理 |
| 8 | Action Dispatch | 補助機能 | NFAシミュレーション機能の提供 |

## 画面種別

ツール/分析（開発環境専用）

## URL/ルーティング

特定のURLは存在しない。`ActionDispatch::Journey::GTG::TransitionTable#visualizer`メソッドを呼び出すことでHTMLが生成される。

使用例：
```ruby
# Rails consoleでの使用例
table = Rails.application.routes.router.gtg.transition_table
html = table.visualizer(Rails.application.routes.routes.map(&:ast), "My App Routes")
File.write("fsm.html", html)
```

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| route | 入力 | String | いいえ | シミュレーション対象のルートパス（例: "/articles/new"） |

## 表示項目

| 項目名 | データ型 | 説明 | ソース |
|--------|----------|------|--------|
| タイトル | String | ページタイトル（"FSM"または指定値） | `title`変数 |
| FSMグラフ | SVG | 状態マシンの可視化グラフ | `TransitionTable#to_svg` |
| ルート入力フォーム | HTML | ルートパス入力とシミュレーションボタン | テンプレート固定 |
| サンプルルート | Array | 試行用のサンプルルートリンク | `fun_routes`変数 |
| 定義済みルート一覧 | Array | 現在定義されているルート一覧 | `paths`変数 |
| ヘッダー | String | "Routes FSM with NFA simulation" | テンプレート固定値 |

## イベント仕様

### 1-シミュレーション実行（simulateボタン）

**処理内容**：入力されたルートパスに対してNFAシミュレーションを実行し、マッチする状態遷移をアニメーションでハイライト表示する。

**トリガー**：フォーム送信（simulateボタンクリック）またはEnterキー押下

**処理フロー**：
1. 入力されたルートパスを`tokenize`関数でトークン分割
2. 初期状態（状態0）からシミュレーション開始
3. 各トークンに対して遷移テーブル（`tt()`関数）を参照
4. マッチする遷移が見つかった場合、エッジと状態をハイライト
5. 最終状態がaccepting状態の場合は青色、そうでない場合は赤色でハイライト

**画面遷移**：なし（同一画面内でのアニメーション）

### 2-グラフリセット（resetボタン）

**処理内容**：すべてのハイライトをクリアし、グラフを初期状態に戻す。

**トリガー**：resetボタンクリック

**処理フロー**：
1. `reset_graph`関数を呼び出し
2. すべてのエッジの色を黒に戻す
3. すべてのノードの塗りつぶしを白に戻す

**画面遷移**：なし（同一画面内でのリセット）

### 3-サンプルルート選択

**処理内容**：サンプルルートをルート入力フィールドに設定し、シミュレーションを実行する。

**トリガー**：サンプルルートリンクのクリック

**処理フロー**：
1. クリックされたリンクのテキストをルート入力フィールドに設定
2. 自動的にシミュレーションを実行

**画面遷移**：なし（同一画面内での操作）

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| なし | なし | なし | 本画面はデータベースへの操作を行わない |

## メッセージ仕様

| メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|-------------|---------------|---------------|----------|
| MSG-001 | 情報 | "Routes FSM with NFA simulation" | 常時ヘッダーに表示 |
| MSG-002 | 情報 | "Type a route in to the box and click 'simulate'." | 常時説明文として表示 |
| MSG-003 | 情報 | "Some fun routes to try:" | 常時サンプルルート前に表示 |
| MSG-004 | 情報 | "This is a FSM for a system that has the following routes:" | 常時ルート一覧前に表示 |

## 例外処理

| 例外種別 | 発生条件 | 処理内容 |
|---------|---------|---------|
| なし | - | JavaScript側でのエラーハンドリングのみ |

## 備考

- この画面はRailsフレームワーク内部のデバッグ・分析ツールである
- D3.js（v3.4.8）をCDNから読み込む
- 外部CSSリセット（Meyer Reset 2.0）を使用
- SVGはGraphviz（dot）を使用して生成される
- GTG（Generalized Transition Graph）はNFA（非決定性有限オートマトン）の一種
- 大規模なルーティングではグラフが複雑になり、描画に時間がかかる場合がある

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、TransitionTableクラスと遷移テーブルの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | transition_table.rb | `actionpack/lib/action_dispatch/journey/gtg/transition_table.rb` | TransitionTableクラス、状態遷移の構造 |

**読解のコツ**:
- 17-23行目: 内部状態（`@stdparam_states`, `@regexp_states`, `@string_states`, `@accepting`）の構造を理解
- 103-118行目: `as_json`メソッドでJavaScriptに渡すデータ構造を確認
- 120-128行目: `to_svg`メソッドでGraphvizを使用したSVG生成を確認
- 130-166行目: `visualizer`メソッドでHTML生成の全体像を把握

#### Step 2: テンプレート構造を理解する

HTMLテンプレートとレイアウトを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.html.erb | `actionpack/lib/action_dispatch/journey/visualizer/index.html.erb` | 全体的なHTML構造、D3.jsの読み込み |

**主要処理フロー**:
- **1-10行目**: HTMLヘッダー、外部CSS/JSの読み込み
- **13-32行目**: メインコンテンツ、フォーム、サンプルルート
- **34-36行目**: SVGグラフの埋め込み
- **37-46行目**: 定義済みルート一覧
- **48-50行目**: JavaScriptの埋め込み

#### Step 3: JavaScriptの動作を理解する

NFAシミュレーションのJavaScript実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fsm.js | `actionpack/lib/action_dispatch/journey/visualizer/fsm.js` | シミュレーションロジック、D3.jsによるハイライト |

**主要処理フロー**:
- **1-6行目**: `tokenize`関数でルートパスをトークン分割
- **8-26行目**: D3.jsでSVGの各ノード/エッジを取得
- **28-45行目**: `reset_graph`関数でハイライトをリセット
- **47-76行目**: `highlight_edge`, `highlight_state`, `highlight_finish`関数
- **77-156行目**: `match`関数でNFAシミュレーションを実行

#### Step 4: スタイルを理解する

CSSスタイルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | fsm.css | `actionpack/lib/action_dispatch/journey/visualizer/fsm.css` | レイアウト、フォームスタイル |

### プログラム呼び出し階層図

```
TransitionTable#visualizer（transition_table.rb:130）
    │
    ├─ fsm.js の読み込み
    ├─ fsm.css の読み込み
    ├─ index.html.erb の読み込み
    │
    ├─ to_json（transition_table.rb:103）
    │      └─ as_json - 遷移テーブルをJSON形式に変換
    │             ├─ regexp_states
    │             ├─ string_states
    │             ├─ stdparam_states
    │             └─ accepting
    │
    ├─ fun_routes の生成（transition_table.rb:137-152）
    │      └─ サンプルルートパスの生成
    │
    ├─ to_svg（transition_table.rb:120）
    │      └─ Graphviz (dot) を呼び出してSVG生成
    │
    └─ ERB.new(erb).result(binding)
           └─ HTML文字列の生成

ブラウザでHTML表示
    │
    ├─ D3.js読み込み（CDN）
    │
    ├─ fsm.js 実行
    │      ├─ SVGノード/エッジの取得
    │      └─ イベントハンドラ設定
    │
    └─ ユーザー操作
           │
           ├─ simulate → match(input)
           │      ├─ tokenize(input)
           │      ├─ tt() で遷移テーブル取得
           │      ├─ 状態遷移シミュレーション
           │      └─ highlight_edge/highlight_state
           │
           └─ reset → reset_graph()
```

### データフロー図

```
[入力]                    [処理]                              [出力]

Rails.application
  .routes          ───▶ TransitionTable#visualizer
                              │
                              ├─ routes.map(&:ast)
                              │      └─ ルート定義のAST
                              │
                              ├─ TransitionTable
                              │      ├─ @string_states
                              │      ├─ @regexp_states
                              │      ├─ @stdparam_states
                              │      └─ @accepting
                              │
                              ├─ to_svg (Graphviz)
                              │      └─ SVG形式のグラフ
                              │
                              └─ ERB rendering
                                     └─ index.html.erb
                                            │
                                            ▼
                                     HTML文字列 ───────▶ ブラウザ表示
                                                              │
ルートパス入力 ─────────────────────────────────────────────▶ match()
"/articles/new"                                              │
                                            tokenize() ◀──────┘
                                                │
                                                ▼
                                            状態遷移
                                            シミュレーション
                                                │
                                                ▼
                                            SVGアニメーション
                                            （ハイライト表示）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| transition_table.rb | `actionpack/lib/action_dispatch/journey/gtg/transition_table.rb` | ソース | 遷移テーブルクラス、visualizerメソッド |
| index.html.erb | `actionpack/lib/action_dispatch/journey/visualizer/index.html.erb` | テンプレート | FSM可視化画面のHTMLテンプレート |
| fsm.js | `actionpack/lib/action_dispatch/journey/visualizer/fsm.js` | JavaScript | NFAシミュレーション、D3.jsによるアニメーション |
| fsm.css | `actionpack/lib/action_dispatch/journey/visualizer/fsm.css` | CSS | 画面スタイル |
| builder.rb | `actionpack/lib/action_dispatch/journey/gtg/builder.rb` | ソース | GTG構築ロジック |
| simulator.rb | `actionpack/lib/action_dispatch/journey/gtg/simulator.rb` | ソース | GTGシミュレータ |
| dot.rb | `actionpack/lib/action_dispatch/journey/nfa/dot.rb` | ソース | Graphviz DOT形式出力 |
