# 画面設計書 81-エージェント割り当て一覧

## 概要

本ドキュメントは、Chatwootのエージェント割り当てポリシー一覧画面の設計を記述したものです。この画面では、会話を自動的にエージェントに割り当てるためのポリシーを一覧表示・管理します。

### 本画面の処理概要

**業務上の目的・背景**：顧客サポート業務において、会話（チャット/問い合わせ）を適切なエージェントに自動割り当てすることで、対応効率の向上と均等な業務負荷の分散を実現します。本画面では、作成済みの割り当てポリシーを一覧表示し、ポリシーの有効/無効状態、関連付けられたインボックス数などを確認できます。

**画面へのアクセス方法**：サイドメニューの「設定」から「割り当てポリシー」を選択し、その後「エージェント割り当て」タブをクリックしてアクセスします。URLパスは `/app/accounts/:accountId/settings/assignment-policy/assignment` です。

**主要な操作・処理内容**：
1. 割り当てポリシーの一覧表示（カード形式でポリシー名、説明、ステータス、関連インボックス数を表示）
2. 新規ポリシー作成画面への遷移（「ポリシーを作成」ボタン）
3. 既存ポリシーの編集画面への遷移（各カードの編集ボタン）
4. ポリシーの削除（削除確認ダイアログ表示後に実行）
5. 各ポリシーに紐づくインボックスの展開表示

**画面遷移**：
- 遷移元：割り当てポリシーインデックス画面
- 遷移先：エージェント割り当て作成画面、エージェント割り当て編集画面

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | 割り当てポリシー | 主機能 | エージェント割り当てルールの一覧表示・管理 |

## 画面種別

一覧

## URL/ルーティング

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

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| accountId | 入力（URLパラメータ） | Number | 必須 | アカウントID |

## 表示項目

### ポリシーカード（AssignmentPolicyCard）

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| ポリシー名 | String | 割り当てポリシーの名前 |
| 説明 | String | ポリシーの説明文 |
| ステータス | Boolean | 有効/無効の状態 |
| 割り当て順序 | String | round_robin（ラウンドロビン）/ balanced（バランス） |
| 会話優先度 | String | earliest_created（作成順）/ longest_waiting（待機時間順） |
| 公平分配制限 | Number | 公平分配の上限値 |
| 公平分配ウィンドウ | Number | 公平分配の時間ウィンドウ（秒） |
| 関連インボックス数 | Number | このポリシーに紐づくインボックスの数 |
| 関連インボックス一覧 | Array | 展開時に表示されるインボックスリスト |

## イベント仕様

### 1-ポリシー作成ボタン押下

「ポリシーを作成」ボタン押下時、エージェント割り当て作成画面（`agent_assignment_policy_create`）に遷移します。

### 2-ポリシー編集ボタン押下

各ポリシーカードの編集アイコンボタン押下時、該当ポリシーのID付きでエージェント割り当て編集画面（`agent_assignment_policy_edit`）に遷移します。

### 3-ポリシー削除ボタン押下

各ポリシーカードの削除アイコンボタン押下時、削除確認ダイアログ（ConfirmDeletePolicyDialog）を表示します。ダイアログで確認後、Vuex Action `assignmentPolicies/delete` を実行してポリシーを削除します。

### 4-インボックス展開

各ポリシーカードの展開トリガー操作時、Vuex Action `assignmentPolicies/getInboxes` を実行し、該当ポリシーに紐づくインボックス一覧を取得・表示します。

### 5-画面マウント時

画面マウント時（onMounted）、Vuex Action `assignmentPolicies/get` を実行し、全ての割り当てポリシーを取得します。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | assignment_policies | SELECT | 全ポリシー一覧の取得 |
| インボックス展開 | inboxes | SELECT | ポリシーに紐づくインボックス取得 |
| ポリシー削除 | assignment_policies | DELETE | 指定ポリシーの削除 |

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

#### assignment_policies

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | account_id = 現在のアカウントID | 一覧取得 |
| DELETE | - | id = 指定のポリシーID | 論理削除ではなく物理削除 |

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|----------|--------------|
| DELETE_POLICY.SUCCESS_MESSAGE | 成功 | ポリシー削除成功時 | ポリシーが正常に削除されました |
| DELETE_POLICY.ERROR_MESSAGE | エラー | ポリシー削除失敗時 | ポリシーの削除に失敗しました |
| INDEX.NO_RECORDS_FOUND | 情報 | ポリシーが0件の場合 | 割り当てポリシーが見つかりません |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| ポリシー取得失敗 | エラーメッセージをアラート表示 |
| ポリシー削除失敗 | エラーメッセージをアラート表示、削除ダイアログは閉じない |
| 権限不足 | 画面アクセス不可（ルートガードで制御） |
| フィーチャーフラグ無効 | 画面アクセス不可（ルートガードで制御） |

## 備考

- Enterprise版またはCloud版でのみ利用可能な機能です
- ASSIGNMENT_V2フィーチャーフラグが有効な場合のみアクセス可能
- ポリシー削除時、紐づくインボックスの割り当て設定は解除されます

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | assignmentPolicies.js | `app/javascript/dashboard/store/modules/assignmentPolicies.js` | state構造（records, uiFlags, inboxUiFlags）とgettersの定義を確認 |
| 1-2 | constants.js | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/constants.js` | ROUND_ROBIN, BALANCED等の定数定義を確認 |

**読解のコツ**: Vuexモジュールの構造はstate -> getters -> actions -> mutationsの順で読むと理解しやすい

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AgentAssignmentIndexPage.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/AgentAssignmentIndexPage.vue` | setup関数内のstore接続、onMountedでのデータ取得、テンプレート構造 |

**主要処理フロー**:
1. **行14-22**: useMapGetterでVuexストアのgettersを取得
2. **行85-87**: onMountedで`assignmentPolicies/get`アクションをディスパッチ
3. **行45-58**: 編集・作成画面への遷移処理
4. **行69-83**: 削除処理の実装

#### Step 3: コンポーネント層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AssignmentPolicyCard.vue | `app/javascript/dashboard/components-next/AssignmentPolicy/AssignmentPolicyCard/AssignmentPolicyCard.vue` | カード表示のUI構造、emitイベント |
| 3-2 | ConfirmDeletePolicyDialog.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/components/ConfirmDeletePolicyDialog.vue` | 削除確認ダイアログの実装 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | assignmentPolicies.js | `app/javascript/dashboard/api/assignmentPolicies.js` | APIクライアントのエンドポイント定義 |
| 4-2 | assignment_policies_controller.rb | `app/controllers/api/v1/accounts/assignment_policies_controller.rb` | バックエンドのコントローラー処理 |

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

```
AgentAssignmentIndexPage.vue (エントリーポイント)
    │
    ├─ onMounted
    │      └─ store.dispatch('assignmentPolicies/get')
    │              └─ AssignmentPoliciesAPI.get()
    │                      └─ GET /api/v1/accounts/:id/assignment_policies
    │
    ├─ AssignmentPolicyCard.vue
    │      ├─ @edit → onClickEditPolicy → router.push
    │      ├─ @delete → handleDelete → ConfirmDeletePolicyDialog
    │      └─ @fetch-inboxes → handleFetchInboxes
    │              └─ store.dispatch('assignmentPolicies/getInboxes')
    │
    └─ ConfirmDeletePolicyDialog.vue
           └─ @delete → handleDeletePolicy
                   └─ store.dispatch('assignmentPolicies/delete')
                           └─ AssignmentPoliciesAPI.delete()
```

### データフロー図

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

画面マウント ────────▶ assignmentPolicies/get ────────▶ ポリシー一覧表示
                              │
                              ▼
                      API: GET /assignment_policies
                              │
                              ▼
                      Vuex State更新
                              │
                              ▼
                      useMapGetter取得
                              │
                              ▼
                      AssignmentPolicyCard表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AgentAssignmentIndexPage.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/AgentAssignmentIndexPage.vue` | ソース | メインページコンポーネント |
| assignmentPolicies.js | `app/javascript/dashboard/store/modules/assignmentPolicies.js` | ソース | Vuexストアモジュール |
| assignmentPolicies.js | `app/javascript/dashboard/api/assignmentPolicies.js` | ソース | APIクライアント |
| AssignmentPolicyCard.vue | `app/javascript/dashboard/components-next/AssignmentPolicy/AssignmentPolicyCard/AssignmentPolicyCard.vue` | ソース | ポリシーカードコンポーネント |
| ConfirmDeletePolicyDialog.vue | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/pages/components/ConfirmDeletePolicyDialog.vue` | ソース | 削除確認ダイアログ |
| assignmentPolicy.routes.js | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/assignmentPolicy.routes.js` | ソース | ルーティング定義 |
| constants.js | `app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/constants.js` | ソース | 定数定義 |
| assignment_policies_controller.rb | `app/controllers/api/v1/accounts/assignment_policies_controller.rb` | ソース | バックエンドコントローラー |
| SettingsLayout.vue | `app/javascript/dashboard/routes/dashboard/settings/SettingsLayout.vue` | ソース | 設定画面共通レイアウト |
| Breadcrumb.vue | `app/javascript/dashboard/components-next/breadcrumb/Breadcrumb.vue` | ソース | パンくずリストコンポーネント |
