# 画面設計書 235-グループ編集

## 概要

本ドキュメントは、GitLabの管理者向けグループ編集画面の設計仕様を定義する。

### 本画面の処理概要

この画面では、管理者が既存のグループの設定を編集することができる。グループ名、パス、説明、可視性レベル、各種権限設定などを変更してグループ情報を更新する。

**業務上の目的・背景**：システム管理者が既存グループの設定を変更する必要がある。組織変更に伴うグループ名変更、セキュリティポリシーに基づく可視性変更、2要素認証の強制適用など、システム全体の管理ポリシーに基づくグループ設定の変更を行うための画面である。ユーザーからの依頼に基づく設定変更や、監査対応のための設定変更にも使用される。

**画面へのアクセス方法**：管理者エリア > グループ一覧 > グループ詳細 > 「Edit」ボタン、またはURL `/admin/groups/:id/edit` に直接アクセス。

**主要な操作・処理内容**：
1. グループ名の変更
2. グループパス（URL）の変更
3. グループ説明の変更
4. アバター画像の変更・削除
5. 可視性レベル（Private/Internal/Public）の変更
6. アクセスリクエスト許可設定の変更
7. LFS有効化設定の変更
8. 2要素認証要求設定の変更
9. Runner登録許可設定の変更
10. プロジェクト作成レベル設定の変更
11. サブグループ作成レベル設定の変更
12. 管理者メモの編集
13. グループ設定の保存

**画面遷移**：
- 遷移元：管理者グループ詳細画面
- 遷移先：成功時はグループ詳細画面、失敗時は本画面（エラー表示）

**権限による表示制御**：管理者権限を持つユーザーのみがアクセス可能。可視性レベルの変更は`can_change_group_visibility_level?`で制御される場合がある。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 112 | グループ管理 | 主機能 | 管理者によるグループ編集 |
| 10 | グループ編集 | 主機能 | グループ編集処理の実行 |
| 11 | グループ削除 | 補助機能 | グループ削除オプション |

## 画面種別

編集

## URL/ルーティング

- URL: `/admin/groups/:id/edit`
- ルート名: `admin_group_edit_path`
- HTTPメソッド: GET (フォーム表示), PATCH/PUT (更新実行)
- コントローラ: `Admin::GroupsController#edit`, `Admin::GroupsController#update`

## 入出力項目

### パスパラメータ

| 項目名 | 種別 | 必須 | 説明 |
|--------|------|------|------|
| id | パスパラメータ | 必須 | グループのフルパス |

### 入力フォーム

| 項目名 | 種別 | 必須 | データ型 | 説明 | バリデーション |
|--------|------|------|----------|------|---------------|
| name | テキスト | 必須 | String | グループ名 | 最大255文字 |
| path | テキスト | 必須 | String | グループパス | URL形式、予約語禁止 |
| description | テキストエリア | 任意 | Text | グループ説明 | |
| avatar | ファイル | 任意 | Image | アバター画像 | 画像形式チェック |
| visibility_level | ラジオボタン | 必須 | Integer | 可視性レベル | 0(Private)/10(Internal)/20(Public) |
| request_access_enabled | チェックボックス | 任意 | Boolean | アクセスリクエスト許可 | |
| lfs_enabled | チェックボックス | 任意 | Boolean | LFS有効化 | |
| require_two_factor_authentication | チェックボックス | 任意 | Boolean | 2FA要求 | |
| two_factor_grace_period | 数値 | 条件付き | Integer | 2FA猶予期間（時間） | 2FA要求時のみ |
| runner_registration_enabled | チェックボックス | 任意 | Boolean | Runner登録許可 | |
| project_creation_level | セレクト | 任意 | Integer | プロジェクト作成レベル | |
| subgroup_creation_level | セレクト | 任意 | Integer | サブグループ作成レベル | |
| enabled_git_access_protocol | セレクト | 任意 | String | Gitアクセスプロトコル | |
| admin_note_attributes[note] | テキストエリア | 任意 | Text | 管理者メモ | |

## 表示項目

### セクション1: 命名と可視性

| 項目名 | 説明 |
|--------|------|
| グループ名 | 現在のグループ名（編集可能） |
| グループパス | 現在のURLパス（編集可能） |
| グループ説明 | 現在の説明文（編集可能） |
| アバター | 現在のグループアイコン（変更・削除可能） |
| 可視性レベル | 現在の可視性設定（変更可能） |

### セクション2: 権限とグループ機能

| 項目名 | 説明 |
|--------|------|
| アクセスリクエスト許可 | 現在の設定（変更可能） |
| 2要素認証設定 | 現在の設定（変更可能） |
| Runner登録許可 | 現在の設定（変更可能） |

### セクション3: 管理者メモ

| 項目名 | 説明 |
|--------|------|
| 管理者メモ | 現在のメモ内容（編集可能） |

## イベント仕様

### 1-グループ更新

「Save changes」ボタンをクリックした際の処理。

1. フォームデータを`Admin::GroupsController#update`に送信
2. `Groups::UpdateService`でグループを更新
3. Runner登録を無効にした場合、登録トークンをリセット
4. 成功時：グループ詳細画面にリダイレクトし、成功メッセージを表示
5. 失敗時：本画面を再表示し、エラーメッセージを表示

### 2-キャンセル

「Cancel」ボタンをクリックすると、グループ詳細画面に戻る。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | namespaces | SELECT | グループ情報の取得 |
| グループ更新 | namespaces | UPDATE | グループ情報の更新 |
| グループ更新 | routes | UPDATE | パス変更時のルート更新 |
| グループ更新 | admin_notes | INSERT/UPDATE | 管理者メモの更新 |
| Runner登録無効化 | ci_runners | UPDATE | 登録トークンのリセット |

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

#### namespaces

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | フォーム入力値 | |
| UPDATE | path | フォーム入力値 | ルート更新も発生 |
| UPDATE | description | フォーム入力値 | |
| UPDATE | visibility_level | フォーム入力値 | |
| UPDATE | lfs_enabled | フォーム入力値 | |
| UPDATE | request_access_enabled | フォーム入力値 | |
| UPDATE | require_two_factor_authentication | フォーム入力値 | |
| UPDATE | two_factor_grace_period | フォーム入力値 | |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| MSG001 | 成功 | Group was successfully updated. | 更新成功時 |
| MSG002 | エラー | {バリデーションエラーメッセージ} | 更新失敗時 |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| グループが存在しない | 404エラー画面を表示 |
| 管理者権限がない | 403アクセス拒否画面を表示 |
| パスが重複 | エラーメッセージを表示して再入力を促す |

## 備考

- グループパスを変更すると、プロジェクトのURLも連動して変更される
- Runner登録を無効にすると、既存の登録トークンがリセットされる
- 管理者メモが存在しない場合は自動的にビルドされる
- 可視性レベルを下げる場合、子グループ・プロジェクトの可視性との整合性チェックが行われる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | group.rb | `app/models/group.rb` | グループモデル、更新バリデーション |

**読解のコツ**: 更新時のバリデーションルール、特に可視性変更時の制約に注目。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | groups_controller.rb | `app/controllers/admin/groups_controller.rb` | edit/updateアクション |

**主要処理フロー**:
1. **32-34行目**: editアクション - 管理者メモがない場合はビルド
2. **49-61行目**: updateアクション - Groups::UpdateServiceで更新
3. **53-55行目**: Runner登録無効時のトークンリセット

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | update_service.rb | `app/services/groups/update_service.rb` | グループ更新ロジック |

**主要処理フロー**:
- グループ属性の更新
- 関連設定の更新
- 失敗時のエラーハンドリング

#### Step 4: ビューテンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | edit.html.haml | `app/views/admin/groups/edit.html.haml` | フォーム表示 |
| 4-2 | _form.html.haml | `app/views/admin/groups/_form.html.haml` | フォーム本体（共通） |

**主要処理フロー**:
- **1-5行目** (edit): パンくずとページタイトル
- **6-7行目** (edit): フォームパーシャルの呼び出し（現在の可視性レベルを渡す）

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

```
Admin::GroupsController#edit
    │
    ├─ group (private method)
    │      └─ Group.find_by_full_path
    │
    └─ @group.build_admin_note (unless exists)
           │
           └─ render view
                  └─ _form.html.haml

Admin::GroupsController#update
    │
    ├─ @group.build_admin_note (unless exists)
    │
    ├─ Groups::UpdateService.new.execute
    │      │
    │      └─ Group#update
    │
    ├─ (if runner_registration disabled)
    │      └─ Ci::Runners::ResetRegistrationTokenService.execute
    │
    └─ Success → redirect_to [:admin, @group]
       Failure → render "edit"
```

### データフロー図

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

group_id (URL) ───▶ Group.find_by_full_path ───▶ @group
                           │
                           ▼
                   edit.html.haml
                           │
                   [ユーザー入力]
                           │
                           ▼
Form Data ───▶ GroupsController#update
                      │
                      ▼
         Groups::UpdateService.execute
                      │
                      ├─ Success ───▶ redirect + flash[:notice]
                      │
                      └─ Failure ───▶ render "edit" + errors
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| groups_controller.rb | `app/controllers/admin/groups_controller.rb` | コントローラ | リクエスト処理 |
| edit.html.haml | `app/views/admin/groups/edit.html.haml` | ビュー | フォーム表示 |
| _form.html.haml | `app/views/admin/groups/_form.html.haml` | パーシャル | フォーム本体 |
| update_service.rb | `app/services/groups/update_service.rb` | サービス | 更新ロジック |
| group.rb | `app/models/group.rb` | モデル | グループモデル |
| admin.rb | `config/routes/admin.rb` | ルート | URLルーティング定義 |
