# 画面設計書 262-ジョブ一覧

## 概要

本ドキュメントは、GitLab管理者エリアにおける「ジョブ一覧」画面の設計を記載したものです。システム全体のCI/CDジョブを一元的に監視・管理するための画面です。

### 本画面の処理概要

**業務上の目的・背景**：大規模なGitLabインスタンスでは、多数のプロジェクトで同時にCI/CDパイプラインが実行されています。管理者は、システム全体のジョブの実行状況を把握し、必要に応じて問題のあるジョブをキャンセルしたり、リソース使用状況を監視したりする必要があります。本画面は、全プロジェクトのジョブを横断的に管理するための統合ビューを提供します。

**画面へのアクセス方法**：管理者エリア > CI/CD > ジョブ、または `/admin/jobs` に直接アクセスします。管理者権限が必要です。

**主要な操作・処理内容**：
1. 全プロジェクトのジョブ一覧表示（ステータス別フィルタリング可能）
2. ジョブの詳細情報の確認（ステータス、プロジェクト、パイプライン等）
3. 実行中・保留中の全ジョブの一括キャンセル
4. ジョブのRunner種別によるフィルタリング（フィーチャーフラグ有効時）
5. 個別ジョブの詳細画面への遷移

**画面遷移**：
- 遷移元：管理者ダッシュボード、サイドバーナビゲーション
- 遷移先：個別ジョブ詳細画面、プロジェクト詳細画面、パイプライン詳細画面

**権限による表示制御**：管理者権限を持つユーザーのみがアクセス可能です。「全てキャンセル」ボタンは `can_admin_all_resources?` が true の場合のみ有効になります。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 116 | ジョブ管理 | 主機能 | システムジョブの一覧表示・キャンセル処理 |
| 48 | ジョブ管理 | 補助機能 | 個別ジョブの詳細表示 |

## 画面種別

一覧

## URL/ルーティング

- URL: `/admin/jobs`
- HTTPメソッド: GET（一覧表示）、POST（全キャンセル）
- コントローラー: `Admin::JobsController#index`, `Admin::JobsController#cancel_all`

## 入出力項目

### フィルター項目

| 項目名 | 物理名 | 型 | 説明 |
|--------|--------|-----|------|
| ステータス | status | String | ジョブのステータスでフィルタ |
| Runner種別 | runner_type | String | Runner種別でフィルタ（フィーチャーフラグ有効時） |

### フィルター値（ステータス）

| 値 | 説明 |
|-----|------|
| pending | 保留中 |
| running | 実行中 |
| finished | 完了 |
| canceled | キャンセル済み |
| failed | 失敗 |
| success | 成功 |

## 表示項目

### ジョブ一覧

| 項目名 | 説明 |
|--------|------|
| ステータス | ジョブの実行ステータス（アイコン表示） |
| ジョブID | ジョブの識別子 |
| プロジェクト | ジョブが属するプロジェクト名 |
| コミット | 関連するコミットのSHA（短縮形） |
| ステージ | パイプライン内のステージ名 |
| 名前 | ジョブ名 |
| Runner | 実行したRunnerの情報 |
| 期間 | ジョブの実行時間 |
| カバレッジ | コードカバレッジ率（該当する場合） |

## イベント仕様

### 1-ジョブ一覧取得

**トリガー**: 画面表示時、フィルター変更時

**処理フロー**:
1. VueコンポーネントがGraphQL APIを呼び出し
2. ステータスフィルターに基づいてジョブを取得
3. ページネーション付きで結果を表示

### 2-全ジョブキャンセル

**トリガー**: 「Cancel all jobs」ボタン押下

**処理フロー**:
1. POSTリクエストを `/admin/jobs/cancel_all` に送信
2. `Ci::Build.running_or_pending` を取得
3. 各ジョブに対して `cancel` メソッドを実行
4. ジョブ一覧画面にリダイレクト

### 3-ステータスフィルタリング

**トリガー**: ステータスドロップダウンの選択変更

**処理フロー**:
1. 選択されたステータスでGraphQLクエリを再実行
2. フィルターされた結果を表示
3. URL パラメータを更新

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 一覧表示 | ci_builds | SELECT | ジョブ情報の取得 |
| 全ジョブキャンセル | ci_builds | UPDATE | ステータスをcanceledに更新 |

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

#### ci_builds

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | status, project_id等 | フィルター条件に基づく |
| UPDATE | status | canceled | キャンセル処理時 |
| UPDATE | finished_at | 現在時刻 | キャンセル処理時 |

## メッセージ仕様

| 種別 | 条件 | メッセージ |
|------|------|----------|
| 空状態 | ジョブが存在しない場合 | 空状態のSVG画像とメッセージを表示 |

## 例外処理

| 状態 | 処理 |
|------|------|
| 権限不足 | アクセス拒否画面にリダイレクト |
| API エラー | エラーメッセージを表示 |

## 備考

- 画面はVueコンポーネント（`#admin-jobs-app`）で実装されている
- ジョブデータはGraphQL APIを通じて取得される
- `admin_jobs_filter_runner_type` フィーチャーフラグが有効な場合、Runner種別フィルターが利用可能
- 1ページあたり30件のジョブを表示（`BUILDS_PER_PAGE`定数）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | build.rb | `app/models/ci/build.rb` | ジョブ（ビルド）モデルの属性とスコープ |
| 1-2 | processable.rb | `app/models/ci/processable.rb` | ステータス管理の親クラス |

**読解のコツ**: `state_machine`の定義でジョブのステータス遷移を理解する。`running_or_pending`スコープがキャンセル対象の取得に使用される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | jobs_controller.rb | `app/controllers/admin/jobs_controller.rb` | indexとcancel_allアクション |
| 2-2 | jobs_helper.rb | `app/helpers/admin/jobs_helper.rb` | Vueコンポーネントに渡すデータ |

**主要処理フロー**:
1. **行13**: `index`アクション - Vueコンポーネントをレンダリング
2. **行15-18**: `cancel_all`アクション - 実行中・保留中の全ジョブをキャンセル
3. **行5-12**: `admin_jobs_app_data` - Vueに渡すデータ構造

#### Step 3: ビューを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/admin/jobs/index.html.haml` | シンプルなVueマウントポイント |

**主要処理フロー**:
- **行1**: ページ固有スタイルの読み込み
- **行7**: `#admin-jobs-app` - Vueコンポーネントのマウントポイント

#### Step 4: フロントエンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | admin_jobs_app.vue | `app/assets/javascripts/ci/admin/jobs_table/admin_jobs_app.vue` | メインVueコンポーネント |
| 4-2 | graphql queries | `app/assets/javascripts/ci/admin/jobs_table/graphql/` | データ取得クエリ |

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

```
Admin::JobsController#index
    │
    └─ admin_jobs_app_data (helper)
           ├─ job_statuses
           ├─ image_path (empty state SVG)
           ├─ cancel_all_admin_jobs_path
           └─ can_admin_all_resources?

Admin::JobsController#cancel_all
    │
    └─ Ci::Build.running_or_pending.each(&:cancel)
           └─ Ci::Build#cancel
```

### データフロー図

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

ページ表示 ─────────▶ admin_jobs_app_data ──────────▶ Vue props

status filter ────────▶ GraphQL Query ────────────▶ Job list

Cancel All ───────────▶ cancel_all action ────────▶ redirect
                              │
                              └─ Build.running_or_pending
                                    └─ each(&:cancel)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| jobs_controller.rb | `app/controllers/admin/jobs_controller.rb` | コントローラー | リクエスト処理 |
| jobs_helper.rb | `app/helpers/admin/jobs_helper.rb` | ヘルパー | Vueデータ生成 |
| index.html.haml | `app/views/admin/jobs/index.html.haml` | テンプレート | 画面表示 |
| build.rb | `app/models/ci/build.rb` | モデル | ジョブデータモデル |
| admin.rb | `config/routes/admin.rb` | ルーティング | URL定義 |
| ci_status.scss | `app/assets/stylesheets/page_bundles/ci_status.scss` | スタイル | ステータス表示用CSS |
