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

## 概要

本ドキュメントは、組織配下のグループ編集画面の設計書である。GitLab組織機能において、グループの設定変更・削除を行う管理画面の仕様を定義する。

### 本画面の処理概要

組織（Organization）配下に作成されたグループの設定を編集するための画面である。グループ名、説明、公開設定などの基本情報を変更でき、グループの削除も実行可能である。

**業務上の目的・背景**：GitLab組織機能において、グループは複数のプロジェクトやメンバーを束ねる重要な階層構造である。組織管理者は、業務要件の変化に応じてグループ設定を柔軟に変更する必要がある。本画面は、組織内でのグループガバナンスを効率的に管理するために必要不可欠である。

**画面へのアクセス方法**：
1. 左サイドバーから「組織」を選択
2. 対象の組織を選択
3. 「グループとプロジェクト」タブから対象グループを選択
4. グループ設定の「編集」をクリック

**主要な操作・処理内容**：
1. グループ名の変更
2. グループパスの変更
3. グループの説明文の編集
4. 公開範囲（visibility）の変更
5. グループアバターの設定
6. グループの削除（削除スケジュール設定、即時削除）

**画面遷移**：
- 遷移元: 組織グループ・プロジェクト一覧、グループ詳細画面
- 遷移先: グループ詳細画面、組織グループ・プロジェクト一覧（削除後）

**権限による表示制御**：
- グループの編集には `view_edit_page` 権限が必要
- グループの削除には `remove_group` 権限が必要
- 即時削除は `allow_immediate_namespaces_deletion_for_user?` 設定により制限

## 関連機能

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

## 画面種別

編集

## URL/ルーティング

```
GET /-/organizations/:organization_path/groups/*id/edit
```

## 入出力項目

| 項目名 | 項目ID | 入出力 | 型 | 必須 | 説明 |
|--------|--------|--------|-----|------|------|
| グループ名 | name | 入力 | string | Yes | グループの表示名 |
| グループパス | path | 入力 | string | Yes | URLに使用されるパス |
| 説明 | description | 入力 | text | No | グループの説明文 |
| 公開範囲 | visibility_level | 入力 | integer | Yes | 0:Private, 10:Internal, 20:Public |
| アバター | avatar | 入力 | file | No | グループのアバター画像 |

## 表示項目

本画面はVue.jsコンポーネント（`#js-organizations-groups-edit`）によりレンダリングされるため、表示項目はフロントエンドで定義される。

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| グループ名 | @group.name | 現在のグループ名 |
| グループパス | @group.path | 現在のグループパス |
| フルパス | @group.full_path | ルートからのフルパス |
| 説明 | @group.description | グループの説明 |
| 公開範囲 | @group.visibility_level | 現在の公開設定 |

## イベント仕様

### 1-グループ更新

**トリガー**: 保存ボタン押下

**処理フロー**:
1. フォームデータのバリデーション
2. `Groups::UpdateService` を呼び出してグループ情報を更新
3. 成功時: グループ詳細画面へリダイレクト
4. 失敗時: エラーメッセージを表示して画面に留まる

### 2-グループ削除スケジュール

**トリガー**: 削除ボタン押下

**処理フロー**:
1. 削除確認ダイアログを表示
2. 確認後、DELETE `/organizations/:organization_path/groups_organization` へリクエスト
3. `Groups::MarkForDeletionService` により削除をスケジュール
4. 成功時: 削除予定日を含むメッセージを表示
5. 失敗時: エラーメッセージを返却

### 3-グループ即時削除

**トリガー**: 永久削除ボタン押下（削除スケジュール済みグループ）

**処理フロー**:
1. `permanently_remove=true` パラメータ付きで DELETE リクエスト
2. `Gitlab::CurrentSettings.allow_immediate_namespaces_deletion_for_user?` 権限チェック
3. 権限あり: `Groups::DestroyService.async_execute` で非同期削除
4. 権限なし: アクセス拒否エラー

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| グループ更新 | namespaces | UPDATE | グループ情報の更新 |
| グループ削除スケジュール | namespaces | UPDATE | marked_for_deletion_on カラムを設定 |
| グループ即時削除 | namespaces | DELETE | グループレコードの削除 |
| グループ即時削除 | projects | DELETE | 配下プロジェクトの削除 |
| グループ即時削除 | members | DELETE | メンバーシップの削除 |

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

#### namespaces

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | フォーム入力値 | グループ名 |
| UPDATE | path | フォーム入力値 | グループパス |
| UPDATE | description | フォーム入力値 | 説明文 |
| UPDATE | visibility_level | フォーム入力値 | 公開範囲 |
| UPDATE | marked_for_deletion_on | 現在日時 | 削除スケジュール時 |
| UPDATE | updated_at | 現在日時 | 更新日時 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| MSG-001 | 成功 | '%{group_name}' has been scheduled for deletion and will be deleted on %{date}. | 削除スケジュール成功時 |
| MSG-002 | 成功 | Group '%{group_name}' is being deleted. | 即時削除成功時 |
| MSG-003 | エラー | (Groups::DestroyService::DestroyError message) | 削除失敗時 |
| MSG-004 | エラー | (Validation error messages) | バリデーション失敗時 |

## 例外処理

| 例外 | 発生条件 | 対応処理 |
|-----|---------|---------|
| 404 Not Found | 指定されたグループが存在しない | render_404 |
| 403 Forbidden | view_edit_page 権限がない | access_denied! |
| 403 Forbidden | 即時削除権限がない | access_denied! |
| 422 Unprocessable Entity | グループ作成/更新のバリデーション失敗 | エラーメッセージをJSON返却 |

## 備考

- 本画面はVue.jsによるSPA実装であり、サーバーサイドではデータの提供とAPIエンドポイントを担当する
- グループ削除は段階的に行われ、デフォルトでは即座に削除されずスケジュールされる
- 即時削除はシステム設定により有効/無効が制御される

---

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

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

### 推奨読解順序

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

まず、グループ（namespace）のデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | namespace.rb | `app/models/namespace.rb` | グループの基底モデル、属性定義を確認 |
| 1-2 | group.rb | `app/models/group.rb` | Namespaceを継承したGroupモデルの機能を確認 |

**読解のコツ**: GitLabでは `Group` は `Namespace` を継承している。グループ関連の処理では両方のモデルを参照する必要がある。

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

処理の起点となるコントローラーを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | groups_controller.rb | `app/controllers/organizations/groups_controller.rb` | edit/destroyアクションの実装を確認 |

**主要処理フロー**:
1. **17行目**: `edit` アクション - 編集画面の表示
2. **30-54行目**: `destroy` アクション - 削除処理の分岐（スケジュール削除/即時削除）
3. **58-60行目**: `group` メソッド - 対象グループの取得ロジック

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.html.haml | `app/views/organizations/groups/edit.html.haml` | Vue.jsコンポーネントへのデータ受け渡しを確認 |

**主要処理フロー**:
- **5行目**: `#js-organizations-groups-edit` - Vue.jsマウントポイント、`organization_groups_edit_app_data` ヘルパーでデータを渡す

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | mark_for_deletion_service.rb | `app/services/groups/mark_for_deletion_service.rb` | 削除スケジュールのロジック |
| 4-2 | destroy_service.rb | `app/services/groups/destroy_service.rb` | 即時削除のロジック |

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

```
Organizations::GroupsController#edit
    │
    ├─ authorize_read_organization!
    │      └─ can?(current_user, :read_organization, organization)
    │
    ├─ authorize_view_edit_page!
    │      └─ can?(current_user, :view_edit_page, group)
    │
    └─ render 'edit'
           └─ organization_groups_edit_app_data(@organization, @group)

Organizations::GroupsController#destroy
    │
    ├─ authorize_remove_group!
    │      └─ can?(current_user, :remove_group, group)
    │
    ├─ [permanently_remove=true]
    │      └─ Groups::DestroyService#async_execute
    │
    └─ [permanently_remove=false]
           └─ Groups::MarkForDeletionService#execute
```

### データフロー図

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

グループID ───▶ Groups::GroupsFinder ───▶ @group
    │
organization_id ───▶ Organization.find ───▶ @organization
    │
フォームデータ ───▶ Groups::UpdateService ───▶ 更新結果
    │
削除リクエスト ───▶ Groups::MarkForDeletionService ───▶ 削除スケジュール
    │
即時削除リクエスト ───▶ Groups::DestroyService ───▶ 削除完了
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| groups_controller.rb | `app/controllers/organizations/groups_controller.rb` | コントローラー | リクエスト処理 |
| edit.html.haml | `app/views/organizations/groups/edit.html.haml` | テンプレート | ビューレンダリング |
| group.rb | `app/models/group.rb` | モデル | グループのデータ定義 |
| namespace.rb | `app/models/namespace.rb` | モデル | 名前空間の基底モデル |
| mark_for_deletion_service.rb | `app/services/groups/mark_for_deletion_service.rb` | サービス | 削除スケジュール |
| destroy_service.rb | `app/services/groups/destroy_service.rb` | サービス | グループ削除 |
| organizations.rb | `config/routes/organizations.rb` | 設定 | ルーティング定義 |
| groups_helper.rb | `app/helpers/groups_helper.rb` | ヘルパー | ビューヘルパーメソッド |
