# 画面設計書 5-ジョブ詳細

## 概要

本ドキュメントは、Apache Flink Web Dashboardのジョブ詳細画面の設計仕様を記述したものである。本画面は選択されたジョブの詳細情報を表示するコンテナ画面として機能し、各種タブ（概要、例外、タイムライン等）を管理する。

### 本画面の処理概要

ジョブ詳細画面は、特定のFlinkジョブに関する詳細情報を表示する親コンテナとして機能する。ジョブの基本情報（名前、状態、開始時刻等）を上部に表示し、タブナビゲーションにより各種詳細画面（Overview、Exceptions、Data Skew、TimeLine、Checkpoints、Configuration）への遷移を提供する。

**業務上の目的・背景**：個別ジョブの詳細な監視・分析を行うための中核画面である。運用者はジョブの実行状態、パフォーマンス問題、エラー情報など多角的な視点からジョブを分析し、問題の特定や最適化の判断を行うことができる。

**画面へのアクセス方法**：ジョブ一覧画面（実行中/完了済み）からジョブを選択してクリック、または`/job/running/:jobId`または`/job/completed/:jobId`パスに直接アクセスする。

**主要な操作・処理内容**：
1. ジョブ詳細情報の取得・表示
2. ジョブステータス情報のリアルタイム更新
3. タブナビゲーションによる子画面への遷移
4. ジョブのキャンセル操作（JobStatusComponentから）
5. エラー発生時の例外情報表示

**画面遷移**：
- 遷移元：実行中ジョブ一覧、完了済みジョブ一覧
- 遷移先（タブ内）：ジョブ概要、タイムライン、例外情報、データスキュー、チェックポイント、ジョブ設定

**権限による表示制御**：本画面に関しては、特別な権限制御は実装されていない。REST APIへのアクセス権があれば全ての情報が表示される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 32 | REST API | 主機能 | ジョブ詳細情報の取得（/jobs/{jobid} API） |
| 23 | ジョブ管理 | 補助機能 | ジョブのキャンセル操作 |

## 画面種別

詳細 / コンテナ

## URL/ルーティング

- パス: `/job/:status/:jid`
  - `:status` - running または completed
  - `:jid` - ジョブID
- 例: `/job/running/abc123def456`

## 入出力項目

| 項目名 | 種別 | データ型 | 説明 |
|--------|------|----------|------|
| jid | URLパラメータ | string | ジョブID |
| status | URLパラメータ | string | ジョブ状態区分（running/completed） |

## 表示項目

### ジョブステータスバー（JobStatusComponent）

| 項目名 | データ型 | 説明 | 取得元 |
|--------|----------|------|--------|
| ジョブ名 | string | ジョブの名前 | `/jobs/{jobid}` API |
| ジョブ状態 | string | 現在のジョブ状態 | `/jobs/{jobid}` API |
| 開始時刻 | timestamp | ジョブ開始日時 | `/jobs/{jobid}` API |
| 終了時刻 | timestamp | ジョブ終了日時（完了時） | `/jobs/{jobid}` API |
| 実行時間 | duration | 経過時間 | `/jobs/{jobid}` API |
| タスク統計 | object | タスク状態別カウント | `/jobs/{jobid}` API |

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

| タブ名 | パス | 説明 |
|--------|------|------|
| Overview | overview | DAGグラフ表示 |
| Exceptions | exceptions | 例外情報 |
| Data Skew | dataskew | データスキュー分析 |
| TimeLine | timeline | タイムライン表示 |
| Checkpoints | checkpoints | チェックポイント情報 |
| Configuration | configuration | ジョブ設定 |

## イベント仕様

### 1-画面初期化

**トリガー**: コンポーネント初期化時（ngOnInit）

**処理フロー**:
1. ActivatedRouteからjidパラメータを取得
2. StatusService.refresh$をサブスクライブ
3. JobService.loadJob()でジョブ詳細を取得
4. JobLocalServiceにジョブ詳細を設定（子コンポーネントへ共有）
5. エラー時はisErrorフラグを設定し、例外情報を取得

**API呼び出し**:
- GET `/jobs/{jobid}`
- GET `/jobs/{jobid}/exceptions?maxExceptions=10`（エラー時のみ）

### 2-自動リフレッシュ

**トリガー**: StatusServiceのrefresh$イベント発火

**処理フロー**:
1. 定期的にrefresh$イベントが発火
2. 最新のジョブ詳細を再取得
3. JobLocalServiceを通じて子コンポーネントに通知
4. 画面表示を更新

### 3-ジョブ取得エラー

**トリガー**: ジョブ詳細取得時のAPIエラー

**処理フロー**:
1. catchErrorでエラーをキャッチ
2. isErrorをtrueに設定
3. loadExceptions()で例外情報を取得
4. errorDetailsにroot-exceptionを設定
5. エラー情報を画面に表示

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

本画面自体はデータ参照のみを行う。ジョブキャンセル操作は子コンポーネント（JobStatusComponent）から実行される。

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

| 操作（イベント） | 対象 | 操作種別 | 概要 |
|----------------|------|---------|------|
| 画面表示 | - | SELECT | ジョブ詳細情報の取得 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| error-alert | エラー | APIから取得したエラー詳細 | ジョブ詳細取得失敗時 |

## 例外処理

| 例外種別 | 発生条件 | 処理内容 |
|----------|----------|----------|
| ジョブ取得エラー | `/jobs/{jobid}` APIエラー | isError=true、例外情報を取得して表示 |
| 例外情報取得エラー | `/jobs/{jobid}/exceptions` APIエラー | 例外情報なしで表示を継続 |

## 備考

- JobLocalServiceを使用して、子コンポーネントにジョブ詳細情報を共有
- ReplaySubjectを使用して、後から登録されたサブスクライバーにも最新データを提供
- スケルトンローディング（NzSkeletonModule）を使用してロード中表示を実現
- エラー時はNzAlertModuleでエラー情報を表示

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | job-detail.ts | `src/app/interfaces/job-detail.ts` | JobDetail型、JobDetailCorrect型の定義。ジョブ詳細のデータ構造を把握 |
| 1-2 | job-exception.ts | `src/app/interfaces/job-exception.ts` | 例外情報のデータ構造 |

**読解のコツ**: JobDetailCorrectはJobDetailを拡張し、planプロパティにlinks/streamNodes/streamLinksを追加している。これはサービス層で変換される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | job-detail.component.ts | `src/app/pages/job/job-detail/job-detail.component.ts` | メインコンポーネント。ngOnInit()が処理の起点 |

**主要処理フロー**:
1. **53-80行目**: ngOnInit()でデータ取得ストリーム構築
2. **57-58行目**: ActivatedRouteからjidを取得してloadJob()呼び出し
3. **59-61行目**: 取得成功時にJobLocalServiceにデータを設定
4. **62-72行目**: エラー時に例外情報を取得

#### Step 3: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | job.service.ts | `src/app/services/job.service.ts` | loadJob()メソッドとconvertJob()プライベートメソッド |
| 3-2 | job-local.service.ts | `src/app/pages/job/job-local.service.ts` | ジョブ詳細データの共有サービス |

**主要処理フロー**:
- **88-92行目** (job.service.ts): loadJob() - APIレスポンスをconvertJob()で変換
- **211-266行目** (job.service.ts): convertJob() - planノードとリンクの構築
- **36-67行目** (job-local.service.ts): ReplaySubjectを使用したデータ共有

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

```
JobDetailComponent
    │
    ├─ ActivatedRoute.snapshot.params.jid
    │
    ├─ StatusService.refresh$（イベント監視）
    │
    ├─ JobService
    │      ├─ loadJob() ──▶ GET /jobs/{jobid}
    │      │      └─ convertJob() ──▶ JobDetailCorrect変換
    │      │
    │      └─ loadExceptions() ──▶ GET /jobs/{jobid}/exceptions
    │
    ├─ JobLocalService
    │      └─ setJobDetail() ──▶ 子コンポーネントへデータ共有
    │
    ├─ JobStatusComponent（子）
    │      └─ ジョブステータス表示・操作
    │
    └─ RouterOutlet
           └─ 各タブの子コンポーネント
```

### データフロー図

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

URLパラメータ(jid) ────▶ JobDetailComponent
                              │
                              ▼
StatusService.refresh$ ───▶ JobService.loadJob()
                              │
                              ▼
                        /jobs/{jobid}
                              │
                              ▼
                        convertJob()
                              │
                              ▼
                        JobLocalService.setJobDetail()
                              │
                              ├─▶ JobStatusComponent（ヘッダー表示）
                              │
                              └─▶ 子コンポーネント（タブ内容）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| job-detail.component.ts | `src/app/pages/job/job-detail/job-detail.component.ts` | ソース | メインコンテナ |
| job-detail.component.html | `src/app/pages/job/job-detail/job-detail.component.html` | テンプレート | レイアウト定義 |
| job-status.component.ts | `src/app/pages/job/job-detail/status/job-status.component.ts` | ソース | ステータスバー |
| job-local.service.ts | `src/app/pages/job/job-local.service.ts` | ソース | データ共有サービス |
| job.service.ts | `src/app/services/job.service.ts` | ソース | ジョブ情報サービス |
| job-detail.ts | `src/app/interfaces/job-detail.ts` | 型定義 | ジョブ詳細型 |
| job.config.ts | `src/app/pages/job/job.config.ts` | 設定 | タブ設定 |
