# 画面設計書 47-インボックス一覧画面

## 概要

本ドキュメントは、Chatwootのインボックス一覧画面の設計仕様を定義するものである。

### 本画面の処理概要

アカウントに設定されているインボックス（受信チャネル）の一覧を表示・管理する画面。各インボックスの設定画面への遷移、インボックスの削除を行うことができる。

**業務上の目的・背景**：インボックスは顧客からの問い合わせを受け付けるチャネルであり、Website（チャットウィジェット）、Facebook、WhatsApp、Email、SMS、Telegramなど様々なチャネルタイプをサポートしている。管理者はこの画面で全インボックスの状態を把握し、必要に応じて設定変更や削除を行う。

**画面へのアクセス方法**：サイドメニューの「設定」から「インボックス」を選択することでアクセスする。管理者権限を持つユーザーのみがアクセス可能。

**主要な操作・処理内容**：
1. インボックス一覧の表示（アバター/アイコン、名前、チャネルタイプ）
2. 新規インボックス作成画面への遷移
3. 既存インボックスの設定画面への遷移
4. インボックスの削除

**画面遷移**：
- 遷移元：設定メニュー
- 遷移先：インボックス新規作成画面、インボックス設定画面

**権限による表示制御**：管理者（administrator）のみがアクセス可能。追加・設定・削除ボタンは管理者のみに表示。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | インボックス基本管理 | 主機能 | インボックスの一覧表示 |
| 18 | マルチチャネル対応 | 補助機能 | 各チャネルタイプの表示 |

## 画面種別

一覧

## URL/ルーティング

```
/app/accounts/:accountId/settings/inboxes/list
```

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

## 入出力項目

なし（一覧表示のみ）

## 表示項目

### ヘッダー

| 項目名 | 型 | 説明 |
|--------|-----|------|
| タイトル | String | 「インボックス」 |
| 説明文 | String | インボックス管理の説明 |
| 新規作成ボタン | Button | 新規インボックス作成画面へ遷移（管理者のみ） |

### インボックス一覧テーブル

| 項目名 | 型 | 説明 |
|--------|-----|------|
| アバター/アイコン | Image/Icon | インボックスのアバター画像またはチャネルアイコン |
| 名前 | String | インボックスの表示名 |
| チャネルタイプ | String | Website/Facebook/WhatsApp/Email等のチャネル種別 |
| 設定ボタン | Button | インボックス設定画面へ遷移（管理者のみ） |
| 削除ボタン | Button | 削除確認モーダルを開く（管理者のみ） |

## イベント仕様

### 1-新規作成画面への遷移

**トリガー**: 新規作成ボタンクリック

**処理フロー**:
1. ユーザーが新規作成ボタンをクリック
2. Vue Routerで`settings_inbox_new`ルートに遷移
3. ChannelList.vue（インボックス新規作成画面）が表示される

### 2-設定画面への遷移

**トリガー**: 設定ボタンクリック

**処理フロー**:
1. ユーザーが設定ボタンをクリック
2. Vue Routerで`settings_inbox_show`ルートに遷移
3. Settings.vue（インボックス設定画面）が表示される

### 3-インボックス削除

**トリガー**: 削除ボタンクリック → 確認後削除実行

**処理フロー**:
1. ユーザーが削除ボタンをクリック
2. `openDelete`で削除確認モーダルを表示
3. インボックス名の入力による確認
4. 確認後、`confirmDeletion`が`inboxes/delete`をディスパッチ
5. APIエンドポイント`DELETE /api/v1/accounts/:accountId/inboxes/:id`にリクエスト
6. DeleteObjectJobでバックグラウンド削除処理
7. 成功時：一覧から削除、成功メッセージ表示
8. 失敗時：エラーメッセージ表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| インボックス削除 | inboxes | DELETE | インボックスレコード削除 |
| インボックス削除 | conversations | UPDATE/DELETE | 関連会話の処理 |
| インボックス削除 | inbox_members | DELETE | インボックスメンバー削除 |

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

#### inboxes

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | account_id | 現在のアカウントID | 一覧取得条件 |
| DELETE | id | 削除対象ID | インボックス削除 |

## メッセージ仕様

| 種別 | メッセージキー | メッセージ内容 |
|------|---------------|---------------|
| 成功 | INBOX_MGMT.DELETE.API.SUCCESS_MESSAGE | インボックスが正常に削除されました |
| エラー | INBOX_MGMT.DELETE.API.ERROR_MESSAGE | インボックスの削除に失敗しました |
| 空状態 | INBOX_MGMT.LIST.404 | インボックスが見つかりません |

## 例外処理

| 例外状態 | 処理内容 |
|----------|---------|
| API通信エラー | エラートースト表示 |
| 権限不足 | 403エラー、アクセス拒否画面表示 |
| データなし | 空メッセージ表示 |
| 削除確認キャンセル | モーダルを閉じて元の状態に戻る |

## 備考

- インボックスは名前のアルファベット順でソートされて表示
- 削除時はインボックス名の入力確認が必要（woot-confirm-delete-modal）
- インボックス削除はバックグラウンドジョブ（DeleteObjectJob）で非同期処理
- アバターがない場合はチャネルタイプに応じたアイコンを表示

---

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

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

### 推奨読解順序

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

まず、インボックスデータの構造とVuexストアの状態管理を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | inboxes.js | `app/javascript/dashboard/store/modules/inboxes.js` | state構造、getters、delete action |

**読解のコツ**:
- `state.records`にインボックスリストが格納
- `getInboxes`でソートされていない生データ取得
- `delete`アクションでAPI呼び出し

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Index.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/Index.vue` | メインコンポーネント |

**主要処理フロー**:
1. **L23-24**: ref定義 - showDeletePopup, selectedInbox
2. **L26**: inboxes useMapGetter
3. **L28-30**: inboxesList computed - 名前順ソート
4. **L52-68**: deleteInbox、closeDelete、confirmDeletion関数
5. **L69-72**: openDelete関数

#### Step 3: 子コンポーネントを理解する

チャネル名表示を担当するコンポーネント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ChannelName.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/components/ChannelName.vue` | チャネル種別表示 |
| 3-2 | ChannelIcon.vue | `app/javascript/dashboard/components-next/icon/ChannelIcon.vue` | チャネルアイコン |

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

バックエンドとの通信。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | inboxes.js | `app/javascript/dashboard/api/inboxes.js` | インボックスAPI |

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

Rails側のコントローラ。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | inboxes_controller.rb | `app/controllers/api/v1/accounts/inboxes_controller.rb` | index, destroy action |

**主要処理フロー**:
- **L10-12**: index - インボックス一覧取得
- **L68-71**: destroy - DeleteObjectJobでバックグラウンド削除

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

```
Index.vue (settings/inbox)
    │
    ├─ useMapGetter('inboxes/getInboxes')
    │      └─ Vuex inboxes/getInboxes getter
    │
    ├─ inboxesList computed
    │      └─ sort by name (localeCompare)
    │
    ├─ router-link to settings_inbox_new
    │      └─ ChannelList.vue (インボックス新規作成画面)
    │
    ├─ router-link to settings_inbox_show
    │      └─ Settings.vue (インボックス設定画面)
    │
    └─ confirmDeletion()
           └─ deleteInbox()
                  └─ inboxes/delete dispatch
                         └─ InboxesAPI.delete()
                                └─ DELETE /api/v1/.../inboxes/:id
```

### データフロー図

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

初期化       ───▶  inboxes/getInboxes       ───▶  インボックス一覧表示
                            │
名前ソート   ───▶  inboxesList computed     ───▶  ソート済みリスト
                            │
削除確認     ───▶  inboxes/delete dispatch  ───▶  インボックス削除
                                                   (バックグラウンド)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Index.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/Index.vue` | ソース | メイン画面コンポーネント |
| ChannelName.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/components/ChannelName.vue` | ソース | チャネル名表示 |
| ChannelIcon.vue | `app/javascript/dashboard/components-next/icon/ChannelIcon.vue` | ソース | チャネルアイコン |
| SettingsLayout.vue | `app/javascript/dashboard/routes/dashboard/settings/SettingsLayout.vue` | ソース | 設定レイアウト |
| BaseSettingsHeader.vue | `app/javascript/dashboard/routes/dashboard/settings/components/BaseSettingsHeader.vue` | ソース | ヘッダーコンポーネント |
| inbox.routes.js | `app/javascript/dashboard/routes/dashboard/settings/inbox/inbox.routes.js` | 設定 | ルーティング定義 |
| inboxes.js (store) | `app/javascript/dashboard/store/modules/inboxes.js` | ソース | Vuexストアモジュール |
| inboxes.js (api) | `app/javascript/dashboard/api/inboxes.js` | ソース | APIクライアント |
| inboxes_controller.rb | `app/controllers/api/v1/accounts/inboxes_controller.rb` | ソース | Railsコントローラ |
| inbox.rb | `app/models/inbox.rb` | ソース | インボックスモデル |
