# 画面設計書 85-エージェント容量作成

## 概要

本ドキュメントは、Chatwootのエージェント容量ポリシー作成画面の設計を記述したものです。この画面では、新しいエージェント容量ポリシーを作成します。

### 本画面の処理概要

**業務上の目的・背景**：顧客サポート業務において、エージェントの会話処理容量を制限するポリシーを定義します。ポリシーでは除外ルール（特定ラベルの会話を除外、古い会話を除外）を設定でき、エージェントの適切な業務負荷管理を実現します。

**画面へのアクセス方法**：エージェント容量一覧画面から「ポリシーを作成」ボタンをクリックしてアクセスします。URLパスは `/app/accounts/:accountId/settings/assignment-policy/capacity/create` です。

**主要な操作・処理内容**：
1. ポリシー名の入力（必須）
2. ポリシー説明の入力（任意）
3. 除外ルールの設定（除外ラベル、除外時間）
4. フォーム送信によるポリシー作成

**画面遷移**：
- 遷移元：エージェント容量一覧画面
- 遷移先：作成成功時はエージェント容量編集画面に自動遷移（エージェント設定のため）

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

## 関連機能

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

## 画面種別

登録

## URL/ルーティング

- **パス**: `/app/accounts/:accountId/settings/assignment-policy/capacity/create`
- **ルート名**: `agent_capacity_policy_create`

## 入出力項目

### 入力項目

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

## 表示項目

### 基本情報セクション（BaseInfo）

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| ポリシー名入力 | テキストフィールド | 必須入力、プレースホルダー付き |
| 説明入力 | テキストエリア | 任意入力、プレースホルダー付き |

### 除外ルールセクション（ExclusionRules）

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| 除外ラベル | マルチセレクト | 容量計算から除外するラベルを選択 |
| 除外時間 | 数値入力 | 指定時間（時間単位）より古い会話を除外 |

## イベント仕様

### 1-フォーム送信

フォームのsubmitイベント時、以下の処理を実行します：
1. バリデーション確認（nameが空でないか）
2. Vuex Action `agentCapacityPolicies/create` を実行
3. 成功時：成功メッセージを表示し、作成されたポリシーの編集画面に遷移
4. 失敗時：エラーメッセージを表示

### 2-パンくずリストクリック

パンくずリストの「エージェント容量」クリック時、エージェント容量一覧画面（`agent_capacity_policy_index`）に遷移します。

### 3-除外ラベル選択

ラベルセレクタで選択/解除時、state.exclusionRules.excludedLabelsを更新します。

### 4-バリデーション状態変更

BaseInfoコンポーネントからのvalidationChangeイベント時、送信ボタンの有効/無効状態を更新します。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| フォーム送信 | agent_capacity_policies | INSERT | 新規ポリシーの作成 |

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

#### agent_capacity_policies

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | フォーム入力値 | 必須、最大255文字 |
| INSERT | description | フォーム入力値 | 任意 |
| INSERT | exclusion_rules | JSONオブジェクト | excluded_labels, exclude_older_than_hours |
| INSERT | account_id | 現在のアカウントID | 自動設定 |

## メッセージ仕様

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

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| 名前が空 | 送信ボタンを無効化、バリデーションエラー表示 |
| API呼び出し失敗 | エラーメッセージをアラート表示 |
| 権限不足 | 画面アクセス不可（ルートガードで制御） |
| フィーチャーフラグ無効 | 画面アクセス不可（ルートガードで制御） |

## 備考

- 作成成功後は自動的に編集画面に遷移し、エージェントの紐づけやインボックス容量制限の設定が可能になります
- 除外ルールにより、特定条件の会話を容量計算から除外できます
- Enterprise版またはCloud版でのみ利用可能です

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | agentCapacityPolicies.js | `app/javascript/dashboard/store/modules/agentCapacityPolicies.js` | createアクションの実装（行69-86） |
| 1-2 | agent_capacity_policy.rb | `enterprise/app/models/agent_capacity_policy.rb` | exclusion_rulesのJSONB構造 |

**読解のコツ**: exclusion_rulesはJSONBカラムとして保存される点に注意

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AgentCapacityCreatePage.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/AgentCapacityCreatePage.vue` | handleSubmit関数、labelsList getter |

**主要処理フロー**:
1. **行17-18**: formRefとuiFlagsの取得
2. **行20-26**: allLabels computedでラベル一覧を整形
3. **行44-66**: handleSubmit関数でcreateアクションをディスパッチ
4. **行55-60**: 成功時に編集画面へルーター遷移

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AgentCapacityPolicyForm.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/components/AgentCapacityPolicyForm.vue` | フォームのstate構造、ExclusionRulesセクション |
| 3-2 | BaseInfo.vue | `app/javascript/dashboard/components-next/AssignmentPolicy/components/BaseInfo.vue` | 名前・説明の入力コンポーネント |
| 3-3 | ExclusionRules.vue | `app/javascript/dashboard/components-next/AssignmentPolicy/components/ExclusionRules.vue` | 除外ルール設定のUI |

**主要処理フロー（AgentCapacityPolicyForm.vue）**:
- **行82-90**: stateのリアクティブ定義（exclusionRules含む）
- **行158-164**: ExclusionRulesコンポーネントの使用
- **行129-131**: handleSubmitでemit('submit', state)

#### Step 4: API層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | agentCapacityPolicies.js（API） | `app/javascript/dashboard/api/agentCapacityPolicies.js` | ApiClientの継承とエンドポイント |
| 4-2 | agent_capacity_policies_controller.rb | `enterprise/app/controllers/api/v1/accounts/agent_capacity_policies_controller.rb` | createアクションのpermitted_params |

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

```
AgentCapacityCreatePage.vue (エントリーポイント)
    │
    └─ AgentCapacityPolicyForm.vue
           │
           ├─ BaseInfo.vue
           │      └─ @validation-change → validationState更新
           │
           ├─ ExclusionRules.vue
           │      ├─ v-model:excluded-labels → state.exclusionRules.excludedLabels
           │      └─ v-model:exclude-older-than-minutes → state.exclusionRules.excludeOlderThanHours
           │
           └─ @submit → handleSubmit
                  └─ store.dispatch('agentCapacityPolicies/create')
                          │
                          ├─ AgentCapacityPoliciesAPI.create()
                          │      └─ POST /api/v1/accounts/:id/agent_capacity_policies
                          │
                          └─ 成功時: router.push → agent_capacity_policy_edit
```

### データフロー図

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

フォーム入力 ─────────▶ state（reactive） ─────────────▶
                              │
                              ▼
                      @submit イベント
                              │
                              ▼
                      handleSubmit
                              │
                              ▼
                      agentCapacityPolicies/create
                              │
                              ▼
                      POST /agent_capacity_policies ───▶ 新規ポリシーレコード
                              │
                              ▼
                      Vuex State更新
                              │
                              ▼
                      router.push（編集画面へ遷移）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AgentCapacityCreatePage.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/AgentCapacityCreatePage.vue` | ソース | 作成ページコンポーネント |
| AgentCapacityPolicyForm.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/components/AgentCapacityPolicyForm.vue` | ソース | フォームコンポーネント |
| BaseInfo.vue | `app/javascript/dashboard/components-next/AssignmentPolicy/components/BaseInfo.vue` | ソース | 基本情報入力 |
| ExclusionRules.vue | `app/javascript/dashboard/components-next/AssignmentPolicy/components/ExclusionRules.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` | ソース | バックエンドコントローラー |
| agent_capacity_policy.rb | `enterprise/app/models/agent_capacity_policy.rb` | ソース | モデル定義 |
| SettingsLayout.vue | `app/javascript/dashboard/routes/dashboard/settings/SettingsLayout.vue` | ソース | 設定画面共通レイアウト |
