# 画面設計書 132-Runner編集

## 概要

本ドキュメントは、GitLabにおけるプロジェクトレベルのRunner編集画面の設計を定義するものである。

### 本画面の処理概要

**業務上の目的・背景**：既存のプロジェクトRunnerの設定を変更する必要がある場合、この画面を使用する。Runnerの説明、タグ、アクセスレベル、タイムアウト設定などを更新することで、CI/CDパイプラインの実行条件やセキュリティ設定を調整できる。例えば、新しいジョブタイプに対応するためにタグを追加したり、セキュリティ要件の変更により保護ブランチのみの実行に切り替えたりする際に使用される。

**画面へのアクセス方法**：プロジェクト画面から「設定」>「CI/CD」>「Runners」セクションに移動し、対象Runnerの「編集」ボタンをクリック、またはRunner詳細画面から「Edit」ボタンをクリックすることでアクセスできる。URLパスは `/:namespace/:project/-/runners/:id/edit` となる。

**主要な操作・処理内容**：
1. Runnerの説明文を変更
2. ジョブマッチング用タグの追加・削除
3. アクセスレベル（保護ブランチのみ/すべてのブランチ）の変更
4. タグなしジョブの実行可否設定の変更
5. アクティブ/非アクティブ状態の切り替え
6. 最大タイムアウト時間の変更
7. メンテナンスノートの編集

**画面遷移**：
- 遷移元：Runner詳細画面、CI/CD設定画面（Runnersセクション）
- 遷移先：Runner詳細画面、CI/CD設定画面

**権限による表示制御**：対象Runnerに対する `update_runner` 権限を持つユーザーのみがこの画面にアクセスできる。プロジェクトの管理者権限が必要である。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 51 | Runnerレジストレーション | 主機能 | Runner設定の編集・更新処理 |

## 画面種別

編集

## URL/ルーティング

| メソッド | パス | コントローラ#アクション |
|---------|------|------------------------|
| GET | `/:namespace_id/:project_id/-/runners/:id/edit` | `projects/runners#edit` |
| PATCH/PUT | `/:namespace_id/:project_id/-/runners/:id` | `projects/runners#update` |

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 入出力 | バリデーション | 説明 |
|--------|--------|-----|------|--------|---------------|------|
| Runner ID | id | Integer | Yes | 入力 | Runner存在チェック | 編集対象のRunner ID |
| 説明 | description | String | No | 入出力 | 最大1024文字 | Runnerの説明文 |
| タグ | tag_list | Array | No | 入出力 | 最大50個 | ジョブマッチング用タグ |
| アクセスレベル | access_level | Enum | Yes | 入出力 | not_protected/ref_protected | 保護ブランチ制限 |
| タグなし実行 | run_untagged | Boolean | No | 入出力 | - | タグなしジョブの実行可否 |
| アクティブ | active | Boolean | No | 入出力 | - | Runnerの有効/無効 |
| ロック状態 | locked | Boolean | No | 入出力 | - | プロジェクトへのロック |
| 最大タイムアウト | maximum_timeout_human_readable | String | No | 入出力 | 10分以上 | ジョブの最大実行時間 |
| メンテナンスノート | maintenance_note | String | No | 入出力 | 最大1024文字 | 管理者向けメモ |

## 表示項目

この画面はVue.jsコンポーネント（`#js-project-runner-edit`）によりレンダリングされる。

| 項目名 | 説明 |
|--------|------|
| パンくずリスト | CI/CD Settings > Runner名 > Edit |
| ページタイトル | Edit {Runner短縮名} |
| Runner設定フォーム | Vueコンポーネントでレンダリング |

## イベント仕様

### 1-Runner更新

**トリガー**：Vueコンポーネント内の「Save changes」ボタンクリック

**処理フロー**：
1. フロントエンドでフォームのバリデーション実行
2. GraphQL Mutation `runnerUpdate` を呼び出し
3. Ci::Runners::UpdateRunnerService でRunner更新処理を実行
4. 更新成功時、Runner詳細画面にリダイレクト
5. 更新失敗時、エラーメッセージを表示

**データフロー**：
```
Vue Component -> GraphQL API -> Ci::Runners::UpdateRunnerService -> Ci::Runner (update)
```

### 2-キャンセル

**トリガー**：「Cancel」ボタンまたはパンくずリストクリック

**処理フロー**：
1. Runner詳細画面へリダイレクト

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Runner更新 | ci_runners | UPDATE | Runnerレコード更新 |
| タグ更新 | ci_runner_taggings | INSERT/DELETE | タグの追加・削除 |

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

#### ci_runners

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | description | 入力値 | 説明文 |
| UPDATE | access_level | 入力値 | 0=not_protected, 1=ref_protected |
| UPDATE | run_untagged | 入力値 | タグなしジョブ実行 |
| UPDATE | locked | 入力値 | ロック状態 |
| UPDATE | active | 入力値 | 有効/無効 |
| UPDATE | maximum_timeout | 入力値（秒変換） | 最大タイムアウト |
| UPDATE | maintainer_note | 入力値 | メンテナンスノート |
| UPDATE | updated_at | 現在時刻 | 更新日時 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 成功 | Runner was successfully updated. | Runner更新成功時 |
| MSG002 | エラー | Runner was not updated. | Runner更新失敗時 |
| MSG003 | エラー | Tags list can not be empty when runner is not allowed to pick untagged jobs | タグなし+untagged無効 |
| MSG004 | エラー | Too many tags specified. Please limit the number of tags to 50 | タグ数超過 |
| MSG005 | エラー | Maximum job timeout needs to be at least 10 minutes | タイムアウト10分未満 |

## 例外処理

| 例外条件 | 処理内容 | 遷移先 |
|---------|---------|--------|
| Runner未検出 | 404 Not Found | Not Found画面 |
| 権限不足 | 403 Forbidden | アクセス拒否画面 |
| バリデーションエラー | エラーメッセージ表示 | 同一画面 |

## 備考

- この画面はVue.jsコンポーネント（`#js-project-runner-edit`）によりレンダリングされる
- Runner IDとRunner詳細画面へのパスがdata属性で渡される
- FORM_EDITABLE定数により編集可能な項目が定義されている：description, tag_list, active, run_untagged, locked, access_level, maximum_timeout_human_readable
- maximum_timeout_human_readableは人間が読みやすい形式（例：「1h 30m」）で入力可能

---

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

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

### 推奨読解順序

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

Runnerモデルと編集可能な項目を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | runner.rb | `app/models/ci/runner.rb` | FORM_EDITABLE定数（行91）で編集可能項目を確認 |
| 1-2 | runner.rb | `app/models/ci/runner.rb` | バリデーション定義（行245-279）を確認 |

**読解のコツ**: `FORM_EDITABLE` 定数には `%i[description tag_list active run_untagged locked access_level maximum_timeout_human_readable]` が定義されており、これが編集フォームで変更可能な項目を表す。

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

ビューテンプレートとコントローラの処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | edit.html.haml | `app/views/projects/runners/edit.html.haml` | Vueコンポーネントのマウントポイント、data属性でrunner_idとrunner_pathを渡す |
| 2-2 | runners_controller.rb | `app/controllers/projects/runners_controller.rb` | before_action、権限チェック、editアクション |

**主要処理フロー**:
1. **行7**: `runner` メソッドでRunnerを取得
2. **行13-15**: `authorize_runner!(:update_runner)` で更新権限チェック
3. **行28**: `edit` アクションは空（ビューレンダリングのみ）

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

Runner更新のビジネスロジックを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | update_runner_service.rb | `app/services/ci/runners/update_runner_service.rb` | Runner更新のビジネスロジック |

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

```
projects/runners/edit.html.haml
    │
    └─ #js-project-runner-edit (Vue Component)
           │
           ├─ data: runner_id
           └─ data: runner_path
                  │
                  └─ GraphQL Mutation (runnerUpdate)
                         │
                         └─ Ci::Runners::UpdateRunnerService
                                │
                                └─ Ci::Runner.update
```

### データフロー図

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

Runner ID ──────▶ RunnersController#edit ──────▶ Vue Component mount
                           │
                           ▼
                    @runner 取得
                           │
Form Data ──────────────────────────────────▶ GraphQL Mutation
(description,                                        │
 tag_list,                                           ▼
 access_level, etc.)              Ci::Runners::UpdateRunnerService
                                                     │
                                                     ▼
                                        ci_runners (UPDATE)
                                                     │
                                                     ▼
                                        Runner詳細画面へリダイレクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| edit.html.haml | `app/views/projects/runners/edit.html.haml` | テンプレート | Runner編集画面のビュー |
| runners_controller.rb | `app/controllers/projects/runners_controller.rb` | コントローラ | HTTPリクエスト処理 |
| runner.rb | `app/models/ci/runner.rb` | モデル | Runnerエンティティ定義 |
| update_runner_service.rb | `app/services/ci/runners/update_runner_service.rb` | サービス | Runner更新ロジック |
| project.rb | `config/routes/project.rb` | ルーティング | URLルーティング定義（行102-107） |
| runners_helper.rb | `app/helpers/runners_helper.rb` | ヘルパー | runner_short_name等のヘルパーメソッド |
