# 機能設計書 13-終了ノード

## 概要

本ドキュメントは、Giselleワークフローエンジンにおける終了ノード（EndNode）の機能設計を記述する。終了ノードは、ワークフローの終点を定義し、アプリケーションフローの完了を示すための操作ノードである。

### 本機能の処理概要

終了ノードは、ワークフローの終点を明示的に定義する機能である。アプリエントリーノードと組み合わせることで、完結したアプリケーションフロー（ConnectedApp）を構築できる。タスク実行時には、終了ノードに接続されたノードの出力が最終結果として扱われる。

**業務上の目的・背景**：AIワークフローにおいて、処理の終点を明確に定義することは重要である。終了ノードにより、ワークフローのどのノードが最終出力を提供するかを明示し、GitHubトリガー連携時の自動応答や、API経由での結果返却を可能にする。

**機能の利用シーン**：
- 完結したアプリケーションフローを定義する場合
- GitHubトリガーによるワークフロー実行後、自動応答を行う場合
- API経由でワークフローを実行し、結果を取得する場合
- ワークフローの最終出力を明示的に指定する場合

**主要な処理内容**：
1. ワークフロー終点の定義（視覚的なマーカー）
2. 接続されたノードの最終出力識別
3. タスク作成時のnodeIdsConnectedToEnd設定
4. ConnectedApp作成時のendNodeId指定

**関連システム・外部連携**：
- アプリエントリーノード（AppEntryNode）との組み合わせ
- GitHubトリガー連携（自動応答時のend.type設定）
- アプリ管理機能（ConnectedApp保存）

**権限による制御**：特になし（ワークスペース編集権限に依存）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | ワークフローエディタ画面 | 主画面 | 終了ノードの追加・接続配置 |

## 機能種別

設定定義 / フロー制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| type | "end" | Yes | ノードコンテンツタイプ | リテラル値 |

### 入力データソース

- **接続**: 他のノードからの接続（終了ノードへのデータ流入）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| - | - | 終了ノード自体は出力を持たない |

### 出力先

- 終了ノードは出力ポートを持たない
- 接続されたノードの出力がワークフローの最終結果として扱われる

## 処理フロー

### 処理シーケンス

```
1. ノード生成（createEndNode）
   └─ 空のinputs/outputs配列で初期化
   └─ content.type = "end"を設定

2. ワークフローへの配置
   └─ 他ノードからの接続を受け付け
   └─ 視覚的な終点マーカーとして機能

3. タスク作成時（createTask）
   └─ EndNodeの検出
   └─ EndNodeへ接続されているノードIDを特定
   └─ nodeIdsConnectedToEndとしてTask情報に設定

4. アプリ保存時（save-app）
   └─ EndNodeが存在する場合、ConnectedAppとして保存
   └─ endNodeIdをApp情報に設定
```

### フローチャート

```mermaid
flowchart TD
    A[終了ノード追加] --> B[ワークフロー配置]
    B --> C[他ノードからの接続]
    C --> D{タスク作成時}
    D --> E[EndNode検出]
    E --> F[接続ノードID特定]
    F --> G[nodeIdsConnectedToEnd設定]
    G --> H{アプリ保存時}
    H --> I{EndNode存在?}
    I -->|Yes| J[ConnectedApp保存]
    I -->|No| K[DisconnectedApp保存]
    J --> L[endNodeId設定]
    K --> M[保存完了]
    L --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 単一終了ノード制約 | 1つのワークフロー（ノードグループ）には最大1つの終了ノードのみ許容 | タスク作成時にチェック |
| BR-002 | 出力なし | 終了ノードはoutputs配列が空で生成される | ノード生成時 |
| BR-003 | ConnectedApp条件 | 終了ノードが存在する場合のみConnectedAppとして保存可能 | アプリ保存時 |
| BR-004 | 処理スキップ | 終了ノード自体は処理ステップとしてスキップされる | タスク実行時 |

### 計算ロジック

nodeIdsConnectedToEnd算出:
```
nodeIdsConnectedToEnd = connections
  .filter(connection => connection.inputNode.id === endNodeId)
  .map(connection => connection.outputNode.id)
  .distinct()
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | 本ノード単体ではDB操作なし |

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

終了ノード単体でのDB操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | 同一ワークフローに複数の終了ノード | "Workspace {id} has multiple end nodes: {nodeId1}, {nodeId2}" エラーを返却 |

### リトライ仕様

本機能はリトライ機構を持たない。

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

本ノード単体でのトランザクション制御はない。

## パフォーマンス要件

特になし（設定定義ノードのため）

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

特になし

## 備考

- 終了ノードはタスク実行時の処理ステップから除外される（isEndNodeチェックによりスキップ）
- GitHubトリガー連携時、終了ノードが存在しAppが設定されている場合、end.type = "endNode"として設定される

---

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

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

### 推奨読解順序

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

まず、終了ノードのスキーマ定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | end.ts | `packages/protocol/src/node/operations/end.ts` | EndContentのスキーマ定義、シンプルな構造 |
| 1-2 | operation-node.ts | `packages/protocol/src/node/operations/operation-node.ts` | EndNode型、isEndNode判定関数 |

**読解のコツ**: EndContentはtype: "end"のみを持つ最もシンプルな構造。

#### Step 2: ノード生成ファクトリを理解する

ノードがどのように生成されるかを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | node-factories.ts | `packages/node-registry/src/node-factories.ts` | endFactoryImplの実装 |

**主要処理フロー**:
- **434-460行目**: endFactoryImplのcreate/clone実装
- **995-997行目**: createEndNode関数のエクスポート

#### Step 3: タスク作成時の処理を理解する

タスク作成時に終了ノードがどのように処理されるかを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create-task.ts | `packages/giselle/src/tasks/create-task.ts` | EndNodeの検出と処理 |

**主要処理フロー**:
- **93-104行目**: 終了ノードの検出と単一性チェック
- **105-114行目**: nodeIdsConnectedToEndの算出
- **149-154行目**: 終了ノードを処理ステップから除外

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

```
createEndNode (node-factories.ts)
    │
    └─ EndNode生成
           ├─ id: NodeId.generate()
           ├─ type: "operation"
           ├─ content.type: "end"
           ├─ inputs: []
           └─ outputs: []

createTask (create-task.ts)
    │
    ├─ isEndNode チェック
    │      └─ 複数EndNode検出時エラー
    │
    └─ nodeIdsConnectedToEnd算出
           └─ 接続元ノードIDの収集
```

### データフロー図

```
[ノード生成]                    [タスク作成時]

createEndNode ──▶ EndNode ──▶ isEndNode チェック
                                    │
                                    ▼
                             複数存在チェック
                                    │
                                    ▼
                    ┌───────────────┴───────────────┐
                    │                               │
                    ▼                               ▼
            1つのみ存在                      複数存在
                    │                               │
                    ▼                               ▼
        nodeIdsConnectedToEnd算出              エラー発生
                    │
                    ▼
              Task.nodeIdsConnectedToEnd設定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| end.ts | `packages/protocol/src/node/operations/end.ts` | ソース | EndContentスキーマ定義 |
| operation-node.ts | `packages/protocol/src/node/operations/operation-node.ts` | ソース | EndNode型、isEndNode関数 |
| node-factories.ts | `packages/node-registry/src/node-factories.ts` | ソース | ノード生成ファクトリ |
| create-task.ts | `packages/giselle/src/tasks/create-task.ts` | ソース | タスク作成時のEndNode処理 |
| app.ts | `packages/protocol/src/app/app.ts` | ソース | ConnectedApp.endNodeId定義 |
| task.ts | `packages/protocol/src/task/task.ts` | ソース | Task.nodeIdsConnectedToEnd定義 |
