# 機能設計書 77-マクロのグローバル化

## 概要

本ドキュメントは、Chatwootにおけるマクロの公開範囲（visibility）設定機能の仕様を定義する機能設計書である。

### 本機能の処理概要

マクロの公開範囲をpersonal（個人用）またはglobal（全体共有）に設定する機能。Administratorがマクロをグローバルに設定することで、アカウント内のすべてのユーザーがそのマクロを利用できるようになる。

**業務上の目的・背景**：カスタマーサポートチームでは、共通の対応フローやルールが存在する。各エージェントが個別に同じマクロを作成するのは非効率であり、設定のばらつきも生じやすい。本機能により、Administratorが標準マクロをグローバルに共有することで、チーム全体の対応品質の均一化と設定作業の効率化を実現する。

**機能の利用シーン**：
- チーム共通の問い合わせクローズフローをグローバルマクロとして共有
- 新人エージェント向けの定型対応マクロを全員に公開
- 特定キャンペーン対応用のマクロを一時的に全員に共有
- 個人で作成したマクロをテスト後にグローバル化

**主要な処理内容**：
1. マクロ作成・更新時にvisibilityパラメータを受け取る
2. ユーザー権限に基づいてvisibility値を決定
3. エージェントの場合は強制的にpersonalに設定
4. Administratorの場合はリクエスト値をそのまま使用

**関連システム・外部連携**：特になし

**権限による制御**：
- Administrator：personal/globalの両方を設定可能
- Agent：personalのみ設定可能（globalは自動的にpersonalに変換）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | マクロ新規作成画面 | 主画面 | マクロの共有設定（visibility） |
| 64 | マクロ編集画面 | 主画面 | 既存マクロの共有設定変更 |

## 機能種別

設定変更 / 権限制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| visibility | String | No | 公開範囲 | "personal"または"global"、デフォルトpersonal |

### 入力データソース

- マクロ作成・更新APIのリクエストボディ
- 管理画面のフォーム入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| visibility | String | 設定された公開範囲（personal/global） |

### 出力先

- データベース（macrosテーブルのvisibilityカラム）
- APIレスポンス

## 処理フロー

### 処理シーケンス

```
1. マクロ作成/更新リクエスト受信
   └─ POST/PATCH /api/v1/accounts/:account_id/macros
2. visibilityパラメータ取得
   └─ params[:visibility]
3. ユーザー権限判定
   └─ user.agent? を確認
4. visibility値決定
   └─ エージェントの場合: personal
   └─ それ以外の場合: リクエスト値
5. マクロ保存
   └─ visibility値を含めて保存
```

### フローチャート

```mermaid
flowchart TD
    A[マクロ作成/更新リクエスト] --> B[visibilityパラメータ取得]
    B --> C{ユーザーはAgent?}
    C -->|Yes| D[visibility = personal]
    C -->|No| E{visibilityパラメータあり?}
    E -->|Yes| F[リクエスト値を使用]
    E -->|No| G[デフォルト値 personal]
    D --> H[マクロ保存]
    F --> H
    G --> H
    H --> I[レスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-77-01 | エージェント制限 | エージェントはglobalマクロを作成できない | 作成・更新時 |
| BR-77-02 | デフォルト値 | visibility未指定時はpersonalが設定される | enumデフォルト |
| BR-77-03 | グローバル閲覧 | globalマクロは全ユーザーが閲覧・実行可能 | マクロ一覧取得時 |
| BR-77-04 | グローバル編集 | globalマクロは作成者またはAdministratorが編集可能 | 更新時 |

### 計算ロジック

set_visibilityメソッドの実装：
```ruby
def set_visibility(user, params)
  self.visibility = params[:visibility]
  self.visibility = :personal if user.agent?
end
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| visibility設定 | macros | INSERT/UPDATE | visibilityカラムの設定 |

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

#### macros

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | visibility | 0 (personal) または 1 (global) | enum値として保存 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 422 | Unprocessable Entity | 不正なvisibility値 | personal/globalのみ指定 |
| 403 | Forbidden | エージェントがglobalマクロを編集しようとした | Administrator権限でアクセス |

### リトライ仕様

特になし

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

マクロの更新処理全体がトランザクション内で実行される。

## パフォーマンス要件

- visibility設定はマクロ作成・更新の一部として200ms以内

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

- エージェント権限ではglobal設定を強制的にpersonalに変換（サーバーサイドで制御）
- フロントエンドでの制御だけでなく、バックエンドでも権限チェックを実施

## 備考

- visibility enumは整数として保存（personal: 0, global: 1）
- グローバルマクロの作成者が削除された場合でも、マクロは残り続ける（orphan_record?で管理者が削除可能）

---

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

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

### 推奨読解順序

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

Macroモデルのvisibility enumを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | macro.rb | `app/models/macro.rb` | visibility enum定義、set_visibilityメソッド |

**読解のコツ**:
- **8行目**: visibilityカラムがdefault("personal")で定義
- **29行目**: `enum visibility: { personal: 0, global: 1 }`
- **37-40行目**: set_visibilityメソッドでエージェント制限を実装

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

コントローラーでのset_visibility呼び出しを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | macros_controller.rb | `app/controllers/api/v1/accounts/macros_controller.rb` | create/updateでのset_visibility呼び出し |

**主要処理フロー**:
1. **20行目**: createアクションで`@macro.set_visibility(current_user, permitted_params)`
2. **35行目**: updateアクションで`@macro.set_visibility(current_user, permitted_params)`

#### Step 3: 権限制御を理解する

MacroPolicyでのglobalマクロに関する権限を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | macro_policy.rb | `app/policies/macro_policy.rb` | globalマクロの編集・削除権限 |

**主要処理フロー**:
- **14-16行目**: update? - 作成者または（管理者かつglobal）で編集可能
- **32-35行目**: orphan_record? - 作成者なしのglobalマクロは管理者が削除可能

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

```
MacrosController#create/update
    │
    ├─ @macro.set_visibility(current_user, permitted_params)
    │      │
    │      ├─ self.visibility = params[:visibility]
    │      │
    │      └─ if user.agent?
    │             self.visibility = :personal
    │
    └─ @macro.save!
           └─ macros.visibility カラムに保存

[マクロ一覧取得時]
Macro.with_visibility(user, params)
    │
    ├─ Current.account.macros.global
    │
    └─ .or(personal.where(created_by_id: user.id))
```

### データフロー図

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

visibility                  権限チェック                    DB保存
パラメータ ─────────▶ set_visibility ────────────▶ macros.visibility
                            │
                            ├─ Agent? → personal強制
                            └─ Admin → リクエスト値使用
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| macro.rb | `app/models/macro.rb` | モデル | visibility enum、set_visibilityメソッド |
| macros_controller.rb | `app/controllers/api/v1/accounts/macros_controller.rb` | コントローラー | set_visibility呼び出し |
| macro_policy.rb | `app/policies/macro_policy.rb` | ポリシー | globalマクロの権限制御 |
