# 機能設計書 20-タスク作成

## 概要

本ドキュメントは、Giselleワークフローエンジンにおけるタスク作成機能（createTask）の設計を記述する。タスク作成機能は、ワークフローの実行インスタンス（タスク）を作成し、実行準備を整えるための機能である。

### 本機能の処理概要

タスク作成機能は、ワークフロー定義に基づいて実行可能なタスクインスタンスを生成する機能である。ワークスペース内のノードと接続を解析し、実行順序（レベル）を決定し、各ステップに対応する生成（Generation）オブジェクトを作成する。

**業務上の目的・背景**：Giselleワークフローエンジンにおいて、ワークフローの定義と実行を分離することは重要である。タスク作成機能は、ワークフロー定義を解析して実行可能な形式に変換し、タスクの状態追跡と実行制御を可能にする。

**機能の利用シーン**：
- ユーザーがワークフローエディタで「実行」ボタンをクリックした場合
- APIを通じてアプリを実行する場合
- GitHubトリガーによりワークフローが起動される場合
- プレイグラウンドでアプリをテスト実行する場合

**主要な処理内容**：
1. ワークスペースの取得（workspaceIdから）
2. 実行対象のノードと接続の特定
3. ノードのレベル（実行順序）の算出
4. 各操作ノードに対するGeneration（生成）オブジェクトの作成
5. シーケンスとステップの構築
6. Task、Generation情報のストレージ保存
7. ワークスペースタスクインデックスへの追加

**関連システム・外部連携**：
- ワークスペース管理機能（No.1-5）
- 生成機能（No.28-32）
- タスク開始機能（No.21）
- ストレージ機能

**権限による制御**：ワークスペースへのアクセス権限に依存

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | ワークフローエディタ画面 | 主画面 | ワークフロー実行時のタスク作成 |
| 18 | プレイグラウンド画面 | 主画面 | アプリ実行テスト時のタスク作成 |

## 機能種別

タスク管理 / ワークフロー実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| workspaceId | WorkspaceId | 条件付き | ワークスペースID | workspace未指定時は必須 |
| workspace | Workspace | 条件付き | ワークスペースオブジェクト | workspaceId未指定時は必須 |
| connectionIds | ConnectionId[] | 条件付き | 実行対象の接続ID配列 | nodeId未指定時は必須 |
| nodeId | NodeId | 条件付き | 実行対象のノードID | connectionIds未指定時は必須 |
| inputs | GenerationContextInput[] | Yes | 入力パラメータ配列 | 配列形式 |
| generationOriginType | string | Yes | 生成起点タイプ | studio/github-app/api/stage |

### 入力データソース

- **ワークフローエディタ**: 実行ボタンクリック時
- **API呼び出し**: HTTP経由でのタスク作成リクエスト
- **GitHubトリガー**: Webhookイベント受信時

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| task | Task | 作成されたタスクオブジェクト |
| generations | CreatedGeneration[] | 作成された生成オブジェクト配列 |

### Task構造

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | TaskId | タスクID（tsk-で始まる） |
| starter | TaskStarter | 起動元情報（run-button/github-trigger/app） |
| workspaceId | WorkspaceId | ワークスペースID |
| name | string | タスク名 |
| status | string | ステータス（created/inProgress/completed/failed/cancelled） |
| steps | object | ステップ状態カウント |
| sequences | Sequence[] | 実行シーケンス配列 |
| nodeIdsConnectedToEnd | NodeId[] | 終了ノードに接続されたノードID |
| createdAt | number | 作成日時 |
| updatedAt | number | 更新日時 |

### 出力先

- ストレージ（タスクパス、ワークスペースタスクインデックス）
- 呼び出し元への戻り値

## 処理フロー

### 処理シーケンス

```
1. ワークスペース取得
   └─ workspaceId指定時: getWorkspaceで取得
   └─ workspace指定時: そのまま使用

2. 実行対象の特定
   └─ connectionIds指定時: 直接使用
   └─ nodeId指定時: findNodeGroupByNodeIdで接続を取得

3. ノードと接続のフィルタリング
   └─ 対象connectionIdsに関連するノードと接続を抽出
   └─ 単一ノード実行の場合は特別処理

4. 終了ノードの検出
   └─ EndNodeの検出（複数存在時エラー）
   └─ nodeIdsConnectedToEndの算出

5. レベル算出（buildLevels）
   └─ ノード間の依存関係からレベル（実行順序）を決定

6. Generation生成
   └─ 各操作ノードに対してCreatedGenerationを生成
   └─ ソースノードの特定と設定

7. Sequence/Step構築
   └─ レベルごとにSequenceを作成
   └─ 各Generationに対応するStepを作成

8. TaskStarter設定
   └─ generationOriginTypeに応じたstarter情報設定

9. Task生成
   └─ Task、Sequenceを組み立て

10. 保存処理
    └─ storage.setJsonでTask保存
    └─ addWorkspaceIndexItemでインデックス追加
    └─ 各GenerationのsetGeneration
    └─ onCreateコールバック実行
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{workspaceId指定?}
    B -->|Yes| C[getWorkspace]
    B -->|No| D[workspace使用]
    C --> E{connectionIds指定?}
    D --> E
    E -->|Yes| F[connectionIds使用]
    E -->|No| G[findNodeGroupByNodeId]
    F --> H[関連ノード/接続抽出]
    G --> H
    H --> I{EndNode検出}
    I -->|複数| J[エラー]
    I -->|0-1| K[nodeIdsConnectedToEnd算出]
    K --> L[buildLevels]
    L --> M[Generation生成]
    M --> N[Sequence/Step構築]
    N --> O{generationOriginType}
    O -->|studio| P[run-button starter]
    O -->|github-app| Q[github-trigger starter]
    O -->|api/stage| R[app starter]
    P --> S[Task生成]
    Q --> S
    R --> S
    S --> T[ストレージ保存]
    T --> U[インデックス追加]
    U --> V[Generation保存]
    V --> W[onCreateコールバック]
    W --> X[終了]
    J --> X
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ワークスペース必須 | workspace or workspaceIdのいずれかが必須 | タスク作成時 |
| BR-002 | 単一EndNode | 1つのワークフローに複数のEndNodeは許容しない | タスク作成時 |
| BR-003 | 未設定チェック | AppEntryNodeがunconfiguredの場合エラー | api/stage起点時 |
| BR-004 | 操作ノードのみ処理 | VariableNode、AppEntryNode、EndNodeは処理ステップから除外 | Generation生成時 |
| BR-005 | レベル順実行 | ノードはレベル（依存関係）順に実行される | Sequence構築時 |

### 計算ロジック

#### buildLevels算出
- ノード間の接続（入力→出力）を解析
- 依存関係のないノードをレベル0
- 依存ノードが全て処理済みのノードを次レベル
- 全ノードがレベル割り当てされるまで繰り返し

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Task保存 | - | INSERT | ストレージにTask情報を保存 |
| Generation保存 | - | INSERT | ストレージにGeneration情報を保存 |
| インデックス追加 | - | INSERT | ワークスペースタスクインデックスに追加 |

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

ストレージベースの保存（ファイルシステムまたはメモリ）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | workspaceもworkspaceIdも未指定 | "workspace or workspaceId is required" |
| - | Error | nodeIdが存在しないノードグループ | "Node {nodeId} is not part of any node group" |
| - | Error | connectionIdsもnodeIdも未指定 | "Either connectionIds or nodeId must be provided" |
| - | Error | 複数のEndNode | "Workspace {id} has multiple end nodes: {id1}, {id2}" |
| - | Error | AppEntryNodeが未設定 | "Start node is unconfigured" |
| - | Error | starterNode不正 | "starterNode must be an start node" / "starterNode must be a trigger node" |

### リトライ仕様

本機能はリトライ機構を持たない。エラー時は即座に失敗として処理される。

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

- Task、Generation、インデックスの保存はPromise.allで並列実行
- 部分的な失敗時のロールバック機構は現状なし

## パフォーマンス要件

特になし

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

- ワークスペースへのアクセス権限チェックは呼び出し元で実施
- 入力パラメータはGenerationContextInputとしてタスクに紐付けて保存される

## 備考

- TaskId: "tsk-"で始まるID
- SequenceId: "sqn-"で始まるID
- StepId: "stp-"で始まるID
- GenerationId: "gen-"で始まるID

---

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

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

### 推奨読解順序

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

まず、タスクと関連するデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | task.ts | `packages/protocol/src/task/task.ts` | Task、Sequence、Step、TaskStarterのスキーマ定義 |
| 1-2 | task-id.ts | `packages/protocol/src/task/task-id.ts` | TaskId生成関数 |
| 1-3 | generation | `packages/protocol/src/generation/` | Generation関連のスキーマ定義 |

**読解のコツ**: Taskは階層構造（Task → Sequence[] → Step[]）を持つ。各StepはGenerationIdで実際の生成処理と紐付く。

#### Step 2: タスク作成ロジックを理解する

タスク作成の主要ロジックを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | create-task.ts | `packages/giselle/src/tasks/create-task.ts` | createTask関数の全体フロー |

**主要処理フロー**:
- **35-45行目**: CreateTaskInputsスキーマ定義
- **49-348行目**: createTask関数本体
- **54-62行目**: ワークスペース取得処理
- **64-80行目**: connectionIds特定処理
- **93-114行目**: EndNode検出とnodeIdsConnectedToEnd算出
- **136-228行目**: Generation/Sequence/Step生成
- **230-294行目**: TaskStarter設定
- **296-348行目**: Task生成と保存

#### Step 3: レベル算出ロジックを理解する

ノードの実行順序決定ロジックを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | build-levels.ts | `packages/giselle/src/utils/build-levels.ts` | buildLevels関数 |

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

```
createTask (create-task.ts)
    │
    ├─ getWorkspace (optional)
    │
    ├─ findNodeGroupByNodeId (optional)
    │
    ├─ buildLevels
    │      └─ ノード間依存関係の解析
    │
    ├─ Generation生成ループ
    │      └─ CreatedGeneration作成
    │
    ├─ Sequence/Step構築
    │
    ├─ TaskStarter設定
    │
    └─ 保存処理
           ├─ storage.setJson (Task)
           ├─ addWorkspaceIndexItem
           ├─ setGeneration (各Generation)
           └─ onCreate callback
```

### データフロー図

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

workspaceId/workspace ──▶ Workspace取得
connectionIds/nodeId ───▶ 対象ノード/接続特定
                              │
                              ▼
                        buildLevels
                              │
                              ▼
                    ┌─────────┴─────────┐
                    │                   │
                    ▼                   ▼
              Sequence生成        Generation生成
                    │                   │
                    ▼                   ▼
                Step生成          CreatedGeneration[]
                    │                   │
                    └─────────┬─────────┘
                              │
                              ▼
                         Task生成
                              │
                    ┌─────────┼─────────┐
                    │         │         │
                    ▼         ▼         ▼
              Task保存  Index追加  Generation保存
                    │         │         │
                    └─────────┴─────────┘
                              │
                              ▼
                     { task, generations }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| create-task.ts | `packages/giselle/src/tasks/create-task.ts` | ソース | タスク作成メインロジック |
| task.ts | `packages/protocol/src/task/task.ts` | ソース | Task、Sequence、Stepスキーマ |
| task-id.ts | `packages/protocol/src/task/task-id.ts` | ソース | TaskId生成 |
| build-levels.ts | `packages/giselle/src/utils/build-levels.ts` | ソース | レベル算出ロジック |
| get-workspace.ts | `packages/giselle/src/workspaces/get-workspace.ts` | ソース | ワークスペース取得 |
| path.ts | `packages/giselle/src/path.ts` | ソース | ストレージパス生成 |
| workspace-index.ts | `packages/giselle/src/utils/workspace-index.ts` | ソース | インデックス操作 |
