# 画面設計書 38-グループ管理一覧画面

## 概要

本ドキュメントは、Fat Free CRMにおけるグループ管理一覧画面（管理者用）の設計仕様を記載する。本画面は管理者がシステム内のグループを一覧表示・管理するための機能を提供する。

### 本画面の処理概要

本画面は、管理者がシステム内の全グループを一覧表示し、グループの新規作成、編集、削除などの管理操作を行うための画面である。グループはユーザーをまとめて管理するための単位であり、アクセス権限の設定などに利用される。

**業務上の目的・背景**：CRMシステムでは、ユーザーをグループ単位で管理することで、エンティティ（取引先、商談、連絡先等）へのアクセス権限を効率的に設定できる。例えば、「営業1部」グループに所属するユーザー全員に特定の取引先へのアクセス権を付与するといった運用が可能になる。本画面は、そのグループの作成・管理を行う管理者向けの機能を提供する。

**画面へのアクセス方法**：以下の方法でアクセス可能：
1. 管理画面のナビゲーションから「Groups」を選択
2. URL `/admin/groups` に直接アクセス

**主要な操作・処理内容**：
1. システム内の全グループ一覧を表示（ページネーション対応）
2. 新規グループの作成
3. グループ情報の編集
4. グループの削除（確認ダイアログ付き）
5. グループメンバーの確認

**画面遷移**：
- 遷移元：管理画面トップ、ナビゲーションメニュー
- 遷移先：グループ管理詳細画面、グループ管理新規作成フォーム、グループ管理編集フォーム

**権限による表示制御**：管理者（admin）ユーザーのみがアクセス可能。Admin::ApplicationControllerの認証・認可により制御される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 65 | グループ管理一覧 | 主機能 | グループ一覧表示（管理者用） |
| 68 | グループ削除 | 補助機能 | グループの削除処理 |

## 画面種別

一覧（管理）

## URL/ルーティング

| HTTPメソッド | URL | コントローラ#アクション | 説明 |
|-------------|-----|----------------------|------|
| GET | /admin/groups | admin/groups#index | グループ一覧表示 |
| GET | /admin/groups/new | admin/groups#new | 新規作成フォーム |
| POST | /admin/groups | admin/groups#create | グループ作成 |
| GET | /admin/groups/:id | admin/groups#show | グループ詳細 |
| GET | /admin/groups/:id/edit | admin/groups#edit | 編集フォーム |
| PUT/PATCH | /admin/groups/:id | admin/groups#update | グループ更新 |
| DELETE | /admin/groups/:id | admin/groups#destroy | グループ削除 |

## 入出力項目

本画面は一覧表示が主機能のため、入力項目はページネーションのみ。

| 項目名 | 項目ID | 入力タイプ | 必須 | 備考 |
|--------|--------|-----------|------|------|
| ページ番号 | page | hidden | - | ページネーション用 |

## 表示項目

### グループ一覧（各行）

| 項目名 | データソース | 表示形式 | 備考 |
|--------|------------|---------|------|
| グループ名 | Group#name | リンク | 編集フォームへ遷移（Ajax） |
| メンバー | Group#users | リンクリスト | ユーザープロフィールへ遷移 |

### 操作リンク（各行）

| リンク名 | 遷移先/動作 | 備考 |
|---------|------------|------|
| Edit | /admin/groups/:id/edit | 編集フォーム（Ajax） |
| Delete | /admin/groups/:id | 削除（確認ダイアログ付き） |

## イベント仕様

### 1-画面表示（一覧取得）

**トリガー**: 画面アクセス（GET /admin/groups）

**処理フロー**:
1. Admin::GroupsController#index アクションが呼び出される
2. @groups.unscoped.paginate(page: params[:page]) でグループ一覧を取得
3. index.html.haml が描画される

**コントローラ処理（admin/groups_controller.rb 15-17行目）**:
```ruby
def index
  @groups = @groups.unscoped.paginate(page: params[:page])
end
```

### 2-グループ新規作成リンク押下

**トリガー**: 「Create Group」リンクのクリック

**処理フロー**:
1. Ajax で GET /admin/groups/new リクエストが送信される
2. _new.html.haml パーシャルが応答
3. #create_group 領域に新規作成フォームを展開

### 3-グループ編集リンク押下

**トリガー**: 編集リンク（グループ名）のクリック

**処理フロー**:
1. Ajax で GET /admin/groups/:id/edit リクエストが送信される
2. _edit.html.haml パーシャルが応答
3. 連続編集のため previous パラメータで前回の編集フォームを特定

### 4-グループ削除

**トリガー**: 「Delete」リンクのクリック（確認後）

**処理フロー**:
1. グループに紐付く権限（Permission）の数をカウント
2. 0件以外の場合、確認メッセージを表示
3. 確認後、DELETE /admin/groups/:id リクエストが送信される
4. @group.destroy を実行
5. destroy.js.haml が応答し、一覧から削除

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | groups, users, groups_users | SELECT | グループ一覧とメンバーを取得 |
| グループ削除 | groups | DELETE | グループを削除 |
| グループ削除 | groups_users | DELETE | グループ・ユーザー関連を削除 |
| グループ削除 | permissions | UPDATE/DELETE | 関連権限を更新/削除 |

### テーブル別クエリ詳細

#### groups

| 操作 | 条件 | 備考 |
|-----|------|------|
| SELECT | ORDER BY id（unscoped） | ページネーション適用 |
| DELETE | WHERE id = :id | グループ削除時 |

#### permissions

| 操作 | 条件 | 備考 |
|-----|------|------|
| SELECT COUNT | WHERE group_id = :id | 削除確認メッセージ用 |

## メッセージ仕様

| 種別 | メッセージキー | 表示内容 | 表示条件 |
|------|--------------|---------|---------|
| ラベル | groups | グループ | 画面タイトル |
| ラベル | create_group | グループ作成 | 作成リンク |
| ラベル | group_members | メンバー | メンバー表示ラベル |
| 確認 | confirm_group_delete | このグループには{count}件の権限設定があります。削除しますか？ | 権限設定がある場合 |

## 例外処理

| 例外 | 対応 |
|------|------|
| 未認証アクセス | ログイン画面へリダイレクト |
| 管理者以外のアクセス | 403 Forbidden を返却 |
| グループが見つからない | 404 Not Found を返却 |

## 備考

- グループが空の場合は shared/empty パーシャルが表示される
- styles_for :group により グループ用のスタイルシートが読み込まれる
- 削除時に Permission のカウントを確認し、関連データがある場合は確認メッセージを表示
- グループ名リンクは連続編集に対応（previous パラメータで前回フォームを特定）
- ページネーションは will_paginate を使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | group.rb | `app/models/users/group.rb` | Groupモデルの構造、アソシエーション（8-11行目） |
| 1-2 | schema.rb | `db/schema.rb` | groupsテーブル（273-277行目）、groups_usersテーブル（279-285行目） |

**読解のコツ**: Groupモデルは `has_and_belongs_to_many :users`（9行目）と `has_many :permissions`（10行目）のアソシエーションを持つ。

```ruby
class Group < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_many :permissions
  validates :name, presence: true, uniqueness: true
end
```

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | routes.rb | `config/routes.rb` | admin/groups リソース（166行目） |
| 2-2 | admin/groups_controller.rb | `app/controllers/admin/groups_controller.rb` | index, destroy アクション |

**主要処理フロー**:
1. **12行目**: `load_resource` で @group, @groups をロード
2. **15-17行目**: index アクションで `@groups.unscoped.paginate(page: params[:page])`
3. **55-60行目**: destroy アクションで `@group.destroy`

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/admin/groups/index.html.haml` | 全体構造（1-19行目） |
| 3-2 | _group.html.haml | `app/views/admin/groups/_group.html.haml` | グループ行表示（1-17行目） |

**主要処理フロー**:
- **index.html.haml 4行目**: `link_to_inline(:create_group, new_admin_group_path)` で作成リンク
- **index.html.haml 13-14行目**: グループが存在する場合 _group パーシャルを描画、なければ shared/empty
- **_group.html.haml 4行目**: `link_to_edit [:admin, group]` で編集リンク
- **_group.html.haml 5-7行目**: Permission.where(group_id: group.id).count で削除確認メッセージ生成
- **_group.html.haml 10-11行目**: グループ名リンク（Ajax編集対応）
- **_group.html.haml 13-16行目**: メンバーリスト表示

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

```
リクエスト: GET /admin/groups
    │
    ├─ routes.rb
    │      └─ namespace :admin { resources :groups }
    │
    ├─ Admin::GroupsController
    │      ├─ before_action :setup_current_tab
    │      ├─ load_resource (CanCanCan)
    │      │
    │      └─ index (15-17行目)
    │             └─ @groups.unscoped.paginate(page:)
    │
    └─ index.html.haml
           ├─ link_to_inline(:create_group)
           │
           ├─ @groups.any? ?
           │      ├─ render partial: "_group", collection: @groups
           │      │      └─ _group.html.haml
           │      │             ├─ link_to_edit
           │      │             ├─ link_to_delete (confirm付き)
           │      │             ├─ グループ名リンク（Ajax）
           │      │             └─ メンバーリスト
           │      │
           │      └─ render "shared/empty"
           │
           └─ render "shared/paginate"
```

### データフロー図

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

HTTPリクエスト   ───▶ Admin::GroupsController  ───▶ index.html.haml
GET /admin/groups     │                            │
                      ├─ load_resource             ├─ グループ一覧
                      │                            │      └─ _group.html.haml
                      └─ @groups.paginate          │
                                                   ├─ ページネーション
                                                   │      └─ shared/paginate
                                                   │
                                                   └─ 空の場合
                                                          └─ shared/empty
```

```
[削除フロー]

リンクclick      ───▶ JavaScript確認 ───▶ Admin::GroupsController#destroy
DELETE /admin/        │                        │
groups/:id            └─ Permission.count      └─ @group.destroy
                           │                         │
                           └─ 確認メッセージ生成       ├─ DELETE groups
                                                     └─ DELETE groups_users
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.html.haml | `app/views/admin/groups/index.html.haml` | ビュー | グループ管理一覧画面 |
| _group.html.haml | `app/views/admin/groups/_group.html.haml` | パーシャル | グループ行表示 |
| _new.html.haml | `app/views/admin/groups/_new.html.haml` | パーシャル | 新規作成フォーム |
| _edit.html.haml | `app/views/admin/groups/_edit.html.haml` | パーシャル | 編集フォーム |
| groups_controller.rb | `app/controllers/admin/groups_controller.rb` | コントローラ | 管理者用グループ操作 |
| group.rb | `app/models/users/group.rb` | モデル | Groupモデル定義 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
| _paginate.html.haml | `app/views/shared/_paginate.html.haml` | パーシャル | ページネーション |
| _empty.html.haml | `app/views/shared/_empty.html.haml` | パーシャル | 空表示 |
