# 画面設計書 30-エージェントレポート画面

## 概要

本ドキュメントは、Chatwootのエージェントレポート画面の設計仕様を記述したものである。

### 本画面の処理概要

エージェントレポート画面は、エージェント（オペレーター）別のパフォーマンス統計を表示し、個別のエージェントの業績を分析する機能を提供する画面である。

**業務上の目的・背景**：カスタマーサポートチームの管理において、個々のエージェントのパフォーマンスを把握することは重要である。本画面により、マネージャーは各エージェントの会話対応数、応答時間、解決率などの指標を確認し、個別のフィードバックやトレーニング計画、リソース配分の最適化に活用できる。

**画面へのアクセス方法**：ダッシュボードのサイドバーから「レポート」メニューを選択し、「エージェント」サブメニューをクリックすることでアクセスする。URLは `/app/accounts/:accountId/reports/agent` の形式となる。

**主要な操作・処理内容**：
1. エージェント選択によるフィルタリング
2. エージェント別統計のサマリー表示
3. 各指標のチャート表示
4. 日付範囲フィルタの設定
5. グループ化期間（日/週/月/年）の選択
6. 営業時間ベースの計算切り替え
7. レポートのCSVダウンロード

**画面遷移**：レポート概要画面、他のレポート画面から遷移可能。

**権限による表示制御**：管理者（administrator）権限を持つユーザーのみアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 110 | エージェント別レポート | 主機能 | エージェントパフォーマンス分析 |

## 画面種別

レポート

## URL/ルーティング

| パス | ルート名 | 説明 |
|------|----------|------|
| `/app/accounts/:accountId/reports/agent` | reports_agent | エージェントレポート画面 |

## 入出力項目

### 入力項目（フィルタ）

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| agentId | 数値 | 必須 | 対象エージェントのID |
| from | 日付 | 必須 | 集計開始日（UNIXタイムスタンプ） |
| to | 日付 | 必須 | 集計終了日（UNIXタイムスタンプ） |
| groupBy | 文字列 | 必須 | グループ化期間（day, week, month, year） |
| businessHours | 真偽値 | 任意 | 営業時間ベースで計算するか |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| summary | Object | エージェント別サマリー統計データ |
| chartData | Object | 各指標のチャートデータ |

## 表示項目

### ヘッダー

| 項目名 | 説明 |
|--------|------|
| タイトル | 「エージェントレポート」（i18nキー: AGENT_REPORTS.HEADER） |
| ダウンロードボタン | CSVダウンロード |

### フィルタセクション

| 項目名 | 説明 |
|--------|------|
| エージェントセレクタ | 対象エージェントを選択 |
| 日付範囲ピッカー | 開始日と終了日を選択 |
| グループ化セレクタ | 日/週/月/年を選択 |
| 営業時間トグル | 営業時間ベースの計算を切り替え |

### レポート指標

| 指標名 | 説明 | キー |
|--------|------|------|
| 会話数 | 期間内の担当会話総数 | conversations_count |
| 送信メッセージ数 | エージェントからのメッセージ数 | outgoing_messages_count |
| 平均初回応答時間 | 最初のメッセージへの応答時間 | avg_first_response_time |
| 平均解決時間 | 会話開始から解決までの時間 | avg_resolution_time |
| 解決数 | 解決した会話数 | resolutions_count |
| 返信時間 | メッセージへの返信時間 | reply_time |

## イベント仕様

### 1-画面初期表示

画面マウント時、エージェント一覧を取得する。

**処理フロー**:
1. `agents/get` アクションでエージェント一覧を取得
2. エージェント一覧を`filterItemsList`として表示

### 2-エージェント選択

エージェントを選択してレポートを表示する。

**処理フロー**:
1. `onFilterChange`を実行
2. `selectedFilter`にエージェントを設定
3. `fetchAllData`を実行

### 3-日付範囲変更

日付範囲を変更する。

**処理フロー**:
1. `onDateRangeChange`を実行
2. `from`, `to`, `groupBy`を更新
3. グループ化オプションを日付範囲に応じて更新
4. `fetchAllData`を実行

### 4-サマリー取得

エージェント別サマリーを取得する。

**処理フロー**:
1. `fetchAllData`内でサマリー取得
2. `fetchAccountSummary`アクションに`type: 'agent'`, `id: agentId`を渡す

### 5-チャートデータ取得

各指標のチャートデータを取得する。

**処理フロー**:
1. `fetchChartData`を実行
2. 6つの指標（incoming_messages_count除く）に対して`fetchAccountReport`をディスパッチ
3. `type: 'agent'`, `id: agentId`を渡す

### 6-レポートダウンロード

CSVレポートをダウンロードする。

**処理フロー**:
1. `downloadReports`を実行
2. `downloadAgentReports`アクションをディスパッチ

### 7-営業時間トグル

営業時間ベースの計算を切り替える。

**処理フロー**:
1. `onBusinessHoursToggle`を実行
2. `businessHours`を更新
3. `fetchAllData`を実行
4. トラッキングイベント送信

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| エージェント一覧取得 | users | SELECT | エージェント一覧取得 |
| サマリー取得 | conversations, messages | SELECT | エージェント別集計クエリ実行 |
| チャートデータ取得 | conversations, messages | SELECT | エージェント別時系列集計 |

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

本画面は参照のみで更新処理なし。

#### conversations

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | assignee_id, created_at, resolved_at, first_reply_created_at | 期間条件、エージェント条件 | 統計集計用 |

## メッセージ仕様

| 種別 | コード | メッセージ | 表示条件 |
|------|--------|-----------|----------|
| エラー | REPORT.DATA_FETCHING_FAILED | データの取得に失敗しました | データ取得エラー時 |
| ボタン | REPORT.DOWNLOAD_AGENT_REPORTS | エージェントレポートをダウンロード | ダウンロードボタンラベル |

## 例外処理

| 例外条件 | 処理内容 |
|----------|---------|
| エージェント一覧取得失敗 | エラーハンドリング |
| データ取得失敗 | アラートメッセージを表示 |
| 権限不足 | 画面へのアクセスがブロック |

## 備考

- WootReportsコンポーネントを再利用（type='agent'で動作）
- エージェント選択は必須（選択しないとレポートが表示されない）
- 会話レポートと比較して`incoming_messages_count`が含まれない（エージェント側は送信のみ）
- グループ化オプションは日付範囲によって動的に変更される

---

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

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

### 推奨読解順序

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

まず、レポートのデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | reports.js (api) | `app/javascript/dashboard/api/reports.js` | getReports, getSummary, getAgentReportsメソッド |

**読解のコツ**: type='agent', id=agentIdのパラメータに注目。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AgentReports.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/AgentReports.vue` | エントリーポイント、WootReportsへのprops |

**主要処理フロー**:
1. **行6-13**: WootReportsにpropsを渡す（type='agent', getter-key='agents/getAgents', action-key='agents/get'）

#### Step 3: 共通レポートコンポーネントを理解する

WootReportsの実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WootReports.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/components/WootReports.vue` | 共通レポートコンポーネント |

**主要処理フロー**:
1. **行36-65**: propsで動作をカスタマイズ
2. **行78-80**: filterItemsListでエージェント一覧を取得
3. **行81-95**: reportKeysでエージェント用の指標を定義
4. **行98-99**: mountedでアクション実行（agents/get）
5. **行101-114**: fetchAllDataでサマリーとチャート取得
6. **行115-133**: fetchChartDataで各指標取得
7. **行134-147**: downloadReportsでダウンロード処理

#### Step 4: APIレイヤーを理解する

バックエンドとの通信処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | reports.js | `app/javascript/dashboard/api/reports.js` | getReports（type, id付き）, getAgentReports |

**主要処理フロー**:
- **行11-32**: `getReports`でtype='agent', id=agentIdを渡す
- **行58-62**: `getAgentReports`でCSVダウンロード

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

```
AgentReports.vue (エントリー)
    │
    └─ WootReports.vue (共通コンポーネント)
           │
           ├─ mounted
           │      └─ store.dispatch('agents/get')
           │             └─ エージェント一覧取得
           │
           ├─ ReportHeader
           │      └─ downloadReports
           │             └─ store.dispatch('downloadAgentReports')
           │
           ├─ ReportFilters
           │      ├─ @date-range-change="onDateRangeChange"
           │      ├─ @filter-change="onFilterChange"
           │      ├─ @group-by-filter-change="onGroupByFilterChange"
           │      └─ @business-hours-toggle="onBusinessHoursToggle"
           │             └─ fetchAllData
           │                    ├─ store.dispatch('fetchAccountSummary', { type: 'agent', id })
           │                    └─ fetchChartData
           │                           └─ store.dispatch('fetchAccountReport', { type: 'agent', id, metric })
           │
           └─ ReportContainer
                  └─ チャート表示
```

### データフロー図

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

エージェント選択 ─────────▶ onFilterChange
日付範囲                        │
グループ化                      ▼
営業時間                   fetchAllData
                                │
                                ├─ fetchAccountSummary ───▶ サマリーカード
                                │      └─ ReportsAPI.getSummary({ type: 'agent', id })
                                │
                                └─ fetchChartData ───▶ 各指標チャート
                                       └─ ReportsAPI.getReports({ type: 'agent', id }) x6
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AgentReports.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/AgentReports.vue` | ソース | エントリーポイント |
| WootReports.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/components/WootReports.vue` | ソース | 共通レポートコンポーネント |
| ReportHeader.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/components/ReportHeader.vue` | ソース | レポートヘッダー |
| ReportFilters.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/components/ReportFilters.vue` | ソース | フィルタコンポーネント |
| ReportContainer.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/ReportContainer.vue` | ソース | レポートコンテナ |
| reports.js (api) | `app/javascript/dashboard/api/reports.js` | ソース | レポートAPI |
| constants.js | `app/javascript/dashboard/routes/dashboard/settings/reports/constants.js` | ソース | 定数定義 |
| agents/index.js | `app/javascript/dashboard/store/modules/agents.js` | ソース | エージェントストア |
