# 機能設計書 204-App設定

## 概要

本ドキュメントは、ChatwootのApp設定（App Configs）機能について記載する。Super Admin管理画面から、各種サードパーティ連携の設定やシステム設定をカテゴリ別に管理する機能である。

### 本機能の処理概要

App設定機能は、Chatwootの各種統合機能に必要なAPIキーやシークレット、システム全体の設定をカテゴリ別に管理する機能である。Facebook、Instagram、WhatsApp、Slack、Google、Captainなど、多様な外部サービスとの連携設定を一元的に管理し、環境変数を使わずにデータベース上で動的に設定変更を可能にする。

**業務上の目的・背景**：Chatwootは多数のチャネル（Facebook、Instagram、WhatsApp、SMS等）やサードパーティサービス（Slack、Linear、Shopify等）と連携する。これらの連携にはAPIキーやシークレットが必要であり、運用中に設定を変更したい場合がある。本機能により、サーバー再起動なしに連携設定を変更できる。

**機能の利用シーン**：
- システム管理者がFacebook/Instagram連携のAPI設定を行う場面
- WhatsApp Business APIの認証情報を設定する場面
- Slack連携の認証情報を設定する場面
- Captain AI機能のOpenAI APIキーを設定する場面
- 一般設定（サインアップ有効化、ファイルアップロードサイズ等）を調整する場面

**主要な処理内容**：
1. カテゴリ別の設定項目表示（Facebook、Instagram、WhatsApp、Slack等）
2. 設定項目の説明とデフォルト値の表示
3. 設定値の一括更新
4. 更新成功/失敗のフィードバック

**関連システム・外部連携**：本機能で設定された値は、各種チャネル統合機能（Facebook、Instagram、WhatsApp等）やサードパーティ統合（Slack、Linear等）、AI機能（Captain）から参照される。

**権限による制御**：本機能はSuper Admin権限を持つユーザーのみがアクセス可能である。設定変更は即座に反映される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | App Config設定画面 | 主画面 | カテゴリ別設定の表示・編集 |

## 機能種別

設定管理 / CRUD操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| config | String | No | 設定カテゴリ（default: 'general'） | 許可されたカテゴリのみ |
| app_config | Hash | Yes | 設定キー・値のハッシュ | allowed_configsで制限 |

### 入力データソース

Super Admin管理画面のフォーム入力

### 設定カテゴリ一覧

| カテゴリ | 設定項目 |
|---------|---------|
| general（デフォルト） | ENABLE_ACCOUNT_SIGNUP, FIREBASE_PROJECT_ID, FIREBASE_CREDENTIALS, WEBHOOK_TIMEOUT, MAXIMUM_FILE_UPLOAD_SIZE |
| facebook | FB_APP_ID, FB_VERIFY_TOKEN, FB_APP_SECRET, IG_VERIFY_TOKEN, FACEBOOK_API_VERSION, ENABLE_MESSENGER_CHANNEL_HUMAN_AGENT |
| shopify | SHOPIFY_CLIENT_ID, SHOPIFY_CLIENT_SECRET |
| microsoft | AZURE_APP_ID, AZURE_APP_SECRET |
| email | MAILER_INBOUND_EMAIL_DOMAIN |
| linear | LINEAR_CLIENT_ID, LINEAR_CLIENT_SECRET |
| slack | SLACK_CLIENT_ID, SLACK_CLIENT_SECRET |
| instagram | INSTAGRAM_APP_ID, INSTAGRAM_APP_SECRET, INSTAGRAM_VERIFY_TOKEN, INSTAGRAM_API_VERSION, ENABLE_INSTAGRAM_CHANNEL_HUMAN_AGENT |
| tiktok | TIKTOK_APP_ID, TIKTOK_APP_SECRET, TIKTOK_API_VERSION |
| whatsapp_embedded | WHATSAPP_APP_ID, WHATSAPP_APP_SECRET, WHATSAPP_CONFIGURATION_ID, WHATSAPP_API_VERSION |
| notion | NOTION_CLIENT_ID, NOTION_CLIENT_SECRET |
| google | GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET, GOOGLE_OAUTH_REDIRECT_URI, ENABLE_GOOGLE_OAUTH_LOGIN |
| captain | CAPTAIN_OPEN_AI_API_KEY, CAPTAIN_OPEN_AI_MODEL, CAPTAIN_OPEN_AI_ENDPOINT |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @app_config | Hash | 現在の設定値（設定名 => 値） |
| @installation_configs | Hash | 設定の説明情報 |
| @config | String | 現在のカテゴリ |

### 出力先

Super Admin管理画面の設定ビュー

## 処理フロー

### 処理シーケンス

```
1. 認証チェック
   └─ Super Adminとしてログインしているか確認
2. カテゴリ設定
   └─ パラメータからカテゴリを取得（デフォルト: 'general'）
3. 許可設定項目の決定
   └─ カテゴリに応じた設定項目リストを生成
4. 表示処理（showアクション）
   └─ 現在の設定値とメタ情報を取得
5. 更新処理（createアクション）
   └─ 許可された設定のみを更新
   └─ エラーがあれば収集
6. リダイレクト
   └─ 成功/失敗メッセージとともにリダイレクト
```

### フローチャート

```mermaid
flowchart TD
    A[Super Admin アクセス] --> B{認証済み?}
    B -->|No| C[ログイン画面へリダイレクト]
    B -->|Yes| D[カテゴリ決定]
    D --> E[許可設定項目リスト生成]
    E --> F{アクション種別}
    F -->|show| G[設定値取得]
    G --> H[メタ情報取得]
    H --> I[設定画面表示]
    F -->|create| J[設定値ループ処理]
    J --> K{許可された設定?}
    K -->|No| L[スキップ]
    K -->|Yes| M[first_or_create]
    M --> N[値更新]
    N --> O{保存成功?}
    O -->|No| P[エラー収集]
    O -->|Yes| Q[次の設定へ]
    L --> Q
    P --> Q
    Q --> R{全設定処理完了?}
    R -->|No| J
    R -->|Yes| S{エラーあり?}
    S -->|Yes| T[エラー表示]
    S -->|No| U[成功メッセージ表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 許可リスト制限 | 許可されたキーのみ更新可能 | 更新時 |
| BR-002 | カテゴリマッピング | カテゴリごとに許可キーが決まっている | 常時 |
| BR-003 | first_or_create | 存在しない設定は新規作成 | 更新時 |
| BR-004 | locked: false | Super Admin経由の設定はlocked: falseで作成 | 作成時 |

### 計算ロジック

設定値の取得ロジック：
```ruby
@app_config = InstallationConfig.where(name: @allowed_configs)
                                .pluck(:name, :serialized_value)
                                .map { |name, serialized_value| [name, serialized_value['value']] }
                                .to_h
```

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定表示 | installation_configs | SELECT | カテゴリ内設定を取得 |
| 設定更新 | installation_configs | INSERT/UPDATE | 設定を作成または更新 |

### テーブル別操作詳細

#### installation_configs

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | name, serialized_value | name IN @allowed_configs | カテゴリフィルタ |
| INSERT/UPDATE | serialized_value, locked | 入力値, false | first_or_create使用 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | 認証エラー | Super Admin未ログイン | ログイン画面へリダイレクト |
| 422 | バリデーションエラー | 設定値の形式不正 | エラーメッセージ表示 |

### リトライ仕様

本機能にリトライ処理は実装されていない。

## トランザクション仕様

各設定項目は個別に保存されるため、一部の設定が失敗しても他の設定は保存される。エラーは収集されてまとめて表示される。

## パフォーマンス要件

特別なパフォーマンス要件なし。

## セキュリティ考慮事項

- Super Admin権限のみアクセス可能
- APIキーやシークレットを含む機密情報を扱う
- 設定値はデータベースに保存されるため、データベースセキュリティに注意
- Enterprise版ではSAMLプロバイダの設定も管理可能（prepend_mod_with）

## 備考

- ConfigLoaderからメタ情報を取得
- Enterprise版で追加設定が可能（prepend_mod_with）
- 許可リストにないキーは無視される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | installation_config.rb | `app/models/installation_config.rb` | 設定データの保存構造 |

**読解のコツ**: App設定はInstallationConfigモデルを使用して保存される。serialized_valueカラムにJSONB形式で値が保存される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | app_configs_controller.rb | `app/controllers/super_admin/app_configs_controller.rb` | show/createアクションの実装 |

**主要処理フロー**:
1. **2-3行目**: before_actionでset_configとallowed_configsを呼び出し
2. **4-15行目**: showアクションで現在の設定値とメタ情報を取得
3. **17-32行目**: createアクションで設定を一括更新
4. **36-38行目**: set_configでカテゴリを決定（デフォルト: 'general'）
5. **40-60行目**: allowed_configsでカテゴリ別許可リストを生成

#### Step 3: カテゴリマッピングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | app_configs_controller.rb | `app/controllers/super_admin/app_configs_controller.rb` | allowed_configsメソッドのマッピング定義 |

**主要処理フロー**:
- **41-54行目**: カテゴリごとの許可設定項目マッピング
- **56-59行目**: mapping.fetchでデフォルト値（general）を設定

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

```
SuperAdmin::AppConfigsController
    │
    ├─ before_action :set_config
    │      └─ params[:config] || 'general'
    │
    ├─ before_action :allowed_configs
    │      └─ mapping[config] || default_configs
    │
    ├─ show
    │      ├─ InstallationConfig.where(name: @allowed_configs)
    │      │      └─ pluck → map → to_h
    │      └─ ConfigLoader.new.general_configs
    │
    └─ create
           └─ params['app_config'].each
                  └─ InstallationConfig.where(name: key).first_or_create
                         └─ update value
```

### データフロー図

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

params[:config] ───▶ set_config ───────────▶ @config
                          │
                          ▼
                    allowed_configs ────────▶ @allowed_configs
                          │
                          ▼
params[:app_config] ─▶ create ─────────────▶ installation_configs
                          │                    テーブル更新
                          ▼
                    エラー収集/成功 ─────────▶ flash[:alert/notice]
                          │
                          ▼
                    redirect_to
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| app_configs_controller.rb | `app/controllers/super_admin/app_configs_controller.rb` | コントローラー | 設定の表示・更新 |
| installation_config.rb | `app/models/installation_config.rb` | モデル | 設定データの管理 |
| application_controller.rb | `app/controllers/super_admin/application_controller.rb` | コントローラー | Super Admin共通処理 |
| config_loader.rb | `app/services/config_loader.rb` | サービス | 設定メタ情報の提供 |
