# 画面設計書 72-連携詳細画面

## 概要

本ドキュメントはChatwootの連携詳細画面（IntegrationHooks）に関する設計書です。各種外部サービス連携の詳細設定とHook（接続設定）の管理を行う画面について記述しています。

### 本画面の処理概要

本画面では、外部サービスとの連携設定（Hook）の作成・削除を管理します。連携アプリには「Single」タイプ（アカウント全体で1つの設定）と「Multiple」タイプ（複数のインボックスごとに設定可能）があり、それぞれに応じた管理機能を提供します。

**業務上の目的・背景**：企業が利用する様々な外部ツール（Dialogflow、OpenAI、dyte等）とChatwootを連携させることで、AIによる自動応答、ビデオ通話機能、その他の高度な機能を会話に追加できます。この画面では、それらの連携設定を一元管理し、必要に応じてインボックス単位での細かな設定が可能です。

**画面へのアクセス方法**：サイドバーの「設定」から「連携」メニューを選択し、連携アプリ一覧から任意の連携アプリをクリックしてアクセスします。または、URLで直接 `/app/accounts/:accountId/settings/integrations/:integration_id` にアクセスすることもできます。

**主要な操作・処理内容**：
1. 連携設定（Hook）の一覧表示：現在の連携状態と設定済みHookの確認
2. 新しいHookの追加：インボックスを選択して新しい連携設定を作成
3. 既存Hookの削除：不要になった連携設定を削除
4. 連携タイプに応じた表示切り替え：SingleタイプとMultipleタイプで異なるUIを表示

**画面遷移**：
- 遷移元：連携アプリ一覧画面（settings_applications）
- 遷移先：連携アプリ一覧画面

**権限による表示制御**：管理者（administrator）権限を持つユーザーのみがアクセス可能です。連携タイプに応じて追加ボタンの表示/非表示が制御されます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 143 | Hooks（Integrations） | 主機能 | 各連携の詳細設定とHook管理 |

## 画面種別

一覧・設定

## URL/ルーティング

| 項目 | 値 |
|------|-----|
| パス | `/app/accounts/:accountId/settings/integrations/:integration_id` |
| ルート名 | `settings_applications_integration` |
| コンポーネント | `IntegrationHooks.vue` |

## 入出力項目

| 項目名 | 項目ID | 種別 | 型 | 必須 | バリデーション | 説明 |
|--------|--------|------|-----|------|---------------|------|
| 連携ID | integrationId | URLパラメータ | String/Number | Yes | - | 連携アプリの識別子 |

## 表示項目

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| 連携情報 | integration | 連携アプリの基本情報（名前、説明、ロゴ等） |
| Hook一覧 | integration.hooks | 設定済みのHook一覧 |
| 連携タイプ | isIntegrationMultiple/isIntegrationSingle | 連携のタイプ（複数/単一） |
| Hookタイプ | isHookTypeInbox | Hookがインボックス単位かどうか |

## イベント仕様

### 1-Hook追加ボタン押下

**トリガー**: Multipleタイプ連携で「Add」ボタンのクリック

**処理フロー**:
1. `showAddHookModal`をtrueに設定
2. NewHookモーダルを表示
3. ユーザーがインボックスを選択
4. 送信時に`integrations/createHook`アクションを呼び出し
5. 成功時、ストアにHookを追加しモーダルを閉じる

### 2-Hook削除ボタン押下

**トリガー**: 各Hook行の「Delete」ボタンのクリック

**処理フロー**:
1. `selectedHook`に削除対象のHookを設定
2. 削除確認モーダル（`showDeleteConfirmationPopup`）を表示
3. 確認後、`confirmDeletion`メソッドを実行
4. `integrations/deleteHook`アクションを呼び出し
5. 成功時、ストアからHookを削除しアラートを表示

### 3-モーダルクローズ

**トリガー**: 各モーダルの「Cancel」ボタン押下またはモーダル外クリック

**処理フロー**:
1. モーダルの表示フラグをfalseに設定
2. 選択状態をリセット

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Hook追加 | integrations_hooks | INSERT | 新しい連携Hookの作成 |
| Hook削除 | integrations_hooks | DELETE | 連携Hookの削除 |

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

#### integrations_hooks

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | app_id | integration_id | 連携アプリID |
| INSERT | account_id | 現在のアカウントID | - |
| INSERT | inbox_id | 選択されたインボックスID | Multipleタイプの場合 |
| INSERT | settings | Hook固有の設定値 | 連携ごとに異なる |
| DELETE | id | selectedHook.id | 削除対象のHook ID |

## メッセージ仕様

| 種別 | キー | メッセージ | 表示条件 |
|------|-----|-----------|---------|
| 成功 | INTEGRATION_APPS.DELETE.API.SUCCESS_MESSAGE | Hookが正常に削除されました | Hook削除成功時 |
| エラー | INTEGRATION_APPS.DELETE.API.ERROR_MESSAGE | Hookの削除に失敗しました | Hook削除失敗時 |
| 確認 | INTEGRATION_APPS.DELETE.TITLE.INBOX | インボックス連携を削除しますか？ | Inbox Hookタイプの削除確認 |
| 確認 | INTEGRATION_APPS.DELETE.TITLE.ACCOUNT | アカウント連携を削除しますか？ | Account Hookタイプの削除確認 |
| 確認 | INTEGRATION_APPS.DELETE.MESSAGE.INBOX | この操作は取り消せません | Inbox Hookタイプの削除確認メッセージ |
| 確認 | INTEGRATION_APPS.DELETE.MESSAGE.ACCOUNT | この操作は取り消せません | Account Hookタイプの削除確認メッセージ |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 権限不足 | 管理者権限がない場合、画面にアクセスできない |
| 連携が見つからない | 空の状態を表示 |
| API通信エラー | エラーメッセージをアラートで表示 |
| Hook作成失敗 | エラーメッセージを表示し、モーダルを維持 |

## 備考

- 連携タイプ（Single/Multiple）は連携アプリの定義によって決定される
- Singleタイプの連携はアカウント全体で1つの設定のみ可能
- Multipleタイプの連携は複数のインボックスに対して個別に設定可能
- Dialogflowなど一部の連携ではヘッダーが非表示になる特別な設定がある

---

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

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

### 推奨読解順序

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

まず、連携アプリとHookのデータ構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | integrations.js (store) | `app/javascript/dashboard/store/modules/integrations.js` | integration.hooks配列の構造、hookオブジェクトのプロパティ |

**読解のコツ**: integrationオブジェクト内のhooks配列がどのように管理され、ADD_INTEGRATION_HOOKS/DELETE_INTEGRATION_HOOKSミューテーションでどのように更新されるかを確認する。

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

処理の起点となるVueコンポーネントを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | IntegrationHooks.vue | `app/javascript/dashboard/routes/dashboard/settings/integrations/IntegrationHooks.vue` | setup関数でのuseIntegrationHook composable利用 |

**主要処理フロー**:
1. **行22-36**: `setup`関数で`useIntegrationHook`を呼び出し、連携情報を取得
2. **行47-53**: `computed`で連携の存在確認とUIフラグ
3. **行88-105**: `confirmDeletion`メソッドでHook削除処理

#### Step 3: Composableを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | useIntegrationHook.js | `app/javascript/dashboard/composables/useIntegrationHook.js` | 連携タイプの判定ロジック |

**主要処理フロー**:
- `isIntegrationMultiple`: hook_typeが'inbox'の場合true
- `isIntegrationSingle`: hook_typeが'account'の場合true

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SingleIntegrationHooks.vue | `app/javascript/dashboard/routes/dashboard/settings/integrations/SingleIntegrationHooks.vue` | Singleタイプの表示ロジック |
| 4-2 | MultipleIntegrationHooks.vue | `app/javascript/dashboard/routes/dashboard/settings/integrations/MultipleIntegrationHooks.vue` | Multipleタイプの表示ロジック |
| 4-3 | NewHook.vue | `app/javascript/dashboard/routes/dashboard/settings/integrations/NewHook.vue` | Hook追加フォーム |

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

```
IntegrationHooks.vue (エントリーポイント)
    │
    ├─ setup
    │      └─ useIntegrationHook(integrationId)
    │             └─ 連携タイプ判定
    │
    ├─ SingleIntegrationHooks.vue (条件付き表示)
    │      ├─ 連携設定表示
    │      └─ @add / @delete イベント発火
    │
    ├─ MultipleIntegrationHooks.vue (条件付き表示)
    │      ├─ Hook一覧表示
    │      └─ @add / @delete イベント発火
    │
    ├─ NewHook.vue (モーダル)
    │      └─ store.dispatch('integrations/createHook')
    │             └─ IntegrationsAPI.createHook()
    │
    └─ woot-delete-modal
           └─ confirmDeletion()
                  └─ store.dispatch('integrations/deleteHook')
                         └─ IntegrationsAPI.deleteHook()
```

### データフロー図

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

integration_id ────────▶ useIntegrationHook ──────────▶ integration object
       │                        │
       │                        ▼
       │                 isIntegrationMultiple?
       │                        │
       ├── Yes ────────▶ MultipleIntegrationHooks ───▶ Hook一覧表示
       │                        │
       └── No ─────────▶ SingleIntegrationHooks ────▶ 単一Hook表示

[Hook操作]

NewHook form ─────────▶ createHook action ───────────▶ Hook追加
       │                        │
       │                        ▼
       │                 ADD_INTEGRATION_HOOKS ───────▶ UI更新

Delete button ────────▶ deleteHook action ───────────▶ Hook削除
       │                        │
       │                        ▼
       │                 DELETE_INTEGRATION_HOOKS ────▶ UI更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IntegrationHooks.vue | `app/javascript/dashboard/routes/dashboard/settings/integrations/IntegrationHooks.vue` | ソース | メイン画面コンポーネント |
| SingleIntegrationHooks.vue | `app/javascript/dashboard/routes/dashboard/settings/integrations/SingleIntegrationHooks.vue` | ソース | Single連携タイプの表示 |
| MultipleIntegrationHooks.vue | `app/javascript/dashboard/routes/dashboard/settings/integrations/MultipleIntegrationHooks.vue` | ソース | Multiple連携タイプの表示 |
| NewHook.vue | `app/javascript/dashboard/routes/dashboard/settings/integrations/NewHook.vue` | ソース | Hook追加モーダル |
| useIntegrationHook.js | `app/javascript/dashboard/composables/useIntegrationHook.js` | ソース | 連携Hook管理のComposable |
| integrations.js (API) | `app/javascript/dashboard/api/integrations.js` | ソース | API通信クラス |
| integrations.js (store) | `app/javascript/dashboard/store/modules/integrations.js` | ソース | Vuexストアモジュール |
| integrations.routes.js | `app/javascript/dashboard/routes/dashboard/settings/integrations/integrations.routes.js` | ソース | ルーティング定義 |
