# 画面設計書 4-完了済みジョブ一覧

## 概要

本ドキュメントは、Apache Flink Web Dashboardの完了済みジョブ一覧画面の設計仕様を記述したものである。本画面は完了した（成功・キャンセル・失敗）Flinkジョブを一覧表示する。

### 本画面の処理概要

完了済みジョブ一覧画面は、Flinkクラスターで完了したジョブを一覧表示する。完了状態にはFINISHED（成功）、CANCELED（キャンセル）、FAILED（失敗）の3種類が含まれる。ユーザーはジョブの実行結果を確認し、過去のジョブ詳細画面にアクセスできる。

**業務上の目的・背景**：バッチ処理やストリーム処理ジョブの実行履歴を確認することは、運用監視や障害分析において重要である。本画面により、過去に実行されたジョブの成功・失敗状況を把握し、失敗したジョブの詳細を確認して原因究明に役立てることができる。

**画面へのアクセス方法**：ナビゲーションメニューの「Completed Jobs」をクリックするか、`/job/completed`パスに直接アクセスする。

**主要な操作・処理内容**：
1. 完了済みジョブ一覧の自動取得・表示
2. ジョブ名、開始時刻、終了時刻、実行時間、状態でのソート
3. ジョブ行クリックによる詳細画面への遷移
4. 状態バッジによる視覚的な結果確認（成功=緑、失敗=赤など）

**画面遷移**：
- 遷移元：ナビゲーションメニュー、オーバービュー画面
- 遷移先：ジョブ詳細画面（`/job/completed/:jobId`）

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 32 | REST API | 主機能 | 完了済みジョブ一覧の取得・表示（/jobs/overview API） |
| 23 | ジョブ管理 | 補助機能 | ジョブステータス（FINISHED/FAILED/CANCELED）のフィルタリング |

## 画面種別

一覧

## URL/ルーティング

- パス: `/job/completed`

## 入出力項目

| 項目名 | 種別 | データ型 | 説明 |
|--------|------|----------|------|
| なし | - | - | 本画面は入力項目を持たない（表示専用） |

## 表示項目

### ジョブ一覧テーブル

| 項目名 | データ型 | 説明 | ソート可能 | 取得元 |
|--------|----------|------|------------|--------|
| Job Name | string | ジョブ名 | 可 | `/jobs/overview` API |
| State | string | ジョブ終了状態（FINISHED/FAILED/CANCELED） | 可 | `/jobs/overview` API |
| Start Time | timestamp | ジョブ開始日時 | 可 | `/jobs/overview` API |
| End Time | timestamp | ジョブ終了日時 | 可 | `/jobs/overview` API |
| Duration | duration | 実行時間 | 可 | `/jobs/overview` API |
| Tasks | object | タスク状態別カウント | 不可 | `/jobs/overview` API |

## イベント仕様

### 1-画面初期化

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

**処理フロー**:
1. ActivatedRouteからURLパスを解析
2. isCompletedフラグをtrueに設定（completed）
3. StatusService.refresh$をサブスクライブ
4. JobService.loadJobs()でジョブ一覧を取得
5. completed=trueでフィルタリングして表示

**API呼び出し**:
- GET `/jobs/overview`

**フィルタリング条件**:
- state が 'FINISHED', 'FAILED', 'CANCELED' のいずれか
- job.completed === true

### 2-ジョブ行クリック

**トリガー**: ジョブ一覧の行をクリック

**処理フロー**:
1. ジョブ状態をチェック（完了済みジョブは全て遷移可能）
2. ジョブIDを取得してnavigate()を呼び出し
3. 親コンポーネント（JobComponent）がジョブ詳細画面に遷移

**遷移先**: `/job/completed/{jobId}`

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

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

**処理フロー**:
1. 定期的にrefresh$イベントが発火
2. 最新のジョブ一覧を再取得
3. フィルタリングを適用して画面表示を更新

### 4-ソート操作

**トリガー**: テーブルヘッダーのソートアイコンクリック

**処理フロー**:
1. 選択されたカラムに応じたソート関数を適用
2. 一覧を並び替えて再表示

**ソート関数**:
- sortJobNameFn: ジョブ名でソート（文字列比較）
- sortStartTimeFn: 開始時刻でソート（数値比較）
- sortEndTimeFn: 終了時刻でソート（数値比較）
- sortDurationFn: 実行時間でソート（数値比較）
- sortStateFn: 状態でソート（文字列比較）

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

本画面はデータ参照のみを行い、データベースへの更新処理は発生しない。

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 該当なし | - | SELECT | 全ての操作は参照のみ |

## メッセージ仕様

本画面では明示的なメッセージ表示は行われない。

## 例外処理

| 例外種別 | 発生条件 | 処理内容 |
|----------|----------|----------|
| API通信エラー | REST APIへの接続失敗 | catchError演算子でEMPTYを返却 |
| データ取得エラー | サーバーからのレスポンスエラー | 同上 |

## 備考

- No.3「実行中ジョブ一覧」と同一のコンポーネント構成（JobComponent + JobListComponent）を使用
- URLパスの「completed」セグメントによりisCompletedフラグがtrueになる
- 完了済みジョブはINITIALIZING状態のチェックが不要（常に詳細画面に遷移可能）
- JobBadgeComponentでジョブ状態を色分け表示（FINISHED=緑、FAILED=赤、CANCELED=黄）

---

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

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

### 推奨読解順序

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

No.3「実行中ジョブ一覧」と同一のデータ構造を使用する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | job-overview.ts | `src/app/interfaces/job-overview.ts` | JobsItem型のcompletedプロパティに注目。フィルタリングの判定基準 |

**読解のコツ**: completed属性はサービス層で追加される派生プロパティであり、元のAPIレスポンスには含まれない。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | job.component.ts | `src/app/pages/job/job.component.ts` | 75行目のisCompleted判定ロジック |
| 2-2 | job-list.component.ts | `src/app/components/job-list/job-list.component.ts` | 103行目のフィルタリング条件 |

**主要処理フロー**:
1. **75行目** (job.component.ts): `segments[1].path === 'completed'`でcompletedを判別
2. **103行目** (job-list.component.ts): `item.completed === this.completed`でフィルタ

#### Step 3: サービス層のデータ変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | job.service.ts | `src/app/services/job.service.ts` | 76行目のcompleted属性追加ロジック |

**主要処理フロー**:
- **76行目**: `['FINISHED', 'FAILED', 'CANCELED'].indexOf(job.state) > -1`でcompleted判定

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

```
JobComponent（親）
    │
    ├─ ActivatedRoute（URLパス解析）
    │      └─ path === 'completed' → isCompleted = true
    │
    └─ JobListComponent（子）
           │
           ├─ StatusService.refresh$（イベント監視）
           │
           └─ JobService.loadJobs()
                  │
                  ├─ HttpClient.get('/jobs/overview')
                  │
                  └─ map(): completed属性を追加
```

### データフロー図

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

URLパス ───────────────▶ JobComponent ──────────▶ isCompleted=true
                              │
                              ▼
StatusService.refresh$ ───▶ JobListComponent
                              │
                              ▼
                        JobService.loadJobs()
                              │
                              ▼
                        /jobs/overview
                              │
                              ▼
                        completed=trueでフィルタ ──▶ ジョブ一覧表示
                        (FINISHED/FAILED/CANCELED)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| job.component.ts | `src/app/pages/job/job.component.ts` | ソース | 親コンテナコンポーネント |
| job.component.html | `src/app/pages/job/job.component.html` | テンプレート | 条件分岐とルーターアウトレット |
| job-list.component.ts | `src/app/components/job-list/job-list.component.ts` | ソース | ジョブ一覧コンポーネント |
| job-list.component.html | `src/app/components/job-list/job-list.component.html` | テンプレート | 一覧テーブルレイアウト |
| job.service.ts | `src/app/services/job.service.ts` | ソース | ジョブ情報サービス |
| job-overview.ts | `src/app/interfaces/job-overview.ts` | 型定義 | ジョブ型定義 |
| job-badge.component.ts | `src/app/components/job-badge/job-badge.component.ts` | ソース | 状態バッジコンポーネント |
| task-badge.component.ts | `src/app/components/task-badge/task-badge.component.ts` | ソース | タスクバッジコンポーネント |
