# 画面設計書 65-Webhook編集画面

## 概要

本ドキュメントは、FizzyアプリケーションにおけるWebhook編集画面の設計仕様を定義するものである。

### 本画面の処理概要

この画面は、既存のWebhookの名前と購読イベントを編集するためのフォーム画面である。セキュリティ上の理由から、ペイロードURLは編集できない仕様となっている。

**業務上の目的・背景**：Webhookの設定を柔軟に変更できるようにし、運用中の外部連携を調整可能にする。例えば、特定のイベントのみを通知するように変更したり、Webhookの識別名を分かりやすく変更したりできる。URLの変更を禁止することで、意図しないエンドポイントへの通知漏洩を防止する。

**画面へのアクセス方法**：Webhook詳細画面の編集ボタン（鉛筆アイコン）をクリックしてアクセスする。管理者権限を持つユーザーのみがアクセス可能。

**主要な操作・処理内容**：
1. Webhook名の編集（必須）
2. 購読するイベントの変更（複数選択可能）
3. 「Save Changes」ボタンで変更を保存
4. Escキーまたは「Go back」リンクでキャンセル

**画面遷移**：
- 遷移元：Webhook詳細画面
- 遷移先：更新成功時はWebhook詳細画面、キャンセル時はWebhook一覧画面

**権限による表示制御**：管理者（admin）権限を持つユーザーのみがこの画面にアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 83 | Webhook編集 | 主機能 | Webhookの設定を編集 |
| 84 | Webhook削除 | 補助機能 | Webhookを削除 |

## 画面種別

編集

## URL/ルーティング

- 画面表示: `GET /boards/:board_id/webhooks/:id/edit`
- 更新処理: `PUT /boards/:board_id/webhooks/:id`

## 入出力項目

| 項目名 | 項目ID | データ型 | 必須 | 最大長 | 入力形式 | 説明 |
|--------|--------|----------|------|--------|----------|------|
| Webhook名 | name | string | 必須 | - | テキスト | Webhookの識別名 |
| 購読イベント | subscribed_actions | array | - | - | チェックボックス | 通知するイベントの種類（複数選択可） |

**注意**: ペイロードURL（url）は編集不可

## 表示項目

| 項目名 | 説明 |
|--------|------|
| ページタイトル | 既存のWebhook名 |
| 戻るリンク | Webhook詳細画面への戻りリンク |
| 名前入力フィールド | Webhook名を編集するテキストフィールド |
| イベント選択ラベル | 「Events」と「Trigger a call to the Payload URL when:」 |
| イベントチェックボックス | 各イベントタイプの選択チェックボックス |
| Enable all ボタン | 全イベントを選択 |
| Disable all ボタン | 全イベントの選択を解除 |
| 保存ボタン | 「Save Changes」 |

## イベント仕様

### 1-Save Changesボタン押下

1. フォームバリデーション実行
   - name: 必須チェック
2. バリデーション成功時、`PUT /boards/:board_id/webhooks/:id` にリクエスト送信
3. Webhookレコードを更新（URLは除外して更新）
4. Webhook詳細画面にリダイレクト

### 2-Enable allボタン押下

全てのイベントチェックボックスをチェック状態にする。

### 3-Disable allボタン押下

全てのイベントチェックボックスのチェックを外す。

### 4-戻るリンク押下・Escキー押下

Webhook一覧画面に遷移する。

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Save Changes押下 | webhooks | UPDATE | Webhookレコードを更新 |

### テーブル別更新項目詳細

#### webhooks

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | フォーム入力値 | 必須 |
| UPDATE | subscribed_actions | フォーム入力値（配列） | JSON形式で保存 |
| UPDATE | updated_at | 現在日時 | 自動更新 |

**注意**: urlはupdateアクションで意図的に除外されている

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 表示条件 |
|---------------|---------------|----------|
| バリデーションエラー | Name can't be blank | 名前が未入力の場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 未認証アクセス | ログイン画面へリダイレクト |
| 権限不足（非管理者） | 403 Forbidden |
| Webhookが見つからない | 404エラー |
| バリデーションエラー | フォームを再表示、エラーメッセージ表示 |

## 備考

- URLは編集不可（セキュリティ対策）：`webhook_params.except(:url)` でパラメータから除外
- 新規作成画面とは異なり、URLフィールドは表示されない
- subscribed_actionsの正規化はモデル側で処理される

---

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

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

### 推奨読解順序

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

Webhookモデルのバリデーションと更新処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | webhook.rb | `app/models/webhook.rb` | バリデーション、PERMITTED_ACTIONS定数 |

**読解のコツ**:
- `normalizes :subscribed_actions`（38行目）で入力値の正規化処理を確認
- `validates :name, presence: true`（40行目）で名前の必須バリデーションを確認

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

コントローラーのedit/updateアクションを理解する。

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

**主要処理フロー**:
1. **5行目**: set_webhookがedit/update前に実行される
2. **23-24行目**: editアクション - @webhookは既に設定済み
3. **26-29行目**: updateアクション - `webhook_params.except(:url)` でURLを除外して更新

#### Step 3: ビューテンプレートを理解する

編集フォームのUI構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.html.erb | `app/views/webhooks/edit.html.erb` | 編集フォームテンプレート |
| 3-2 | _actions.html.erb | `app/views/webhooks/form/_actions.html.erb` | イベント選択パーシャル（新規作成と共通） |

**主要処理フロー（edit.html.erb）**:
- **1行目**: ページタイトルを既存のWebhook名に設定
- **5行目**: 戻るリンク（Webhook詳細画面へ）
- **10行目**: form_withでフォーム開始（method: :put）
- **12行目**: 名前入力フィールド（required, autofocus）
- **20行目**: イベント選択パーシャルをレンダリング
- **23-25行目**: 保存ボタン

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

```
[ユーザー] 編集ボタンクリック
    │
    ├─ GET /boards/:board_id/webhooks/:id/edit
    │      │
    │      ├─ BoardScoped#set_board
    │      │
    │      ├─ WebhooksController#set_webhook
    │      │
    │      └─ WebhooksController#edit
    │             │
    │             └─ render "webhooks/edit"
    │                    │
    │                    └─ render "webhooks/form/actions"
    │
    └─ PUT /boards/:board_id/webhooks/:id（送信時）
           │
           └─ WebhooksController#update
                  │
                  ├─ webhook_params.except(:url)
                  │      └─ URLを除外
                  │
                  ├─ @webhook.update!
                  │      │
                  │      └─ webhooks テーブルをUPDATE
                  │
                  └─ redirect_to @webhook
```

### データフロー図

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

フォーム送信 ───────────▶ WebhooksController#update ─────▶ Webhook詳細画面
  - name                        │
  - subscribed_actions[]        ├─ webhook_params.except(:url)
                                │      │
                                │      └─ URLを除外
                                │
                                ├─ @webhook.update!
                                │      │
                                │      └─ webhooks テーブルをUPDATE
                                │
                                └─ redirect_to @webhook
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| webhooks_controller.rb | `app/controllers/webhooks_controller.rb` | コントローラー | Webhook CRUD操作を処理 |
| webhook.rb | `app/models/webhook.rb` | モデル | Webhookデータの管理、バリデーション |
| edit.html.erb | `app/views/webhooks/edit.html.erb` | ビュー | 編集フォーム |
| _actions.html.erb | `app/views/webhooks/form/_actions.html.erb` | パーシャル | イベント選択UI |
| webhooks_helper.rb | `app/helpers/webhooks_helper.rb` | ヘルパー | イベント選択オプション生成 |
| board_scoped.rb | `app/controllers/concerns/board_scoped.rb` | Concern | ボードスコープ設定 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
