# 機能設計書 67-グループ編集

## 概要

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

### 本機能の処理概要

管理者が既存グループの情報を更新するための機能である。グループ名の変更や所属ユーザーの追加・削除を行うことができる。

**業務上の目的・背景**：組織の変更やプロジェクトの進行に伴い、グループの構成を柔軟に変更する必要がある。本機能により、グループ名の変更やメンバーの入れ替えを効率的に行うことができる。

**機能の利用シーン**：
- 部署名変更に伴うグループ名の更新
- チームメンバーの追加・削除
- プロジェクト体制変更に伴うグループ構成の変更
- 誤って登録したグループ情報の修正

**主要な処理内容**：
1. 編集対象グループの特定と既存情報の取得
2. 編集フォームの表示（AJAX）
3. フォーム入力値のバリデーション
4. グループ情報の更新（グループ名、所属ユーザー）

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

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 41 | グループ管理編集フォーム | 主画面 | グループ情報更新 |
| 38 | グループ管理一覧画面 | 参照画面 | 編集リンクからの遷移元 |

## 機能種別

CRUD操作（Update）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | Integer | Yes | 編集対象グループID | 存在するグループID |
| group[name] | String | Yes | グループ名 | 必須、一意性 |
| group[user_ids] | Array | No | 所属ユーザーID配列 | 存在するユーザーID |

### 入力データソース

- 画面入力（編集フォーム）
- URL パラメータ（グループID）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @group | Group | 更新後のグループオブジェクト |
| errors | Array | バリデーションエラーメッセージ |

### 出力先

- 画面表示（AJAX レスポンスによる部分更新）
- groups テーブル
- groups_users テーブル（ユーザー所属変更時）

## 処理フロー

### 処理シーケンス

```
1. 管理者がグループ一覧画面で編集リンクをクリック
   └─ AJAX リクエスト: GET /admin/groups/:id/edit

2. edit アクションで編集フォームを表示
   └─ @group にグループ情報をロード
   └─ 編集フォーム HTML を返却

3. 管理者がフォームに情報を入力して送信
   └─ AJAX リクエスト: PUT /admin/groups/:id

4. update アクションでグループ情報を更新
   └─ group_params でパラメータをフィルタリング
   └─ @group.update でバリデーションと保存

5. 更新結果を返却
   └─ 成功時: グループ一覧の該当行を更新
   └─ 失敗時: エラーメッセージを表示
```

### フローチャート

```mermaid
flowchart TD
    A[編集リンククリック] --> B[GET /admin/groups/:id/edit]
    B --> C[load_resource でグループ取得]
    C --> D[編集フォーム表示]
    D --> E[フォーム入力・送信]
    E --> F[PUT /admin/groups/:id]
    F --> G[group_params でフィルタリング]
    G --> H{バリデーション}
    H -->|成功| I[グループ情報更新]
    I --> J[groups_users 関連更新]
    J --> K[画面更新 JS 返却]
    H -->|失敗| L[エラー表示]
    L --> D
    K --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-67-01 | グループ名必須 | グループ名は必須入力 | 常時 |
| BR-67-02 | グループ名一意性 | 他のグループと重複しない名前である必要がある | 常時 |
| BR-67-03 | ユーザー差分更新 | 選択されたユーザーと現在の所属を比較し、差分を更新 | 常時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| グループ情報更新 | groups | UPDATE | グループ名の更新 |
| ユーザー関連更新 | groups_users | DELETE/INSERT | グループとユーザーの関連再構築 |

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

#### groups

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | フォーム入力値 | 一意性チェック |
| UPDATE | updated_at | 現在時刻 | 自動更新 |

#### groups_users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE/INSERT | group_id | 対象グループID | HABTM により管理 |
| DELETE/INSERT | user_id | 選択されたユーザーID | HABTM により管理 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バリデーションエラー | グループ名が未入力 | フォームにエラーメッセージを表示 |
| - | バリデーションエラー | グループ名が重複 | フォームにエラーメッセージを表示 |
| - | 認可エラー | 非管理者によるアクセス | ルート画面にリダイレクト |

### リトライ仕様

バリデーションエラー時は編集フォームを再表示し、ユーザーが修正後に再送信可能。

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

ActiveRecord のデフォルトトランザクションにより、update メソッド実行時に自動的にトランザクション管理される。HABTM 関連（groups_users）の更新も同一トランザクション内で処理される。

## パフォーマンス要件

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

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

- 管理者権限チェック（before_action :require_admin_user）
- Strong Parameters によるパラメータフィルタリング
- CSRF トークンによるクロスサイトリクエストフォージェリ対策

## 備考

- 編集フォームは AJAX で表示されるため、ページ遷移なしで操作可能
- ユーザー選択は select2 による複数選択 UI
- グループ名をクリックしても編集フォームが開く

---

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

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

### 推奨読解順序

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

まず、グループモデルのバリデーションとユーザーとの関連を理解することが重要。

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

**読解のコツ**:
- **12行目**: `validates :name, presence: true, uniqueness: true` で必須・一意性バリデーション
- **9行目**: `has_and_belongs_to_many :users` によりユーザーとの多対多関連

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

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

**主要処理フロー**:
- **32-35行目**: edit アクション

```ruby
def edit
  respond_with(@group)
end
```

- **47-52行目**: update アクション

```ruby
def update
  @group.update(group_params)
  respond_with(@group)
end
```

- **64-66行目**: group_params メソッド

```ruby
def group_params
  params.require(:group).permit(:name, user_ids: [])
end
```

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.js.haml | `app/views/admin/groups/edit.js.haml` | 編集フォーム表示 JS |
| 3-2 | _edit.html.haml | `app/views/admin/groups/_edit.html.haml` | 編集フォーム HTML |
| 3-3 | _form.html.haml | `app/views/admin/groups/_form.html.haml` | フォーム共通部分 |
| 3-4 | update.js.haml | `app/views/admin/groups/update.js.haml` | 更新完了後の JS 処理 |

**読解のコツ**:
- `_edit.html.haml` は `.remote` クラス内でフォームを定義
- `_form.html.haml` は新規作成と編集で共通利用

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

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

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

```
[Admin::GroupsController#edit]
    │
    ├─ load_resource (CanCanCan)
    │      └─ Group.find(params[:id]) → @group
    │
    └─ respond_with(@group)
           └─ edit.js.haml
                  └─ _edit.html.haml
                         └─ _form.html.haml

[Admin::GroupsController#update]
    │
    ├─ load_resource (CanCanCan)
    │      └─ Group.find(params[:id]) → @group
    │
    ├─ group_params
    │      └─ params.require(:group).permit(:name, user_ids: [])
    │
    ├─ @group.update(group_params)
    │      ├─ Group バリデーション
    │      │      ├─ name presence
    │      │      └─ name uniqueness
    │      └─ groups_users 関連更新
    │
    └─ respond_with(@group)
           └─ update.js.haml
```

### データフロー図

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

編集フォーム入力    ───▶ group_params              ───▶ groups テーブル
                           │                              │
group[name]         ───▶ バリデーション           ───▶ groups_users テーブル
group[user_ids]     ───▶ HABTM関連更新                  │
                                                         ▼
                                                   画面更新（AJAX）
                                                   一覧の行を更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| groups_controller.rb | `app/controllers/admin/groups_controller.rb` | コントローラー | edit/update アクションの実装 |
| application_controller.rb | `app/controllers/admin/application_controller.rb` | コントローラー | 管理者権限チェック |
| group.rb | `app/models/users/group.rb` | モデル | グループモデル定義、バリデーション |
| edit.js.haml | `app/views/admin/groups/edit.js.haml` | ビュー | 編集フォーム表示 JS |
| _edit.html.haml | `app/views/admin/groups/_edit.html.haml` | ビュー | 編集フォーム HTML |
| _form.html.haml | `app/views/admin/groups/_form.html.haml` | ビュー | フォーム共通部分 |
| update.js.haml | `app/views/admin/groups/update.js.haml` | ビュー | 更新完了後 JS |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
| schema.rb | `db/schema.rb` | 設定 | データベーススキーマ |
