# 機能設計書 44-Issueラベル付与イベント

## 概要

本ドキュメントは、GitHubリポジトリでIssueにラベルが付与されたときにGiselleワークフローを自動起動するトリガーイベント機能の設計を記述する。

### 本機能の処理概要

GitHubでIssueにラベルが付与されたことをWebhookイベントとして受信し、特定のラベル名が条件に一致する場合にワークフローを自動実行する機能である。

**業務上の目的・背景**：Issue管理において、ラベルはIssueの分類や優先度を示す重要な属性である。特定のラベルが付与されたときにワークフローを起動することで、ラベルに応じた自動処理（自動アサイン、通知送信、関連タスク作成など）を実現する。これにより、Issue管理の一貫性と効率性が向上する。

**機能の利用シーン**：Issueに「bug」「high-priority」「needs-review」などのラベルが付与された際に、対応するワークフローを起動する場面で利用される。例えば、「high-priority」ラベルが付与されたIssueに対して、自動的に担当者への通知を送信し、優先対応を促すワークフローを構築できる。

**主要な処理内容**：
1. GitHubからのWebhook（issues.labeled）を受信
2. リポジトリノードIDに基づいてトリガー設定を検索
3. イベント種別（github.issue.labeled）との一致を確認
4. 付与されたラベル名がトリガー設定のlabels条件に含まれるか確認
5. Issueのタイトル、本文、番号、ラベル名をペイロードとして抽出
6. ワークフロータスクを作成・開始
7. 処理進捗をGitHubコメントとして投稿（オプション）

**関連システム・外部連携**：GitHub API（Webhook受信、リアクション追加、コメント投稿）、Giselle Storage（トリガー設定の永続化）

**権限による制御**：GitHub Appのインストール権限が必要。リポジトリへのread/write権限（issues、comments）が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | ワークフローエディタ画面 | 主画面 | トリガーノードの追加・設定、GitHubイベント種別の選択、対象ラベル設定 |
| 28 | インテグレーション設定画面 | 参照画面 | GitHubリポジトリ連携の管理 |

## 機能種別

イベント駆動処理 / Webhook処理 / データ連携 / 条件分岐処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| issueNumber | number | Yes | Issue番号 | 正の整数 |
| title | string | Yes | Issueのタイトル | 空文字列不可 |
| body | string | No | Issueの本文 | - |
| labelName | string | Yes | 付与されたラベル名 | 空文字列不可 |

### 入力データソース

- GitHub Webhook（issues.labeledイベント）
- ペイロードに含まれるIssueデータ（issue.number、issue.title、issue.body）
- ペイロードに含まれるラベルデータ（label.name）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| issueNumber | generated-text | Issue番号（文字列として出力） |
| title | generated-text | Issueのタイトル |
| body | generated-text | Issueの本文（空の場合は空文字列） |
| labelName | generated-text | 付与されたラベル名 |

### 出力先

- ワークフロー内の次のノードへの入力として接続
- トリガーノードの各出力ポートから接続先ノードへデータを伝播

## 処理フロー

### 処理シーケンス

```
1. Webhook受信
   └─ handleGitHubWebhookV2でHTTPリクエストを受信
2. イベント検証
   └─ Webhookシークレットによる署名検証
3. リポジトリ連携確認
   └─ repository.node_idからトリガー設定を検索
4. トリガー設定取得
   └─ flowTriggerIdからトリガーデータを取得
5. イベント種別照合
   └─ handleIssueLabeledでイベント種別を確認
6. ラベル条件照合
   └─ conditions.labelsに付与されたラベル名が含まれるか確認
7. リアクション追加
   └─ IssueにEYESリアクションを追加
8. タスク作成・開始
   └─ createAndStartTaskでワークフロー実行
9. ペイロード解決
   └─ resolveTriggerでIssue・ラベルデータを出力に変換
10. 進捗通知（オプション）
    └─ 処理進捗をコメントとして投稿
```

### フローチャート

```mermaid
flowchart TD
    A[Webhook受信] --> B{署名検証}
    B -->|失敗| Z[処理終了]
    B -->|成功| C[リポジトリ連携確認]
    C --> D{トリガー設定存在?}
    D -->|No| Z
    D -->|Yes| E[トリガー設定取得]
    E --> F{イベント種別一致?}
    F -->|No| Z
    F -->|Yes| G{Issue/ラベル存在?}
    G -->|No| Z
    G -->|Yes| H{ラベル条件設定あり?}
    H -->|No| Z
    H -->|Yes| I{ラベル名一致?}
    I -->|No| Z
    I -->|Yes| J[EYESリアクション追加]
    J --> K[タスク作成・開始]
    K --> L[ペイロード解決]
    L --> M[ワークフロー実行]
    M --> N[進捗通知]
    N --> O[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-44-01 | イベント種別照合 | Webhookイベントがissues.labeledかつトリガー設定がgithub.issue.labeledの場合のみ処理を実行 | 常時 |
| BR-44-02 | ラベル条件必須 | conditions.labelsが配列として設定されている必要がある | 常時 |
| BR-44-03 | ラベル名照合 | 付与されたラベル名がconditions.labelsに含まれる場合のみ処理を実行 | 常時 |
| BR-44-04 | リアクション追加 | 処理開始時にIssueにEYESリアクションを追加して処理中であることを示す | トリガーが有効な場合 |
| BR-44-05 | 進捗コメント | shouldPostInProgressCommentがtrueの場合、処理進捗をコメントとして投稿 | 設定に基づく |

### 計算ロジック

- ラベル条件照合: `conditions.labels.includes(addedLabel.name)` でラベル名の一致を確認

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| トリガー設定取得 | Storage（JSON） | SELECT | flow-triggers/{triggerId}.jsonからトリガー設定を取得 |
| リポジトリ連携確認 | Storage（JSON） | SELECT | github-integration-indexes/{repositoryNodeId}.jsonから連携情報を取得 |

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

#### flow-triggers/{triggerId}.json

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, workspaceId, nodeId, configuration | triggerId一致 | トリガー設定全体を取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-44-01 | 認証エラー | GitHub認証情報が未設定 | integrationConfigsのgithub.authV2を確認 |
| E-44-02 | トリガー未設定 | リポジトリに対応するトリガーが存在しない | ワークフローエディタでトリガーを設定 |
| E-44-03 | 署名検証失敗 | Webhookシークレットが不一致 | Webhookシークレットの再設定 |
| E-44-04 | ラベル条件未設定 | conditions.labelsが未設定または空配列 | トリガー設定で対象ラベルを指定 |
| E-44-05 | ラベル不一致 | 付与されたラベルがconditions.labelsに含まれない | 対象ラベルを確認して再設定 |

### リトライ仕様

- Webhook処理自体にリトライ機構はなし
- GitHub側のWebhook再送機能に依存（最大3回、指数バックオフ）

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

- 各処理ステップは独立して実行
- タスク作成・生成処理はStorage操作として個別にコミット
- エラー発生時は該当トリガーの処理のみスキップし、他のトリガーは継続処理

## パフォーマンス要件

- Webhook応答: 10秒以内（GitHub推奨）
- ペイロード解決: 1秒以内
- 複数トリガー並列処理: Promise.allによる並列実行

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

- Webhookシークレットによる署名検証必須
- GitHub App認証（Installation Token）による安全なAPI呼び出し
- プライベートキーの安全な管理（環境変数経由）
- ラベル条件によるアクセス制御（特定ラベルのみトリガー）

## 備考

- Issue本文（body）はオプショナルで、空の場合は空文字列として処理
- ラベル名（labelName）は付与された単一のラベル名（複数ラベル付与の場合、各ラベルで個別イベント発火）
- 同一Issueに複数のラベルを同時付与した場合、ラベルごとに別々のWebhookイベントが発火

---

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

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

### 推奨読解順序

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

まず、Issueラベル付与イベントのペイロード定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | github.ts | `packages/trigger-registry/src/github.ts` | githubIssueLabeledEventの定義（62-74行目）、ペイロードスキーマ（issueNumber, title, body, labelName） |
| 1-2 | trigger.ts | `packages/protocol/src/node/operations/trigger.ts` | TriggerContentの型定義、トリガー状態の管理 |

**読解のコツ**: Issue作成/クローズイベントと比較して、labelNameフィールドが追加されている点に注目。

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

Webhook受信からイベント処理への流れを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | handle-webhook-v2.ts | `packages/giselle/src/github/handle-webhook-v2.ts` | handleGitHubWebhookV2関数（39-93行目）、サポートイベント一覧（29行目：issues.labeled） |

**主要処理フロー**:
1. **46-49行目**: GitHub認証情報の取得と検証
2. **50-75行目**: dispatch関数の定義（イベント処理のメインロジック）
3. **88-92行目**: handleWebhookでWebhook署名検証とイベントディスパッチ

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

Issueラベル付与イベントの具体的な処理ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | event-handlers.ts | `packages/giselle/src/github/event-handlers.ts` | handleIssueLabeled関数（354-385行目）、ラベル条件照合ロジック |
| 3-2 | event-handlers.ts | `packages/giselle/src/github/event-handlers.ts` | processEvent関数（478-813行目）、タスク作成とコールバック処理 |

**主要処理フロー**:
- **357-363行目**: Webhookイベントとトリガー設定のイベント種別照合
- **364-369行目**: Issueとラベルの存在確認
- **371-378行目**: conditions.labelsの存在確認
- **380行目**: `conditions.labels.includes(addedLabel.name)` でラベル名照合
- **382-384行目**: 条件一致時にリアクションNodeIdを返す

#### Step 4: ペイロード解決を理解する

Issue・ラベルデータをワークフロー出力に変換する処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | trigger-utils.ts | `packages/giselle/src/github/trigger-utils.ts` | resolveIssueLabeledTrigger関数（131-183行目）、ペイロード各フィールドの処理 |
| 4-2 | resolve-trigger.ts | `packages/giselle/src/triggers/resolve-trigger.ts` | resolveTrigger関数（15-193行目）、トリガー解決のメインロジック |

**主要処理フロー**:
- **132-137行目**: イベント種別の確認（issues.labeledかつgithub.issue.labeled）
- **138-182行目**: ペイロードフィールド（title, body, issueNumber, labelName）の解決
- **167-175行目**: labelNameフィールドの出力生成（label?.name ?? ""）

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

```
handleGitHubWebhookV2 (handle-webhook-v2.ts)
    │
    ├─ handleWebhook (github-tool)
    │      └─ Webhook署名検証
    │
    └─ process (handle-webhook-v2.ts:125-192)
           │
           ├─ getGitHubRepositoryIntegrationIndex
           │      └─ リポジトリ連携情報取得
           │
           └─ processEvent (event-handlers.ts:478-813)
                  │
                  ├─ handleIssueLabeled (event-handlers.ts:354-385)
                  │      │
                  │      ├─ conditions.labels取得
                  │      │
                  │      └─ labels.includes(addedLabel.name)
                  │
                  ├─ addReaction
                  │      └─ EYESリアクション追加
                  │
                  └─ createAndStartTask
                         │
                         └─ resolveTrigger (resolve-trigger.ts)
                                │
                                └─ resolveIssueLabeledTrigger (trigger-utils.ts:131-183)
                                       └─ ペイロード解決
```

### データフロー図

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

GitHub Webhook ───────▶ handleGitHubWebhookV2 ───────▶ Giselle Task
(issues.labeled)             │                           │
      │                      │                           │
      ▼                      ▼                           ▼
┌─────────────┐      ┌─────────────────┐       ┌────────────────────┐
│ issue.number│      │ processEvent    │       │ outputId: issueNumber │
│ issue.title │      │ handleIssueLabeled │    │ outputId: title    │
│ issue.body  │  ──▶ │ labels.includes │  ──▶ │ outputId: body     │
│ label.name  │      │ resolveTrigger  │       │ outputId: labelName│
└─────────────┘      └─────────────────┘       └────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| github.ts | `packages/trigger-registry/src/github.ts` | ソース | GitHubイベント定義（ペイロードスキーマ） |
| handle-webhook-v2.ts | `packages/giselle/src/github/handle-webhook-v2.ts` | ソース | Webhook受信エントリーポイント |
| event-handlers.ts | `packages/giselle/src/github/event-handlers.ts` | ソース | イベントハンドラー群 |
| trigger-utils.ts | `packages/giselle/src/github/trigger-utils.ts` | ソース | トリガーペイロード解決 |
| resolve-trigger.ts | `packages/giselle/src/triggers/resolve-trigger.ts` | ソース | トリガー解決メインロジック |
| utils.ts | `packages/giselle/src/triggers/utils.ts` | ソース | トリガー設定の読み書き |
| trigger.ts | `packages/protocol/src/node/operations/trigger.ts` | ソース | トリガーノード型定義 |
| index.ts | `packages/trigger-registry/src/index.ts` | ソース | トリガーレジストリエクスポート |
