# 機能設計書 184-容量ポリシー

## 概要

本ドキュメントは、Chatwootにおける「容量ポリシー」機能の設計仕様を定義する。本機能は、エージェントごとの会話受注容量を制限するためのエンタープライズ専用機能である。

### 本機能の処理概要

本機能は、管理者がエージェント容量ポリシーを作成・管理し、各エージェントが同時に担当できる会話数を制御することを可能にする。ポリシーにはインボックスごとの会話制限や、除外ルール（特定ラベル、一定時間経過した会話の除外）を設定できる。

**業務上の目的・背景**：カスタマーサポート業務において、エージェントの負荷を適切に管理することは品質維持に不可欠である。エージェントに過度な会話が割り当てられると、応答品質の低下や燃え尽き症候群のリスクが高まる。容量ポリシーにより、エージェントの作業負荷を適切にコントロールし、サービス品質を維持する。

**機能の利用シーン**：新しいエージェントチームを構成する際に、各メンバーの経験やスキルに応じた容量ポリシーを作成する。繁忙期と閑散期で容量を調整する。特定のインボックス（複雑な案件が多いなど）に対して個別の制限を設ける。

**主要な処理内容**：
1. 容量ポリシーの作成（CRUD）
2. ポリシーへのエージェント割り当て（No.185で詳述）
3. ポリシーへのインボックス制限追加（No.186で詳述）
4. 除外ルールの設定（ラベル除外、時間経過除外）

**関連システム・外部連携**：自動割り当て機能（容量を考慮したラウンドロビン）、チーム管理機能

**権限による制御**：エンタープライズアカウントの管理者のみがアクセス可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 84 | エージェント容量一覧 | 主画面 | 容量ポリシーの一覧表示 |
| 85 | エージェント容量作成 | 主画面 | 新しい容量ポリシーの作成 |
| 86 | エージェント容量編集 | 主画面 | 既存ポリシーの編集 |

## 機能種別

CRUD操作 / 設定管理 / Enterprise機能

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | ポリシー名 | 最大255文字 |
| description | Text | No | ポリシーの説明 | - |
| exclusion_rules | Object | No | 除外ルール | JSON形式 |
| exclusion_rules.exclude_older_than_hours | Integer | No | 指定時間より古い会話を除外 | 正の整数 |
| exclusion_rules.excluded_labels | Array | No | 除外するラベルのリスト | 文字列配列 |

### 入力データソース

- APIリクエスト（JSON形式）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | ポリシーID |
| name | String | ポリシー名 |
| description | Text | ポリシーの説明 |
| exclusion_rules | Object | 除外ルール設定 |
| created_at | DateTime | 作成日時 |
| updated_at | DateTime | 更新日時 |

### 出力先

- HTTPレスポンス（JSON形式）

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ CRUD操作の種別を判定

2. 認可チェック
   └─ エンタープライズアカウントかつ管理者権限を確認

3. CRUD処理の実行
   ├─ index: ポリシー一覧の取得
   ├─ show: 単一ポリシーの取得
   ├─ create: 新規ポリシーの作成
   ├─ update: 既存ポリシーの更新
   └─ destroy: ポリシーの削除

4. レスポンス返却
   └─ JSON形式でポリシー情報を返却
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信] --> B{エンタープライズ?}
    B -->|No| C[403 Forbidden]
    B -->|Yes| D[認可チェック]

    D --> E{アクション}
    E -->|index| F[ポリシー一覧取得]
    E -->|show| G[単一ポリシー取得]
    E -->|create| H[新規ポリシー作成]
    E -->|update| I[ポリシー更新]
    E -->|destroy| J[ポリシー削除]

    F --> K[レスポンス返却]
    G --> K
    H --> K
    I --> K
    J --> L[head :ok]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-184-01 | エンタープライズ専用 | 本機能はエンタープライズエディションでのみ利用可能 | 常時 |
| BR-184-02 | 名前必須 | ポリシー名は必須、最大255文字 | 作成・更新時 |
| BR-184-03 | アカウント境界 | ポリシーはアカウント内でのみ有効 | 常時 |
| BR-184-04 | 削除時の関連解除 | ポリシー削除時、関連するaccount_usersのポリシー参照はnullになる | 削除時 |

### 計算ロジック

除外ルールの適用ロジック：
- `exclude_older_than_hours`: 指定時間より前に作成された会話は容量カウントから除外
- `excluded_labels`: 指定ラベルが付与された会話は容量カウントから除外

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 一覧取得 | agent_capacity_policies | SELECT | アカウント内の全ポリシー取得 |
| 詳細取得 | agent_capacity_policies | SELECT | 単一ポリシーの取得 |
| 新規作成 | agent_capacity_policies | INSERT | 新しいポリシーの作成 |
| 更新 | agent_capacity_policies | UPDATE | 既存ポリシーの更新 |
| 削除 | agent_capacity_policies | DELETE | ポリシーの削除 |

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

#### agent_capacity_policies

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | account_id = Current.account.id | 一覧取得 |
| SELECT | * | id = params[:id] | 詳細取得 |
| INSERT | name | リクエストパラメータ | 必須 |
| INSERT | description | リクエストパラメータ | オプション |
| INSERT | exclusion_rules | リクエストパラメータ（JSONB） | オプション |
| INSERT | account_id | Current.account.id | 自動設定 |
| UPDATE | name, description, exclusion_rules | リクエストパラメータ | |
| DELETE | - | id = params[:id] | CASCADE削除でinbox_capacity_limitsも削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | Forbidden | 非エンタープライズアカウント | エラーレスポンス返却 |
| 403 | Forbidden | 権限不足 | エラーレスポンス返却 |
| 404 | Not Found | ポリシーが存在しない | エラーレスポンス返却 |
| 422 | Unprocessable Entity | バリデーションエラー | エラーメッセージ返却 |

### リトライ仕様

同期処理のため、リトライ仕様は適用されない。

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

create! / update! / destroy! による暗黙的なトランザクション制御。失敗時は自動ロールバック。

## パフォーマンス要件

- 単純なCRUD操作のため、特別なパフォーマンス要件なし
- 応答時間: 通常100ms以内

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

- エンタープライズエディション専用機能
- EnterpriseAccountsControllerを継承し、エンタープライズ認証を実施
- 管理者権限のチェック（check_authorization）
- アカウント境界の厳守

## 備考

- 本機能はenterpriseディレクトリ配下に実装
- OSS版では利用不可

---

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

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

### 推奨読解順序

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

まず、容量ポリシーのデータモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | agent_capacity_policy.rb | `enterprise/app/models/agent_capacity_policy.rb` | ポリシーモデルの構造 |
| 1-2 | inbox_capacity_limit.rb | `enterprise/app/models/inbox_capacity_limit.rb` | インボックス制限の構造 |

**読解のコツ**:
- **17-27行目**（agent_capacity_policy.rb）: リレーション定義、バリデーション
- **18行目**: MAX_NAME_LENGTH定数 - 名前の最大長
- **21行目**: has_many :inbox_capacity_limits - インボックス制限との関連
- **23行目**: has_many :account_users - エージェントとの関連

#### Step 2: コントローラーアクションを理解する

CRUD APIの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | agent_capacity_policies_controller.rb | `enterprise/app/controllers/api/v1/accounts/agent_capacity_policies_controller.rb` | CRUDアクション |

**主要処理フロー**:
- **1行目**: EnterpriseAccountsControllerを継承 - エンタープライズ認証
- **2行目**: check_authorization - 権限チェック
- **5-7行目**: indexアクション - ポリシー一覧取得
- **11-13行目**: createアクション - 新規作成
- **15-17行目**: updateアクション - 更新
- **19-22行目**: destroyアクション - 削除
- **26-31行目**: permitted_params - 許可パラメータの定義

#### Step 3: エンタープライズ基盤を理解する

エンタープライズ認証の仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | enterprise_accounts_controller.rb | `enterprise/app/controllers/api/v1/accounts/enterprise_accounts_controller.rb` | エンタープライズ認証基盤 |

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

```
APIリクエスト
    │
    ├─ EnterpriseAccountsController (継承)
    │      └─ エンタープライズアカウント認証
    │
    └─ AgentCapacityPoliciesController
           │
           ├─ before_action :check_authorization
           ├─ before_action :fetch_policy (show, update, destroy)
           │
           ├─ index
           │      └─ Current.account.agent_capacity_policies
           │
           ├─ create
           │      └─ agent_capacity_policies.create!(permitted_params)
           │
           ├─ update
           │      └─ @agent_capacity_policy.update!(permitted_params)
           │
           └─ destroy
                  └─ @agent_capacity_policy.destroy!
```

### データフロー図

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

APIリクエスト ─────────▶ AgentCapacityPoliciesController ──────▶ JSON Response
(JSON)                       │
                             ▼
                     エンタープライズ認証
                             │
                             ▼
                     CRUD処理
                             │
                             ▼
                     agent_capacity_policies テーブル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| agent_capacity_policies_controller.rb | `enterprise/app/controllers/api/v1/accounts/agent_capacity_policies_controller.rb` | コントローラー | CRUDアクション |
| agent_capacity_policy.rb | `enterprise/app/models/agent_capacity_policy.rb` | モデル | ポリシーモデル |
| inbox_capacity_limit.rb | `enterprise/app/models/inbox_capacity_limit.rb` | モデル | インボックス制限モデル |
| enterprise_accounts_controller.rb | `enterprise/app/controllers/api/v1/accounts/enterprise_accounts_controller.rb` | コントローラー | エンタープライズ基盤 |
