# 画面設計書 161-Runner一覧

## 概要

本ドキュメントはGitLabのグループRunner一覧画面の設計仕様を記載したものである。

### 本画面の処理概要

グループに関連付けられたCI/CD Runnerの一覧を表示・管理する画面である。グループ管理者やRunner管理権限を持つユーザーが、グループレベルでRunnerの状態確認、フィルタリング、新規登録への遷移を行える。

**業務上の目的・背景**：CI/CDパイプラインを実行するためにはRunnerが必要であり、グループ単位でRunnerを共有・管理することで、複数プロジェクトで効率的にCI/CDリソースを活用できる。本画面により、グループ配下のすべてのプロジェクトで利用可能なRunnerの状態監視と管理が一元化される。

**画面へのアクセス方法**：グループメニュー > Build > Runners からアクセスする。または直接URL `/{group_path}/-/runners` にアクセスする。

**主要な操作・処理内容**：
1. Runnerの一覧表示（ステータス、タグ、最終接続時刻等）
2. ステータス（オンライン/オフライン/未接続/古い）によるフィルタリング
3. Runnerタイプ（グループ/プロジェクト）によるフィルタリング
4. 検索文字列によるRunner検索
5. 新規Runner作成画面への遷移
6. Runner詳細・編集画面への遷移

**画面遷移**：
- 遷移元：グループトップページ、グループ設定画面
- 遷移先：Runner詳細画面、Runner新規登録画面、Runner編集画面

**権限による表示制御**：
- `read_runners`権限：一覧表示・詳細閲覧が可能
- `create_runners`権限：新規Runner作成ボタンが表示される
- `register_group_runners`権限：登録トークンが表示される

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 51 | Runnerレジストレーション | 主機能 | グループRunnerの一覧表示 |

## 画面種別

一覧

## URL/ルーティング

- パス: `/{group_path}/-/runners`
- コントローラー: `Groups::RunnersController#index`
- HTTPメソッド: GET

## 入出力項目

| 項目名 | 項目ID | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|--------|----------|------|------|
| グループID | group_id | 入力 | Integer | 必須 | 対象グループのID |
| 検索クエリ | search | 入力 | String | 任意 | Runner検索文字列 |
| ステータスフィルター | status | 入力 | String | 任意 | online/offline/never_contacted/stale |
| タイプフィルター | type | 入力 | String | 任意 | group_type/project_type |
| ページ番号 | page | 入力 | Integer | 任意 | ページネーション用 |

## 表示項目

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| ステータスアイコン | ci_runners.contacted_at | オンライン/オフライン等の状態 |
| Runner ID | ci_runners.id | Runner識別子（#番号形式） |
| 説明 | ci_runners.description | Runnerの説明文 |
| バージョン | ci_runner_managers.version | Runnerのバージョン |
| タグ | ci_tags | 関連付けられたタグ一覧 |
| プロジェクト数 | ci_runner_projects | 関連プロジェクト数 |
| 最終接続 | ci_runners.contacted_at | 最後にRunnerが接続した時刻 |
| トークン有効期限 | ci_runners.token_expires_at | 認証トークンの有効期限 |

## イベント仕様

### 1-新規Runner作成ボタン押下

新規Runner作成画面へ遷移する。

- トリガー: 「New group runner」ボタンクリック
- 遷移先: `/{group_path}/-/runners/new`
- 条件: `create_runners`権限を持つ場合のみ表示

### 2-Runner行クリック

Runner詳細画面へ遷移する。

- トリガー: Runner行クリック
- 遷移先: `/{group_path}/-/runners/{runner_id}`

### 3-フィルター変更

フィルター条件に基づいてRunner一覧を再取得する。

- トリガー: ステータスタブ変更、タイプフィルター変更、検索実行
- 処理: GraphQL APIでRunner一覧を再取得

### 4-ページ変更

指定ページのRunner一覧を取得する。

- トリガー: ページネーションコントロール操作
- 処理: GraphQL APIでページング処理

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 一覧表示 | ci_runners | SELECT | Runner一覧の取得 |
| 一覧表示 | ci_runner_namespaces | SELECT | グループとの関連取得 |
| 一覧表示 | ci_runner_projects | SELECT | プロジェクト関連数の取得 |
| 一覧表示 | ci_tags | SELECT | タグ情報の取得 |

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

#### ci_runners

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, description, active, contacted_at, token_expires_at | runner_namespaces.namespace_idがグループ階層に含まれる | グループおよび子グループのRunner |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| MSG001 | 情報 | No runners found | Runner一覧が空の場合 |
| MSG002 | 警告 | Runner is stale; last contact was X ago | Runnerが7日以上未接続の場合 |
| MSG003 | エラー | Something went wrong. Please try again. | API通信エラー発生時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 権限不足 | 404ページを表示 |
| グループ未存在 | 404ページを表示 |
| API通信エラー | エラーメッセージを表示し再試行を促す |

## 備考

- 本画面はVue.jsコンポーネント（GroupRunnersApp）によるSPA構成
- データ取得はGraphQL APIを使用
- Runner登録トークンは`allow_runner_registration_token?`設定に依存
- ステータスはRunnerの最終接続時刻から自動計算される

---

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

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

### 推奨読解順序

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

まず、Runnerのデータモデルを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | runner.rb | `app/models/ci/runner.rb` | Runnerモデルの定義、ステータス計算ロジック、スコープ定義を確認 |

**読解のコツ**: `enum :runner_type`（行43-47）でRunnerタイプ、`AVAILABLE_STATUSES`（行87）でステータス種別を確認。`scope :belonging_to_group`（行148-150）でグループ所属判定ロジックを確認。

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

HAMLテンプレートとコントローラーの処理起点を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.html.haml | `app/views/groups/runners/index.html.haml` | Vueアプリケーションのマウントポイント定義 |
| 2-2 | runners_controller.rb | `app/controllers/groups/runners_controller.rb` | indexアクションでの権限チェックとデータ準備 |

**主要処理フロー**:
1. **行3**: `#js-group-runners`要素にVueアプリをマウント
2. **行17-24**: コントローラーでregistration_token、new_runner_pathを設定

#### Step 3: フロントエンド初期化を理解する

Vue.jsアプリケーションの初期化処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.js | `app/assets/javascripts/pages/groups/runners/index/index.js` | エントリーポイント |
| 3-2 | index.js | `app/assets/javascripts/ci/runner/group_runners/index.js` | Vueアプリ初期化 |

**主要処理フロー**:
- **行16-53**: `initGroupRunners`関数でApolloクライアント設定、Vueインスタンス作成

#### Step 4: ヘルパー関数を理解する

テンプレートに渡すデータ属性の生成ロジックを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | runners_helper.rb | `app/helpers/ci/runners_helper.rb` | `group_runners_data_attributes`メソッド（行128-136） |

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

```
Groups::RunnersController#index
    │
    ├─ authorize_read_runners! (認可チェック)
    │
    ├─ group_runners_data_attributes (ヘルパー)
    │      └─ Ci::Runner::ONLINE_CONTACT_TIMEOUT
    │      └─ Ci::Runner::STALE_TIMEOUT
    │
    └─ View: index.html.haml
           └─ JavaScript: initGroupRunners()
                  └─ Vue: GroupRunnersApp
                         └─ GraphQL: getGroupRunnersQuery
```

### データフロー図

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

URLリクエスト ───▶ RunnersController#index ───▶ HAMLテンプレート
                         │
                         ▼
                  認可チェック
                         │
                         ▼
                  data属性設定
                         │
                         ▼
                  Vue初期化 ───▶ GraphQL API ───▶ Runner一覧表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.html.haml | `app/views/groups/runners/index.html.haml` | テンプレート | Vueマウントポイント定義 |
| runners_controller.rb | `app/controllers/groups/runners_controller.rb` | コントローラー | リクエスト処理・認可 |
| runner.rb | `app/models/ci/runner.rb` | モデル | Runnerデータ定義 |
| runners_helper.rb | `app/helpers/ci/runners_helper.rb` | ヘルパー | データ属性生成 |
| index.js | `app/assets/javascripts/ci/runner/group_runners/index.js` | JavaScript | Vue初期化 |
| group_runners_app.vue | `app/assets/javascripts/ci/runner/group_runners/group_runners_app.vue` | Vue | メインコンポーネント |
