# 画面設計書 80-環境編集

## 概要

本ドキュメントは、GitLabの環境編集画面の設計を記述したものである。

### 本画面の処理概要

**業務上の目的・背景**：環境編集画面は、既存のデプロイ環境の設定を変更するための画面である。外部URL、説明、Kubernetes連携設定などを更新できる。ただし、環境名は作成後に変更できないため、本画面では編集不可となっている。

**画面へのアクセス方法**：環境詳細画面の「Edit」ボタンをクリック、またはURL直接アクセス（`/:namespace/:project/-/environments/:id/edit`）によりアクセスする。

**主要な操作・処理内容**：
1. 説明の編集（Markdown対応）
2. 外部URLの変更
3. GitLab Agentの選択変更（Kubernetes連携）
4. Kubernetes Namespaceの変更
5. Flux Resourceの設定変更
6. 環境情報の更新

**画面遷移**：
- 遷移元：環境詳細画面、環境一覧画面
- 遷移先：環境詳細画面（更新成功時）、環境一覧画面（キャンセル時）

**権限による表示制御**：
- `update_environment`権限がない場合はアクセス不可

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 55 | 環境管理 | 主機能 | 環境の編集 |

## 画面種別

編集

## URL/ルーティング

| パス | HTTPメソッド | アクション |
|------|-------------|-----------|
| `/:namespace/:project/-/environments/:id/edit` | GET | edit |
| `/:namespace/:project/-/environments/:id` | PATCH/PUT | update |

## 入出力項目

### URLパラメータ

| 項目名 | 必須 | 型 | 説明 |
|--------|------|-----|------|
| id | 必須 | integer | 環境ID |

### フォーム入力項目

| 項目名 | 必須 | 型 | 説明 | バリデーション |
|--------|------|-----|------|---------------|
| name | - | string | 環境名（表示のみ、編集不可） | - |
| description | 任意 | string | 環境の説明（Markdown対応） | - |
| external_url | 任意 | string | 外部URL | http://またはhttps://で始まること |
| cluster_agent_id | 任意 | string | GitLab Agent ID | - |
| kubernetes_namespace | 任意 | string | Kubernetes Namespace | Agent選択時のみ |
| flux_resource_path | 任意 | string | Flux Resourceパス | Agent選択時のみ |

## 表示項目

### フォーム

| 項目名 | 説明 |
|--------|------|
| タイトル | "Edit environment" |
| 環境名表示欄 | 環境名（編集不可、disabled状態で表示） |
| 環境名変更不可説明 | "You cannot rename an environment after it's created." |
| 説明入力欄 | Markdownエディタ（プレビュー機能付き） |
| 外部URL入力欄 | URLを入力するテキストボックス |
| GitLab Agent選択 | プロジェクトで利用可能なAgentのドロップダウン |
| Namespace選択 | Agent選択時に表示されるNamespaceセレクター |
| Flux Resource選択 | Agent選択時に表示されるFluxリソースセレクター |
| Protected Environment設定リンク | 保護環境設定へのリンク（ライセンス有効時） |
| 保存ボタン | フォームを送信して環境を更新 |
| キャンセルボタン | 環境一覧に戻る |

## イベント仕様

### 1-環境更新

**処理内容**：環境情報を更新する。

**処理フロー**：
1. フォームに必要事項を入力
2. 保存ボタンをクリック
3. GraphQL `environmentUpdate` mutationを実行
4. 成功時：更新された環境の詳細画面にリダイレクト
5. 失敗時：エラーメッセージをアラート表示

### 2-Agent選択変更

**処理内容**：GitLab Agentを変更する。

**処理フロー**：
1. Agentドロップダウンをクリック
2. `getUserAuthorizedAgents` GraphQLクエリで利用可能なAgentを取得
3. Agentを選択
4. 既存のNamespaceとFlux Resource設定がクリアされる
5. Namespace選択とFlux Resource選択UIが表示される

### 3-キャンセル

**処理内容**：環境編集をキャンセルする。

**処理フロー**：
1. キャンセルボタンをクリック
2. 環境一覧画面にリダイレクト

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 編集画面表示 | environments | SELECT | 環境情報の取得 |
| 環境更新 | environments | UPDATE | 環境情報の更新 |

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

#### environments

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | idで特定 | 初期表示用 |
| UPDATE | external_url | 入力値 | 任意 |
| UPDATE | cluster_agent_id | 選択されたAgent ID | 任意 |
| UPDATE | updated_at | 現在時刻 | 自動更新 |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|----------|---------|
| 情報 | You cannot rename an environment after it's created. | 環境名フィールドの下に常時表示 |
| エラー | The URL should start with http:// or https:// | URL形式が不正な場合 |
| エラー | GraphQL mutation errors | 更新失敗時（エラー内容を表示） |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| 権限不足 | 403 Forbiddenを返す |
| 環境未検出 | 404 Not Foundを返す |
| バリデーションエラー | エラーメッセージをアラート表示 |

## 備考

- 環境名は作成後に変更できない（リネーム用のヘルプリンク表示あり）
- 説明欄はMarkdownレンダリング対応
- Protected Environment設定はライセンス機能
- Agent変更時は既存のKubernetes設定がリセットされる
- KAS Tunnel URLを使用してKubernetes APIにアクセス

---

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

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

### 推奨読解順序

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

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

**主要処理フロー**:
1. **91行目**: editアクションは空（environmentが既にbefore_actionで設定）
2. **107-113行目**: updateアクションで環境を更新し、JSON応答
3. **20行目**: authorize_update_environment!で権限チェック

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | edit_environment.vue | `app/assets/javascripts/environments/components/edit_environment.vue` | 編集ロジック |
| 2-2 | environment_form.vue | `app/assets/javascripts/environments/components/environment_form.vue` | フォーム共通部品 |

**主要処理フロー**:
1. **15-28行目** (edit_environment.vue): GraphQLクエリで既存環境データを取得
2. **45-79行目** (edit_environment.vue): onSubmitでGraphQL updateMutationを実行
3. **109-111行目** (environment_form.vue): isNameDisabledで環境名を編集不可に設定

#### Step 3: GraphQL APIを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | update_environment.mutation.graphql | `app/assets/javascripts/environments/graphql/mutations/update_environment.mutation.graphql` | 更新mutation |

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

```
[ブラウザ] GET /project/-/environments/:id/edit
    │
    └─ EnvironmentsController#edit
           │
           └─ @environment = project.environments.find(id)
                  │
                  └─ edit.html.haml
                         │
                         └─ #js-edit-environment

[Vue.js] edit_environment.vue
    │
    ├─ GraphQL: getEnvironment query（初期データ取得）
    │
    ├─ environment_form.vue
    │      │
    │      ├─ 環境名（disabled）
    │      ├─ MarkdownEditor（説明入力）
    │      ├─ GlCollapsibleListbox（Agent選択）
    │      ├─ EnvironmentNamespaceSelector
    │      └─ EnvironmentFluxResourceSelector
    │
    └─ onSubmit()
           │
           └─ GraphQL: environmentUpdate mutation
                  │
                  ├─ 成功: visitUrl(path)
                  └─ 失敗: createAlert(message)
```

### データフロー図

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

URL (/environments/:id/edit) ──▶ EnvironmentsController#edit
                                       │
                                       └─ @environment
                                              │
                                              ▼
                               edit.html.haml ─────────▶ edit_environment.vue
                                                              │
                                                              ▼
                                               GraphQL: getEnvironment ─▶ フォーム初期化
                                                              │
フォーム入力 ─────────────────────────────────────────────────┘
  (description, externalUrl,       │
   agentId, namespace)             └─ environment_form.vue
                                          │
                                          ├─ バリデーション
                                          │
                                          └─ onSubmit
                                                │
                                                ▼
                                   GraphQL environmentUpdate ────▶ environments UPDATE
                                                │
                                                ├─ 成功 ────▶ 環境詳細画面へリダイレクト
                                                │
                                                └─ 失敗 ────▶ エラーアラート表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| environments_controller.rb | `app/controllers/projects/environments_controller.rb` | コントローラー | edit/updateアクション |
| edit.html.haml | `app/views/projects/environments/edit.html.haml` | ビュー | Vueマウント |
| edit_environment.vue | `app/assets/javascripts/environments/components/edit_environment.vue` | Vueコンポーネント | 編集UI |
| environment_form.vue | `app/assets/javascripts/environments/components/environment_form.vue` | Vueコンポーネント | フォーム共通部品 |
| update_environment.mutation.graphql | `app/assets/javascripts/environments/graphql/mutations/update_environment.mutation.graphql` | GraphQL | 更新mutation |
| environment.query.graphql | `app/assets/javascripts/environments/graphql/queries/environment.query.graphql` | GraphQL | 環境取得クエリ |
| environment.rb | `app/models/environment.rb` | モデル | データモデル |
