# 画面設計書 41-ラベルレポート詳細

## 概要

本ドキュメントは、Chatwootのラベルレポート詳細画面の設計仕様を定義するものである。

### 本画面の処理概要

特定のラベルに関連する会話統計レポートを詳細に表示する画面。ラベルごとのパフォーマンス分析を行い、会話数、メッセージ数、応答時間、解決時間などのメトリクスをチャートとサマリーで可視化する。

**業務上の目的・背景**：ラベルは会話を分類・整理するために使用される機能であり、特定のラベルが付与された会話のパフォーマンスを把握することで、カテゴリ別の対応品質を分析できる。例えば「重要顧客」「技術サポート」「クレーム」などのラベル別に対応状況を把握し、改善施策の効果測定やリソース配分の最適化に活用できる。

**画面へのアクセス方法**：サイドメニューの「レポート」から「ラベル」を選択し、ラベルレポート概要画面で特定のラベルをクリックすることでこの詳細画面に遷移する。URLパラメータにラベルIDを含む形式でアクセスする。

**主要な操作・処理内容**：
1. 期間フィルタによるレポート期間の選択（日次/週次/月次/年次）
2. グループ化オプションによる集計単位の変更
3. 営業時間ベースでの計算切り替え
4. 各種メトリクス（会話数、メッセージ数、応答時間、解決時間）のチャート表示
5. CSVレポートのダウンロード

**画面遷移**：
- 遷移元：ラベルレポート概要画面（label_reports_index）
- 遷移先：戻るボタンでラベルレポート概要画面へ戻る

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 112 | ラベル別レポート | 主機能 | 特定ラベルの詳細レポート表示 |
| 78 | ラベル作成・管理 | 補助機能 | ラベル情報の取得と表示 |

## 画面種別

詳細

## URL/ルーティング

```
/app/accounts/:accountId/reports/labels/:id
```

- ルート名: `label_reports_show`
- パラメータ:
  - `accountId`: アカウントID
  - `id`: ラベルID

## 入出力項目

### フィルタ入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| 期間（from/to） | Date | ○ | レポート対象期間 |
| グループ化 | Select | ○ | 日/週/月/年による集計単位 |
| 営業時間ベース | Boolean | - | 営業時間のみで計算するかどうか |

## 表示項目

### レポートヘッダー

| 項目名 | 型 | 説明 |
|--------|-----|------|
| レポートタイトル | String | 「ラベルレポート」 |
| 戻るボタン | Button | 概要画面に戻る |
| ダウンロードボタン | Button | CSVレポートをダウンロード |

### サマリーメトリクス

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 会話数 | Number | 対象期間の総会話数 |
| 受信メッセージ数 | Number | 顧客からの受信メッセージ数 |
| 送信メッセージ数 | Number | エージェントからの送信メッセージ数 |
| 初回応答時間（平均） | Duration | 最初の応答までの平均時間 |
| 解決時間（平均） | Duration | 会話解決までの平均時間 |
| 解決数 | Number | 対象期間の解決済み会話数 |
| 返信時間（平均） | Duration | 各返信までの平均時間 |

### チャート表示

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 会話数チャート | LineChart | 期間別の会話数推移 |
| メッセージ数チャート | LineChart | 期間別のメッセージ数推移 |
| 応答時間チャート | LineChart | 期間別の応答時間推移 |
| 解決時間チャート | LineChart | 期間別の解決時間推移 |

## イベント仕様

### 1-フィルタ変更イベント

**トリガー**: 期間フィルタ、グループ化オプション、または営業時間トグルの変更時

**処理フロー**:
1. ユーザーがフィルタ条件を変更
2. `onDateRangeChange`/`onGroupByFilterChange`/`onBusinessHoursToggle`メソッドが呼び出される
3. `fetchAllData`メソッドでサマリーとチャートデータを再取得
4. Vuexストアに`fetchAccountSummary`と`fetchAccountReport`がディスパッチされる
5. APIからデータ取得後、画面が更新される

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

**トリガー**: ダウンロードボタンクリック

**処理フロー**:
1. `downloadReports`メソッドが呼び出される
2. `downloadLabelReports`アクションがディスパッチされる
3. APIエンドポイント`/api/v2/accounts/:accountId/reports/labels`にCSV形式でリクエスト
4. レスポンスをCSVファイルとしてダウンロード

### 3-戻るボタン

**トリガー**: 戻るボタンクリック

**処理フロー**:
1. Vue Routerで`label_reports_index`ルートに遷移

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| フィルタ変更 | reporting_events | SELECT | 集計データの取得 |
| フィルタ変更 | conversations | SELECT | 会話データの集計 |

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

#### reporting_events

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | account_id | 現在のアカウントID | フィルタ条件 |
| SELECT | name | メトリクスタイプ | conversations_count等 |
| SELECT | created_at | フィルタ期間内 | 期間フィルタ |
| SELECT | label_id | 指定ラベルID | ラベルフィルタ |

## メッセージ仕様

| 種別 | メッセージキー | メッセージ内容 |
|------|---------------|---------------|
| エラー | REPORT.DATA_FETCHING_FAILED | データの取得に失敗しました |
| 成功 | - | (特になし、自動更新) |

## 例外処理

| 例外状態 | 処理内容 |
|----------|---------|
| ラベルが存在しない | スピナー表示のまま待機（ラベル取得完了まで） |
| API通信エラー | エラートースト表示 |
| 権限不足 | 403エラー、アクセス拒否画面表示 |
| データなし | 空のチャートとゼロ値のサマリー表示 |

## 備考

- レポートデータは選択された期間に基づいてリアルタイムで集計される
- グループ化オプションは選択期間の長さに応じて利用可能なオプションが変化する
- 営業時間ベースの計算はアカウントの営業時間設定に依存する

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | reports.js | `app/javascript/dashboard/store/modules/reports.js` | レポートのVuex state構造とgetters |
| 1-2 | labels.js | `app/javascript/dashboard/store/modules/labels.js` | ラベルデータの取得と管理 |

**読解のコツ**: Vuexストアのstate定義から、どのようなデータが保持されるかを把握する。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LabelReportsShow.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/LabelReportsShow.vue` | メインコンポーネント、mounted時のラベル取得 |

**主要処理フロー**:
1. **L9-11**: Vuex store/routeからラベル情報を取得
2. **L13**: mountedでlabels/get dispatchしてラベルデータ取得
3. **L17-27**: WootReportsコンポーネントにpropsを渡してレンダリング

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

WootReportsコンポーネントが実際のレポート表示とデータ取得を担当。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WootReports.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/components/WootReports.vue` | レポートの主要ロジック |

**主要処理フロー**:
- **L102-114**: fetchAllData - サマリーとチャートデータの取得
- **L116-132**: fetchChartData - 各メトリクスのチャートデータ取得
- **L134-146**: downloadReports - CSVダウンロード処理

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

バックエンドとの通信を担当するAPI層。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | reports.js | `app/javascript/dashboard/api/reports.js` | レポートAPI定義 |

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

Rails側のコントローラとサービス層。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | reports_controller.rb | `app/controllers/api/v2/accounts/reports_controller.rb` | レポートAPIエンドポイント |
| 5-2 | ReportBuilder | `app/builders/v2/reports/` | レポートデータ集計ロジック |

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

```
LabelReportsShow.vue
    │
    ├─ useFunctionGetter('labels/getLabelById', route.params.id)
    │      └─ Vuex labels/getLabelById getter
    │
    ├─ store.dispatch('labels/get')
    │      └─ LabelsAPI.get()
    │             └─ GET /api/v1/accounts/:accountId/labels
    │
    └─ WootReports.vue
           ├─ fetchAllData()
           │      ├─ fetchAccountSummary dispatch
           │      │      └─ GET /api/v2/accounts/:id/reports/summary
           │      │
           │      └─ fetchChartData()
           │             └─ fetchAccountReport dispatch (各メトリクス)
           │                    └─ GET /api/v2/accounts/:id/reports
           │
           └─ downloadReports()
                  └─ downloadLabelReports dispatch
                         └─ GET /api/v2/accounts/:id/reports/labels (CSV)
```

### データフロー図

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

ラベルID(URL)  ───▶  labels/getLabelById  ───▶  ラベル情報
                            │
期間フィルタ   ───▶  fetchAccountSummary  ───▶  サマリーメトリクス
                            │
グループ化     ───▶  fetchAccountReport   ───▶  チャートデータ
                            │
ダウンロード   ───▶  downloadLabelReports ───▶  CSVファイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LabelReportsShow.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/LabelReportsShow.vue` | ソース | メイン画面コンポーネント |
| WootReports.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/components/WootReports.vue` | ソース | 共通レポートコンポーネント |
| ReportFilters.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/components/ReportFilters.vue` | ソース | フィルタUIコンポーネント |
| ReportContainer.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/ReportContainer.vue` | ソース | チャート表示コンテナ |
| ReportHeader.vue | `app/javascript/dashboard/routes/dashboard/settings/reports/components/ReportHeader.vue` | ソース | ヘッダーコンポーネント |
| reports.routes.js | `app/javascript/dashboard/routes/dashboard/settings/reports/reports.routes.js` | 設定 | ルーティング定義 |
| reports.js (store) | `app/javascript/dashboard/store/modules/reports.js` | ソース | Vuexストアモジュール |
| reports.js (api) | `app/javascript/dashboard/api/reports.js` | ソース | APIクライアント |
| reports_controller.rb | `app/controllers/api/v2/accounts/reports_controller.rb` | ソース | Railsコントローラ |
| en.json | `app/javascript/dashboard/i18n/locale/en/report.json` | 設定 | 国際化メッセージ |
