# 機能設計書 200-プラットフォームアカウントユーザー

## 概要

本ドキュメントは、ChatwootにおけるPlatform API用アカウントユーザー管理機能の設計を記載したものである。この機能により、外部アプリケーションがPlatform APIを通じてアカウントとユーザーの関連付け（アカウントユーザー）の作成・取得・削除が可能となる。

### 本機能の処理概要

**業務上の目的・背景**：マルチテナント環境では、ユーザーを特定のアカウントに所属させる必要がある。Platform APIを通じてアカウントユーザーを管理することで、外部アプリケーションがユーザーのアカウントへの追加・削除、ロールの設定をプログラムから行える。これにより、SaaS製品の顧客管理やエンタープライズ環境でのユーザー管理の自動化が可能となる。

**機能の利用シーン**：SaaS製品が顧客のユーザーを特定のChatwootアカウントに追加する。ユーザーのロール（エージェント/管理者）を変更する。顧客がユーザーをアカウントから削除する。

**主要な処理内容**：
1. アカウントに所属するユーザー一覧の取得
2. ユーザーをアカウントに追加（ロール設定含む）
3. アカウントからユーザーを削除

**関連システム・外部連携**：Platform App（api_access_token）を通じた認証。

**権限による制御**：Platform Appに関連付けられたアカウントのみ操作可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | APIのみ（画面なし） |

## 機能種別

CRUD操作（一部）

## 入力仕様

### 入力パラメータ

#### indexアクション

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| account_id | Integer | Yes | アカウントID（URLパラメータ） | 存在するアカウント |

#### createアクション

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| account_id | Integer | Yes | アカウントID（URLパラメータ） | 存在するアカウント |
| user_id | Integer | Yes | ユーザーID | 存在するユーザー |
| role | String | No | ロール（agent/administrator） | デフォルト: agent |

#### destroyアクション

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| account_id | Integer | Yes | アカウントID（URLパラメータ） | 存在するアカウント |
| user_id | Integer | Yes | ユーザーID | 存在するユーザー |

### 入力データソース

- Platform API経由のHTTPリクエスト（JSON形式）
- api_access_tokenヘッダーによる認証

## 出力仕様

### 出力データ（index）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| account_users | Array | アカウントユーザー一覧 |

### アカウントユーザーの構造

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | アカウントユーザーID |
| user_id | Integer | ユーザーID |
| account_id | Integer | アカウントID |
| role | String | ロール（agent/administrator） |
| availability | Integer | 可用性状態 |
| auto_offline | Boolean | 自動オフライン設定 |
| active_at | DateTime | 最終アクティブ日時 |
| created_at | DateTime | 作成日時 |
| updated_at | DateTime | 更新日時 |

### 出力先

- JSON形式でAPIレスポンスとして返却

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ api_access_tokenヘッダーの検証
2. Platform App確認
   └─ アクセストークンの所有者がPlatform Appか確認
3. アカウント設定
   └─ set_resourceでアカウントを取得
4. Permissible検証
   └─ Platform Appに関連付けられているか確認
5. アクション実行
   ├─ index: アカウントユーザー一覧を返却
   ├─ create: ユーザーをアカウントに追加（既存の場合は更新）
   └─ destroy: アカウントからユーザーを削除
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信] --> B{api_access_token有効?}
    B -->|No| C[401 Unauthorized]
    B -->|Yes| D{Platform App?}
    D -->|No| C
    D -->|Yes| E[set_resource: Account.find]
    E --> F{Permissible?}
    F -->|No| G[401 Non permissible]
    F -->|Yes| H{アクション?}
    H -->|index| I[account_users一覧返却]
    H -->|create| J[find_or_initialize_by + update!]
    H -->|destroy| K[find_by + destroy!]
    I --> L[レスポンス返却]
    J --> L
    K --> M[204 No Content]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-200-01 | Platform App認証 | api_access_tokenがPlatform Appに紐づいている必要がある | 常時 |
| BR-200-02 | Permissible検証 | 操作対象アカウントがPlatform Appに関連付けられている必要がある | 常時 |
| BR-200-03 | Upsert動作 | createは既存の場合は更新（find_or_initialize_by） | create |
| BR-200-04 | デフォルトロール | ロール未指定時はagentがデフォルト | create |

### 計算ロジック

なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| index | account_users | SELECT | アカウントユーザー一覧取得 |
| create | account_users | INSERT/UPDATE | アカウントユーザー作成または更新 |
| destroy | account_users | DELETE | アカウントユーザー削除 |

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

#### account_users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | account_id = params[:account_id] | 一覧取得 |
| INSERT/UPDATE | user_id, role | リクエストパラメータ | find_or_initialize_by(user_id) |
| DELETE | * | account_id, user_id | 条件一致で削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | Unauthorized | api_access_tokenが無効 | エラーメッセージ「Invalid access_token」 |
| 401 | Unauthorized | Platform Appに関連付けられていないアカウント | エラーメッセージ「Non permissible resource」 |

### リトライ仕様

なし

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

- アカウントユーザーの作成・更新・削除は単一トランザクションで実行

## パフォーマンス要件

- 特になし

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

- api_access_tokenによるPlatform App認証
- Permissible検証によるアクセス制御

## 備考

- createアクションはUpsert動作（既存の場合は更新）
- destroyアクションは存在しない場合でもエラーにならない（&.destroy!のセーフナビゲーション）

---

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

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

### 推奨読解順序

#### Step 1: 基底コントローラーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | platform_controller.rb | `app/controllers/platform_controller.rb` | Platform API共通処理 |

**主要処理フロー**:
1. **4行目**: `before_action :ensure_access_token` - トークン検証
2. **5行目**: `before_action :set_platform_app` - Platform App設定
3. **6-7行目**: `before_action :set_resource, :validate_platform_app_permissible` - リソース検証
4. **32-36行目**: `validate_platform_app_permissible`メソッド - Permissible検証

#### Step 2: アカウントユーザーコントローラーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | account_users_controller.rb | `app/controllers/platform/api/v1/account_users_controller.rb` | アカウントユーザー管理API |

**主要処理フロー**:
1. **2行目**: `before_action :set_resource` - アカウント取得
2. **3行目**: `before_action :validate_platform_app_permissible` - Permissible検証
3. **5-7行目**: `index`アクション - アカウントユーザー一覧返却
4. **9-13行目**: `create`アクション - find_or_initialize_by + update!
5. **15-18行目**: `destroy`アクション - find_by + destroy!
6. **22-24行目**: `set_resource`メソッド - Account.find
7. **26-28行目**: `account_user_params`メソッド - パラメータ定義

**読解のコツ**: `find_or_initialize_by`と`update!`の組み合わせはUpsertパターン。既存レコードがあれば更新、なければ新規作成する。`&.destroy!`はセーフナビゲーション演算子で、レコードが見つからない場合はnilを返す。

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

```
Platform::Api::V1::AccountUsersController
    │
    ├─ PlatformController (継承)
    │      ├─ ensure_access_token
    │      │      └─ AccessToken.find_by(token: ...)
    │      └─ set_platform_app
    │             └─ @access_token.owner.is_a?(PlatformApp)
    │
    ├─ set_resource (before_action)
    │      └─ Account.find(params[:account_id])
    │
    ├─ validate_platform_app_permissible (before_action)
    │      └─ @platform_app.platform_app_permissibles.find_by(permissible: @resource)
    │
    ├─ index
    │      └─ @resource.account_users
    │
    ├─ create
    │      ├─ @resource.account_users.find_or_initialize_by(user_id: ...)
    │      └─ @account_user.update!(account_user_params)
    │
    └─ destroy
           └─ @resource.account_users.find_by(user_id: ...)&.destroy!
```

### データフロー図

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

api_access_token   ───▶ PlatformController
(Header)                    │
                            ▼
                    ensure_access_token
                            │
                            ▼
                    set_platform_app
                            │
                            ▼
account_id         ───▶ set_resource
(URL param)                 │
                            ▼
                    validate_platform_app_permissible
                            │
                            ▼
user_id, role      ───▶ AccountUsersController#create
                            │
                            ▼
                    find_or_initialize_by(user_id)
                            │
                            ▼
                    update!(account_user_params)
                            │
                            ▼
                    { account_user JSON }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| account_users_controller.rb | `app/controllers/platform/api/v1/account_users_controller.rb` | ソース | アカウントユーザー管理APIコントローラー |
| platform_controller.rb | `app/controllers/platform_controller.rb` | ソース | Platform API基底コントローラー |
| account_user.rb | `app/models/account_user.rb` | ソース | AccountUserモデル |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（497-501行目） |
