# 帳票設計書 6-会話トラフィックレポート（CSV）

## 概要

本ドキュメントは、Chatwootシステムにおける時間帯別・日別の会話トラフィックヒートマップデータ（CSV形式）の設計仕様を定義する。

### 本帳票の処理概要

会話トラフィックレポートは、指定期間内の会話発生数を時間帯別・日別に集計し、ヒートマップ形式のデータをCSV形式で出力する帳票である。1時間単位で各日の会話数を横断的に表示することで、トラフィックパターンを可視化できる。

**業務上の目的・背景**：カスタマーサポート業務では、問い合わせのピーク時間帯を把握することが人員配置の最適化に不可欠である。本帳票により、どの時間帯・曜日に問い合わせが集中するかを分析し、シフト計画やリソース配分の意思決定を支援する。また、キャンペーンや製品リリース後のトラフィック変化を追跡する際にも活用される。

**帳票の利用シーン**：シフト計画の策定、ピーク時間帯の特定、人員増強時期の判断、サポート体制の見直し検討時に利用される。

**主要な出力内容**：
1. タイムゾーン情報（データの基準となるタイムゾーン）
2. 時間帯別・日別の会話数マトリクス（各行が時間帯、各列が日付）

**帳票の出力タイミング**：管理者がレポート画面から任意のタイミングでダウンロードボタンをクリックした際にオンデマンドで生成・出力される。

**帳票の利用者**：アカウント管理者、シフト管理者、オペレーションマネージャー

## 帳票種別

ヒートマップデータ（マトリクス形式）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | レポート画面（トラフィック） | `/app/accounts/:account_id/reports/traffic` | 「Download」ボタンクリック |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | CSV |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | `conversation_traffic_reports.csv` |
| 出力方法 | ダウンロード |
| 文字コード | UTF-8 |

### CSV固有設定

| 項目 | 内容 |
|-----|------|
| 区切り文字 | カンマ（,） |
| 囲み文字 | ダブルクォート（"） |
| ヘッダー行 | あり（1行目：タイムゾーン情報、2行目：日付ヘッダー） |
| BOM | なし |

## 帳票レイアウト

### レイアウト概要

CSVファイルは以下の構成で出力される。1行目にタイムゾーン情報、2行目に日付ヘッダー、3行目以降に各時間帯の会話数が出力される。

```
┌─────────────────────────────────────────────────────────────┐
│        タイムゾーン情報（1行目）                              │
├─────────────────────────────────────────────────────────────┤
│ Start of the hour | 2024-01-01 | 2024-01-02 | ...（2行目）   │
├─────────────────────────────────────────────────────────────┤
│   00:00           |    5       |     3      | ...            │
│   01:00           |    2       |     1      | ...            │
│   02:00           |    0       |     2      | ...            │
│   ...             |   ...      |    ...     | ...            │
│   23:00           |    8       |     6      | ...            │
└─────────────────────────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Timezone | データの基準タイムゾーン | `params[:timezone_offset]` | "Timezone, {タイムゾーン名}" |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | Start of the hour | 時間帯（0-23時） | 計算値 | "HH:00" 形式 | - |
| 2-N | 日付列 | 各日の会話数 | `conversations.count` | 整数 | - |

### フッター部

フッターなし

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| timezone_offset | タイムゾーンオフセット（時間単位） | Yes |
| days_before | 集計対象日数（デフォルト: 6日） | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 時間帯 | 昇順（00:00 - 23:00） |
| 2 | 日付 | 昇順 |

### 改ページ条件

N/A（CSV形式のため改ページなし）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| conversations | 会話数のカウント | `conversations.account_id = Current.account.id` |
| reporting_events | タイムシリーズデータ取得（V2::ReportBuilder経由） | - |

### テーブル別参照項目詳細

#### conversations / reporting_events

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| COUNT(*) | 各セルの会話数 | `created_at` を時間・日で GROUP BY | タイムゾーン変換後に集計 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 時間帯別会話数 | COUNT(conversations) GROUP BY hour, date | 整数 | タイムゾーン変換後に集計 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[ダウンロード要求] --> B[check_authorization]
    B --> C[conversation_traffic]
    C --> D[generate_conversations_heatmap_report]
    D --> E[generate_heatmap_data_for_timezone]
    E --> F[generate_heatmap_data]
    F --> G[V2::ReportBuilder.build]
    G --> H[transform_data]
    H --> I[group_traffic_data]
    I --> J[generate_csv - CSVレスポンス生成]
    J --> K[ERBテンプレートでCSV出力]
    K --> L[ファイルダウンロード]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 認可エラー | レポート閲覧権限がない場合 | HTTP 403 | 管理者権限を持つユーザーでログイン |
| タイムゾーン不正 | 無効なtimezone_offsetの場合 | N/A | 正しいタイムゾーンオフセットを指定 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 24時間 x 7日 = 168セル |
| 目標出力時間 | 数秒以内 |
| 同時出力数上限 | 特に制限なし |

## セキュリティ考慮事項

- レポート閲覧は `report:view?` ポリシーで認可チェックを実施
- トラフィックデータはアカウント内の権限を持つユーザーのみアクセス可能

## 備考

- デフォルトでは過去6日間のデータを出力（days_beforeパラメータで変更可能）
- タイムゾーン変換はActiveSupport::TimeZoneを使用
- ヒートマップデータは行が時間帯（00:00-23:00）、列が日付の形式
- 会話数が0の場合もセルは出力される（空白またはnull）

---

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

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

### 推奨読解順序

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

まず、帳票出力に使用されるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | en.yml | `config/locales/en.yml` | reports.conversation_traffic_csvセクション（行183-184）でタイムゾーンラベルを確認 |

**読解のコツ**: ヒートマップデータは2次元配列形式で構築される。1次元目が行（時間帯）、2次元目が列（日付）を表す。

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

処理の起点となるコントローラーを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | reports_controller.rb | `app/controllers/api/v2/accounts/reports_controller.rb` | conversation_trafficアクション（行46-52）がエントリーポイント |

**主要処理フロー**:
1. **行5**: `check_authorization` で権限チェック
2. **行47**: `generate_conversations_heatmap_report` でデータ生成
3. **行48-49**: タイムゾーン情報を取得
4. **行51**: `generate_csv` でCSVレスポンスを生成

#### Step 3: Helperメソッドを理解する

ヒートマップデータ生成のヘルパーメソッドを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | heatmap_helper.rb | `app/helpers/api/v2/accounts/heatmap_helper.rb` | `generate_conversations_heatmap_report` メソッド（行2-6）と関連メソッド |

**主要処理フロー**:
- **行2-6**: `generate_conversations_heatmap_report` がエントリー
- **行59-66**: `generate_heatmap_data_for_timezone` でタイムゾーン変換
- **行68-81**: `generate_heatmap_data` で V2::ReportBuilder を使用してデータ取得
- **行10-57**: `group_traffic_data` でヒートマップ形式に変換

#### Step 4: データ変換ロジックを理解する

ヒートマップ形式への変換処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | heatmap_helper.rb | `app/helpers/api/v2/accounts/heatmap_helper.rb` | `group_traffic_data` メソッド（行10-57）の変換ロジック |

**主要処理フロー**:
- **行15**: 日付のユニーク値を取得・ソート
- **行19**: 1行目にヘッダー行（日付列）を追加
- **行26-44**: 各時間帯（0-23）についてループし、日付ごとの値を取得
- **行28**: 時間帯を"HH:00"形式にフォーマット

#### Step 5: CSVテンプレートを理解する

最終的なCSV出力のテンプレートを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | conversation_traffic.erb | `app/views/api/v2/accounts/reports/conversation_traffic.erb` | CSVの行構造と出力形式（全6行） |

**主要処理フロー**:
- **行1**: タイムゾーン情報を1行目に出力
- **行3-5**: @report_dataの各行（時間帯別データ）をCSV出力

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

```
Api::V2::Accounts::ReportsController#conversation_traffic
    │
    ├─ check_authorization (before_action)
    │      └─ ReportPolicy#view?
    │
    ├─ Api::V2::Accounts::HeatmapHelper#generate_conversations_heatmap_report
    │      │
    │      ├─ #generate_heatmap_data_for_timezone
    │      │      │
    │      │      ├─ #generate_heatmap_data
    │      │      │      └─ V2::ReportBuilder#build (group_by: 'hour')
    │      │      │
    │      │      └─ #transform_data
    │      │
    │      └─ #group_traffic_data (ヒートマップ形式に変換)
    │
    └─ #generate_csv
           └─ render 'api/v2/accounts/reports/conversation_traffic'
                  └─ conversation_traffic.erb
```

### データフロー図

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

params[:timezone_offset] ──┐
params[:days_before]     ──┼──▶  generate_heatmap_data      ──▶   raw timeseries
                           │            │
                           │            └─▶ V2::ReportBuilder
                           │
                           └──▶  transform_data              ──▶   [{date, hour, value}]
                                        │
                                        ▼
                                 group_traffic_data
                                        │
                                        ▼
                           [['Start of hour', '2024-01-01', ...],
                            ['00:00', 5, 3, ...],
                            ['01:00', 2, 1, ...],
                            ...]
                                        │
                                        ▼
                           conversation_traffic.erb
                                        │
                                        ▼
                           conversation_traffic_reports.csv
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| reports_controller.rb | `app/controllers/api/v2/accounts/reports_controller.rb` | コントローラー | エントリーポイント、CSV生成制御 |
| heatmap_helper.rb | `app/helpers/api/v2/accounts/heatmap_helper.rb` | ヘルパー | ヒートマップデータ生成 |
| report_builder.rb | `app/builders/v2/report_builder.rb` | ビルダー | 時系列データの構築 |
| conversation_traffic.erb | `app/views/api/v2/accounts/reports/conversation_traffic.erb` | テンプレート | CSV出力フォーマット定義 |
| en.yml | `config/locales/en.yml` | 設定 | タイムゾーンラベルの翻訳定義 |
| report_policy.rb | `app/policies/report_policy.rb` | ポリシー | レポート閲覧権限制御 |
