# 画面設計書 20-ルーティングパネル

## 概要

本ドキュメントは、Symfony WebProfilerBundleが提供する「ルーティングパネル」画面の設計書である。リクエストに対するルーティングマッチング情報を表示するプロファイラーのコレクターパネルを定義する。

### 本画面の処理概要

**業務上の目的・背景**：Symfonyのルーティングシステムにおいて、リクエストURLがどのルートにマッチしたか、マッチしなかったルートはなぜマッチしなかったかを把握することは、ルーティング問題のデバッグに不可欠である。本パネルは、TraceableUrlMatcherを使用してルーティングマッチングの詳細なトレースログを表示し、URLパスに対する全ルートのマッチング結果を視覚化する。マッチしたルート、部分的にマッチしたルート、マッチしなかったルートを色分けして表示する。

**画面へのアクセス方法**：プロファイラーパネル画面の左サイドメニューから「Routing」を選択してアクセスする。パネル内部ではRouterControllerへのサブリクエストが発行される。

**主要な操作・処理内容**：
1. マッチしたルートの確認 -- 現在のリクエストがマッチしたルート名の表示
2. ルートパラメータの確認 -- マッチしたルートのパラメータ（名前と値）
3. ルートリダイレクト情報の確認 -- ルートがリダイレクトする場合のリダイレクト先
4. ルートマッチングログの確認 -- 全ルートに対するマッチング結果のトレースログ（マッチ/部分マッチ/非マッチ）

**画面遷移**：
- 遷移元：プロファイラーパネルのメニュー選択
- 遷移先：プロファイラーの他パネルへの遷移

**権限による表示制御**：開発環境でのみ利用可能。ルーターが無効の場合は「The Router is not enabled.」と表示される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | WebProfilerBundle | 主機能 | ルーティングマッチング情報を表示するパネル |
| 3 | Routing | 主機能 | Routingコンポーネントによるルートマッチング結果の表示 |

## 画面種別

詳細（コレクターパネル）

## URL/ルーティング

| ルート名 | URL | コントローラー |
|---------|-----|--------------|
| _profiler | `/_profiler/{token}?panel=router` | `web_profiler.controller.profiler::panelAction` |
| _profiler_router | `/_profiler/{token}/router` | `web_profiler.controller.router::panelAction` |

## 入出力項目

| 項目名 | 種別 | 型 | 説明 |
|--------|------|-----|------|
| token | 入力（URLパラメータ） | string | プロファイラートークン |
| panel | 入力（クエリパラメータ） | string | "router"固定 |
| request | テンプレート変数 | RequestDataCollector | リクエスト情報コレクター |
| router | テンプレート変数 | RouterDataCollector | ルーターデータコレクター |
| traces | テンプレート変数 | array | ルートマッチングのトレース結果 |

## 表示項目

### パネル表示（RouterController::panelAction経由）

| 表示項目 | データソース | 表示形式 | 説明 |
|----------|-------------|---------|------|
| Matched route | request.route | メトリクス | マッチしたルート名（なければ"(none)"） |
| Route Parameters | request.routeParams | テーブル | ルートパラメータ（Name/Value） |
| Route Redirection | router.redirect, router.targetUrl, router.targetRoute | テキスト | リダイレクト先URLとルート名 |
| Path to match | request.pathinfo | コード表示 | マッチ対象のURLパス |
| Route Matching Logs | traces | テーブル | 全ルートのマッチング結果 |

### ルートマッチングログテーブル

| カラム | データソース | 説明 |
|--------|-------------|------|
| # | loop.index | 連番 |
| Route name | trace.name | ルート名 |
| Path | trace.path | ルートのパスパターン |
| Log | trace.log | マッチング結果（レベルに応じた色分け） |

トレースレベルの色分け：
- level 0：非マッチ（通常色）-- "Path does not match"
- level 1：部分マッチ（status-warning / 黄色）-- "Path almost matches, but {理由}"
- level 2：完全マッチ（status-success / 緑色）-- マッチ結果の詳細

## イベント仕様

本パネルはデータ表示専用であり、ユーザー操作によるイベントは最小限である。テーブルのスクロールのみ。

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

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

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

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 表示条件 |
|--------------|--------------|---------|
| 情報 | "The Router is not enabled." | ルーターが無効の場合 |
| 情報 | "No parameters." | ルートパラメータがない場合 |
| ヘルプ | "Note: These matching logs are based on the current router configuration, which might differ from the configuration used when profiling this request." | 常時表示 |

## 例外処理

| 例外条件 | 処理 | レスポンス |
|---------|------|----------|
| profilerがnull | NotFoundHttpException発生 | 404エラー |
| matcherまたはroutesがnull | "The Router is not enabled."メッセージを返却 | 200 |

## 備考

- ルーティングパネルは2段構成：router.html.twigがpanelブロックでRouterController::panelActionへサブリクエストを発行し、Router/panel.html.twigが実際の内容を描画する
- RouterControllerはTraceableUrlMatcherを使用してルートマッチングのトレースを生成する（80-98行目）
- ExpressionLanguageProviderのサポートあり（94-96行目）
- ルーティングのトレースは現在のルーター設定に基づくため、プロファイリング時の設定とは異なる可能性がある
- ツールバーブロックは空（定義なし）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RouterController.php | `src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php` | traces配列の構造を`getTraces`メソッド（80-98行目）で確認。TraceableUrlMatcherが返す配列（name, path, level, log） |

**読解のコツ**: トレース結果のlevelフィールド（0=非マッチ, 1=部分マッチ, 2=完全マッチ）がUI表示に直結する。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | router.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/router.html.twig` | panelブロック（12-14行目）で`render(controller('web_profiler.controller.router::panelAction'))`を呼び出し |
| 2-2 | RouterController.php | `src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php` | `panelAction`メソッド（53-75行目）: プロファイルからリクエスト/ルーター情報を取得し、トレースを生成 |

**主要処理フロー**:
1. **55-57行目**: プロファイラー有効確認
2. **59行目**: プロファイラー無効化（自身のリクエストを記録しない）
3. **61-63行目**: matcherまたはroutesがnullならエラーメッセージ
4. **65行目**: プロファイルの読み込み
5. **68行目**: RequestDataCollectorの取得
6. **70-74行目**: Router/panel.html.twigのレンダリング（request, router, traces変数）
7. **82-98行目**: getTraces内でTraceableUrlMatcherによるマッチングトレース生成

#### Step 3: テンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Router/panel.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig` | マッチルート表示（3-8行目）、ルートパラメータ（10-19行目）、リダイレクト情報（22-30行目）、マッチングログテーブル（32-66行目） |

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

```
GET /_profiler/{token}?panel=router
    |
    +-- ProfilerController::panelAction()
            |
            +-- Twig::render(router.html.twig)
                    |
                    +-- extends layout.html.twig
                    |
                    +-- render(controller('...router::panelAction'))
                            |
                            +-- RouterController::panelAction()  [53行目]
                                    |
                                    +-- Profiler::loadProfile()  [65行目]
                                    +-- Profile::getCollector('request')  [68行目]
                                    +-- Profile::getCollector('router')
                                    +-- getTraces()  [73行目]
                                    |       +-- TraceableUrlMatcher::getTracesForRequest()  [98行目]
                                    |
                                    +-- Twig::render(Router/panel.html.twig)  [70行目]
                                            |
                                            +-- include table.html.twig  [18行目]
```

### データフロー図

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

token (URL)          ProfilerController              Router/panel.html.twig
panel=router    -->  ::panelAction()             -->  (ルーティングパネル)
                          |
                     render(controller(...))
                          |
                     RouterController::panelAction()
                          |
                     Profiler::loadProfile()
                          |
                     +-- RequestDataCollector (route, routeParams, pathinfo)
                     +-- RouterDataCollector (redirect, targetUrl, targetRoute)
                     +-- TraceableUrlMatcher::getTracesForRequest()
                              |
                              [{name, path, level, log}, ...]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RouterController.php | `src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php` | ソース | ルーターパネルのコントローラー |
| ProfilerController.php | `src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php` | ソース | panelActionメソッド |
| router.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/router.html.twig` | テンプレート | パネル外枠（サブリクエスト呼出し） |
| Router/panel.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig` | テンプレート | ルーティングパネルの実体 |
| table.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/table.html.twig` | テンプレート | テーブル表示コンポーネント |
| layout.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig` | テンプレート | パネル共通レイアウト |
| profiler.php | `src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.php` | 設定 | ルーティング定義（_profiler_router） |
