# 画面設計書 32-Messengerパネル

## 概要

本ドキュメントは、Symfony WebProfilerBundleが提供するMessengerパネルの画面設計書である。Messengerコンポーネントを通じてディスパッチされたメッセージの一覧と詳細情報をプロファイラー上で確認するためのコレクターパネルである。

### 本画面の処理概要

本画面は、Symfony Messengerコンポーネントのメッセージバスを通じてディスパッチされたメッセージの情報を時系列で表示する。

**業務上の目的・背景**：CQRSパターンやイベント駆動アーキテクチャを採用したアプリケーションにおいて、メッセージの送信状況、バス間の振り分け、スタンプの付与状況、例外の発生状況を開発時に確認・デバッグするために必要な画面である。メッセージハンドラーの動作確認やミドルウェアチェーンのデバッグに有用である。

**画面へのアクセス方法**：Webデバッグツールバーのメッセンジャーアイコンをクリックするか、プロファイラーパネルの左メニューから「Messages」を選択してアクセスする。URLは `/_profiler/{token}?panel=messenger` の形式となる。

**主要な操作・処理内容**：
1. ディスパッチされたメッセージの総数をツールバーに表示する
2. 複数バス使用時はバスごとのタブで切り替え、「All」タブで全バス横断の一覧を表示する
3. 各メッセージのクラス名、呼び出し元（Caller）、メッセージ内容をダンプ表示する
4. ディスパッチ前後のEnvelope Stampsを表示する
5. 例外発生時は例外情報をハイライト表示する
6. 呼び出し元のソースコード抜粋をトグル表示する

**画面遷移**：プロファイラーパネルメイン画面からパネル切替で遷移する。Webデバッグツールバーからも直接遷移可能。他のコレクターパネルへはパネル切替で遷移できる。

**権限による表示制御**：プロファイラーは開発環境でのみ有効。メッセージが0件の場合はメニューがdisabled状態となり、空メッセージが表示される。例外が発生している場合はメニューにエラーステータスが表示される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | WebProfilerBundle | 主機能 | Messengerのメッセージディスパッチ情報を表示するパネル |
| 37 | Messenger | 主機能 | Messengerコンポーネントによるメッセージバスのディスパッチ情報の表示 |

## 画面種別

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

## URL/ルーティング

- **URL**: `/_profiler/{token}?panel=messenger`
- **ルート名**: `_profiler`（パネルパラメータで切替）
- **HTTP メソッド**: GET

## 入出力項目

| 項目名 | 入出力 | 型 | 説明 |
|--------|--------|------|------|
| token | 入力（URLパラメータ） | string | プロファイラートークン |
| panel | 入力（クエリパラメータ） | string | パネル名（"messenger"） |

## 表示項目

### ツールバー表示

| 項目名 | 型 | 説明 |
|--------|------|------|
| メッセンジャーアイコン | SVG | Messengerアイコン |
| メッセージ総数 | integer | ディスパッチされたメッセージの総数 |
| バス別件数 | integer | 各バス名と件数。例外ありの場合は赤いステータスバッジ |

### メニュー表示

| 項目名 | 型 | 説明 |
|--------|------|------|
| Messagesラベル | string | メニュー項目名 |
| 例外件数バッジ | integer | 例外が発生したメッセージ数（エラーステータス付き） |

### パネル本体（メッセージ一覧）

| 項目名 | 型 | 説明 |
|--------|------|------|
| メッセージクラス名 | string | ディスパッチされたメッセージのFQCN（profiler_dump表示） |
| 例外ラベル | string | 例外発生時に"exception"ラベルを表示 |
| Caller | string | メッセージをディスパッチした呼び出し元のファイル名・行番号 |
| ソースコード抜粋 | HTML | 呼び出し元のソースコード（トグル表示） |
| Bus名 | string | メッセージが処理されたバス名（All表示時のみ） |
| Message | dump | メッセージオブジェクトの内容（profiler_dump、maxDepth: 2） |
| Envelope stamps（ディスパッチ前） | dump | ディスパッチ前のEnvelopeスタンプ一覧 |
| Envelope stamps（ディスパッチ後） | dump | ディスパッチ後のEnvelopeスタンプ一覧 |
| Exception | dump | 例外オブジェクトの内容（profiler_dump、maxDepth: 1） |

## イベント仕様

### 1-パネル切替

プロファイラーレイアウトの左メニューから「Messages」を選択すると、当パネルの内容が表示される。

### 2-ツールバーアイコンクリック

Webデバッグツールバーのメッセンジャーアイコンをクリックすると、プロファイラーのMessengerパネルに遷移する。例外がある場合は赤いステータス色で表示される。

### 3-バスタブ切替

複数バスが登録されている場合、「All」タブと各バス名のタブを切り替えてメッセージを表示する。各タブにはメッセージ件数バッジが表示され、例外の有無に応じてステータスカラーが変わる。

### 4-メッセージ詳細トグル

各メッセージのヘッダー行をクリックすると、Caller、Message、Envelope stamps等の詳細情報がトグル表示される。最初のメッセージはデフォルトで展開状態となる。

### 5-ソースコードトグル

Callerの行番号をクリックすると、呼び出し元のソースコード抜粋がトグル表示される。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| パネル表示 | - | SELECT | Profilerストレージからプロファイルデータを読み込む（ファイルシステムベース） |

### テーブル別更新項目詳細

データベースへの直接的な更新は行わない。プロファイルデータはファイルシステム上のProfilerストレージに保存される。

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|---------|
| 情報 | "No messages have been collected." | メッセージが1件も収集されていない場合 |
| 情報 | "No items" | Envelope stampsが空の場合 |
| 説明 | "Ordered list of dispatched messages across all your buses" | All タブ表示時 |
| 説明 | "Ordered list of messages dispatched on the `{bus}` bus" | 個別バスタブ表示時 |

## 例外処理

- プロファイラートークンが不明な場合、プロファイラー情報画面にフォールバックする
- メッセージディスパッチ時に例外が発生した場合、メッセージ一覧に"exception"ラベルが表示され、詳細に例外ダンプが含まれる
- ツールバーでは例外発生時にステータスカラーが赤になる

## 備考

- テンプレートファイル: `@WebProfiler/Collector/messenger.html.twig`
- データコレクター: `MessengerDataCollector`（コレクター名: "messenger"）
- LateDataCollectorInterfaceを実装しており、カーネル終了時にデータを収集する
- TraceableMessageBusを通じてメッセージディスパッチを追跡する
- メッセージは全バス横断で時系列（callTime）順にソートされる
- バスが1つの場合はタブ切替UIを省略し、直接一覧を表示する

---

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

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

### 推奨読解順序

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

TraceableMessageBusがメッセージディスパッチの情報を記録し、MessengerDataCollectorがそれを収集する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TraceableMessageBus.php | `src/Symfony/Component/Messenger/TraceableMessageBus.php` | ディスパッチされたメッセージの記録構造（message, stamps, caller, callTime） |
| 1-2 | MessengerDataCollector.php | `src/Symfony/Component/Messenger/DataCollector/MessengerDataCollector.php` | バス登録（行30-33）、lateCollect()でのデータ整形（行40-57）、バスごと/全体のメッセージ取得 |

**読解のコツ**: MessengerDataCollectorはLateDataCollectorInterfaceを実装しており、lateCollect()でデータを収集する。これによりリクエスト中のすべてのメッセージディスパッチが完了した後にデータが確定する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MessengerDataCollector.php | `src/Symfony/Component/Messenger/DataCollector/MessengerDataCollector.php` | registerBus()（行30-33）によるバス登録、lateCollect()（行40-57）によるデータ収集 |

**主要処理フロー**:
1. **行30-33**: registerBus()で各バスをTraceableMessageBusとして登録
2. **行40-57**: lateCollect()でgetDispatchedMessages()を呼びcallTime順でソート
3. **行82-107**: collectMessage()でメッセージのデバッグ表現を構築
4. **行109-117**: getExceptionsCount()で例外件数を算出
5. **行119-131**: getMessages()でバス名によるフィルタリング

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | messenger.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/messenger.html.twig` | バスタブ構成、render_bus_messagesマクロ、メッセージ詳細のトグル表示 |

**主要処理フロー**:
- **行42-67**: toolbarブロック - 例外ありの場合は赤いステータス色
- **行69-79**: menuブロック - 例外件数でエラーラベル切替
- **行81-119**: panelブロック - 単一バス/複数バスの分岐とタブ生成
- **行121-215**: render_bus_messagesマクロ - メッセージごとのテーブル、トグル、Caller表示

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

```
ProfilerController::panelAction()
    |
    +-- Profiler::loadProfile(token)
    |       +-- MessengerDataCollector
    |               +-- lateCollect()
    |               |       +-- TraceableMessageBus::getDispatchedMessages()
    |               +-- getMessages(?bus)
    |               +-- getBuses()
    |               +-- getExceptionsCount(?bus)
    |
    +-- Twig::render('messenger.html.twig')
            +-- collector.messages / collector.buses
            +-- render_bus_messages(messages, showBus)
                    +-- profiler_dump(dispatchCall.message.type)
                    +-- profiler_dump(dispatchCall.message.value)
                    +-- profiler_dump(dispatchCall.stamps)
```

### データフロー図

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

MessageBus::dispatch() ------> TraceableMessageBus -------> ディスパッチ記録
                                (メッセージ追跡)              (message, stamps, caller, callTime)
                                     |
                                     v
                               MessengerDataCollector
                               (lateCollect()でcallTime順ソート)
                                     |
                                     v
                               messenger.html.twig --------> HTML表示
                               (バスタブ/メッセージ一覧)      (パネル/ツールバー/メニュー)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| messenger.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/messenger.html.twig` | テンプレート | パネルUI表示 |
| MessengerDataCollector.php | `src/Symfony/Component/Messenger/DataCollector/MessengerDataCollector.php` | ソース | メッセージデータの収集・集計 |
| TraceableMessageBus.php | `src/Symfony/Component/Messenger/TraceableMessageBus.php` | ソース | メッセージバスのトレース記録 |
| messenger.svg | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Icon/messenger.svg` | リソース | ツールバー・メニュー用アイコン |
| layout.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig` | テンプレート | プロファイラーレイアウト（親テンプレート） |
| chevron-down.svg | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Icon/chevron-down.svg` | リソース | トグルボタン用アイコン |
