# 機能設計書 68-グループ削除

## 概要

本ドキュメントは、Fat Free CRM の管理機能における「グループ削除」機能の設計を記述する。

### 本機能の処理概要

管理者がシステムからグループを削除するための機能である。グループに紐付いているアクセス権限（Permission）がある場合は、削除前に確認ダイアログが表示される。

**業務上の目的・背景**：組織改編やプロジェクト終了に伴い、不要になったグループを削除することで、システムの整理と管理効率の向上を図る。ただし、アクセス権限に影響を与える可能性があるため、削除には注意が必要である。

**機能の利用シーン**：
- 解散した部署やチームのグループ削除
- 終了したプロジェクトのグループ削除
- 誤って作成したグループの削除
- システム整理時の不要グループの削除

**主要な処理内容**：
1. 削除対象グループの特定
2. 関連するアクセス権限の確認
3. 確認メッセージの表示（権限が存在する場合）
4. グループレコードの削除
5. 関連するユーザー紐付けの削除

**関連システム・外部連携**：なし

**権限による制御**：本機能は管理者権限（admin: true）を持つユーザーのみが実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 38 | グループ管理一覧画面 | 主画面 | グループの削除処理 |

## 機能種別

CRUD操作（Delete）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | Integer | Yes | 削除対象グループID | 存在するグループID |

### 入力データソース

- URL パラメータ（グループID）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @group | Group | 削除対象のグループオブジェクト |

### 出力先

- 画面表示（AJAX レスポンスによる部分更新）
- groups テーブル（レコード削除）
- groups_users テーブル（関連レコード削除）

## 処理フロー

### 処理シーケンス

```
1. 管理者がグループ一覧画面で削除リンクをクリック
   └─ 関連 Permission がある場合は確認ダイアログを表示

2. 削除確認
   └─ AJAX リクエスト: DELETE /admin/groups/:id

3. destroy アクションで削除処理を実行
   └─ @group.destroy でレコード削除

4. 結果を返却
   └─ 成功時: グループ一覧から該当行をスライドアウトで削除
   └─ 失敗時: 警告メッセージを表示
```

### フローチャート

```mermaid
flowchart TD
    A[削除リンククリック] --> B{関連 Permission あり?}
    B -->|Yes| C[確認ダイアログ表示]
    B -->|No| D[DELETE /admin/groups/:id]
    C --> E{削除確認}
    E -->|OK| D
    E -->|キャンセル| F[終了]
    D --> G[@group.destroy]
    G --> H{削除成功?}
    H -->|Yes| I[一覧から行を削除]
    H -->|No| J[警告メッセージ表示]
    I --> F
    J --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-68-01 | 関連権限確認 | グループに紐付く Permission が存在する場合は確認メッセージを表示 | Permission.where(group_id: group.id).count > 0 |
| BR-68-02 | カスケード削除 | 削除時に groups_users の関連レコードも自動削除 | 常時 |
| BR-68-03 | 物理削除 | 論理削除ではなく物理削除を行う | 常時 |

### 計算ロジック

**確認メッセージの判定（_group.html.haml）**：
```ruby
count = Permission.where(group_id: group.id).count
confirm = (count.zero? ? nil : "#{t(:confirm_group_delete, count)}")
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| グループ削除 | groups | DELETE | グループレコードの削除 |
| ユーザー関連削除 | groups_users | DELETE | HABTM により自動削除 |

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

#### groups

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | id = params[:id] | 物理削除 |

#### groups_users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | group_id = 削除グループID | HABTM 関連 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 認可エラー | 非管理者によるアクセス | ルート画面にリダイレクト |
| - | 削除エラー | 削除に失敗した場合 | 警告メッセージを表示 |

### リトライ仕様

削除失敗時は警告メッセージを表示し、ユーザーは原因を確認後に再試行可能。

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

ActiveRecord の destroy メソッドにより、関連レコード（groups_users）の削除も含めてトランザクション内で処理される。

## パフォーマンス要件

- AJAX リクエストのため、レスポンス時間は 500ms 以内を目標
- 単一グループの削除処理であり、特別なパフォーマンス考慮は不要

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

- 管理者権限チェック（before_action :require_admin_user）
- CSRF トークンによるクロスサイトリクエストフォージェリ対策
- 関連 Permission がある場合は確認メッセージを表示

## 備考

- グループを削除しても、そのグループが持っていた Permission は自動削除されない（Permission テーブルの group_id は残る可能性あり）
- 削除前に Permission の count を確認し、影響範囲をユーザーに通知する
- 削除は物理削除であり、復元は不可能

---

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

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

### 推奨読解順序

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

まず、グループモデルと Permission との関連を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | group.rb | `app/models/users/group.rb` | グループモデルの定義、has_many :permissions |
| 1-2 | schema.rb | `db/schema.rb` | groups テーブル、groups_users テーブル、permissions テーブルの構造 |

**読解のコツ**:
- **10行目**: `has_many :permissions` によりアクセス権限との関連
- **9行目**: `has_and_belongs_to_many :users` によりユーザーとの多対多関連
- permissions テーブルは group_id を持ち、グループベースの権限設定に使用される

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | groups_controller.rb | `app/controllers/admin/groups_controller.rb` | destroy アクション |
| 2-2 | application_controller.rb | `app/controllers/admin/application_controller.rb` | 管理者権限チェック |

**主要処理フロー**:
- **55-60行目**: destroy アクション

```ruby
def destroy
  @group.destroy
  respond_with(@group)
end
```

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | _group.html.haml | `app/views/admin/groups/_group.html.haml` | 削除リンクと確認メッセージ |
| 3-2 | destroy.js.haml | `app/views/admin/groups/destroy.js.haml` | 削除後の画面更新処理 |

**読解のコツ**:
- `_group.html.haml` の5-7行目で Permission.count により確認メッセージを設定
- `link_to_delete` に `confirm:` オプションで確認ダイアログを表示

#### Step 4: ルーティングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | routes.rb | `config/routes.rb` | admin/groups のルート定義 |

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

```
[削除リンククリック]
    │
    ├─ Permission.where(group_id: group.id).count
    │      └─ count > 0 の場合、確認メッセージ設定
    │
    └─ link_to_delete [:admin, group], confirm: confirm
           │
           └─ 確認ダイアログ表示（confirm が設定されている場合）

[Admin::GroupsController#destroy]
    │
    ├─ load_resource (CanCanCan)
    │      └─ Group.find(params[:id]) → @group
    │
    ├─ @group.destroy
    │      └─ groups_users 関連レコード削除（HABTM）
    │
    └─ respond_with(@group)
           └─ destroy.js.haml
                  └─ @group.destroyed? で成功/失敗を判定
```

### データフロー図

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

グループID        ───▶ load_resource             ───▶ @group
                           │
                   ───▶ Permission.count チェック
                         （ビュー側で実行）
                           │
                   ───▶ @group.destroy
                           │
                           ├─ groups テーブル削除
                           └─ groups_users 削除
                                    │
                                    ▼
                              画面更新（AJAX）
                              一覧から行を削除
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| groups_controller.rb | `app/controllers/admin/groups_controller.rb` | コントローラー | destroy アクションの実装 |
| application_controller.rb | `app/controllers/admin/application_controller.rb` | コントローラー | 管理者権限チェック |
| group.rb | `app/models/users/group.rb` | モデル | グループモデル定義 |
| _group.html.haml | `app/views/admin/groups/_group.html.haml` | ビュー | グループ行、削除リンク |
| destroy.js.haml | `app/views/admin/groups/destroy.js.haml` | ビュー | 削除後の画面更新 JS |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
| schema.rb | `db/schema.rb` | 設定 | データベーススキーマ |
