# 画面設計書 86-エージェント容量編集

## 概要

本ドキュメントは、Chatwootのエージェント容量ポリシー編集画面の設計を記述したものです。この画面では、既存のエージェント容量ポリシーの設定変更、エージェントの紐づけ管理、およびインボックスごとの容量制限設定を行います。

### 本画面の処理概要

**業務上の目的・背景**：作成済みの容量ポリシーの設定を変更し、適用対象のエージェントを管理します。エージェントをポリシーに紐づけることで、そのエージェントに対して容量制限ルールが適用されます。また、インボックスごとに異なる容量制限を設定することも可能です。

**画面へのアクセス方法**：エージェント容量一覧画面から各ポリシーカードの編集ボタンをクリック、または新規作成完了後に自動遷移でアクセスします。URLパスは `/app/accounts/:accountId/settings/assignment-policy/capacity/edit/:id` です。

**主要な操作・処理内容**：
1. ポリシー基本情報（名前、説明）の編集
2. 除外ルールの変更
3. インボックス容量制限の追加・編集・削除
4. エージェントの追加（ポリシーへの紐づけ）
5. エージェントの削除（ポリシーからの紐づけ解除）
6. 設定変更の保存

**画面遷移**：
- 遷移元：エージェント容量一覧画面、エージェント容量作成画面（作成成功時）
- 遷移先：パンくずリストからエージェント容量一覧画面

**権限による表示制御**：管理者（administrator）ロールのユーザーのみがアクセス可能です。ASSIGNMENT_V2フィーチャーフラグが有効な場合にのみ表示されます。Enterprise版またはCloud版でのみ利用可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 184 | 容量ポリシー | 主機能 | 容量設定の編集 |

## 画面種別

編集

## URL/ルーティング

- **パス**: `/app/accounts/:accountId/settings/assignment-policy/capacity/edit/:id`
- **ルート名**: `agent_capacity_policy_edit`
- **パラメータ**: id（ポリシーID）

## 入出力項目

### 入力項目（フォーム）

| 項目名 | データ型 | 必須 | 初期値 | バリデーション | 説明 |
|--------|----------|------|--------|----------------|------|
| name | String | 必須 | 既存値 | 空でないこと | ポリシー名 |
| description | String | 任意 | 既存値 | なし | ポリシーの説明 |
| exclusionRules.excludedLabels | Array | 任意 | 既存値 | なし | 除外するラベルのリスト |
| exclusionRules.excludeOlderThanHours | Number | 任意 | 既存値 | 正の整数 | 指定時間より古い会話を除外 |

### インボックス容量制限管理

| 操作 | データ型 | 説明 |
|------|----------|------|
| インボックス制限追加 | Object | inboxId, conversationLimit |
| インボックス制限更新 | Object | limitId, conversationLimit |
| インボックス制限削除 | Number | limitId |

### エージェント管理

| 操作 | データ型 | 説明 |
|------|----------|------|
| エージェント追加 | Object | userId, capacity（デフォルト20） |
| エージェント削除 | Number | userId |

## 表示項目

### 基本情報セクション

作成画面と同一のフォームフィールドを表示（初期値は既存データ）

### インボックス容量制限セクション（showInboxLimitSection=true）

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| セクションタイトル | ラベル | 「インボックス容量制限」 |
| 追加ボタン | ドロップダウン付きボタン | インボックス一覧から選択して追加 |
| 制限一覧 | テーブル | インボックス名、制限値、削除ボタン |
| 制限値入力 | 数値入力 | 各インボックスの会話上限 |

### エージェントセクション（showUserSection=true）

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| セクションタイトル | ラベル | 「エージェント」 |
| 追加ボタン | ドロップダウン付きボタン | エージェント一覧から選択して追加 |
| エージェント一覧 | データテーブル | 紐づけ済みエージェントの一覧（削除ボタン付き） |

## イベント仕様

### 1-画面マウント/ルートID変更

watchでrouteIdの変化を監視し、以下を実行：
1. ポリシーがストアにない場合、`agentCapacityPolicies/show`でフェッチ
2. `agentCapacityPolicies/getUsers`で紐づきエージェントを取得
3. `agents/get`でエージェント一覧を取得

### 2-フォーム送信

1. Vuex Action `agentCapacityPolicies/update` を実行
2. 成功時：成功メッセージを表示
3. 失敗時：エラーメッセージを表示

### 3-エージェント追加

1. `agentCapacityPolicies/addUser`を実行（デフォルトcapacity: 20）
2. ストアのusersを更新

### 4-エージェント削除

1. `agentCapacityPolicies/removeUser`を実行
2. Vuex Stateから該当エージェントを削除

### 5-インボックス制限追加

1. `agentCapacityPolicies/createInboxLimit`を実行
2. ストアのinboxCapacityLimitsを更新

### 6-インボックス制限更新

1. `agentCapacityPolicies/updateInboxLimit`を実行
2. 該当制限のconversationLimitを更新

### 7-インボックス制限削除

1. `agentCapacityPolicies/deleteInboxLimit`を実行
2. ストアから該当制限を削除

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | agent_capacity_policies | SELECT | ポリシー情報取得 |
| 画面表示 | account_users | SELECT | 紐づきエージェント取得 |
| フォーム送信 | agent_capacity_policies | UPDATE | ポリシー情報更新 |
| エージェント追加 | account_users | INSERT/UPDATE | agent_capacity_policy_id設定 |
| エージェント削除 | account_users | UPDATE | agent_capacity_policy_idをnull |
| 制限追加 | inbox_capacity_limits | INSERT | 新規制限レコード作成 |
| 制限更新 | inbox_capacity_limits | UPDATE | conversation_limit更新 |
| 制限削除 | inbox_capacity_limits | DELETE | 制限レコード削除 |

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

#### agent_capacity_policies

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | id = URLパラメータのid | 単一ポリシー取得 |
| UPDATE | name, description, exclusion_rules | フォーム入力値 | 部分更新 |

#### account_users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | agent_capacity_policy_id = ポリシーID | 紐づきエージェント |
| UPDATE | agent_capacity_policy_id | ポリシーID or null | 紐づけ/解除 |

#### inbox_capacity_limits

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | inbox_id, conversation_limit, agent_capacity_policy_id | フォーム入力値 | 新規制限 |
| UPDATE | conversation_limit | フォーム入力値 | 制限値更新 |
| DELETE | - | id = 指定のlimitId | 制限削除 |

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|----------|--------------|
| EDIT.API.SUCCESS_MESSAGE | 成功 | ポリシー更新成功時 | ポリシーが正常に更新されました |
| EDIT.API.ERROR_MESSAGE | エラー | ポリシー更新失敗時 | ポリシーの更新に失敗しました |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| ポリシーが見つからない | ストアからフェッチ試行、失敗時はエラー |
| 名前が空 | 送信ボタンを無効化 |
| API呼び出し失敗 | エラーメッセージをアラート表示 |

## 備考

- エージェントは1つのポリシーにのみ紐づけ可能
- 編集画面ではエージェントセクションとインボックス制限セクションが表示される（作成画面では非表示）
- インボックス容量制限により、特定インボックスでの会話上限を個別に設定可能
- Enterprise版またはCloud版でのみ利用可能です

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | agentCapacityPolicies.js | `app/javascript/dashboard/store/modules/agentCapacityPolicies.js` | getters, actions（show, update, getUsers, addUser, removeUser, createInboxLimit等） |
| 1-2 | inbox_capacity_limit.rb | `enterprise/app/models/inbox_capacity_limit.rb` | インボックス容量制限のモデル定義 |

**読解のコツ**: 編集画面特有のアクションが多いため、actions部分を重点的に読む

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AgentCapacityEditPage.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/AgentCapacityEditPage.vue` | watchによるデータフェッチ、各ハンドラ関数 |

**主要処理フロー**:
1. **行31-33**: routeIdとselectedPolicyのcomputed定義
2. **行76-90**: formDataの構築（既存値をフォームに反映）
3. **行147-158**: fetchPolicyDataでポリシーとユーザーをフェッチ
4. **行134-145**: handleSubmitでupdateアクションをディスパッチ
5. **行95-107**: handleAddUser / handleDeleteUser
6. **行109-132**: インボックス制限の追加・更新・削除ハンドラ

#### Step 3: フォームコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AgentCapacityPolicyForm.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/components/AgentCapacityPolicyForm.vue` | showUserSection/showInboxLimitSection時のセクション表示 |
| 3-2 | InboxCapacityLimits.vue | `app/javascript/dashboard/components-next/AssignmentPolicy/components/InboxCapacityLimits.vue` | インボックス容量制限の管理UI |
| 3-3 | DataTable.vue | `app/javascript/dashboard/components-next/AssignmentPolicy/components/DataTable.vue` | エージェント一覧テーブル |

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

```
AgentCapacityEditPage.vue (エントリーポイント)
    │
    ├─ watch(routeId) → fetchPolicyData
    │      ├─ agentCapacityPolicies/show（ポリシー未取得時）
    │      ├─ agentCapacityPolicies/getUsers
    │      └─ agents/get
    │
    ├─ AgentCapacityPolicyForm.vue
    │      │
    │      ├─ @submit → handleSubmit
    │      │      └─ agentCapacityPolicies/update
    │      │
    │      ├─ InboxCapacityLimits.vue
    │      │      ├─ @add → handleAddInboxLimit
    │      │      │      └─ agentCapacityPolicies/createInboxLimit
    │      │      ├─ @update → handleLimitChange
    │      │      │      └─ agentCapacityPolicies/updateInboxLimit
    │      │      └─ @delete → handleDeleteInboxLimit
    │      │              └─ agentCapacityPolicies/deleteInboxLimit
    │      │
    │      ├─ @add-user → handleAddUser
    │      │      └─ agentCapacityPolicies/addUser
    │      │
    │      └─ @delete-user → handleDeleteUser
    │              └─ agentCapacityPolicies/removeUser
```

### データフロー図

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

URL params.id ─────────▶ fetchPolicyData ──────────────▶
                              │
                              ▼
                      agentCapacityPolicies/show
                      agentCapacityPolicies/getUsers
                      agents/get
                              │
                              ▼
                      Vuex State更新
                              │
                              ▼
                      formData computed生成 ────────────▶ フォーム表示
                              │
フォーム入力 ─────────────────▶
                              │
                              ▼
                      @submit → handleSubmit
                              │
                              ▼
                      agentCapacityPolicies/update ─────▶ DB更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AgentCapacityEditPage.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/AgentCapacityEditPage.vue` | ソース | 編集ページコンポーネント |
| AgentCapacityPolicyForm.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/components/AgentCapacityPolicyForm.vue` | ソース | フォームコンポーネント |
| InboxCapacityLimits.vue | `app/javascript/dashboard/components-next/AssignmentPolicy/components/InboxCapacityLimits.vue` | ソース | インボックス容量制限管理 |
| DataTable.vue | `app/javascript/dashboard/components-next/AssignmentPolicy/components/DataTable.vue` | ソース | データテーブル |
| AddDataDropdown.vue | `app/javascript/dashboard/components-next/AssignmentPolicy/components/AddDataDropdown.vue` | ソース | 追加ドロップダウン |
| agentCapacityPolicies.js | `app/javascript/dashboard/store/modules/agentCapacityPolicies.js` | ソース | Vuexストア |
| agentCapacityPolicies.js | `app/javascript/dashboard/api/agentCapacityPolicies.js` | ソース | APIクライアント |
| agent_capacity_policies_controller.rb | `enterprise/app/controllers/api/v1/accounts/agent_capacity_policies_controller.rb` | ソース | バックエンドコントローラー |
| users_controller.rb | `enterprise/app/controllers/api/v1/accounts/agent_capacity_policies/users_controller.rb` | ソース | ユーザー関連コントローラー |
| inbox_limits_controller.rb | `enterprise/app/controllers/api/v1/accounts/agent_capacity_policies/inbox_limits_controller.rb` | ソース | 制限関連コントローラー |
