# 機能設計書 85-Webhookアクティベーション

## 概要

本ドキュメントは、Fizzyアプリケーションにおける「Webhookアクティベーション」機能の設計仕様を定義する。無効化されたWebhookを再度有効化する機能である。

### 本機能の処理概要

Webhookアクティベーション機能は、配信失敗などにより自動的に無効化されたWebhookを再度有効化するための機能である。Webhookが再アクティベートされると、再びイベント発生時にペイロードが送信されるようになる。

**業務上の目的・背景**：Webhookは配信先の障害などにより自動的に無効化されることがある。外部サービスの復旧後に、Webhookを手動で再有効化することで、連携を再開する必要がある。この機能により、管理者が意図的にWebhook連携を再開できる。

**機能の利用シーン**：Webhook詳細画面で「Reactivate」ボタンをクリックして、無効化されたWebhookを再有効化する。主に、配信先サービスの復旧後や、一時的な障害からの回復時に使用される。

**主要な処理内容**：
1. 指定されたWebhookの存在確認
2. Webhookのactiveフラグをtrueに更新
3. 更新完了後、Webhook詳細画面へリダイレクト

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

**権限による制御**：ボードの管理者（admin）権限を持つユーザーのみがWebhookを再アクティベートできる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 64 | Webhook詳細画面 | 主画面 | Reactivateボタンを表示・操作 |

## 機能種別

CRUD操作（Update）/ 状態変更

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| board_id | UUID | Yes | ボードID | URLパラメータ |
| webhook_id | UUID | Yes | WebhookID | URLパラメータ |

### 入力データソース

URLパラメータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| active | Boolean | true（アクティブ状態） |

### 出力先

- データベース（webhooksテーブルのactiveカラム）
- 画面遷移（Webhook詳細画面へリダイレクト）

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ POST /boards/:board_id/webhooks/:webhook_id/activation
2. 認証・認可チェック
   └─ ログインユーザーかつボード管理者権限を確認
3. ボード取得
   └─ Current.userのボードからboard_idで検索
4. Webhook取得
   └─ @board.webhooks.find(params[:webhook_id])
5. アクティベーション実行
   └─ webhook.activate
6. 状態更新
   └─ active = trueに更新（既にtrueの場合はスキップ）
7. リダイレクト
   └─ Webhook詳細画面へ遷移
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{ログイン済み?}
    B -->|No| C[ログイン画面へ]
    B -->|Yes| D{管理者権限?}
    D -->|No| E[403 Forbidden]
    D -->|Yes| F[ボード取得]
    F --> G{ボード存在?}
    G -->|No| H[404 Not Found]
    G -->|Yes| I[Webhook取得]
    I --> J{Webhook存在?}
    J -->|No| K[404 Not Found]
    J -->|Yes| L{既にアクティブ?}
    L -->|Yes| M[何もしない]
    L -->|No| N[activeをtrueに更新]
    M --> O[詳細画面へリダイレクト]
    N --> O
    O --> P[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-85-01 | 冪等性 | 既にアクティブなWebhookに対しては何も行わない | active=true時 |
| BR-85-02 | 再アクティブ化 | active=falseの場合のみtrueに更新 | active=false時 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Webhook取得 | webhooks | SELECT | 指定IDのWebhookを取得 |
| Webhook更新 | webhooks | UPDATE | activeをtrueに更新 |

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

#### webhooks

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 全カラム | id = params[:webhook_id] AND board_id = @board.id | 単一レコード取得 |
| UPDATE | active | true | 既にtrueの場合はスキップ |
| UPDATE | updated_at | 現在時刻 | 自動設定 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | Unauthorized | 未ログイン | ログイン画面へリダイレクト |
| 403 | Forbidden | 管理者権限なし | 権限エラー表示 |
| 404 | NotFound | ボードまたはWebhookが存在しない | エラーページ表示 |

### リトライ仕様

該当なし

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

単一レコードの更新のため、ActiveRecordのデフォルトトランザクション制御に従う。

## パフォーマンス要件

- レスポンス時間: 500ms以内

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

- 管理者権限チェックによる認可制御
- CSRF対策（Railsデフォルト、POSTメソッド使用）

## 備考

Webhookの無効化（deactivate）は、配信失敗が続いた場合にシステムにより自動的に行われる。手動での無効化機能は現時点では提供されていない。

---

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

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

### 推奨読解順序

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

Webhookモデルのactivate/deactivateメソッドを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | webhook.rb | `app/models/webhook.rb` | activate/deactivateメソッドの実装 |

**読解のコツ**: `activate`メソッドは`update! active: true unless active?`という実装で、冪等性を確保している。

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

コントローラーのcreateアクション（アクティベーション）が処理の起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | activations_controller.rb | `app/controllers/webhooks/activations_controller.rb` | createアクションの処理フロー |

**主要処理フロー**:
1. **1行目**: `BoardScoped`モジュールのインクルード
2. **5行目**: `before_action :ensure_admin` - 管理者権限チェック
3. **7-10行目**: `create`アクション - アクティベーション処理
4. **8行目**: `webhook.activate` - アクティベーション実行

#### Step 3: ビュー（ボタン表示）を理解する

詳細画面でのReactivateボタンの表示条件を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.erb | `app/views/webhooks/show.html.erb` | Reactivateボタンの条件分岐 |

**主要処理フロー**:
- **23-27行目**: `unless @webhook.active?`でボタン表示を制御
- **25行目**: `button_to "Reactivate"`でPOSTリクエストを送信

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

```
Webhooks::ActivationsController#create
    │
    ├─ BoardScoped#set_board
    │      └─ Current.user.boards.find(params[:board_id])
    │
    ├─ ApplicationController#ensure_admin
    │      └─ Current.user.admin?
    │
    └─ webhook.activate
           │
           └─ update! active: true unless active?
```

### データフロー図

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

URLパラメータ ───▶ ActivationsController ───▶ webhooksテーブル
  - board_id              │                      UPDATE active = true
  - webhook_id            │
                          ▼
                    Webhook#activate
                      - 冪等性チェック
                      - active更新
                          │
                          ▼
                    リダイレクト ───▶ Webhook詳細画面
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| activations_controller.rb | `app/controllers/webhooks/activations_controller.rb` | ソース | アクティベーションコントローラー |
| webhook.rb | `app/models/webhook.rb` | ソース | Webhookモデル（activate/deactivateメソッド） |
| show.html.erb | `app/views/webhooks/show.html.erb` | テンプレート | Reactivateボタン表示 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（49行目） |
