# 機能設計書 31-生成取得

## 概要

本ドキュメントは、Giselleワークフローエンジンにおける「生成取得」機能の設計を記述する。本機能は、タスク実行中に生成されたAIモデルの出力結果（Generation）を、一意の生成IDを指定して取得するAPIを提供する。

### 本機能の処理概要

本機能は、ワークフロー実行時に作成された生成結果（テキスト生成、画像生成など）をストレージから取得し、呼び出し元に返却する。

**業務上の目的・背景**：ワークフローの実行結果を確認・表示するためには、各ノードで実行された生成処理の結果を取得する必要がある。タスク詳細画面やプレイグラウンドでの結果表示、デバッグ、監査ログの確認などに活用される。

**機能の利用シーン**：
- タスク詳細画面で各ノードの生成結果を表示する場合
- プレイグラウンドでリアルタイムに生成結果を確認する場合
- 外部システムからAPI経由で生成結果を取得する場合

**主要な処理内容**：
1. 生成ID（GenerationId）を受け取る
2. ストレージから該当する生成データを取得
3. 生成コンテキストをパースして正規化
4. 生成結果（Generation）を返却

**関連システム・外部連携**：GiselleStorageを介したファイルストレージとの連携

**権限による制御**：ワークスペースへのアクセス権限を持つユーザーのみが生成結果を取得可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | タスク詳細画面 | 主画面 | タスク内の各生成結果の取得 |

## 機能種別

データ取得（SELECT操作）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| context | GiselleContext | Yes | Giselle実行コンテキスト（ストレージ参照を含む） | - |
| generationId | GenerationId | Yes | 取得対象の生成ID | `gen-`プレフィックス付きID形式 |

### 入力データソース

- ストレージ（GiselleStorage）から生成データを取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | GenerationId | 生成ID |
| context | GenerationContext | 生成コンテキスト（オペレーションノード、入力データなど） |
| status | GenerationStatus | 生成ステータス（created/queued/running/completed/failed/cancelled） |
| createdAt | number | 作成日時（Unixタイムスタンプ） |
| queuedAt | number | キュー投入日時（オプション） |
| startedAt | number | 開始日時（オプション） |
| completedAt | number | 完了日時（オプション） |
| messages | Message[] | 生成メッセージ履歴 |
| outputs | GenerationOutput[] | 生成出力（completedの場合） |
| error | GenerationError | エラー情報（failedの場合） |

### 出力先

呼び出し元への戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. 生成IDからストレージパスを計算
   └─ `generations/{generationId}/generation.json`

2. ストレージから生成データを取得
   └─ GiselleStorage.getJson()でJSONデータを読み込み

3. 生成コンテキストをパース
   └─ GenerationContext.parse()で正規化

4. 生成結果を返却
   └─ Generation型オブジェクトとして返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[生成IDを受け取る]
    B --> C[ストレージパスを計算]
    C --> D[ストレージからJSON取得]
    D --> E[Generationスキーマでパース]
    E --> F[GenerationContextをパース]
    F --> G[Generation返却]
    G --> H[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-31-001 | 生成ID形式 | 生成IDは`gen-`プレフィックス付きのUUID形式 | 常時 |
| BR-31-002 | ステータス依存データ | statusによって含まれるフィールドが異なる（completedにはoutputs、failedにはerror） | 常時 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 生成取得 | ストレージ（ファイル） | SELECT | generations/{id}/generation.jsonの読み込み |

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

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

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 全フィールド | generationIdでパス指定 | Zodスキーマでバリデーション |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル不在 | 指定IDの生成データが存在しない | 404エラーとして処理 |
| - | スキーマエラー | JSONデータがスキーマに適合しない | バリデーションエラーとして処理 |

### リトライ仕様

該当なし（読み取り操作のため）

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

該当なし（読み取り専用操作）

## パフォーマンス要件

- レスポンス時間：100ms以内（ストレージアクセス込み）
- 同時アクセス：ストレージドライバの制限に依存

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

- GiselleContextを通じてアクセス制御
- ワークスペース境界を超えたアクセスは不可

## 備考

- Generation型はdiscriminated union（status別に異なる型）として定義
- ストレージパスは`generations/{generationId}/generation.json`の形式

---

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

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

### 推奨読解順序

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

まず、生成（Generation）の型定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/protocol/src/generation/index.ts` | Generation型とそのステータス別バリアント（Created/Queued/Running/Completed/Failed/Cancelled）を理解 |
| 1-2 | generation-id.ts | `packages/protocol/src/generation/generation-id.ts` | GenerationIdの生成規則を理解 |
| 1-3 | context.ts | `packages/protocol/src/generation/context.ts` | GenerationContextの構造を理解 |

**読解のコツ**: Zodのdiscriminated unionパターンに注目。statusフィールドの値によって異なる型が適用される。

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

処理の起点となる関数を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | get-generation.ts | `packages/giselle/src/generations/get-generation.ts` | 公開API関数。contextとgenerationIdを受け取り内部関数を呼び出す |

**主要処理フロー**:
1. **5-8行目**: 引数の型定義（context, generationId）
2. **9-12行目**: 内部ユーティリティ関数getGenerationInternalの呼び出し

#### Step 3: ユーティリティ層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | utils.ts | `packages/giselle/src/generations/utils.ts` | getGeneration関数の実装（392-409行目） |

**主要処理フロー**:
- **392行目**: generationPath関数でストレージパスを生成
- **400-401行目**: storage.getJson()でJSONを取得しGenerationスキーマでパース
- **404行目**: GenerationContext.parse()でコンテキストを正規化
- **405-408行目**: 正規化されたコンテキストを含むGenerationを返却

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

```
getGeneration (get-generation.ts)
    │
    └─ getGenerationInternal (utils.ts)
           │
           ├─ generationPath() - ストレージパス生成
           │
           └─ storage.getJson()
                  │
                  └─ Generation.parse() - Zodスキーマ検証
                         │
                         └─ GenerationContext.parse()
```

### データフロー図

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

generationId ───▶ generationPath() ───▶ ストレージパス
                         │
                         ▼
              storage.getJson() ───▶ 生JSONデータ
                         │
                         ▼
              Generation.parse() ───▶ パース済みGeneration
                         │
                         ▼
          GenerationContext.parse() ───▶ Generation返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| get-generation.ts | `packages/giselle/src/generations/get-generation.ts` | ソース | 公開API関数 |
| utils.ts | `packages/giselle/src/generations/utils.ts` | ソース | 内部ユーティリティ（getGeneration実装） |
| index.ts | `packages/protocol/src/generation/index.ts` | ソース | Generation型定義 |
| generation-id.ts | `packages/protocol/src/generation/generation-id.ts` | ソース | GenerationId生成 |
| context.ts | `packages/protocol/src/generation/context.ts` | ソース | GenerationContext型 |
| output.ts | `packages/protocol/src/generation/output.ts` | ソース | GenerationOutput型 |
