# 画面設計書 88-Captain設定画面

## 概要

本ドキュメントは、ChatwootのCaptain AI設定画面の設計を記述したものです。この画面では、Captain AIの各機能で使用するAIモデルの選択や、機能の有効化/無効化を管理します。

### 本画面の処理概要

**業務上の目的・背景**：Captain AIはChatwootに統合されたAIアシスタント機能です。本画面では、エディター補助、AIアシスタント、コパイロットなど各機能で使用するAIモデルを設定し、ラベル提案やヘルプセンター検索、音声文字起こしなどの機能の有効化/無効化を管理できます。

**画面へのアクセス方法**：サイドメニューの「設定」から「Captain」を選択してアクセスします。URLパスは `/app/accounts/:accountId/settings/captain` です。

**主要な操作・処理内容**：
1. AIモデルの選択（エディター、アシスタント、コパイロット）
2. 機能トグル（ラベル提案、ヘルプセンター検索、音声文字起こし）
3. 各機能で使用するモデルの変更

**画面遷移**：
- 遷移元：設定メニュー
- 遷移先：特になし

**権限による表示制御**：管理者（administrator）ロールのユーザーのみがアクセス可能です。Captain機能が無効な場合はPaywallが表示されます。一部機能はEnterprise版のみ利用可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 83 | キャプテン設定 | 主機能 | Captain AIの設定 |

## 画面種別

設定

## URL/ルーティング

- **パス**: `/app/accounts/:accountId/settings/captain`
- **ルート名**: `captain_settings_index`

## 入出力項目

### モデル設定

| 項目名 | データ型 | 必須 | 説明 |
|--------|----------|------|------|
| editor | String | - | エディター機能で使用するモデル |
| assistant | String | - | アシスタント機能で使用するモデル（Enterprise） |
| copilot | String | - | コパイロット機能で使用するモデル（Enterprise） |

### 機能トグル

| 項目名 | データ型 | 必須 | 説明 |
|--------|----------|------|------|
| label_suggestion | Boolean | - | ラベル提案機能の有効/無効 |
| help_center_search | Boolean | - | ヘルプセンター検索機能の有効/無効（Enterprise） |
| audio_transcription | Boolean | - | 音声文字起こし機能の有効/無効（Enterprise） |

## 表示項目

### ヘッダー（BaseSettingsHeader）

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| タイトル | テキスト | 「Captain設定」 |
| 説明 | テキスト | 機能の説明 |
| アイコン | アイコン | captain |

### モデル設定セクション（SectionLayout）

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| セクションタイトル | テキスト | 「モデル設定」 |
| セクション説明 | テキスト | AIモデル選択の説明 |
| エディターモデル | ModelSelector | エディター補助のモデル選択 |
| アシスタントモデル | ModelSelector | AIアシスタントのモデル選択（Enterprise） |
| コパイロットモデル | ModelSelector | コパイロットのモデル選択（Enterprise） |

### 機能セクション（SectionLayout）

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| セクションタイトル | テキスト | 「機能」 |
| セクション説明 | テキスト | 機能設定の説明 |
| ラベル提案 | FeatureToggle | ラベル提案のON/OFF |
| ヘルプセンター検索 | FeatureToggle | ヘルプセンター検索のON/OFF（Enterprise） |
| 音声文字起こし | FeatureToggle | 音声文字起こしのON/OFF（Enterprise） |

### Paywall（captainEnabled = false時）

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| CaptainPaywall | モーダル | Captain機能の有効化を促すUI |

## イベント仕様

### 1-画面マウント時

onMountedで`captainConfigStore.fetch()`を実行し、現在の設定を取得します。

### 2-モデル変更

ModelSelectorの@changeイベント時：
1. `captainConfigStore.updatePreferences({ captain_models: { [feature]: model } })`を実行
2. 成功時：成功メッセージを表示
3. 失敗時：エラーメッセージを表示、設定を再フェッチ

### 3-機能トグル

FeatureToggleの@changeイベント時：
1. `captainConfigStore.updatePreferences({ captain_features: { [feature]: enabled } })`を実行
2. 成功時：成功メッセージを表示
3. 失敗時：エラーメッセージを表示、設定を再フェッチ

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 設定取得 | accounts | SELECT | captain_preferences設定の取得 |
| モデル変更 | accounts | UPDATE | captain_models設定の更新 |
| 機能トグル | accounts | UPDATE | captain_features設定の更新 |

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

#### accounts（または関連設定テーブル）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | captain_preferences | account_id = 現在のアカウントID | 設定取得 |
| UPDATE | captain_models | { feature: model } | モデル設定 |
| UPDATE | captain_features | { feature: enabled } | 機能有効化設定 |

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|----------|--------------|
| CAPTAIN_SETTINGS.API.SUCCESS | 成功 | 設定更新成功時 | 設定が正常に更新されました |
| CAPTAIN_SETTINGS.API.ERROR | エラー | 設定更新失敗時 | 設定の更新に失敗しました |
| CAPTAIN_SETTINGS.NOT_ENABLED | 情報 | Captain無効時 | Captain機能が有効ではありません |
| CAPTAIN_SETTINGS.LOADING | 情報 | 読み込み中 | 設定を読み込み中... |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| Captain無効 | Paywallを表示 |
| API呼び出し失敗 | エラーメッセージを表示、設定を再フェッチ |
| Enterprise機能へのアクセス（非Enterprise） | 機能を無効化表示（opacity低下） |

## 備考

- Captain機能はCloud版またはEnterprise版でのみ利用可能
- assistant, copilot, help_center_search, audio_transcription機能はEnterprise版のみ
- モデル選択はプロバイダー（OpenAI, Anthropic, Gemini）ごとにソートされて表示
- coming_soon属性を持つモデルはリストの末尾に表示

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | preferences.js | `app/javascript/dashboard/store/captain/preferences.js` | Piniaストアの構造（providers, models, features）、getters、actions |
| 1-2 | preferences.js（API） | `app/javascript/dashboard/api/captain/preferences.js` | APIエンドポイントの定義 |

**読解のコツ**: PiniaストアはVuexとは異なる構文なので、defineStoreの使い方に注意

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Index.vue | `app/javascript/dashboard/routes/dashboard/settings/captain/Index.vue` | captainEnabled判定、modelFeatures/featureToggles配列、shouldShowFeature/isFeatureAccessible関数 |

**主要処理フロー**:
1. **行19-21**: useCaptainでcaptainEnabledを取得
2. **行23-25**: useCaptainConfigStoreでPiniaストアを使用
3. **行28-46**: modelFeaturesでモデル選択対象の機能を定義
4. **行48-61**: featureTogglesでトグル対象の機能を定義
5. **行62-91**: shouldShowFeature/isFeatureAccessibleでEnterprise判定
6. **行93-103**: handleFeatureToggleで機能の有効/無効を更新
7. **行105-115**: handleModelChangeでモデル選択を更新
8. **行117-119**: onMountedで設定をフェッチ

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ModelSelector.vue | `app/javascript/dashboard/routes/dashboard/settings/captain/components/ModelSelector.vue` | モデル選択UIの実装 |
| 3-2 | FeatureToggle.vue | `app/javascript/dashboard/routes/dashboard/settings/captain/components/FeatureToggle.vue` | 機能トグルUIの実装、isEnabled状態管理 |
| 3-3 | ModelDropdown.vue | `app/javascript/dashboard/routes/dashboard/settings/captain/components/ModelDropdown.vue` | モデル選択ドロップダウンの実装 |

**主要処理フロー（FeatureToggle.vue）**:
- **行30**: isEnabled refで有効状態を管理
- **行32**: featureConfig computedで設定を取得
- **行94-101**: watchでfeatureConfigからisEnabledを反映
- **行103-106**: toggleFeatureでemit('change')

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

```
Index.vue (エントリーポイント)
    │
    ├─ onMounted
    │      └─ captainConfigStore.fetch()
    │              └─ CaptainPreferencesAPI.get()
    │
    ├─ ModelSelector.vue（v-for="feature in modelFeatures"）
    │      │
    │      └─ @change → handleModelChange
    │              └─ captainConfigStore.updatePreferences({ captain_models })
    │                      └─ CaptainPreferencesAPI.updatePreferences()
    │
    ├─ FeatureToggle.vue（v-for="feature in featureToggles"）
    │      │
    │      ├─ @change → handleFeatureToggle
    │      │      └─ captainConfigStore.updatePreferences({ captain_features })
    │      │
    │      └─ @model-change → handleModelChange
    │
    └─ CaptainPaywall.vue（v-else、captainEnabled = false時）
```

### データフロー図

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

onMounted ──────────────▶ captainConfigStore.fetch() ──▶
                              │
                              ▼
                      API: GET /captain/preferences
                              │
                              ▼
                      Pinia State更新
                              │
                              ▼
                      storeToRefs(uiFlags)
                              │
                              ▼
                      ModelSelector / FeatureToggle表示
                              │
ユーザー操作 ──────────────────▶
                              │
                              ▼
                      @change / @model-change
                              │
                              ▼
                      updatePreferences() ─────────────▶ API呼び出し
                              │                                │
                              ▼                                ▼
                      成功/失敗メッセージ               設定更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Index.vue | `app/javascript/dashboard/routes/dashboard/settings/captain/Index.vue` | ソース | メインページコンポーネント |
| preferences.js | `app/javascript/dashboard/store/captain/preferences.js` | ソース | Piniaストア |
| preferences.js | `app/javascript/dashboard/api/captain/preferences.js` | ソース | APIクライアント |
| ModelSelector.vue | `app/javascript/dashboard/routes/dashboard/settings/captain/components/ModelSelector.vue` | ソース | モデル選択コンポーネント |
| FeatureToggle.vue | `app/javascript/dashboard/routes/dashboard/settings/captain/components/FeatureToggle.vue` | ソース | 機能トグルコンポーネント |
| ModelDropdown.vue | `app/javascript/dashboard/routes/dashboard/settings/captain/components/ModelDropdown.vue` | ソース | モデルドロップダウン |
| CaptainPaywall.vue | `app/javascript/next/captain/pageComponents/Paywall.vue` | ソース | Paywall表示 |
| useCaptain.js | `app/javascript/dashboard/composables/useCaptain.js` | ソース | Captain composable |
| useConfig.js | `app/javascript/dashboard/composables/useConfig.js` | ソース | 設定composable |
| SettingsLayout.vue | `app/javascript/dashboard/routes/dashboard/settings/SettingsLayout.vue` | ソース | 設定画面共通レイアウト |
| SectionLayout.vue | `app/javascript/dashboard/routes/dashboard/settings/account/components/SectionLayout.vue` | ソース | セクションレイアウト |
