# 機能設計書 75-マクロ（ショートカット）

## 概要

本ドキュメントは、Chatwootにおけるマクロ（ショートカット）機能の作成・管理に関する仕様を定義する機能設計書である。

### 本機能の処理概要

会話に対して手動でトリガーできる一連のアクションをマクロとして定義・管理する機能。エージェントが頻繁に行う定型的な操作（ラベル付与、ステータス変更、メッセージ送信など）をワンクリックで実行できるようにし、業務効率を向上させる。

**業務上の目的・背景**：カスタマーサポート業務では、同じ操作を繰り返し行うことが多い。例えば、「問い合わせ完了」時に特定のラベルを付与し、ステータスを解決済みに変更し、定型文を送信するといった一連の操作を毎回手動で行うのは非効率である。本機能により、これらの操作をマクロとして登録し、ワンクリックで実行することで、エージェントの作業時間を削減し、対応の一貫性を確保する。

**機能の利用シーン**：
- 問い合わせクローズ時の定型処理（ラベル付与＋ステータス変更＋メッセージ送信）
- スパム対応（ミュート＋ラベル付与）
- エスカレーション処理（チーム割り当て＋優先度変更）
- 返金対応フロー（定型メッセージ送信＋ラベル付与）

**主要な処理内容**：
1. マクロのCRUD操作（作成・読取・更新・削除）
2. アクション（actions）の定義と検証
3. 公開範囲（visibility）の設定
4. 添付ファイルの管理
5. マクロの一覧取得（personal + global）

**関連システム・外部連携**：
- Webhook送信による外部システム連携
- メール送信サービスとの連携

**権限による制御**：
- マクロ作成：すべてのユーザーが可能
- グローバルマクロ設定：Administrator権限が必要
- マクロ編集・削除：作成者本人またはAdministrator

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 62 | マクロ一覧画面 | 主画面 | マクロの一覧表示・管理 |
| 63 | マクロ新規作成画面 | 主画面 | 新しいマクロの作成 |
| 64 | マクロ編集画面 | 主画面 | 既存マクロの編集 |

## 機能種別

CRUD操作 / 手動トリガー型自動化

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | マクロ名 | 必須 |
| visibility | String | No | 公開範囲（personal/global） | enum値のみ |
| actions | JSON | Yes | アクション配列 | 必須、形式検証 |

### アクション（actions）の構造

```json
[
  {
    "action_name": "add_label",
    "action_params": ["resolved"]
  },
  {
    "action_name": "change_status",
    "action_params": ["resolved"]
  }
]
```

| フィールド | 型 | 説明 |
|-----------|-----|------|
| action_name | String | 実行するアクション名 |
| action_params | Array | アクションのパラメータ |

### サポートされるアクション（ACTIONS_ATTRS）

send_message, add_label, assign_team, assign_agent, mute_conversation, change_status, remove_label, remove_assigned_team, resolve_conversation, snooze_conversation, change_priority, send_email_transcript, send_attachment, add_private_note, send_webhook_event

### 入力データソース

- 管理画面からのフォーム入力
- REST API経由

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | マクロID |
| name | String | マクロ名 |
| visibility | String | 公開範囲（personal/global） |
| created_by | Object | 作成者情報 |
| updated_by | Object | 更新者情報 |
| account_id | Integer | アカウントID |
| actions | JSON | アクション配列 |
| files | Array | 添付ファイル情報 |

### 出力先

- APIレスポンス（JSON形式）
- データベース（macrosテーブル）

## 処理フロー

### 処理シーケンス

```
1. マクロ作成リクエスト受信
   └─ POST /api/v1/accounts/:account_id/macros
2. パラメータ検証
   └─ アクションのJSON形式検証
3. 添付ファイル処理
   └─ send_attachmentアクションがある場合、ファイルをアップロード
4. 公開範囲設定
   └─ set_visibility: エージェントはpersonalのみ設定可能
5. マクロ保存
   └─ macrosテーブルへINSERT
6. レスポンス返却
   └─ 作成されたマクロ情報をJSON形式で返却
```

### フローチャート

```mermaid
flowchart TD
    A[マクロ作成リクエスト] --> B[パラメータ検証]
    B --> C{検証OK?}
    C -->|No| D[422 Unprocessable Entity]
    C -->|Yes| E[添付ファイル処理]
    E --> F[公開範囲設定]
    F --> G{Agent権限?}
    G -->|Yes| H[visibility = personal]
    G -->|No| I[リクエスト値を使用]
    H --> J[マクロ保存]
    I --> J
    J --> K{保存成功?}
    K -->|No| L[エラーレスポンス]
    K -->|Yes| M[ファイル添付]
    M --> N[成功レスポンス]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-75-01 | アクション検証 | actions内のaction_nameはACTIONS_ATTRSに定義されたもののみ | マクロ保存時 |
| BR-75-02 | エージェント制限 | エージェントはvisibility=personalのマクロのみ作成可能 | 作成時、更新時 |
| BR-75-03 | マクロ一覧取得 | globalマクロ＋自分が作成したpersonalマクロを取得 | index API |
| BR-75-04 | 作成者追跡 | created_by_id, updated_by_idで作成者・更新者を記録 | 保存時 |

### 計算ロジック

マクロの公開範囲決定ロジック：
```ruby
def set_visibility(user, params)
  self.visibility = params[:visibility]
  self.visibility = :personal if user.agent?
end
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| マクロ作成 | macros | INSERT | 新規マクロレコードの挿入 |
| マクロ更新 | macros | UPDATE | 既存マクロの更新 |
| マクロ削除 | macros | DELETE | マクロの削除 |
| マクロ一覧取得 | macros | SELECT | global + 自分のpersonalマクロ取得 |
| ファイル添付 | active_storage_* | INSERT | 添付ファイルの保存 |

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

#### macros

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name, visibility, actions, created_by_id, updated_by_id | リクエストパラメータ + current_user | account_idは自動設定 |
| UPDATE | name, visibility, actions, updated_by_id | リクエストパラメータ + current_user | 既存レコードを更新 |
| DELETE | - | id = :id | 論理削除ではなく物理削除 |
| SELECT (index) | * | visibility = 'global' OR (visibility = 'personal' AND created_by_id = current_user.id) | 一覧取得条件 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 422 | Unprocessable Entity | アクションのバリデーションエラー | エラーメッセージに従い修正 |
| 404 | Not Found | 指定マクロが存在しないまたはアクセス権限がない | 正しいIDを指定 |
| 403 | Forbidden | マクロの編集・削除権限がない | 作成者または管理者でアクセス |
| 401 | Unauthorized | 未認証 | ログイン後に再試行 |

### リトライ仕様

特になし（CRUD操作のみ）

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

- マクロ更新時はトランザクション内で処理
- ファイル添付はマクロ保存成功後に実行

## パフォーマンス要件

- マクロ一覧取得：200ms以内
- マクロ作成/更新：500ms以内

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

- Pundit Policyによるアクセス制御
  - show: globalマクロまたは作成者本人
  - update: 作成者本人または（グローバルマクロかつAdministrator）
  - destroy: 作成者本人または孤立レコード（作成者なしのグローバルマクロはAdministratorが削除可能）
  - execute: globalマクロまたは作成者本人

## 備考

- Enterprise版では監査ログ機能が追加される
- マクロの実行は別機能（No.76）で定義

---

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

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

### 推奨読解順序

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

Macroモデルの構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | macro.rb | `app/models/macro.rb` | モデル定義、ACTIONS_ATTRS、visibility enum |

**読解のコツ**:
- **1-18行目**: スキーマ情報でカラム定義を確認
- **29行目**: `enum visibility: { personal: 0, global: 1 }`でvisibility値を確認
- **33-35行目**: ACTIONS_ATTRSでサポートされるアクションを確認
- **37-40行目**: set_visibilityメソッドでエージェント制限を確認
- **42-46行目**: with_visibilityスコープでマクロ一覧取得ロジックを確認

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

APIコントローラーのCRUD操作を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | macros_controller.rb | `app/controllers/api/v1/accounts/macros_controller.rb` | CRUD操作の実装 |

**主要処理フロー**:
1. **7-9行目**: indexアクションでMacro.with_visibilityを使用
2. **15-27行目**: createアクションでマクロ作成、created_by_id設定、set_visibility呼び出し
3. **29-43行目**: updateアクションでトランザクション内更新
4. **45-48行目**: destroyアクションで削除

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

MacroPolicyを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | macro_policy.rb | `app/policies/macro_policy.rb` | 各アクションの権限制御 |

**主要処理フロー**:
- **10-12行目**: show? - globalマクロまたは作成者
- **14-16行目**: update? - 作成者または（管理者かつglobal）
- **18-20行目**: destroy? - 作成者または孤立レコード
- **22-24行目**: execute? - globalマクロまたは作成者

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

```
MacrosController
    │
    ├─ index: マクロ一覧取得
    │      └─ Macro.with_visibility(current_user, params)
    │             └─ global + 自分のpersonal
    │
    ├─ create: マクロ作成
    │      ├─ validate_and_prepare_attachments
    │      ├─ Macro.new(params + created_by_id)
    │      ├─ set_visibility(user, params)
    │      └─ macro.save!
    │
    ├─ update: マクロ更新
    │      └─ トランザクション内で更新
    │
    └─ destroy: マクロ削除
           └─ macro.destroy!

[権限チェック]
MacroPolicy
    │
    ├─ show? / execute?: global? || author?
    ├─ update?: author? || (administrator? && global?)
    └─ destroy?: author? || orphan_record?
```

### データフロー図

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

管理者/エージェント設定     マクロ保存                     DBへ永続化
(name, visibility,  ───▶ MacrosController ──────────▶ macrosテーブル
 actions)                   │
                            ├─ validate_and_prepare_attachments
                            ├─ set_visibility
                            └─ macro.save!
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| macro.rb | `app/models/macro.rb` | モデル | データ構造・バリデーション・スコープ |
| macros_controller.rb | `app/controllers/api/v1/accounts/macros_controller.rb` | コントローラー | CRUD API |
| macro_policy.rb | `app/policies/macro_policy.rb` | ポリシー | 権限制御 |
| _macro.json.jbuilder | `app/views/api/v1/models/_macro.json.jbuilder` | ビュー | JSONレスポンス |
| show.json.jbuilder | `app/views/api/v1/accounts/macros/show.json.jbuilder` | ビュー | 詳細レスポンス |
| index.json.jbuilder | `app/views/api/v1/accounts/macros/index.json.jbuilder` | ビュー | 一覧レスポンス |
