# 画面設計書 77-環境一覧

## 概要

本ドキュメントは、GitLabの環境（Environments）一覧画面の設計を記述したものである。

### 本画面の処理概要

**業務上の目的・背景**：環境一覧画面は、プロジェクトのデプロイ環境（development、staging、production等）を一元管理するための画面である。CI/CDパイプラインによるデプロイ先を定義・管理し、各環境へのデプロイ状況、環境の状態（利用可能/停止中）、自動停止設定などを可視化する。継続的デリバリーにおける環境管理の中核機能である。

**画面へのアクセス方法**：プロジェクト画面の左サイドメニューから「Operate」>「Environments」を選択、またはURL直接アクセス（`/:namespace/:project/-/environments`）によりアクセスする。

**主要な操作・処理内容**：
1. 環境一覧の表示（アクティブ/停止済みのタブ切り替え）
2. 新規環境の作成
3. 環境の停止
4. 環境の削除
5. 環境のフォルダ表示（同一プレフィックスでグループ化）
6. 環境の検索
7. Review Appの有効化
8. 古い環境のクリーンアップ

**画面遷移**：
- 遷移元：プロジェクトダッシュボード、パイプライン詳細画面、ジョブ詳細画面
- 遷移先：環境詳細画面、環境新規作成画面、環境編集画面

**権限による表示制御**：
- `read_environment`権限がない場合はアクセス不可
- `create_environment`権限がある場合のみ「New environment」ボタンが表示
- `stop_environment`権限がある場合のみ停止ボタンが表示
- `admin_environment`権限がある場合のみターミナルアクセスが可能

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 55 | 環境管理 | 主機能 | 環境一覧表示・状態管理 |
| 56 | デプロイメント履歴 | 補助機能 | デプロイ履歴の表示 |

## 画面種別

一覧

## URL/ルーティング

| パス | HTTPメソッド | アクション |
|------|-------------|-----------|
| `/:namespace/:project/-/environments` | GET | index |
| `/:namespace/:project/-/environments/folders/:id` | GET | folder |
| `/:namespace/:project/-/environments/search` | GET | search |

## 入出力項目

### URLパラメータ

| 項目名 | 必須 | 型 | 説明 |
|--------|------|-----|------|
| scope | 任意 | string | 表示するスコープ（active/stopped） |
| search | 任意 | string | 検索キーワード（3文字以上） |
| page | 任意 | integer | ページ番号 |

## 表示項目

### 環境一覧

| 項目名 | 説明 | 型 |
|--------|------|-----|
| 環境名 | 環境の名前 | string |
| デプロイ情報 | 最終デプロイの情報（コミット、時刻、実行者） | object |
| 外部URL | 環境の外部URL（設定されている場合） | string |
| 自動停止 | 自動停止設定（設定されている場合） | datetime |
| 状態 | 環境の状態（available/stopping/stopped） | string |
| アクション | 停止、再デプロイ、ターミナル等のボタン | - |

### タブ

| タブ名 | 説明 |
|--------|------|
| Active | 利用可能な環境（available + stopping） |
| Stopped | 停止済みの環境 |

### フォルダ表示

同一プレフィックス（例：`review/`）を持つ環境はフォルダとしてグループ化され、展開可能なビューで表示される。

## イベント仕様

### 1-環境停止

**処理内容**：選択した環境を停止する。

**処理フロー**：
1. 停止ボタンをクリック
2. 確認モーダル表示
3. POSTリクエストで`stop`アクションを実行
4. `Environments::StopService`で停止処理
5. stop_actionが定義されている場合はそのジョブを実行
6. 環境状態を`stopping`または`stopped`に更新
7. 成功時：環境一覧を更新

### 2-環境削除

**処理内容**：停止済みの環境を削除する。

**処理フロー**：
1. 削除ボタンをクリック（停止済み環境のみ表示）
2. 確認モーダル表示
3. DELETEリクエスト送信
4. 成功時：環境一覧から削除

### 3-自動停止キャンセル

**処理内容**：環境の自動停止をキャンセルする。

**処理フロー**：
1. 自動停止キャンセルボタンをクリック
2. POSTリクエストで`cancel_auto_stop`アクションを実行
3. `Environments::ResetAutoStopService`で自動停止をリセット
4. 成功時：auto_stop_atをnullに設定

### 4-タブ切り替え

**処理内容**：Active/Stoppedタブを切り替える。

**処理フロー**：
1. タブをクリック
2. scopeパラメータを更新
3. 対応する状態の環境一覧を取得
4. 画面を更新

### 5-検索

**処理内容**：環境名で検索する。

**処理フロー**：
1. 検索ボックスに入力（3文字以上）
2. デバウンス後にAPIリクエスト
3. 検索結果を表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 一覧表示 | environments | SELECT | 環境一覧の取得 |
| 停止 | environments | UPDATE | 状態の更新 |
| 停止 | ci_builds | UPDATE | stop_actionジョブの実行 |
| 自動停止キャンセル | environments | UPDATE | auto_stop_atのクリア |
| 削除 | environments | DELETE | 環境の削除 |

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

#### environments

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | project_idでフィルタ、stateでフィルタ | ページネーション対応 |
| UPDATE | state | stopping/stopped | 停止時 |
| UPDATE | auto_stop_at | NULL | 自動停止キャンセル時 |
| DELETE | - | idで特定、停止済みのみ | 物理削除 |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|----------|---------|
| 成功 | Auto stop successfully canceled. | 自動停止キャンセル成功時 |
| エラー | Unauthorized to stop the environment | 停止権限不足時 |
| エラー | Attempted to stop the environment but failed | 停止失敗時 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| 権限不足 | 403 Forbiddenを返す |
| 環境未検出 | 404 Not Foundを返す |
| 停止不可（既に停止） | エラーメッセージを表示 |

## 備考

- 環境名の`/`以前の部分がフォルダ名として扱われる
- ポーリング間隔は3秒（`Gitlab::PollingInterval.set_header`）
- ETag Cachingを使用してパフォーマンス最適化
- Review Appの設定はCI/CD設定ファイルで定義

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | environment.rb | `app/models/environment.rb` | 状態管理（state_machine）、スコープ、関連モデル |

**読解のコツ**: `state_machine :state`の定義と、`available`、`stopping`、`stopped`の状態遷移を理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | environments_controller.rb | `app/controllers/projects/environments_controller.rb` | index/stop/cancel_auto_stopアクション |
| 2-2 | index.html.haml | `app/views/projects/environments/index.html.haml` | Vueコンポーネントマウント |

**主要処理フロー**:
1. **36-57行目**: indexアクションでHTML/JSONレスポンス
2. **115-134行目**: stopアクションでEnvironments::StopServiceを呼び出し
3. **136-155行目**: cancel_auto_stopアクションで自動停止リセット

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | stop_service.rb | `app/services/environments/stop_service.rb` | 停止処理のビジネスロジック |
| 3-2 | reset_auto_stop_service.rb | `app/services/environments/reset_auto_stop_service.rb` | 自動停止リセットロジック |

#### Step 4: フロントエンドコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | environments_app.vue | `app/assets/javascripts/environments/components/environments_app.vue` | メインコンポーネント |
| 4-2 | new_environment_item.vue | `app/assets/javascripts/environments/components/new_environment_item.vue` | 環境アイテム表示 |

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

```
[ブラウザ] GET /project/-/environments
    │
    ├─ EnvironmentsController#index
    │      │
    │      ├─ [HTML] ビューレンダリング
    │      │
    │      └─ [JSON] search_environments
    │             └─ EnvironmentsFinder
    │
    └─ [Vue.js] environments_app.vue
           │
           ├─ GraphQL: environmentAppQuery
           │
           └─ ポーリング（3秒間隔）

[停止操作]
    │
    └─ EnvironmentsController#stop
           │
           └─ Environments::StopService#execute
                  │
                  ├─ 権限チェック
                  ├─ stop_with_actions!
                  │      └─ stop_action.play
                  └─ state更新
```

### データフロー図

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

URLパラメータ ─────────────▶ EnvironmentsController#index ───▶ HTML + Vueマウント
  (scope, search, page)            │
                                   └─ EnvironmentsFinder
                                          │
                                          ▼
GraphQL Query ─────────────────────▶ Resolver ──────────────────▶ JSON (environments)
  (scope, page, search)                                               │
                                                                      ▼
                                                              Vueコンポーネント描画
                                                                      │
                                                              ┌───────┴───────┐
                                                              │               │
                                                              ▼               ▼
                                                         フォルダ表示    フラット表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| environments_controller.rb | `app/controllers/projects/environments_controller.rb` | コントローラー | CRUD操作 |
| index.html.haml | `app/views/projects/environments/index.html.haml` | ビュー | Vueマウント |
| environment.rb | `app/models/environment.rb` | モデル | データモデル |
| stop_service.rb | `app/services/environments/stop_service.rb` | サービス | 停止ロジック |
| environments_app.vue | `app/assets/javascripts/environments/components/environments_app.vue` | Vueコンポーネント | メインUI |
| environments_helper.rb | `app/helpers/environments_helper.rb` | ヘルパー | ビューヘルパー |
| environment_serializer.rb | `app/serializers/environment_serializer.rb` | シリアライザー | JSON変換 |
