# 機能設計書 112-グループ管理

## 概要

本ドキュメントは、GitLab管理画面におけるグループ管理機能の設計仕様を記述する。システム管理者が全グループの一覧表示、詳細閲覧、作成、編集、削除を行うための機能である。

### 本機能の処理概要

**業務上の目的・背景**：GitLabでは、プロジェクトをグループ単位で組織化し、メンバーのアクセス権限を効率的に管理する。システム管理者はインスタンス全体のグループを監督し、適切な組織構造を維持する必要がある。本機能は管理者がグループの作成・編集・削除、メンバーシップの確認、統計情報の閲覧を行うための中核機能である。

**機能の利用シーン**：
- 新規部門・チームに対応するグループの作成
- 組織変更に伴うグループ名・パスの変更
- 不要になったグループの削除
- グループの利用状況（プロジェクト数、ストレージ使用量等）の確認
- グループメンバーの確認とアクセスリクエストの承認

**主要な処理内容**：
1. グループ一覧の表示（統計情報付き）
2. グループ詳細情報の表示（メンバー、プロジェクト、統計情報）
3. 新規グループの作成
4. 既存グループの編集（設定変更、管理者メモ追加）
5. グループの削除（非同期削除）
6. Runner登録設定のリセット

**関連システム・外部連携**：
- Runner登録トークンのリセット機能
- 2要素認証の強制設定
- Git操作プロトコル制限

**権限による制御**：
- 本機能は管理者（Admin）権限を持つユーザーのみがアクセス可能
- グループ作成時のプロジェクト作成レベル、サブグループ作成レベルを設定可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 232 | グループ一覧 | 主画面 | 管理者向けグループ一覧表示 |
| 233 | グループ詳細 | 主画面 | グループ詳細情報、メンバー、プロジェクト表示 |
| 234 | グループ新規作成 | 主画面 | 新規グループ作成フォーム |
| 235 | グループ編集 | 主画面 | グループ設定編集フォーム |

## 機能種別

CRUD操作 / 組織管理

## 入力仕様

### 入力パラメータ

#### グループ作成・編集時

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | グループ名 | 必須、文字列 |
| path | String | Yes | グループパス（URL用） | 必須、英数字とハイフン |
| description | String | No | グループ説明 | テキスト |
| avatar | File | No | グループアバター | 画像ファイル |
| visibility_level | Integer | No | 可視性レベル | 0:private/10:internal/20:public |
| lfs_enabled | Boolean | No | Git LFS有効化 | true/false |
| request_access_enabled | Boolean | No | アクセスリクエスト許可 | true/false |
| runner_registration_enabled | Boolean | No | Runner登録許可 | true/false |
| require_two_factor_authentication | Boolean | No | 2要素認証必須化 | true/false |
| two_factor_grace_period | Integer | No | 2要素認証猶予期間（時間） | 正の整数 |
| enabled_git_access_protocol | String | No | 有効なGitプロトコル | all/ssh/http |
| project_creation_level | Integer | No | プロジェクト作成権限レベル | developer/maintainer/noone |
| subgroup_creation_level | Integer | No | サブグループ作成権限レベル | owner/maintainer |
| organization_id | Integer | No | 所属組織ID | 有効な組織ID |
| admin_note_attributes[note] | String | No | 管理者メモ | テキスト |

### 入力データソース

- 画面入力（グループ作成・編集フォーム）
- URLパラメータ（グループパス）
- セッション情報（現在の管理者ユーザー）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| groups | Array[Group] | グループ一覧（統計情報付き） |
| group | Group | 個別グループ詳細データ |
| members | Array[Member] | グループメンバー一覧 |
| requesters | Array[Member] | アクセスリクエスト一覧 |
| projects | Array[Project] | グループ内プロジェクト一覧（統計付き） |
| flash_message | String | 操作結果メッセージ |

### 出力先

- 画面表示（HTML）
- リダイレクト（操作完了後）
- トースト通知（削除時）

## 処理フロー

### 処理シーケンス

```
1. グループ一覧表示（index）
   └─ render index（Vue.jsコンポーネントで描画）
2. グループ詳細表示（show）
   └─ Group.with_statistics.find → present_members → render
3. グループ作成（create）
   └─ Groups::CreateService.new.execute → redirect
4. グループ更新（update）
   └─ Groups::UpdateService.new.execute → Ci::Runners::ResetRegistrationTokenService → redirect
5. グループ削除（destroy）
   └─ Groups::DestroyService.new.async_execute → redirect
```

### フローチャート

```mermaid
flowchart TD
    A[管理者がグループ管理画面にアクセス] --> B{操作種別}
    B -->|一覧表示| C[index画面表示]

    B -->|詳細表示| D[Group.with_statistics.find]
    D --> E[メンバー取得・プレゼンター変換]
    E --> F[プロジェクト取得]
    F --> G[詳細画面表示]

    B -->|作成| H[new画面表示]
    H --> I[フォーム入力]
    I --> J[Groups::CreateService.execute]
    J --> K{成功?}
    K -->|Yes| L[詳細へリダイレクト]
    K -->|No| M[エラー表示]

    B -->|編集| N[edit画面表示]
    N --> O[フォーム入力]
    O --> P[Groups::UpdateService.execute]
    P --> Q{成功?}
    Q -->|Yes| R{Runner登録無効化?}
    R -->|Yes| S[ResetRegistrationTokenService]
    S --> T[詳細へリダイレクト]
    R -->|No| T
    Q -->|No| U[エラー表示]

    B -->|削除| V[Groups::DestroyService.async_execute]
    V --> W[一覧へリダイレクト]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-112-01 | Runner登録トークンリセット | Runner登録を無効化した場合、登録トークンをリセットする | グループ更新時にrunner_registration_enabled=false |
| BR-112-02 | 統計情報付き表示 | グループ一覧・詳細では統計情報（ストレージ使用量等）を含めて取得 | 一覧・詳細表示時 |
| BR-112-03 | 非同期削除 | グループ削除は非同期で実行される | 削除操作時 |
| BR-112-04 | 管理者メモ | グループには管理者専用のメモを追加可能 | 作成・編集時 |

### 計算ロジック

特になし

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 一覧表示 | namespaces (groups) | SELECT | グループ一覧取得（統計情報付き） |
| 詳細表示 | namespaces, members, projects | SELECT | グループ関連情報取得 |
| 作成 | namespaces, admin_notes | INSERT | 新規グループと管理者メモ作成 |
| 更新 | namespaces, admin_notes | UPDATE | グループ情報更新 |
| 削除 | namespaces, projects, members | DELETE | グループと関連データ削除（非同期） |

### テーブル別操作詳細

#### namespaces（groups）テーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, path, description, visibility_level等 | 統計情報を含むwith_statistics | namespace_detailsも含む |
| INSERT | name, path, type='Group', organization_id等 | フォーム入力値 | |
| UPDATE | name, description, visibility_level等 | フォーム入力値 | |
| DELETE | - | id指定 | 非同期実行 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | 存在しないリソース | 指定されたグループが見つからない | 404エラーページ表示 |
| 422 | バリデーションエラー | 入力値が不正（パス重複等） | エラーメッセージを表示して再入力を促す |

### リトライ仕様

- グループ削除は非同期処理（`async_execute`）で実行され、`Groups::DestroyService`のワーカーによりリトライされる

## トランザクション仕様

- グループ作成・更新はサービスクラス内で単一トランザクションとして処理
- グループ削除は非同期処理のため、削除リクエストは即座にコミットされ、実際の削除は別トランザクションで処理

## パフォーマンス要件

- グループ一覧表示：`with_statistics`で統計情報を効率的に取得
- メンバー一覧：ページネーション対応

## セキュリティ考慮事項

- 管理者権限（Admin）が必須
- 2要素認証の強制設定が可能
- Git操作プロトコルの制限が可能

## 備考

- 本機能はEnterprise Edition（EE）で拡張される可能性があり、`prepend_mod_with`によりモジュールが追加される
- グループ削除はトースト通知で結果を表示

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | group.rb | `app/models/group.rb` | Groupモデルの属性、Namespaceとの継承関係を理解 |
| 1-2 | namespace.rb | `app/models/namespace.rb` | 名前空間の基本構造を理解 |

**読解のコツ**: GroupはNamespaceを継承しており、STI（Single Table Inheritance）パターンで実装されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | groups_controller.rb | `app/controllers/admin/groups_controller.rb` | 各アクションの処理フローを理解 |

**主要処理フロー**:
1. **10行目**: `index`アクション - 一覧表示
2. **13-24行目**: `show`アクション - 統計付き詳細表示、メンバー・プロジェクト取得
3. **36-46行目**: `create`アクション - Groups::CreateService経由でグループ作成
4. **49-61行目**: `update`アクション - Groups::UpdateService経由で更新、Runner登録トークンリセット
5. **63-69行目**: `destroy`アクション - 非同期削除

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

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

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

```
Admin::GroupsController
    │
    ├─ index
    │      └─ (Vue.jsコンポーネントで描画)
    │
    ├─ show
    │      ├─ Group.with_statistics.find
    │      ├─ present_members (MembersPresentation)
    │      └─ AccessRequestsFinder
    │
    ├─ create
    │      └─ Groups::CreateService#execute
    │
    ├─ update
    │      ├─ Groups::UpdateService#execute
    │      └─ Ci::Runners::ResetRegistrationTokenService#execute
    │
    └─ destroy
           └─ Groups::DestroyService#async_execute
```

### データフロー図

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

管理者操作 ───────▶ Admin::GroupsController ───────▶ HTMLレスポンス
  │                      │                              │
  │                      ▼                              │
  │               Groups::*Service                      │
  │                      │                              │
  │                      ▼                              │
  │                 Group Model                         │
  │                      │                              │
  └──────────────▶ namespaces テーブル ────────────▶ トースト通知
                         │
                         ▼
                  関連テーブル
              (members, projects等)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| groups_controller.rb | `app/controllers/admin/groups_controller.rb` | コントローラー | グループ管理のエントリーポイント |
| group.rb | `app/models/group.rb` | モデル | グループデータモデル |
| namespace.rb | `app/models/namespace.rb` | モデル | 名前空間基底モデル |
| create_service.rb | `app/services/groups/create_service.rb` | サービス | グループ作成ロジック |
| update_service.rb | `app/services/groups/update_service.rb` | サービス | グループ更新ロジック |
| destroy_service.rb | `app/services/groups/destroy_service.rb` | サービス | グループ削除ロジック |
| reset_registration_token_service.rb | `app/services/ci/runners/reset_registration_token_service.rb` | サービス | Runner登録トークンリセット |
