# 画面設計書 13-頂点詳細ドロワー

## 概要

本ドキュメントは、Apache Flink Web Dashboardの「頂点詳細ドロワー」画面の設計仕様を記載したものである。DAGグラフで選択した頂点（オペレーター）の詳細情報を表示するドロワーパネルのコンテナコンポーネント。

### 本画面の処理概要

頂点詳細ドロワー画面は、ジョブ概要画面（DAGグラフ）で特定の頂点（オペレーター）を選択した際に画面右側からスライドインするドロワーパネルである。選択された頂点の詳細情報、サブタスク一覧、TaskManager一覧、ウォーターマーク、アキュムレーター、メトリクス、バックプレッシャー、フレームグラフなどの情報を、タブナビゲーションで切り替えて表示するコンテナとしての役割を果たす。

**業務上の目的・背景**：Apache Flinkのストリーム処理では、ジョブは複数のオペレーター（頂点）から構成されるDAG（有向非巡回グラフ）として表現される。各オペレーターの実行状況、パフォーマンス、ボトルネックを詳細に分析するためには、オペレーター単位での情報確認が不可欠である。本ドロワーにより、運用担当者はDAGグラフを見ながら特定のオペレーターを選択し、その詳細情報を即座に確認できる。

**画面へのアクセス方法**：ジョブ詳細画面のOverviewタブ（DAGグラフ表示）で、グラフ上の任意の頂点（ノード）をクリックすることでドロワーが開く。

**主要な操作・処理内容**：
1. DAGグラフ上の頂点クリック時にドロワーがスライドインアニメーションで表示
2. URLパラメータから頂点IDを取得し、JobLocalServiceに選択された頂点を設定
3. タブナビゲーションにより各子画面（Detail, SubTasks, TaskManagers等）を切り替え
4. 閉じるボタンでドロワーを閉じて親画面（DAGグラフ）に戻る
5. 全画面ボタンでドロワーを全幅に拡大

**画面遷移**：
- 遷移元：ジョブ概要画面（DAGグラフ）
- 遷移先（タブ内）：頂点詳細、サブタスク一覧、TaskManager一覧、ウォーターマーク、アキュムレーター、メトリクスチャート、バックプレッシャー、フレームグラフ
- 戻り先：ジョブ概要画面（DAGグラフ）

**権限による表示制御**：特になし。認証されたユーザーであれば閲覧可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 32 | REST API | 主機能 | 選択した頂点（オペレーター）の詳細情報取得 |
| 23 | ジョブ管理 | 補助機能 | サブタスク、TaskManager、メトリクス等の子画面への遷移制御 |

## 画面種別

コンテナ（ドロワーパネル）

## URL/ルーティング

- パス: `/job/running/:jid/overview/:vertexId` または `/job/completed/:jid/overview/:vertexId`
- ルートパラメータ:
  - `jid` - ジョブID
  - `vertexId` - 頂点（オペレーター）ID

## 入出力項目

### 入力項目

| 項目名 | 項目ID | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| ジョブID | jid | string | 必須 | URLパラメータから取得されるジョブ識別子 |
| 頂点ID | vertexId | string | 必須 | URLパラメータから取得される頂点識別子 |

## 表示項目

### タブナビゲーション

| タブ名 | パス | 子コンポーネント | 説明 |
|--------|------|-----------------|------|
| Detail | detail | JobOverviewDrawerDetailComponent | 頂点の基本情報 |
| SubTasks | subtasks | JobOverviewDrawerSubtasksComponent | サブタスク一覧 |
| TaskManagers | taskmanagers | JobOverviewDrawerTaskmanagersComponent | TaskManager一覧 |
| Watermarks | watermarks | JobOverviewDrawerWatermarksComponent | ウォーターマーク情報 |
| Accumulators | accumulators | JobOverviewDrawerAccumulatorsComponent | アキュムレーター情報 |
| BackPressure | backpressure | JobOverviewDrawerBackpressureComponent | バックプレッシャー状態 |
| Metrics | metrics | JobOverviewDrawerChartComponent | メトリクスチャート |
| FlameGraph | flamegraph | JobOverviewDrawerFlameGraphComponent | フレームグラフ |

### 操作ボタン

| ボタン | アイコン | 処理 |
|--------|---------|------|
| 閉じる | right | ドロワーを閉じる（全画面時は縮小） |
| 全画面 | left | ドロワーを全幅に拡大 |

## イベント仕様

### 1-ドロワー開始（頂点選択時）

**トリガー**: DAGグラフ上の頂点クリック

**処理フロー**:
1. Angularルーターにより頂点IDを含むURLに遷移
2. ドロワーコンポーネントが初期化され、@drawerアニメーションでスライドイン
3. ngOnInit()でActivatedRouteからvertexIdを取得
4. JobLocalServiceからジョブ詳細を取得し、nodes配列から該当頂点を検索
5. 見つかった頂点をJobLocalService.setSelectedVertex()で設定
6. 子ルートがない場合、デフォルトタブ（detail）にナビゲート

### 2-閉じるボタン押下

**トリガー**: 閉じるボタン（rightアイコン）クリック

**処理フロー**:
1. fullScreenがtrueの場合
   - fullScreenをfalseに設定
   - JobChartService.resize()を呼び出し
2. fullScreenがfalseの場合
   - router.navigate(['../../'])で親画面に戻る

### 3-全画面ボタン押下

**トリガー**: 全画面ボタン（leftアイコン）クリック

**処理フロー**:
1. fullScreenをtrueに設定
2. JobChartService.resize()を呼び出し、チャートをリサイズ

### 4-コンポーネント破棄時

**トリガー**: ドロワーが閉じられた時（ngOnDestroy）

**処理フロー**:
1. JobLocalService.setSelectedVertex(null)で選択状態をクリア
2. destroy$.next()とdestroy$.complete()でサブスクリプションをクリーンアップ

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | 本画面はデータベースへの更新処理なし |

本画面はコンテナコンポーネントであり、データベースへの直接アクセスは行わない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|--------------|----------|
| - | - | - | 本画面にはメッセージ表示機能なし |

## 例外処理

| 例外状況 | 対応 | 表示 |
|---------|------|------|
| 指定された頂点IDが存在しない | setSelectedVertex(null) | 空のドロワー表示 |

## 備考

- Angularのアニメーショントリガー（@drawer）によりスライドイン/アウトアニメーションを実現
- JOB_OVERVIEW_MODULE_CONFIGによりタブナビゲーションの項目がカスタマイズ可能
- fullScreenプロパティにより全幅表示モードをサポート
- router-outletにより子コンポーネントを動的に読み込み

---

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

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

### 推奨読解順序

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

まず、頂点情報のデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | plan.ts | `flink-runtime-web/web-dashboard/src/app/interfaces/plan.ts` | NodesItemCorrectインターフェース。頂点のid, description, detailなどの構造 |

**読解のコツ**: NodesItemCorrectはDAGグラフの各ノード（頂点）を表現し、job_vertex_id、inputs、detailなどのプロパティを持つ。

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

処理の起点となるコンポーネントファイルを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | job-overview-drawer.component.ts | `flink-runtime-web/web-dashboard/src/app/pages/job/overview/drawer/job-overview-drawer.component.ts` | コンポーネントのアニメーション定義、ライフサイクル、ナビゲーション制御 |

**主要処理フロー**:
1. **41-52行目**: @drawerアニメーショントリガー定義（スライドイン/アウト）
2. **76-77行目**: コンストラクタでモジュール設定からタブナビゲーションを取得
3. **80-93行目**: ngOnInit()でvertexIdとjobDetailを監視し、選択頂点を設定
4. **102-109行目**: closeDrawer()で全画面解除またはドロワーを閉じる
5. **111-114行目**: fullDrawer()で全画面モードに切り替え

#### Step 3: ローカルサービスを理解する

頂点選択状態を管理するサービスを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | job-local.service.ts | `flink-runtime-web/web-dashboard/src/app/pages/job/job-local.service.ts` | selectedVertex$とsetSelectedVertex()の実装 |

**主要処理フロー**:
- **39行目**: selectedVertex$がReplaySubject<NodesItemCorrect | null>として定義
- **61-63行目**: selectedVertexChanges()がObservableを返却
- **65-67行目**: setSelectedVertex()で選択頂点を設定

#### Step 4: ルーティング設定を理解する

ドロワー内のタブルーティングを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | routes.ts | `flink-runtime-web/web-dashboard/src/app/pages/job/overview/routes.ts` | :vertexIdパラメータと子ルート（detail, subtasks等）の定義 |

**主要処理フロー**:
- **30-31行目**: :vertexIdパラメータでドロワーコンポーネントを表示
- **33-108行目**: 各タブに対応するルート定義（detail, subtasks, taskmanagers, watermarks, accumulators, metrics, backpressure, flamegraph）

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

```
JobOverviewDrawerComponent
    │
    ├─ ngOnInit()
    │      ├─ ActivatedRoute.params (vertexId取得)
    │      │
    │      └─ combineLatest([jobDetailChanges(), nodeId$])
    │             ├─ JobLocalService.jobDetailChanges()
    │             │      └─ ReplaySubject<JobDetailCorrect>
    │             │
    │             └─ JobLocalService.setSelectedVertex(node)
    │
    ├─ closeDrawer()
    │      ├─ fullScreen = false
    │      ├─ JobChartService.resize()
    │      └─ router.navigate(['../../'])
    │
    ├─ fullDrawer()
    │      ├─ fullScreen = true
    │      └─ JobChartService.resize()
    │
    └─ ngOnDestroy()
           └─ JobLocalService.setSelectedVertex(null)
```

### データフロー図

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

頂点ID ───▶ ActivatedRoute.params ───▶ JobLocalService
 (URL)                                   ├─ setSelectedVertex()
                                         └─ 子コンポーネントに通知
    │
    ▼
ジョブ詳細 ───▶ JobLocalService.jobDetailChanges()
                     │
                     ▼
              plan.nodes.find(id === vertexId)
                     │
                     ▼
              選択された頂点をstateに保持

                     │
                     ▼
              router-outlet ───▶ 子コンポーネント
                                 (Detail/SubTasks/TaskManagers等)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| job-overview-drawer.component.ts | `flink-runtime-web/web-dashboard/src/app/pages/job/overview/drawer/job-overview-drawer.component.ts` | ソース | メインコンポーネント |
| job-overview-drawer.component.html | `flink-runtime-web/web-dashboard/src/app/pages/job/overview/drawer/job-overview-drawer.component.html` | テンプレート | 画面レイアウト定義 |
| job-overview-drawer.component.less | `flink-runtime-web/web-dashboard/src/app/pages/job/overview/drawer/job-overview-drawer.component.less` | スタイル | スタイル定義 |
| job-local.service.ts | `flink-runtime-web/web-dashboard/src/app/pages/job/job-local.service.ts` | サービス | ジョブ・頂点状態管理 |
| job-overview.config.ts | `flink-runtime-web/web-dashboard/src/app/pages/job/overview/job-overview.config.ts` | 設定 | タブナビゲーション設定 |
| routes.ts | `flink-runtime-web/web-dashboard/src/app/pages/job/overview/routes.ts` | 設定 | ルーティング定義 |
| navigation.component.ts | `flink-runtime-web/web-dashboard/src/app/components/navigation/navigation.component.ts` | 共通コンポーネント | タブナビゲーション |
