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

## 概要

本ドキュメントは、GitLabにおけるグループ編集画面の設計仕様を定義するものである。グループの基本設定、権限設定、高度な設定などを変更するための管理画面を提供する。

### 本画面の処理概要

グループ編集画面は、既存グループの設定を変更するための管理画面である。グループ名、説明、可視性レベル、権限設定、バッジ、高度な設定（パス変更、移行、エクスポート、削除）などの各種設定をセクション別に管理できる。

**業務上の目的・背景**：グループの運用において、組織変更やセキュリティポリシーの変更に伴い、グループ設定の変更が必要となる。グループ編集画面では、名称変更、可視性の調整、権限制御の強化、グループの移行や削除といった管理操作を一元的に行える。各設定はセクション別に分かれており、目的に応じた設定変更が効率的に行える。

**画面へのアクセス方法**：以下のいずれかの方法でアクセス可能である。
- グループ詳細画面のサイドバーから「Settings > General」を選択
- URL直接アクセス: `/groups/{group_path}/-/edit`
- グループ設定メニューから「General」を選択

**主要な操作・処理内容**：
1. 名前、説明、アバター、可視性の変更（Naming, description, visibility セクション）
2. 権限とグループ機能の設定（Permissions and group features セクション）
3. バッジの管理（Badges セクション）
4. 高度な設定：パス変更、グループ移行、エクスポート、削除（Advanced セクション）
5. MR承認設定（EE機能）
6. コンプライアンスフレームワーク設定（EE機能）

**画面遷移**：
- 遷移元：グループ詳細画面、グループ設定メニュー
- 遷移先：更新成功時は同画面（アンカー付き）、グループ移行時は移行先グループ、削除時はダッシュボード

**権限による表示制御**：
- Owner：全セクションへのアクセス、グループ削除権限
- admin_group権限：基本設定、権限設定、高度な設定へのアクセス
- manage_merge_request_settings権限：MR設定セクションへのアクセス
- admin_compliance_framework権限：コンプライアンス設定へのアクセス
- remove_group権限のみ：復元と削除セクションのみ表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | グループ編集 | 主機能 | グループ設定の編集処理 |
| 11 | グループ削除 | 補助機能 | グループ削除オプション |
| 12 | グループ移行 | 補助機能 | グループ移行オプション |

## 画面種別

編集

## URL/ルーティング

- パス: `/groups/{group_path}/-/edit`
- ルーティング: `groups#edit`, `groups#update`
- HTTPメソッド: GET（フォーム表示）, PATCH/PUT（設定更新）

## 入出力項目

| 項目名 | 種別 | 必須 | データ型 | 説明 | バリデーション |
|--------|------|------|----------|------|---------------|
| name | フォーム入力 | 必須 | String | グループ名 | 255文字以内 |
| description | フォーム入力 | 任意 | Text | グループの説明 | - |
| avatar | フォーム入力 | 任意 | File | グループアバター | 画像形式 |
| visibility_level | フォーム選択 | 必須 | Integer | 可視性レベル | 親グループ以下 |
| path | フォーム入力 | 必須 | String | URLパス（Advanced） | 英数字等制限 |
| new_parent_group_id | フォーム選択 | 任意 | Integer | 移行先親グループID | 存在チェック |
| request_access_enabled | フォーム選択 | 任意 | Boolean | アクセスリクエスト許可 | - |
| share_with_group_lock | フォーム選択 | 任意 | Boolean | グループ共有ロック | - |
| require_two_factor_authentication | フォーム選択 | 任意 | Boolean | 2FA必須化 | 親グループで許可時 |

## 表示項目

| 項目名 | データ型 | 説明 | 表示条件 |
|--------|----------|------|----------|
| 基本設定セクション | Section | 名前・説明・可視性 | admin_group権限 |
| 権限設定セクション | Section | 権限とグループ機能 | admin_group権限 |
| AI設定セクション | Section | AI関連設定 | admin_group権限、EE機能 |
| MR設定セクション | Section | マージリクエスト設定 | manage_merge_request_settings権限 |
| バッジセクション | Section | グループバッジ | admin_group権限 |
| コンプライアンスセクション | Section | コンプライアンス設定 | admin_compliance_framework権限 |
| 高度な設定セクション | Section | パス変更、移行、削除 | admin_group権限 |
| 削除セクション | Section | グループ削除 | remove_group権限 |

## イベント仕様

### 1-編集フォーム表示（GET）

1. ユーザー認証・権限確認
2. `authorize_view_edit_page!`による編集画面アクセス権限チェック
3. バッジAPI用のエンドポイント設定（`@badge_api_endpoint`）
4. 各セクションの表示/非表示判定
5. 設定ブロックコンポーネントによるアコーディオン形式表示

### 2-設定更新（PATCH/PUT）

1. ユーザー認証・権限確認（`authorize_admin_group!`）
2. `Groups::UpdateService`の実行
3. namespace_settingsエラーがある場合はフラッシュアラート表示
4. 成功時：編集画面へリダイレクト（アンカー付き）
5. 失敗時：フォーム再表示

### 3-グループ移行（POST /transfer）

1. `authorize_change_group!`による権限確認
2. 移行先グループの存在確認
3. `Groups::TransferService`の実行
4. 成功時：移行後のグループ詳細画面へリダイレクト
5. 失敗時：編集画面へリダイレクト、エラーメッセージ表示

### 4-グループ削除（DELETE）

1. `authorize_remove_group!`による権限確認
2. `Groups::MarkForDeletionService`による削除スケジュール登録
3. 成功時：グループ詳細画面へリダイレクト、削除予定日表示
4. 即座削除（管理者）：`Groups::DestroyService`による即座削除

### 5-グループエクスポート（POST /export）

1. レート制限チェック
2. `Groups::ImportExport::ExportService`によるエクスポート開始
3. 非同期でエクスポート処理を実行
4. 完了後、ダウンロードリンクをメールで通知

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 設定更新 | namespaces | UPDATE | グループ情報更新 |
| 設定更新 | namespace_settings | UPDATE | グループ設定更新 |
| 設定更新 | routes | UPDATE | パス変更時ルート更新 |
| グループ移行 | namespaces | UPDATE | parent_id、traversal_ids更新 |
| グループ削除 | group_deletion_schedules | INSERT | 削除スケジュール登録 |
| エクスポート | import_export_uploads | INSERT | エクスポートファイル情報 |

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

#### namespaces

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | フォーム入力値 | グループ名 |
| UPDATE | description | フォーム入力値 | 説明文 |
| UPDATE | visibility_level | フォーム選択値 | 可視性 |
| UPDATE | path | フォーム入力値 | URLパス |
| UPDATE | parent_id | 移行先グループID | 移行時のみ |

#### namespace_settings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | request_access_enabled | フォーム選択値 | アクセスリクエスト |
| UPDATE | require_two_factor_authentication | フォーム選択値 | 2FA必須 |
| UPDATE | two_factor_grace_period | フォーム入力値 | 2FA猶予期間 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | 成功 | Group '{group_name}' was successfully updated. | 更新成功時 |
| MSG-002 | 成功 | Group '{group_name}' was successfully transferred. | 移行成功時 |
| MSG-003 | 情報 | '{group_name}' has been scheduled for deletion and will be deleted on {date}. | 削除スケジュール時 |
| MSG-004 | 成功 | Group '{group_name}' has been successfully restored. | 復元成功時 |
| MSG-005 | 情報 | Group export started. A download link will be sent by email... | エクスポート開始時 |
| MSG-006 | エラー | Group export could not be started. | エクスポート失敗時 |

## 例外処理

| 例外条件 | 処理内容 | 遷移先 |
|----------|----------|--------|
| 編集権限なし | 編集セクション非表示（削除のみ表示の場合あり） | 条件付き表示 |
| 移行先グループ不存在 | エラーメッセージ表示 | 編集画面 |
| 可視性レベル不正 | バリデーションエラー | 編集画面 |
| エクスポートレート制限 | レート制限エラー | 編集画面 |

## 備考

- 各設定セクションはアコーディオン形式で展開/折りたたみ可能
- `expanded_by_default?`ヘルパーで初期展開状態を決定
- グループ削除は即座削除ではなく、スケジュール削除がデフォルト
- パス変更時は関連するプロジェクトやサブグループのルートも更新される
- EE機能（AI設定、MR承認設定、コンプライアンス）は`render_if_exists`で条件付き表示

---

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

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

### 推奨読解順序

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

グループ設定に関連するモデルとその関連を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | group.rb | `app/models/group.rb` | グループ属性、バリデーション |
| 1-2 | namespace_setting.rb | `app/models/namespace_setting.rb` | 名前空間設定属性 |
| 1-3 | group_deletion_schedule.rb | `app/models/group_deletion_schedule.rb` | 削除スケジュール |

**読解のコツ**: `accepts_nested_attributes_for :variables, :group_feature`などのネスト属性定義を確認。

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

コントローラーの`edit`/`update`アクションを把握する。

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

**主要処理フロー**:
1. **150-152行目**: editアクションでバッジAPIエンドポイント設定
2. **156-169行目**: updateアクションでGroups::UpdateService呼び出し
3. **172-178行目**: リダイレクト先の決定（update_section アンカー）
4. **234-246行目**: transferアクションでグループ移行
5. **180-219行目**: destroyアクションで削除処理

#### Step 3: ビューレイヤーを理解する

設定セクションの構成と権限による表示制御を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.html.haml | `app/views/groups/edit.html.haml` | メインテンプレート |
| 3-2 | settings/_general.html.haml | `app/views/groups/settings/_general.html.haml` | 基本設定パーシャル |
| 3-3 | settings/_permissions.html.haml | `app/views/groups/settings/_permissions.html.haml` | 権限設定パーシャル |
| 3-4 | settings/_advanced.html.haml | `app/views/groups/settings/_advanced.html.haml` | 高度な設定パーシャル |

**主要処理フロー**:
- **10-19行目**: can?(:admin_group)による基本設定セクション表示
- **21-28行目**: 権限設定セクション
- **32-34行目**: MR設定セクション（manage_merge_request_settings権限）
- **54-61行目**: 高度な設定セクション

#### Step 4: サービスレイヤーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | update_service.rb | `app/services/groups/update_service.rb` | グループ更新ロジック |
| 4-2 | transfer_service.rb | `app/services/groups/transfer_service.rb` | グループ移行ロジック |
| 4-3 | mark_for_deletion_service.rb | `app/services/groups/mark_for_deletion_service.rb` | 削除スケジュールロジック |

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

```
GroupsController#edit
    │
    ├─ authorize_view_edit_page! (before_action)
    │
    └─ @badge_api_endpoint 設定
           └─ render 'groups/edit'
                  ├─ SettingsBlockComponent (名前・説明・可視性)
                  ├─ SettingsBlockComponent (権限設定)
                  ├─ render_if_exists 'ai_settings' (EE)
                  ├─ render_if_exists 'merge_requests' (EE)
                  ├─ SettingsBlockComponent (バッジ)
                  ├─ render_if_exists 'compliance_frameworks' (EE)
                  └─ SettingsBlockComponent (高度な設定)

GroupsController#update
    │
    ├─ authorize_admin_group! (before_action)
    │
    └─ Groups::UpdateService.new(@group, current_user, params).execute
           │
           ├─ group.update(params)
           │      ├─ validations
           │      └─ callbacks
           │
           └─ Response
                  ├─ success → redirect_to edit_group_path (anchor)
                  └─ failure → render :edit
```

### データフロー図

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

Form params ─────────────▶ GroupsController#update ─────▶ Redirect
(name, description,               │                      (edit_group_path#anchor)
 visibility_level, etc.)          │
                                  ▼
                          Groups::UpdateService
                                  │
                                  ├── params validation
                                  │
                                  └── group.update
                                         │
                                         ▼
                                    namespaces (UPDATE)
                                    namespace_settings (UPDATE)
                                    routes (UPDATE) ※パス変更時
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| groups_controller.rb | `app/controllers/groups_controller.rb` | コントローラー | edit/update/transfer/destroyアクション |
| update_service.rb | `app/services/groups/update_service.rb` | サービス | グループ更新ロジック |
| transfer_service.rb | `app/services/groups/transfer_service.rb` | サービス | グループ移行ロジック |
| mark_for_deletion_service.rb | `app/services/groups/mark_for_deletion_service.rb` | サービス | 削除スケジュールロジック |
| edit.html.haml | `app/views/groups/edit.html.haml` | ビュー | メインテンプレート |
| _general.html.haml | `app/views/groups/settings/_general.html.haml` | ビュー | 基本設定パーシャル |
| _permissions.html.haml | `app/views/groups/settings/_permissions.html.haml` | ビュー | 権限設定パーシャル |
| _advanced.html.haml | `app/views/groups/settings/_advanced.html.haml` | ビュー | 高度な設定パーシャル |
| settings_block_component.rb | `app/components/layouts/settings_block_component.rb` | コンポーネント | 設定ブロックUI |
