# 画面設計書 46-エージェント一覧画面

## 概要

本ドキュメントは、Chatwootのエージェント一覧画面の設計仕様を定義するものである。

### 本画面の処理概要

アカウントに所属するエージェント（サポート担当者）の一覧を表示・管理する画面。エージェントの追加、編集、削除を行うことができる。各エージェントのロール、確認状態、可用性ステータスなどを一覧で確認できる。

**業務上の目的・背景**：エージェントはカスタマーサポートを担当するユーザーであり、アカウント内で複数のエージェントが協力して顧客対応を行う。管理者はこの画面でエージェントの追加・管理を行い、適切な権限を付与する。エージェントの確認状態（招待メール確認済み/未確認）を把握することで、オンボーディング状況も管理できる。

**画面へのアクセス方法**：サイドメニューの「設定」から「エージェント」を選択することでアクセスする。管理者権限を持つユーザーのみがアクセス可能。

**主要な操作・処理内容**：
1. エージェント一覧の表示（アバター、名前、メール、ロール、確認状態）
2. 新規エージェントの追加（招待メール送信）
3. 既存エージェントの編集（ロール、可用性、カスタムロール変更）
4. エージェントの削除

**画面遷移**：
- 遷移元：設定メニュー
- 遷移先：エージェント追加モーダル、エージェント編集モーダル

**権限による表示制御**：管理者（administrator）のみがアクセス可能。自分自身の編集・削除ボタンは非表示。最後の管理者は削除不可。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | ロール管理 | 主機能 | エージェントの一覧と管理 |
| 12 | カスタムロール | 補助機能 | カスタムロールの表示・適用 |

## 画面種別

一覧

## URL/ルーティング

```
/app/accounts/:accountId/settings/agents
```

- パラメータ:
  - `accountId`: アカウントID

## 入出力項目

### エージェント追加モーダル入力項目

| 項目名 | 型 | 必須 | バリデーション | 説明 |
|--------|-----|------|--------------|------|
| メールアドレス | String | ○ | email形式 | 招待メール送信先 |
| 名前 | String | ○ | - | エージェント表示名 |
| ロール | Select | ○ | - | administrator/agent |
| 可用性 | Select | - | - | online/busy/offline |
| 自動オフライン | Boolean | - | - | 自動オフライン設定 |

### エージェント編集モーダル入力項目

| 項目名 | 型 | 必須 | バリデーション | 説明 |
|--------|-----|------|--------------|------|
| 名前 | String | ○ | - | エージェント表示名 |
| ロール | Select | ○ | - | administrator/agent |
| 可用性 | Select | - | - | online/busy/offline |
| カスタムロール | Select | - | - | カスタムロール選択（カスタムロール有効時） |

## 表示項目

### ヘッダー

| 項目名 | 型 | 説明 |
|--------|-----|------|
| タイトル | String | 「エージェント」 |
| 説明文 | String | エージェント管理の説明 |
| 追加ボタン | Button | 新規エージェント追加モーダルを開く |

### エージェント一覧テーブル

| 項目名 | 型 | 説明 |
|--------|-----|------|
| アバター | Image | エージェントのアバター画像 |
| 可用性ステータス | Badge | online/busy/offlineのインジケータ |
| 名前 | String | エージェントの表示名 |
| メールアドレス | String | エージェントのメールアドレス |
| ロール | String | administrator/agent/カスタムロール名 |
| 確認状態 | Badge | 確認済み/確認待ち |
| 編集ボタン | Button | 編集モーダルを開く |
| 削除ボタン | Button | 削除確認モーダルを開く |

## イベント仕様

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

**トリガー**: 追加ボタンクリック → モーダルで追加実行

**処理フロー**:
1. ユーザーが追加ボタンをクリック
2. `openAddPopup`で追加モーダルを表示
3. フォーム入力後、AddAgentコンポーネントが`agents/create`をディスパッチ
4. APIエンドポイント`POST /api/v1/accounts/:accountId/agents`にリクエスト
5. AgentBuilderで新規エージェント作成、招待メール送信
6. 成功時：モーダルを閉じ、一覧を更新
7. 失敗時：エラーメッセージ表示

### 2-エージェント編集

**トリガー**: 編集ボタンクリック → モーダルで編集実行

**処理フロー**:
1. ユーザーが編集ボタンをクリック
2. `openEditPopup`で編集モーダルを表示
3. フォーム入力後、EditAgentコンポーネントが`agents/update`をディスパッチ
4. APIエンドポイント`PATCH /api/v1/accounts/:accountId/agents/:id`にリクエスト
5. 成功時：モーダルを閉じ、一覧を更新
6. 失敗時：エラーメッセージ表示

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

**トリガー**: 削除ボタンクリック → 確認後削除実行

**処理フロー**:
1. ユーザーが削除ボタンをクリック
2. `openDeletePopup`で削除確認モーダルを表示
3. 確認後、`confirmDeletion`が`agents/delete`をディスパッチ
4. APIエンドポイント`DELETE /api/v1/accounts/:accountId/agents/:id`にリクエスト
5. 成功時：一覧から削除、成功メッセージ表示
6. 失敗時：エラーメッセージ表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| エージェント追加 | users | INSERT | 新規ユーザーレコード作成 |
| エージェント追加 | account_users | INSERT | アカウント-ユーザー関連作成 |
| エージェント編集 | users | UPDATE | ユーザー名の更新 |
| エージェント編集 | account_users | UPDATE | ロール、可用性の更新 |
| エージェント削除 | account_users | DELETE | アカウント-ユーザー関連削除 |
| エージェント削除 | users | DELETE | ユーザーレコード削除（他アカウント関連がない場合） |

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

#### users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | email | フォーム入力値 | メールアドレス |
| INSERT | name | フォーム入力値 | 表示名 |
| UPDATE | name | フォーム入力値 | 表示名更新 |

#### account_users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | role | フォーム選択値 | administrator/agent |
| INSERT | availability | フォーム選択値 | online/busy/offline |
| UPDATE | role | フォーム選択値 | ロール更新 |
| UPDATE | availability | フォーム選択値 | 可用性更新 |
| UPDATE | custom_role_id | フォーム選択値 | カスタムロールID |

## メッセージ仕様

| 種別 | メッセージキー | メッセージ内容 |
|------|---------------|---------------|
| 成功 | AGENT_MGMT.DELETE.API.SUCCESS_MESSAGE | エージェントが正常に削除されました |
| エラー | AGENT_MGMT.DELETE.API.ERROR_MESSAGE | エージェントの削除に失敗しました |
| ローディング | AGENT_MGMT.LOADING | 読み込み中... |
| 空状態 | AGENT_MGMT.LIST.404 | エージェントが見つかりません |

## 例外処理

| 例外状態 | 処理内容 |
|----------|---------|
| API通信エラー | エラートースト表示 |
| 権限不足 | 403エラー、アクセス拒否画面表示 |
| データなし | 空メッセージ表示 |
| 最後の管理者削除試行 | 削除ボタン非表示 |
| ライセンス上限超過 | 402エラー、上限メッセージ表示 |

## 備考

- 自分自身は編集・削除不可（showEditAction、showDeleteActionで制御）
- 確認済み管理者が1人の場合、その管理者は削除不可
- 未確認エージェントは常に削除可能
- エージェント追加時はライセンス数の上限チェックが行われる
- カスタムロールはCloud/Enterprise版で利用可能

---

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

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

### 推奨読解順序

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

まず、エージェントデータの構造とVuexストアの状態管理を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | agents.js | `app/javascript/dashboard/store/modules/agents.js` | state構造、getters、actions |

**読解のコツ**:
- `state.records`にエージェントリストが格納
- `state.uiFlags`でローディング状態を管理
- CRUD操作のactionsを確認

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

処理の起点となるVueコンポーネントを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Index.vue | `app/javascript/dashboard/routes/dashboard/settings/agents/Index.vue` | メインコンポーネント |

**主要処理フロー**:
1. **L22-27**: ref定義 - loading, showAddPopup, showDeletePopup等
2. **L39-42**: computed - agentList, uiFlags, currentUserId, customRoles
3. **L44-47**: onMounted - agents/get、customRole/getCustomRole dispatch
4. **L49-66**: getAgentRoleName、getAgentRolePermissions - ロール表示ロジック
5. **L68-91**: 表示制御関数 - showEditAction、showDeleteAction
6. **L100-135**: イベントハンドラ - openAddPopup、openEditPopup、deleteAgent等

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

追加・編集モーダルを担当するコンポーネント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AddAgent.vue | `app/javascript/dashboard/routes/dashboard/settings/agents/AddAgent.vue` | 追加モーダル |
| 3-2 | EditAgent.vue | `app/javascript/dashboard/routes/dashboard/settings/agents/EditAgent.vue` | 編集モーダル |

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

バックエンドとの通信。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | agents.js | `app/javascript/dashboard/api/agents.js` | エージェントAPI |

#### Step 5: バックエンドを理解する

Rails側のコントローラとビルダー。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | agents_controller.rb | `app/controllers/api/v1/accounts/agents_controller.rb` | コントローラ |
| 5-2 | agent_builder.rb | `app/builders/agent_builder.rb` | エージェント作成ロジック |

**主要処理フロー**:
- **L7-9**: index - エージェント一覧取得
- **L11-23**: create - AgentBuilderで新規作成
- **L25-28**: update - エージェント更新
- **L30-34**: destroy - エージェント削除

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

```
Index.vue (settings/agents)
    │
    ├─ onMounted()
    │      ├─ store.dispatch('agents/get')
    │      │      └─ AgentAPI.get()
    │      │             └─ GET /api/v1/.../agents
    │      │
    │      └─ store.dispatch('customRole/getCustomRole')
    │
    ├─ openAddPopup() → AddAgent.vue
    │      └─ agents/create dispatch
    │             └─ AgentAPI.create()
    │                    └─ POST /api/v1/.../agents
    │
    ├─ openEditPopup() → EditAgent.vue
    │      └─ agents/update dispatch
    │             └─ AgentAPI.update()
    │                    └─ PATCH /api/v1/.../agents/:id
    │
    └─ confirmDeletion()
           └─ deleteAgent()
                  └─ agents/delete dispatch
                         └─ AgentAPI.delete()
                                └─ DELETE /api/v1/.../agents/:id
```

### データフロー図

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

初期化       ───▶  agents/get dispatch       ───▶  エージェント一覧表示
                            │
追加フォーム  ───▶  agents/create dispatch    ───▶  新規エージェント追加
                            │                        招待メール送信
                            │
編集フォーム  ───▶  agents/update dispatch    ───▶  エージェント情報更新
                            │
削除確認     ───▶  agents/delete dispatch    ───▶  エージェント削除
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Index.vue | `app/javascript/dashboard/routes/dashboard/settings/agents/Index.vue` | ソース | メイン画面コンポーネント |
| AddAgent.vue | `app/javascript/dashboard/routes/dashboard/settings/agents/AddAgent.vue` | ソース | 追加モーダル |
| EditAgent.vue | `app/javascript/dashboard/routes/dashboard/settings/agents/EditAgent.vue` | ソース | 編集モーダル |
| SettingsLayout.vue | `app/javascript/dashboard/routes/dashboard/settings/SettingsLayout.vue` | ソース | 設定レイアウト |
| BaseSettingsHeader.vue | `app/javascript/dashboard/routes/dashboard/settings/components/BaseSettingsHeader.vue` | ソース | ヘッダーコンポーネント |
| agents.js (store) | `app/javascript/dashboard/store/modules/agents.js` | ソース | Vuexストアモジュール |
| agents.js (api) | `app/javascript/dashboard/api/agents.js` | ソース | APIクライアント |
| agents_controller.rb | `app/controllers/api/v1/accounts/agents_controller.rb` | ソース | Railsコントローラ |
| agent_builder.rb | `app/builders/agent_builder.rb` | ソース | エージェント作成ロジック |
| user.rb | `app/models/user.rb` | ソース | ユーザーモデル |
| account_user.rb | `app/models/account_user.rb` | ソース | アカウント-ユーザー関連モデル |
