# 機能設計書 148-Notion統合

## 概要

本ドキュメントは、ChatwootとNotion（ドキュメント・データベース管理ツール）を連携する統合機能の設計書である。OAuth認証によりNotionワークスペースと接続し、ChatwootのAI機能（Captain）でNotionのデータベースを知識ベースとして活用することを可能にする。

### 本機能の処理概要

**業務上の目的・背景**：多くの企業ではNotionを社内のナレッジベースとして活用している。Notion統合により、ChatwootのAI機能（Captain）がNotionに蓄積されたドキュメントやFAQを参照できるようになり、より正確で一貫性のあるカスタマーサポートを提供できる。これにより、エージェントの負荷軽減とサポート品質の向上が期待できる。

**機能の利用シーン**：
- CaptainがNotionのFAQデータベースを参照して自動応答
- エージェントがNotionのマニュアルを検索して回答を作成
- Notionに蓄積された製品情報を活用したサポート

**主要な処理内容**：
1. Notion OAuth認証によるワークスペース接続
2. Hookの作成・削除
3. AI機能（Captain）からのNotionデータ参照

**関連システム・外部連携**：
- Notion API（OAuth認証、データベース参照）

**権限による制御**：
- Notion統合の使用にはnotion_integrationフィーチャーフラグが必要
- NOTION_CLIENT_ID/NOTION_CLIENT_SECRET環境変数の設定が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 70 | Notion連携画面 | 主画面 | Notion統合の設定 |
| 65 | 連携アプリ一覧画面 | 参照画面 | Notion統合の有効化状態表示 |

## 機能種別

データ連携 / OAuth認証

## 入力仕様

### 入力パラメータ

Notion統合のコントローラーはdestroyアクションのみを提供しており、Hook作成は別のコールバックコントローラーで処理される。

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| (なし) | - | - | destroyアクションはパラメータ不要 | - |

### 入力データソース

- Notion OAuth認証コールバック（Hook作成時）
- 管理画面のNotion統合削除ボタン

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| hook.id | Integer | HookのID |
| hook.app_id | String | 'notion' |
| hook.access_token | String | Notionアクセストークン（暗号化） |
| hook.status | String | enabled/disabled |

### 出力先

- integrations_hooksテーブル（データベース）

## 処理フロー

### 処理シーケンス（Hook削除）

```
1. 管理者がNotion統合削除を実行
   └─ NotionController#destroy

2. Hookの取得
   └─ fetch_hook
   └─ account.hooks.find_by(app_id: 'notion')

3. Hook削除
   └─ @hook.destroy!

4. レスポンス返却
   └─ head :ok
```

### フローチャート

```mermaid
flowchart TD
    A[管理者がNotion統合削除を実行] --> B[fetch_hook]
    B --> C{Hook存在?}
    C -->|No| D[404 Not Found]
    C -->|Yes| E[hook.destroy!]
    E --> F[200 OK]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-148-01 | フィーチャーフラグ | notion_integrationが有効なアカウントのみ利用可能 | 全操作 |
| BR-148-02 | 環境設定 | NOTION_CLIENT_IDが設定されている場合のみ利用可能 | 全操作 |
| BR-148-03 | 単一Hook | アカウントあたり1つのNotionHookのみ（allow_multiple_hooks: false） | Hook作成時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 削除 | integrations_hooks | DELETE | Notion Hook削除 |

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

#### integrations_hooks

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | app_id = 'notion' AND account_id = ? | Hook取得 |
| DELETE | - | id = ? | Hook削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | Not Found | Hookが存在しない | Notion統合を設定 |
| 403 | Forbidden | 管理者権限がない | 管理者でログイン |

### リトライ仕様

リトライ仕様は存在しない

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

- 削除操作は単一トランザクションで処理

## パフォーマンス要件

- 削除操作: 500ms以内

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

- access_tokenは暗号化して保存
- OAuth認証でNotionワークスペースへのアクセス権限を取得

## 備考

- Notion統合はCaptain（AI機能）のドキュメントソースとして使用される
- Hook作成はNotion認可コントローラー（app/controllers/api/v1/accounts/notion/authorizations_controller.rb）で処理される
- Hookモデルにnotion?メソッドが定義されている

---

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

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

### 推奨読解順序

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

Notion統合の設定を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | apps.yml | `config/integration/apps.yml` | Notionアプリ設定（66-71行目） |
| 1-2 | hook.rb | `app/models/integrations/hook.rb` | notion?メソッド（59-61行目） |

**読解のコツ**:
- **apps.yml 66-71行目**: Notionのhook_type(account)、allow_multiple_hooks(false)を確認
- **hook.rb 59-61行目**: `notion?`メソッドでNotion Hookかどうかを判定

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

Notion統合コントローラーを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | notion_controller.rb | `app/controllers/api/v1/accounts/integrations/notion_controller.rb` | Hook削除 |

**主要処理フロー**:
1. **2行目**: `before_action :fetch_hook`でHook取得
2. **4-7行目**: `destroy`でHook削除
3. **11-13行目**: `fetch_hook`でapp_id='notion'のHook取得

#### Step 3: 認証フローを理解する

Notion認可コントローラーを確認（参考）。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | authorizations_controller.rb | `app/controllers/api/v1/accounts/notion/authorizations_controller.rb` | OAuth認証 |

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

```
NotionController
    │
    ├─ before_action :fetch_hook
    │      └─ account.hooks.find_by(app_id: 'notion')
    │
    └─ #destroy
           └─ @hook.destroy!
           └─ head :ok

[認証フロー（参考）]
Notion::AuthorizationsController
    │
    └─ #create
           └─ Notion OAuthトークン取得
           └─ Hook作成
```

### データフロー図

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

OAuth認証コード        ───▶ authorizations_controller  ───▶ integrations_hooks
(コールバック)                 │                              (access_token)
                               ▼
削除リクエスト         ───▶ notion_controller          ───▶ 200 OK
                               │                              (Hook削除)
                               ▼
                       hook.destroy!
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| notion_controller.rb | `app/controllers/api/v1/accounts/integrations/notion_controller.rb` | コントローラー | Hook削除 |
| authorizations_controller.rb | `app/controllers/api/v1/accounts/notion/authorizations_controller.rb` | コントローラー | OAuth認証 |
| hook.rb | `app/models/integrations/hook.rb` | モデル | notion?メソッド |
| apps.yml | `config/integration/apps.yml` | 設定 | Notionアプリ設定 |
| app.rb | `app/models/integrations/app.rb` | モデル | notion_enabled?メソッド |
