# 画面設計書 15-メンション会話一覧

## 概要

本ドキュメントは、Chatwootのメンション会話一覧画面の設計仕様を記述したものです。現在のユーザーが@メンションされた会話のみを表示する画面です。

### 本画面の処理概要

**業務上の目的・背景**：
チームでの協働において、特定のエージェントに注意を促したり、専門知識を求めたりする際に@メンション機能が使用されます。メンション会話一覧は、自分がメンションされた会話を一元的に確認できる画面で、重要な依頼や質問に迅速に対応することを可能にします。これにより、大量の会話の中から自分への依頼を見逃すことなく、効率的に業務を進められます。

**画面へのアクセス方法**：
1. サイドバーの「Mentions」リンクをクリック
2. URL直接アクセス: `/app/accounts/:accountId/mentions/conversations`

**主要な操作・処理内容**：
1. 自分がメンションされた会話一覧の表示
2. 担当者タブ（自分/未割り当て/すべて）による追加フィルタリング
3. ステータスフィルター（Open/Resolved/Pending/Snoozed）による絞り込み
4. 会話の選択と詳細表示
5. 一括操作（複数会話のステータス変更、割り当て変更など）
6. 高度なフィルター機能

**画面遷移**：
- 遷移元: ダッシュボードホーム画面（サイドバーのMentionsリンク）
- 遷移先: 会話詳細画面（会話クリック時）

**権限による表示制御**：
- administrator: 全機能へのフルアクセス
- agent: 自分がメンションされた会話の閲覧・操作
- conversation_manage: 会話の管理操作が可能
- conversation_unassigned_manage: 未割り当て会話タブの表示
- conversation_participating_manage: 参加中会話の管理

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 25 | 会話CRUD | 主機能 | メンションされた会話の一覧表示 |
| 49 | メンション機能 | 補助機能 | メンションフィルタリング |

## 画面種別

一覧

## URL/ルーティング

| ルート名 | パス | 説明 |
|---------|------|------|
| conversation_mentions | `/accounts/:accountId/mentions/conversations` | メンション会話一覧（詳細なし） |
| conversation_through_mentions | `/accounts/:accountId/mentions/conversations/:conversationId` | メンション会話一覧（詳細あり） |

## 入出力項目

### ルートパラメータ

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| accountId | Number | Yes | アカウントID |
| conversationId | Number | No | 表示する会話ID（詳細表示時） |

### コンポーネントProps

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| conversationType | String | Yes | 'mention'固定 |
| conversationId | String/Number | No | 選択中の会話ID |

## 表示項目

### ヘッダー部

| 項目名 | 型 | 説明 |
|--------|-----|------|
| page_title | String | 「Mentions」（i18n: CHAT_LIST.MENTION_HEADING） |
| conversation_count | Number | フィルタリング結果の会話数 |
| filter_button | Button | 高度なフィルターモーダル表示ボタン |

### 会話一覧

| 項目名 | 型 | 説明 |
|--------|-----|------|
| conversation_card | Component | 会話カード（ConversationItem） |
| inbox_icon | Icon | インボックスのアイコン |
| contact_name | String | 連絡先名 |
| last_message_preview | String | 最新メッセージのプレビュー |
| last_activity_time | DateTime | 最終活動時刻 |
| unread_count | Number | 未読メッセージ数 |
| labels | Array | 付与されているラベル一覧 |
| assignee_avatar | Image | 担当者アバター |
| mention_indicator | Icon | メンションインジケーター |

### 担当者タブ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| me_tab | Tab | 自分に割り当てられた会話 |
| unassigned_tab | Tab | 未割り当ての会話 |
| all_tab | Tab | すべての会話 |
| tab_count | Number | 各タブの会話数 |

## イベント仕様

### 1-メンション一覧表示

**トリガー**: サイドバーの「Mentions」リンクをクリック

**処理フロー**:
1. Vue Routerでconversation_mentionsルートへ遷移
2. ConversationView.vueにconversationType='mention'がpropsとして渡される
3. ChatList.vueのconversationFiltersでconversationType: 'mention'が設定される
4. fetchConversations()でAPIリクエスト
5. サーバー側でメンションフィルタリングが適用された会話一覧を取得

**Vuexアクション**: `fetchAllConversations`

### 2-会話選択

**トリガー**: 会話カードのクリック

**処理フロー**:
1. ConversationItemコンポーネントでクリックイベント発火
2. Vue Routerで`conversation_through_mentions`ルートへ遷移
3. ConversationView.vueのpropsが更新
4. setActiveChat()で選択会話をストアに設定
5. ConversationBox.vueで会話詳細を表示

### 3-新規メンション通知

**トリガー**: WebSocket経由で新規メンション通知を受信

**処理フロー**:
1. WebSocketイベントを受信
2. isOnMentionsView()で現在メンションビューかどうか判定
3. メンションビューの場合、addMentions()で会話を追加/更新
4. 会話一覧がリアルタイムで更新

**Vuexアクション**: `addMentions`

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| メンション会話一覧取得 | conversations | SELECT | メンションを含む会話の取得 |
| メンション会話一覧取得 | mentions | SELECT | メンション情報の取得 |

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

#### conversations（SELECT）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | conversation_type = 'mention' | APIパラメータ |
| SELECT | status | フィルター条件 | ステータスフィルター |
| SELECT | assignee_id | フィルター条件 | 担当者フィルター |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| CHAT_LIST.MENTION_HEADING | タイトル | Mentions | ページタイトル |
| CHAT_LIST.LIST.404 | 情報 | 会話が見つかりません | フィルタリング結果が0件 |
| CHAT_LIST.EOF | 情報 | すべての会話を表示しました | リスト末尾到達時 |

## 例外処理

| 例外状態 | 表示内容 | 処理 |
|---------|---------|------|
| メンションが0件 | 「会話が見つかりません」メッセージ | |
| ネットワークエラー | ローディング継続または再試行 | |

## 備考

- メンションは@記号に続けてエージェント名を入力することで作成される
- プライベートノート内でのメンションも対象となる
- リアルタイム更新はWebSocket経由で実現
- isOnMentionsView()ヘルパー関数でメンションビュー判定

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | conversation.routes.js | `app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js` | 行133-155でメンション関連ルートを確認 |
| 1-2 | actionHelpers.js | `app/javascript/dashboard/store/modules/conversations/helpers/actionHelpers.js` | isOnMentionsView()ヘルパー関数 |

**読解のコツ**: conversationType propsがどのように'mention'として渡されるかを確認してください。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ConversationView.vue | `app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue` | 行47-50でconversationType propsの定義を確認 |

**主要処理フロー**:
1. **行47-50**: conversationType propsの定義（デフォルト空文字列）
2. **行199-208**: ChatListへのconversation-type propsの受け渡し

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ChatList.vue | `app/javascript/dashboard/components/ChatList.vue` | conversationTypeによるフィルタリング処理 |

**主要処理フロー**:
- **行79**: conversationType propsの定義
- **行277-288**: conversationFiltersでconversationTypeをフィルター条件に含める
- **行310-312**: pageTitleで「Mentions」を表示
- **行880-883**: watch(conversationType)で変更時にresetAndFetchData()呼び出し

#### Step 4: リアルタイム更新を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | conversations/actions.js | `app/javascript/dashboard/store/modules/conversations/actions.js` | addMentionsアクション |

**主要処理フロー**:
- **行379-383**: addMentions - メンションビューの場合に会話を更新

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

```
ConversationView.vue
    |
    +-- ChatList.vue (conversationType='mention' props受け渡し)
    |       |
    |       +-- conversationFilters (computed)
    |       |       conversationType: 'mention'
    |       |
    |       +-- pageTitle (computed)
    |       |       $t('CHAT_LIST.MENTION_HEADING')
    |       |
    |       +-- fetchConversations()
    |               |
    |               +-- ConversationApi.get({ conversation_type: 'mention' })
    |
    +-- ConversationBox.vue (選択時)

WebSocket Event
    |
    +-- Vuex Action: addMentions()
            |
            +-- isOnMentionsView() -> true
            |
            +-- updateConversation()
```

### データフロー図

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

URL params          --> Vue Router                --> ConversationView.vue
(/mentions/...)         (route matching)              (conversationType='mention')
                                                          |
                                                          v
                    --> ChatList.vue              --> conversationFilters
                        (conversationType props)      ({ conversationType: 'mention' })
                                                          |
                                                          v
                    --> ConversationApi.get()     --> API Request
                        ({ conversation_type })       (GET /conversations?conversation_type=mention)
                                                          |
                                                          v
                    --> Vuex Store                --> 会話一覧表示
                        (allConversations)

WebSocket           --> addMentions()             --> 会話リスト更新
(mention event)         (リアルタイム更新)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| 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` | ソース | 会話一覧・フィルタリング |
| conversation.js | `app/javascript/dashboard/api/inbox/conversation.js` | ソース | API（conversation_type パラメータ対応） |
| actionHelpers.js | `app/javascript/dashboard/store/modules/conversations/helpers/actionHelpers.js` | ソース | isOnMentionsView()ヘルパー |
| conversations/actions.js | `app/javascript/dashboard/store/modules/conversations/actions.js` | ソース | addMentionsアクション |
