# 機能設計書 36-トリガー解決

## 概要

本ドキュメントは、Giselleワークフローエンジンにおける「トリガー解決」機能の設計を記述する。本機能は、トリガーノードの実行時に、トリガー設定とイベント入力からノードの出力値を解決するAPIを提供する。

### 本機能の処理概要

本機能は、キューに投入されたトリガーノードの生成（QueuedGeneration）を受け取り、トリガー設定とイベント入力（GitHubイベントまたはパラメータ入力）から、トリガーノードの各出力ポートに対応する値を解決し、完了状態（CompletedGeneration）としてストレージに保存する。

**業務上の目的・背景**：ワークフロー実行時、トリガーノードは起動イベントの情報を後続ノードに渡す役割を持つ。GitHubのIssueタイトル・本文やPRのdiff情報、手動入力パラメータなど、イベント固有の情報を抽出して出力に設定する必要がある。

**機能の利用シーン**：
- GitHubイベント（Issue作成、PRオープン等）によるワークフロー起動時
- Studioからの手動実行時（パラメータ入力）
- API経由でのワークフロー実行時

**主要な処理内容**：
1. QueuedGenerationを受け取る
2. トリガーノードの状態が「configured」であることを検証
3. トリガー設定データを取得
4. プロバイダー種別（github/manual）に応じて出力値を解決
5. 各出力ポートに対応するGenerationOutputを生成
6. CompletedGenerationとしてストレージに保存

**関連システム・外部連携**：
- GitHub API（PRのdiff取得、コメント取得など）
- GiselleStorageを介したファイルストレージ

**権限による制御**：タスク実行権限を持つコンテキストからのみ呼び出し可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 18 | プレイグラウンド画面 | バックエンド処理 | タスク実行時のトリガー解決 |

## 機能種別

データ処理 / イベント解決

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| context | GiselleContext | Yes | Giselle実行コンテキスト | - |
| generation | QueuedGeneration | Yes | キューに投入されたトリガー生成 | トリガーノードの生成であること |

### 入力データソース

- QueuedGeneration内のcontextからトリガーノード情報
- トリガー設定（Trigger）
- イベント入力（github-webhook-eventまたはparameters）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | void | ストレージへの保存で完了 |

### 出力先

- ストレージ: `generations/{generationId}/generation.json`（CompletedGeneration）

## 処理フロー

### 処理シーケンス

```
1. 生成コンテキストからオペレーションノードを取得
   └─ トリガーノードでない場合: エラー

2. トリガーノードの状態確認
   └─ configured状態でない場合: エラー

3. トリガー設定データを取得
   └─ getTrigger()でTriggerを取得

4. GenerationContextをパース

5. プロバイダー別の出力解決
   ├─ github: イベント種別に応じてGitHubペイロードから値抽出
   └─ manual: パラメータ入力から値を取得

6. origin別の処理分岐（GitHubの場合）
   ├─ stage/github-app: Webhookイベントから解決
   ├─ studio: パラメータ入力から解決
   └─ api: パラメータ入力から解決

7. CompletedGenerationを生成

8. ストレージに保存
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[QueuedGeneration受け取り]
    B --> C{トリガーノード?}
    C -->|No| D[エラー: Invalid generation type]
    C -->|Yes| E{configured状態?}
    E -->|No| F[エラー: Trigger not configured]
    E -->|Yes| G[getTrigger呼び出し]
    G --> H{Trigger存在?}
    H -->|No| I[エラー: Trigger data not found]
    H -->|Yes| J{provider判定}
    J -->|github| K[GitHub出力解決]
    J -->|manual| L[Manual出力解決]
    K --> M[CompletedGeneration生成]
    L --> M
    M --> N[internalSetGeneration保存]
    N --> O[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-36-001 | ノード種別検証 | トリガーノード以外はエラー | 常時 |
| BR-36-002 | 状態検証 | configured状態でないトリガーはエラー | 常時 |
| BR-36-003 | GitHubイベント解決 | イベント種別に応じたペイロードからの値抽出 | provider === "github" |
| BR-36-004 | Manualパラメータ解決 | パラメータ入力からの値抽出 | provider === "manual" |
| BR-36-005 | 出力マッピング | outputのaccessorに応じて値をマッピング | 常時 |

### 計算ロジック

- 出力値のマッピング: output.accessorと入力のitem.nameを照合

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| トリガー取得 | ストレージ | SELECT | トリガー設定の読み込み |
| 生成保存 | ストレージ | INSERT/UPDATE | CompletedGenerationの保存 |

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

#### ストレージ（generations/{id}/generation.json）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | 全フィールド | CompletedGeneration型 | status: "completed" |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Invalid generation type | トリガーノードでない | エラーをスロー |
| - | Trigger not configured | トリガーが未設定 | エラーをスロー |
| - | Trigger data not found | トリガー設定が存在しない | エラーをスロー |
| - | Missing input | 必要な入力が不足 | エラーをスロー |
| - | Missing GitHub config | GitHub設定が不足 | エラーをスロー |

### リトライ仕様

該当なし（タスク実行レベルでリトライ管理）

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

- 単一の生成保存操作

## パフォーマンス要件

- レスポンス時間：200ms以内（GitHub API呼び出しなしの場合）
- GitHub API呼び出し時：追加で500ms程度

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

- GitHub App認証情報の適切な管理
- installationIdによるリポジトリアクセス制御

## 備考

- サポートされるGitHubイベント:
  - Issue: created, closed, labeled, comment.created
  - PR: opened, ready_for_review, closed, labeled, comment.created, review_comment.created
  - Discussion: created, comment.created

---

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

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

### 推奨読解順序

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

まず、Generation型とTrigger型の構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/protocol/src/generation/index.ts` | QueuedGeneration、CompletedGeneration型を理解 |
| 1-2 | context.ts | `packages/protocol/src/generation/context.ts` | GenerationContext、GenerationOrigin型を理解 |
| 1-3 | index.ts | `packages/protocol/src/trigger/index.ts` | Trigger型、configurationの構造を理解 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | resolve-trigger.ts | `packages/giselle/src/triggers/resolve-trigger.ts` | メイン処理ロジック（全193行） |

**主要処理フロー**:
1. **19-22行目**: トリガーノード検証
2. **23-25行目**: configured状態検証
3. **26-32行目**: トリガーデータ取得
4. **34行目**: GenerationContextパース
5. **37-177行目**: プロバイダー別出力解決
6. **179-192行目**: CompletedGeneration生成・保存

#### Step 3: GitHubトリガー解決を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | trigger-utils.ts | `packages/giselle/src/github/trigger-utils.ts` | resolveGitHubTrigger関数（全936行） |

**主要処理フロー**:
- **21-36行目**: resolveTrigger関数（各イベント種別の解決を試行）
- **38-81行目**: resolveIssueCreatedTrigger（Issue作成イベント）
- **306-383行目**: resolvePullRequestOpenedTrigger（PRオープンイベント）
- **633-749行目**: resolvePullRequestReviewCommentTrigger（PRレビューコメント）

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

```
resolveTrigger (resolve-trigger.ts)
    │
    ├─ isTriggerNode() - ノード種別検証
    │
    ├─ getTrigger() - トリガー設定取得
    │
    ├─ GenerationContext.parse() - コンテキストパース
    │
    ├─ [provider === "github"]
    │      │
    │      └─ resolveGitHubTrigger (trigger-utils.ts)
    │             │
    │             ├─ resolveIssueCreatedTrigger
    │             ├─ resolveIssueClosedTrigger
    │             ├─ resolveIssueLabeledTrigger
    │             ├─ resolveIssueCommentTrigger
    │             ├─ resolvePullRequestOpenedTrigger
    │             ├─ resolvePullRequestReadyForReviewTrigger
    │             ├─ resolvePullRequestClosedTrigger
    │             ├─ resolvePullRequestLabeledTrigger
    │             ├─ resolvePullRequestCommentTrigger
    │             ├─ resolvePullRequestReviewCommentTrigger
    │             ├─ resolveDiscussionCreatedTrigger
    │             └─ resolveDiscussionCommentCreatedTrigger
    │
    ├─ [provider === "manual"]
    │      └─ パラメータからの値抽出
    │
    └─ internalSetGeneration() - 保存
```

### データフロー図

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

QueuedGeneration ───▶ トリガーノード検証 ───▶ 検証済みノード
        │
        ▼
    getTrigger() ───▶ Trigger取得
        │
        ▼
GenerationContext.parse() ───▶ パース済みコンテキスト
        │
        ▼
[provider分岐] ─────────────▶ 出力値解決
        │
        ├─ github: WebhookEvent ───▶ GenerationOutput[]
        │
        └─ manual: parameters ───▶ GenerationOutput[]
        │
        ▼
CompletedGeneration ───▶ internalSetGeneration() ───▶ ストレージ保存
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| resolve-trigger.ts | `packages/giselle/src/triggers/resolve-trigger.ts` | ソース | メイン処理ロジック |
| trigger-utils.ts | `packages/giselle/src/github/trigger-utils.ts` | ソース | GitHubトリガー解決 |
| utils.ts | `packages/giselle/src/triggers/utils.ts` | ソース | getTrigger |
| set-generation.ts | `packages/giselle/src/generations/internal/set-generation.ts` | ソース | internalSetGeneration |
| index.ts | `packages/protocol/src/generation/index.ts` | ソース | Generation型定義 |
| context.ts | `packages/protocol/src/generation/context.ts` | ソース | GenerationContext型 |
| index.ts | `packages/protocol/src/trigger/index.ts` | ソース | Trigger型定義 |
| github.ts | `packages/trigger-registry/src/github.ts` | ソース | GitHubイベント定義 |
