# 機能設計書 38-Webhookハンドリング

## 概要

本ドキュメントは、Giselleワークフローエンジンにおける「Webhookハンドリング」機能の設計を記述する。本機能は、GitHubからのWebhookイベントを受信・処理し、関連するワークフローを自動起動するAPIを提供する。

### 本機能の処理概要

本機能は、GitHubからのWebhookリクエストを受信し、署名検証後にイベント種別に応じた処理を行う。リポジトリに関連付けられたトリガーを検索し、マッチするトリガーに対してワークフロータスクを作成・開始する。

**業務上の目的・背景**：GitHubのIssue、Pull Request、Discussionなどのイベントをトリガーとしてワークフローを自動実行することで、開発プロセスの自動化を実現する。レビュー自動化、Issue対応自動化など多様なユースケースに対応。

**機能の利用シーン**：
- GitHubでIssueが作成されたとき
- GitHubでPull Requestがオープンされたとき
- GitHubでコメントが追加されたとき（コールサイン付き）
- GitHubでDiscussionが作成されたとき

**主要な処理内容**：
1. Webhookリクエストの署名検証
2. イベント種別の判定
3. リポジトリ連携インデックスからトリガーを検索
4. トリガー設定とイベントのマッチング
5. マッチした場合はリアクション追加
6. タスクの作成・開始
7. 進捗コメントの投稿・更新（オプション）

**関連システム・外部連携**：
- GitHub Webhook（受信）
- GitHub API（リアクション追加、コメント投稿）
- GiselleStorageを介したファイルストレージ

**権限による制御**：GitHub Appの認証情報が設定されている場合のみ処理可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 28 | インテグレーション設定画面 | 設定画面 | GitHub連携設定の管理 |
| 38 | GitHub連携完了画面 | コールバック | GitHub App連携完了時のコールバック処理 |

## 機能種別

イベント処理 / 外部連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| context | GiselleContext | Yes | Giselle実行コンテキスト | GitHub認証設定が必要 |
| request | Request | Yes | GitHubからのWebhookリクエスト | 署名検証 |
| onGenerationComplete | OnGenerationComplete | No | 生成完了時コールバック | - |
| onGenerationError | OnGenerationError | No | 生成エラー時コールバック | - |
| onTaskCreate | OnTaskCreate | No | タスク作成時コールバック | - |

### 入力データソース

- GitHub Webhookリクエスト（HTTPリクエスト）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | void | 処理完了（タスク実行は非同期） |

### 出力先

- ストレージ: タスク・生成データ
- GitHub: リアクション、コメント

## 処理フロー

### 処理シーケンス

```
1. GitHub認証設定の確認
   └─ authV2設定がない場合: エラー

2. Webhookハンドラの設定
   └─ 対象イベント: issues.*, pull_request.*, discussion.*, etc.

3. handleWebhookでイベントディスパッチ
   └─ 署名検証 → イベント種別判定 → ハンドラ呼び出し

4. リポジトリ連携インデックスの検索
   └─ repository.node_idでインデックス取得

5. 各トリガーに対する処理
   ├─ トリガー設定の取得
   ├─ イベントハンドラの実行
   ├─ マッチ判定（コールサイン、ラベル等）
   └─ マッチした場合: タスク作成・開始

6. タスク実行時の進捗通知
   ├─ リアクション追加（EYES）
   ├─ 進捗コメント投稿（オプション）
   └─ シーケンス完了時のコメント更新
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[GitHub認証確認]
    B --> C{認証設定あり?}
    C -->|No| D[エラー: GitHub credentials not found]
    C -->|Yes| E[handleWebhook呼び出し]
    E --> F[署名検証]
    F --> G{検証成功?}
    G -->|No| H[リクエスト拒否]
    G -->|Yes| I[イベント種別判定]
    I --> J[リポジトリ連携インデックス取得]
    J --> K{インデックス存在?}
    K -->|No| L[処理終了]
    K -->|Yes| M[各トリガーを処理]
    M --> N[イベントハンドラ実行]
    N --> O{マッチ?}
    O -->|No| P[次のトリガーへ]
    O -->|Yes| Q[リアクション追加]
    Q --> R[タスク作成・開始]
    R --> S[進捗コメント投稿]
    S --> T[タスク実行]
    P --> M
    T --> U[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-38-001 | 署名検証 | Webhookシークレットによる署名検証必須 | 常時 |
| BR-38-002 | トリガー有効性 | enable=falseのトリガーはスキップ | 常時 |
| BR-38-003 | コールサイン検証 | コメントイベントではコールサインのマッチが必要 | コメント系イベント |
| BR-38-004 | ラベル検証 | ラベル付与イベントでは対象ラベルのマッチが必要 | labeled系イベント |
| BR-38-005 | リアクション追加 | マッチしたイベントにはEYESリアクションを追加 | マッチ時 |

### 計算ロジック

- コールサインパース: `/callsign content`形式からコールサインとコンテンツを抽出

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| インデックス取得 | ストレージ | SELECT | リポジトリ連携インデックス |
| トリガー取得 | ストレージ | SELECT | トリガー設定 |
| タスク作成 | ストレージ | INSERT | 新規タスク |
| 生成作成 | ストレージ | INSERT | 新規生成 |

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

該当なし（主にストレージ操作）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | GitHub credentials not found | GitHub認証設定がない | エラーをスロー |
| - | GitHub authV2 configuration is missing | authV2設定がない | エラーをスロー |
| - | 署名検証失敗 | Webhookシークレット不一致 | リクエスト拒否 |

### リトライ仕様

- GitHub API呼び出しエラーはログ出力のみ（タスク実行は継続）

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

- 各トリガーの処理は独立して実行
- エラー発生時も他のトリガーの処理は継続

## パフォーマンス要件

- 初期応答：3秒以内（Webhook応答）
- タスク完了：タスク内容に依存

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

- Webhookシークレットによる署名検証
- GitHub App認証（privateKey、appId）の安全な管理
- installationIdによるリポジトリアクセス制御

## 備考

- 対応イベント一覧:
  - issues.opened, issues.closed, issues.labeled
  - issue_comment.created
  - pull_request.opened, pull_request.ready_for_review, pull_request.closed, pull_request.labeled
  - pull_request_review_comment.created
  - discussion.created, discussion_comment.created

---

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

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

### 推奨読解順序

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

まず、Webhookイベントとトリガー設定の構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/protocol/src/trigger/index.ts` | Trigger型の構造 |
| 1-2 | github.ts | `packages/protocol/src/trigger/github.ts` | GitHubEventConfiguration型 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | handle-webhook-v2.ts | `packages/giselle/src/github/handle-webhook-v2.ts` | メイン処理（全192行） |

**主要処理フロー**:
1. **25-37行目**: 対応イベント一覧の定義
2. **39-93行目**: handleGitHubWebhookV2関数（エントリーポイント）
3. **46-49行目**: GitHub認証確認
4. **50-75行目**: ディスパッチ関数定義
5. **77-92行目**: ハンドラ設定
6. **125-192行目**: process関数（イベント処理本体）

#### Step 3: イベントハンドラを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | event-handlers.ts | `packages/giselle/src/github/event-handlers.ts` | 各イベントハンドラ（全815行） |

**主要処理フロー**:
- **165-181行目**: handleIssueOpened
- **229-258行目**: handlePullRequestCommentCreated
- **296-312行目**: handlePullRequestOpened
- **463-476行目**: eventHandlers配列
- **478-814行目**: processEvent関数（タスク作成・コメント投稿）

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

```
handleGitHubWebhookV2 (handle-webhook-v2.ts)
    │
    ├─ handleWebhook (@giselles-ai/github-tool)
    │      │
    │      └─ 署名検証 → イベントディスパッチ
    │
    └─ process() (handle-webhook-v2.ts)
           │
           ├─ getGitHubRepositoryIntegrationIndex()
           │
           └─ [各トリガーに対して]
                  │
                  ├─ getTrigger()
                  │
                  └─ processEvent() (event-handlers.ts)
                         │
                         ├─ eventHandlers[]の各ハンドラを試行
                         │      ├─ handleIssueOpened
                         │      ├─ handleIssueClosed
                         │      ├─ handleIssueCommentCreated
                         │      ├─ handlePullRequestOpened
                         │      └─ ...
                         │
                         ├─ addReaction()
                         │
                         ├─ createAndStartTask()
                         │
                         └─ コメント投稿・更新
```

### データフロー図

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

Webhookリクエスト ───▶ handleWebhook() ───▶ 署名検証
        │
        ▼
イベントペイロード ───▶ process() ───▶ リポジトリID抽出
        │
        ▼
リポジトリID ───────▶ getGitHubRepositoryIntegrationIndex()
        │                                    │
        │                                    ▼
        │                           トリガーID一覧
        │
        ▼
各トリガー ─────────▶ processEvent() ───▶ イベントハンドラ
        │
        ├─ マッチ判定
        │
        ├─ addReaction() ───▶ リアクション追加
        │
        ├─ createAndStartTask() ───▶ タスク実行
        │
        └─ createComment() ───▶ 進捗コメント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| handle-webhook-v2.ts | `packages/giselle/src/github/handle-webhook-v2.ts` | ソース | メイン処理 |
| event-handlers.ts | `packages/giselle/src/github/event-handlers.ts` | ソース | イベントハンドラ |
| utils.ts | `packages/giselle/src/github/utils.ts` | ソース | parseCommand等ユーティリティ |
| utils.ts | `packages/giselle/src/integrations/utils.ts` | ソース | getGitHubRepositoryIntegrationIndex |
| utils.ts | `packages/giselle/src/triggers/utils.ts` | ソース | getTrigger |
| create-and-start-task.ts | `packages/giselle/src/tasks/create-and-start-task.ts` | ソース | createAndStartTask |
| index.ts | `packages/protocol/src/trigger/index.ts` | ソース | Trigger型 |
