# 画面設計書 10-インボックス別会話一覧

## 概要

本ドキュメントは、Chatwootアプリケーションのインボックス別会話一覧画面に関する設計書です。特定のインボックス（チャネル）に属する会話のみを表示する画面について記述しています。

### 本画面の処理概要

インボックス別会話一覧画面は、特定のインボックス（メール、ウェブチャット、WhatsApp、Facebook等のチャネル）に属する会話のみをフィルタリングして表示します。ダッシュボードホーム画面と同じConversationViewコンポーネントを使用しますが、inboxIdプロパティによりフィルタリングが適用されます。

**業務上の目的・背景**：大規模な組織では、複数のチャネル（インボックス）を運用しており、特定のチャネル専門のエージェントチームが存在する場合があります。本画面は、特定チャネルの会話のみを表示することで、エージェントが担当チャネルに集中して対応できるようにします。例えば、WhatsApp専門チーム、メールサポートチーム、ソーシャルメディアチームなど、役割分担されたチームの業務効率を向上させます。

**画面へのアクセス方法**：サイドバーのインボックスリストから特定のインボックスをクリックするか、URL直接アクセス（`/app/accounts/:accountId/inbox/:inbox_id`）で遷移します。

**主要な操作・処理内容**：
1. 特定インボックスの会話一覧表示
2. 担当者タブによる会話のフィルタリング
3. ステータスによるフィルタリング
4. 会話の選択と詳細表示
5. メッセージの送受信
6. 会話へのラベル付与、エージェント割り当て
7. 会話詳細ページへの遷移（`/app/accounts/:accountId/inbox/:inbox_id/conversations/:conversation_id`）

**画面遷移**：
- 遷移元：サイドバーのインボックスリスト、ダッシュボードホーム画面
- 遷移先：会話詳細画面、他のインボックス画面、ダッシュボードホーム画面

**権限による表示制御**：
- administrator、agent、conversation_manage、conversation_unassigned_manage、conversation_participating_manage権限を持つユーザーがアクセス可能
- ユーザーがインボックスのメンバーである場合のみ表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 25 | 会話CRUD | 主機能 | 特定インボックスの会話一覧表示 |
| 17 | インボックス基本管理 | 補助機能 | インボックスIDによるフィルタリング |

## 画面種別

一覧・詳細（フィルタリングビュー）

## URL/ルーティング

| パス | ルート名 | 説明 |
|------|----------|------|
| `/app/accounts/:accountId/inbox/:inbox_id` | `inbox_dashboard` | インボックス別会話一覧 |
| `/app/accounts/:accountId/inbox/:inbox_id/conversations/:conversation_id` | `conversation_through_inbox` | インボックス経由の会話詳細 |

### ルートパラメータ

| パラメータ | 型 | 説明 |
|-----------|-----|------|
| `accountId` | String | アカウントID |
| `inbox_id` | String | インボックスID |
| `conversation_id` | String | 会話ID（会話詳細時） |

### ルートメタ情報

| メタキー | 値 | 説明 |
|---------|-----|------|
| `permissions` | `['administrator', 'agent', 'conversation_manage', 'conversation_unassigned_manage', 'conversation_participating_manage']` | アクセス権限 |

## 入出力項目

### 入力項目

ダッシュボードホーム画面と同様のフィルタリング操作に加え、URLパラメータでインボックスIDを受け取ります。

| 項目名 | 説明 |
|--------|------|
| インボックスID | URLパラメータで指定 |
| 担当者タブ選択 | 自分/未割当/全員の切り替え |
| ステータスフィルター | オープン/解決済み/保留中のフィルタリング |

### 出力項目

| 項目名 | 説明 | 表示条件 |
|--------|------|----------|
| インボックス名 | 画面タイトルにインボックス名を表示 | 常時 |
| 会話一覧 | インボックスに属する会話リスト | 常時 |
| 会話詳細 | 選択した会話のメッセージと情報 | 会話選択時 |

## 表示項目

| 項目名 | 説明 | 表示条件 |
|--------|------|----------|
| ChatListHeader | インボックス名とフィルターオプション | 常時 |
| ChatTypeTabs | 担当者タブ（自分/未割当/全員） | フィルター未適用時 |
| ConversationItem | 会話アイテム（バーチャルスクロール） | 会話存在時 |
| ConversationBox | 会話詳細ボックス | レイアウト設定に応じて |
| ConversationSidebar | 連絡先情報サイドバー | サイドバー開時 |
| EmptyMessage | 会話なしメッセージ | 会話が存在しない時 |

## イベント仕様

### 1-インボックス別会話読み込み

**トリガー**: 画面マウント時、インボックスID変更時

**処理フロー**:
1. URLパラメータからinbox_idを取得
2. ConversationViewにinboxIdプロパティとして渡す
3. `setActiveInbox` dispatchでインボックスを設定
4. `conversationFilters`にinboxIdを含めてAPI呼び出し
5. インボックスでフィルタリングされた会話を表示

**データフロー**:
```
[URLパラメータ: inbox_id]
    │
    ▼
[ConversationView props: inboxId]
    │
    ▼
[initialize()]
    │
    └─ setActiveInbox(inboxId)
           │
           ▼
[ChatList: conversationFilters]
    │
    └─ inboxId: props.conversationInbox
           │
           ▼
[fetchAllConversations]
    │
    └─ GET /conversations?inbox_id=xxx
           │
           ▼
[インボックスでフィルタリングされた会話一覧]
```

### 2-会話詳細への遷移

**トリガー**: 会話アイテムのクリック

**処理フロー**:
1. `conversation_through_inbox`ルートに遷移
2. URLが`/inbox/:inbox_id/conversations/:conversation_id`形式に
3. 会話詳細が表示される

### 3-インボックス変更

**トリガー**: サイドバーで別のインボックスを選択

**処理フロー**:
1. 新しいinboxIdでルート変更
2. `watch`によりconversationInboxの変更を検知
3. `resetAndFetchData`で会話一覧を再取得

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| インボックス別会話取得 | conversations | SELECT | inbox_id条件で会話を取得 |

ダッシュボードホーム画面と同様の更新操作が可能です。

## メッセージ仕様

| メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|-------------|---------------|---------------|----------|
| CHAT_LIST.LIST.404 | 情報 | 会話が見つかりません | インボックスに会話がない時 |
| CHAT_LIST.EOF | 情報 | これ以上の会話はありません | リスト終端到達時 |

## 例外処理

| 例外条件 | 状態・動作 |
|---------|----------|
| インボックスが存在しない | 404エラーまたはダッシュボードにリダイレクト |
| インボックスへのアクセス権がない | アクセス拒否メッセージを表示 |
| 会話取得エラー | エラーメッセージを表示 |

## 備考

- ConversationViewコンポーネントを再利用し、inboxIdプロパティでフィルタリング
- 画面タイトル（pageTitle）はインボックス名を表示
- インボックスの種類（Webチャット、メール、WhatsApp等）により、会話の表示形式が異なる場合がある
- インボックスメンバーでないユーザーはアクセスできない

---

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

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

### 推奨読解順序

#### Step 1: ルーティング定義を理解する

インボックス関連のルーティングを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | conversation.routes.js | `app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js` | インボックス関連ルートの定義（行38-63） |

**読解のコツ**: `inbox_dashboard`と`conversation_through_inbox`の2つのルートがインボックス関連です。

#### Step 2: プロパティの流れを理解する

inboxIdプロパティの流れを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ConversationView.vue | `app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue` | propsでのinboxId受け取り（行31-33） |
| 2-2 | ChatList.vue | `app/javascript/dashboard/components/ChatList.vue` | conversationInboxプロパティ（行76） |

**主要処理フロー**:
1. **routes.js 行44-46**: URLパラメータからinbox_idを取得しpropsに渡す
2. **ConversationView.vue 行130-131**: `setActiveInbox`でインボックスを設定
3. **ChatList.vue 行279**: conversationFiltersでinboxIdを使用

#### Step 3: フィルタリングロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ChatList.vue | `app/javascript/dashboard/components/ChatList.vue` | conversationFilters computed（行277-288） |
| 3-2 | ChatList.vue | `app/javascript/dashboard/components/ChatList.vue` | pageTitle computed（行297-323） |

**主要処理フロー**:
- **行279**: `inboxId: props.conversationInbox ? props.conversationInbox : undefined`
- **行301-303**: インボックス名をpageTitleとして表示

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

```
conversation.routes.js
    │
    ├─ route: inbox_dashboard (/inbox/:inbox_id)
    │      │
    │      └─ props: { inboxId: route.params.inbox_id }
    │
    └─ route: conversation_through_inbox (/inbox/:inbox_id/conversations/:conversation_id)
           │
           └─ props: { inboxId, conversationId }

ConversationView.vue
    │
    ├─ props.inboxId ──▶ initialize() ──▶ setActiveInbox(inboxId)
    │
    └─ ChatList (conversation-inbox={inboxId})
           │
           └─ conversationFilters.inboxId
                  │
                  ▼
           fetchAllConversations
                  │
                  ▼
           API: GET /conversations?inbox_id=xxx
```

### データフロー図

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

URLパラメータ           ──▶   conversation.routes.js      ──▶   会話一覧表示
inbox_id                      (props extraction)               (フィルタリング済み)
                                  │
                                  ▼
                          ConversationView.vue
                          props: inboxId
                                  │
                                  ▼
                          initialize()
                          setActiveInbox(inboxId)
                                  │
                                  ▼
                          ChatList.vue
                          conversationInbox={inboxId}
                                  │
                                  ▼
                          conversationFilters
                          { inboxId: xxx, ... }
                                  │
                                  ▼
                          fetchAllConversations
                                  │
                                  ▼
                          GET /api/v1/accounts/:accountId/conversations
                          ?inbox_id=xxx
                                  │
                                  ▼
                          [インボックスでフィルタリングされた会話]
                                  │
                                  ▼
                          [pageTitle = inbox.name]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ConversationView.vue | `app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue` | ソース | メイン画面コンポーネント |
| conversation.routes.js | `app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js` | ソース | ルーティング定義 |
| ChatList.vue | `app/javascript/dashboard/components/ChatList.vue` | ソース | 会話一覧コンポーネント |
| inboxes/index.js | `app/javascript/dashboard/store/modules/inboxes/index.js` | ソース | インボックスVuexモジュール |
| inboxes/getters.js | `app/javascript/dashboard/store/modules/inboxes/getters.js` | ソース | インボックスgetter |
| en.json | `app/javascript/dashboard/i18n/locale/en/chatList.json` | 設定 | i18n翻訳ファイル |
