# 画面設計書 50-インボックス設定画面

## 概要

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

### 本画面の処理概要

既存のインボックスの詳細設定を管理する画面。インボックス基本情報、コラボレーター（エージェント）管理、営業時間設定、CSAT設定、プリチャットフォーム設定、ウィジェットビルダー、チャネル固有設定、ボット設定など、複数のタブで構成された包括的な設定画面。

**業務上の目的・背景**：インボックスは顧客対応の窓口であり、その設定はサポート品質に直接影響する。この画面では、インボックスの見た目（アバター、ウェルカムメッセージ）、動作（営業時間、自動割り当て）、品質管理（CSAT）、自動化（ボット）など、あらゆる側面の設定を一元的に管理できる。

**画面へのアクセス方法**：インボックス一覧画面から設定ボタンをクリック、または直接URLでアクセス。管理者権限を持つユーザーのみがアクセス可能。

**主要な操作・処理内容**：
1. インボックス基本情報の編集（名前、アバター、ウェルカムメッセージ等）
2. コラボレーター（エージェント/チーム）の管理
3. 営業時間の設定
4. CSAT（顧客満足度調査）の設定
5. プリチャットフォームの設定（Webウィジェットのみ）
6. ウィジェットビルダーによるデザインカスタマイズ（Webウィジェットのみ）
7. チャネル固有の設定（API設定、WhatsApp設定等）
8. ボット設定

**画面遷移**：
- 遷移元：インボックス一覧画面
- 遷移先：特になし（タブ切り替えで内容変更）

**権限による表示制御**：管理者（administrator）のみがアクセス可能。表示されるタブはインボックスのチャネルタイプにより異なる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | インボックス基本管理 | 主機能 | 既存インボックスの詳細設定 |
| 19 | ウェルカムメッセージ | 補助機能 | グリーティングメッセージ設定 |
| 20 | 営業時間管理 | 補助機能 | 営業時間の設定 |
| 21 | 自動割り当て設定 | 補助機能 | 自動割り当ての設定 |
| 23 | アバター管理 | 補助機能 | インボックスアバターの設定 |
| 182 | ボット割り当て | 補助機能 | インボックスへのボット配置 |

## 画面種別

編集

## URL/ルーティング

```
/app/accounts/:accountId/settings/inboxes/:inboxId/:tab?
```

- ルート名: `settings_inbox_show`
- パラメータ:
  - `accountId`: アカウントID
  - `inboxId`: インボックスID
  - `tab`: タブキー（オプション）

## 入出力項目

### インボックス設定タブ入力項目

| 項目名 | 型 | 必須 | 条件 | 説明 |
|--------|-----|------|------|------|
| インボックス名 | String | ○ | 全チャネル | インボックス表示名 |
| アバター | File | - | 全チャネル | インボックスのアバター画像 |
| Webhook URL | String | - | APIチャネルのみ | コールバックURL |
| ドメイン | String | - | Webウィジェットのみ | Webサイトドメイン |
| ウェルカムタイトル | String | - | Webウィジェットのみ | ウィジェット見出し |
| ウェルカムメッセージ | String | - | Webウィジェットのみ | ウィジェット説明文 |
| ウィジェットカラー | Color | - | Webウィジェットのみ | ウィジェット色 |
| グリーティング有効 | Boolean | - | 全チャネル | 挨拶メッセージの有効/無効 |
| グリーティングメッセージ | String | - | グリーティング有効時 | 挨拶メッセージ内容 |
| 返信時間 | Select | - | Webウィジェットのみ | 予想返信時間 |
| メール収集 | Boolean | - | Webウィジェットのみ | メールアドレス収集の有効/無効 |
| 解決後メッセージ許可 | Boolean | - | Webウィジェットのみ | 解決後のメッセージ送信可否 |
| メール継続 | Boolean | - | Webウィジェットのみ | メールによる会話継続 |
| ヘルプセンター | Select | - | Voice以外 | 連携するヘルプセンターポータル |
| 単一会話ロック | Boolean | - | 特定チャネル | 単一会話に制限 |
| 送信者名タイプ | Radio | - | Web/Email | friendly/friendly_with_business |
| ビジネス名 | String | - | 送信者名で使用時 | ビジネス表示名 |
| 機能フラグ | Checkbox | - | Webウィジェットのみ | 添付ファイル、絵文字等 |

## 表示項目

### タブ構成

| タブキー | タブ名 | 表示条件 | 説明 |
|---------|--------|---------|------|
| inbox-settings | 設定 | 全チャネル | 基本設定 |
| collaborators | コラボレーター | 全チャネル | エージェント/チーム管理 |
| business-hours | 営業時間 | Voice以外 | 営業時間設定 |
| csat | CSAT | Voice以外 | 顧客満足度調査設定 |
| pre-chat-form | プリチャットフォーム | Webウィジェットのみ | チャット前フォーム設定 |
| widget-builder | ウィジェットビルダー | Webウィジェットのみ | ウィジェットデザイン |
| configuration | 設定 | 特定チャネル | チャネル固有設定 |
| bot-configuration | ボット設定 | AGENT_BOTS有効時 | ボット連携設定 |
| whatsapp-health | アカウントヘルス | WhatsApp Cloudのみ | WhatsAppアカウント状態 |

### 再認証バナー

| 項目名 | 表示条件 | 説明 |
|--------|---------|------|
| Microsoft再認証 | Microsoftチャネルで要再認証時 | 再認証リンク表示 |
| Facebook再認証 | Facebookチャネルで要再認証時 | 再認証リンク表示 |
| Google再認証 | Googleチャネルで要再認証時 | 再認証リンク表示 |
| Instagram再認証 | Instagramチャネルで要再認証時 | 再認証リンク表示 |
| TikTok再認証 | TikTokチャネルで要再認証時 | 再認証リンク表示 |
| WhatsApp再認証 | WhatsApp Cloudで要再認証時 | 再認証リンク表示 |

## イベント仕様

### 1-インボックス設定更新

**トリガー**: 更新ボタンクリック

**処理フロー**:
1. ユーザーが設定を変更し更新ボタンをクリック
2. `updateInbox`メソッドが呼び出される
3. バリデーション実行
4. `inboxes/updateInbox`アクションがディスパッチされる
5. APIエンドポイント`PATCH /api/v1/accounts/:accountId/inboxes/:id`にリクエスト
6. 成功時：成功メッセージ表示
7. 失敗時：エラーメッセージ表示

### 2-アバターアップロード

**トリガー**: アバター画像選択

**処理フロー**:
1. ユーザーがアバター画像を選択
2. `handleImageUpload`メソッドで一時的に保存
3. 更新ボタンクリック時にavatarとしてpayloadに含める
4. APIでマルチパートフォームデータとして送信

### 3-アバター削除

**トリガー**: アバター削除ボタンクリック

**処理フロー**:
1. `handleAvatarDelete`メソッドが呼び出される
2. `inboxes/deleteInboxAvatar`アクションがディスパッチされる
3. APIエンドポイント`DELETE /api/v1/accounts/:accountId/inboxes/:id/avatar`にリクエスト

### 4-タブ切り替え

**トリガー**: タブクリック

**処理フロー**:
1. `onTabChange`メソッドが呼び出される
2. `selectedTabIndex`が更新される
3. `updateRouteWithoutRefresh`でURL更新（リロードなし）
4. 該当タブのコンテンツが表示される

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 設定更新 | inboxes | UPDATE | インボックス情報更新 |
| 設定更新 | channel_web_widgets / 等 | UPDATE | チャネル固有情報更新 |
| アバター削除 | active_storage_attachments | DELETE | アバター添付削除 |

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

#### inboxes

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | フォーム入力値 | インボックス名 |
| UPDATE | greeting_enabled | フォーム選択値 | グリーティング有効 |
| UPDATE | greeting_message | フォーム入力値 | グリーティングメッセージ |
| UPDATE | enable_email_collect | フォーム選択値 | メール収集 |
| UPDATE | allow_messages_after_resolved | フォーム選択値 | 解決後メッセージ |
| UPDATE | lock_to_single_conversation | フォーム選択値 | 単一会話ロック |
| UPDATE | sender_name_type | フォーム選択値 | 送信者名タイプ |
| UPDATE | business_name | フォーム入力値 | ビジネス名 |
| UPDATE | portal_id | フォーム選択値 | ヘルプセンターID |

## メッセージ仕様

| 種別 | メッセージキー | メッセージ内容 |
|------|---------------|---------------|
| 成功 | INBOX_MGMT.EDIT.API.SUCCESS_MESSAGE | 設定が正常に更新されました |
| エラー | INBOX_MGMT.EDIT.API.ERROR_MESSAGE | 設定の更新に失敗しました |
| 成功 | INBOX_MGMT.DELETE.API.AVATAR_SUCCESS_MESSAGE | アバターが削除されました |
| エラー | INBOX_MGMT.DELETE.API.AVATAR_ERROR_MESSAGE | アバターの削除に失敗しました |

## 例外処理

| 例外状態 | 処理内容 |
|----------|---------|
| バリデーションエラー | エラーメッセージ表示、送信中止 |
| API通信エラー | エラートースト表示 |
| 権限不足 | 403エラー、アクセス拒否画面表示 |
| インボックスが存在しない | 404エラー |
| 再認証が必要 | 再認証バナー表示 |

## 備考

- タブはURLのpathに反映され、リロード後も同じタブが表示される
- 再認証が必要なチャネル（Facebook、Instagram、TikTok、WhatsApp等）では警告バナーが表示
- WhatsApp CloudチャネルではInboxHealthAPIでアカウントヘルス情報を取得
- ウィジェットビルダータブではリアルタイムプレビューが可能
- inboxMixinでチャネルタイプ判定のヘルパーメソッドを提供

---

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

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

### 推奨読解順序

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

まず、インボックスデータの構造とミックスインを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | inboxMixin.js | `shared/mixins/inboxMixin.js` | チャネルタイプ判定ヘルパー |
| 1-2 | inboxes.js (store) | `app/javascript/dashboard/store/modules/inboxes.js` | getInbox getter、updateInbox action |

**読解のコツ**:
- inboxMixinでisAWebWidgetInbox、isAWhatsAppChannel等の判定メソッド提供
- 各タブの表示条件はこれらの判定メソッドに依存

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

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

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

**主要処理フロー**:
1. **L63-88**: data定義 - フォーム状態
2. **L90-305**: computed - タブ構成、チャネル判定
3. **L320-324**: mounted - fetchInboxSettings、fetchPortals、fetchHealthData
4. **L393-422**: fetchInboxSettings - インボックスデータ取得と状態初期化
5. **L424-460**: updateInbox - 設定更新API呼び出し

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

各タブのコンテンツを担当するコンポーネント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CollaboratorsPage.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/CollaboratorsPage.vue` | コラボレーター管理 |
| 3-2 | WeeklyAvailability.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/components/WeeklyAvailability.vue` | 営業時間設定 |
| 3-3 | CustomerSatisfactionPage.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/CustomerSatisfactionPage.vue` | CSAT設定 |
| 3-4 | PreChatFormSettings.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/PreChatForm/Settings.vue` | プリチャットフォーム |
| 3-5 | WidgetBuilder.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/WidgetBuilder.vue` | ウィジェットビルダー |
| 3-6 | BotConfiguration.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/components/BotConfiguration.vue` | ボット設定 |

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

バックエンドとの通信。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | inboxes.js (api) | `app/javascript/dashboard/api/inboxes.js` | API定義 |
| 4-2 | inboxHealth.js | `app/javascript/dashboard/api/inboxHealth.js` | ヘルスチェックAPI |

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

Rails側のコントローラ。

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

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

```
Settings.vue
    │
    ├─ mounted()
    │      ├─ fetchInboxSettings()
    │      │      └─ inboxes/get dispatch → inbox取得
    │      ├─ fetchPortals()
    │      │      └─ portals/index dispatch
    │      └─ fetchHealthData() (WhatsApp Cloud時)
    │             └─ InboxHealthAPI.getHealthStatus()
    │
    ├─ タブ構成 (computed: tabs)
    │      └─ チャネルタイプとfeature flagsで動的生成
    │
    ├─ inbox-settings タブ
    │      └─ updateInbox()
    │             └─ inboxes/updateInbox dispatch
    │                    └─ PATCH /api/v1/.../inboxes/:id
    │
    ├─ collaborators タブ → CollaboratorsPage.vue
    ├─ business-hours タブ → WeeklyAvailability.vue
    ├─ csat タブ → CustomerSatisfactionPage.vue
    ├─ pre-chat-form タブ → PreChatFormSettings.vue
    ├─ widget-builder タブ → WidgetBuilder.vue
    ├─ configuration タブ → ConfigurationPage.vue
    ├─ bot-configuration タブ → BotConfiguration.vue
    └─ whatsapp-health タブ → AccountHealth.vue
```

### データフロー図

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

inboxId (URL)   ───▶  fetchInboxSettings()      ───▶  フォーム初期値
                            │
タブ切り替え     ───▶  onTabChange()             ───▶  URL更新、タブ表示
                            │
フォーム入力     ───▶  updateInbox()             ───▶  API更新
                            │
アバター選択     ───▶  handleImageUpload()       ───▶  一時保存
                            │
アバター削除     ───▶  handleAvatarDelete()      ───▶  API削除
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Settings.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue` | ソース | メイン画面コンポーネント |
| CollaboratorsPage.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/CollaboratorsPage.vue` | ソース | コラボレーター管理 |
| ConfigurationPage.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/ConfigurationPage.vue` | ソース | チャネル設定 |
| CustomerSatisfactionPage.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/CustomerSatisfactionPage.vue` | ソース | CSAT設定 |
| WeeklyAvailability.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/components/WeeklyAvailability.vue` | ソース | 営業時間設定 |
| PreChatFormSettings.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/PreChatForm/Settings.vue` | ソース | プリチャットフォーム |
| WidgetBuilder.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/WidgetBuilder.vue` | ソース | ウィジェットビルダー |
| BotConfiguration.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/components/BotConfiguration.vue` | ソース | ボット設定 |
| AccountHealth.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/components/AccountHealth.vue` | ソース | WhatsAppヘルス |
| GreetingsEditor.vue | `shared/components/GreetingsEditor.vue` | ソース | グリーティングエディタ |
| inboxMixin.js | `shared/mixins/inboxMixin.js` | ソース | チャネルタイプ判定 |
| 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クライアント |
| inboxHealth.js | `app/javascript/dashboard/api/inboxHealth.js` | ソース | ヘルスチェックAPI |
| inboxes_controller.rb | `app/controllers/api/v1/accounts/inboxes_controller.rb` | ソース | Railsコントローラ |
| inbox.rb | `app/models/inbox.rb` | ソース | インボックスモデル |
