# 画面設計書 18-プレイグラウンド画面

## 概要

本ドキュメントは、Giselle Studio の「プレイグラウンド画面」に関する画面設計書である。公開されたアプリの実行テストを行い、タスクの作成と実行を管理する画面を定義する。

### 本画面の処理概要

**業務上の目的・背景**：ワークフローエディタで作成・公開したアプリを実際に実行し、動作確認やテストを行う環境を提供する。サンプルアプリやチームのアプリを選択し、パラメータを入力して実行することで、ワークフローの動作を検証できる。

**画面へのアクセス方法**：グローバルナビゲーションの「Playground」メニュー、チーム参加成功画面からのリダイレクト、またはタスク詳細画面からの再実行でアクセス可能。

**主要な操作・処理内容**：
1. 実行するアプリの選択（サンプルアプリ/チームアプリ）
2. アプリのパラメータ入力
3. タスクの作成と実行開始
4. アプリの検索・フィルタリング
5. タスク詳細画面への遷移

**画面遷移**：
- 遷移元：ロビー画面、チーム参加成功画面（/join/success）、タスク詳細画面
- 遷移先：タスク詳細画面（/tasks/[taskId]）、ワークスペース一覧画面（/workspaces）

**権限による表示制御**：認証済みユーザーのみアクセス可能。表示されるアプリは現在選択中のチームに紐づく。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 22 | タスク作成・開始 | 主機能 | アプリの実行テスト、タスクの作成と開始処理 |
| 61 | アプリ取得 | 補助機能 | 実行可能なアプリ一覧の取得 |
| 24 | タスクストリーム | API連携 | タスク実行状況のリアルタイムストリーム配信 |

## 画面種別

実行画面

## URL/ルーティング

`/playground`

**クエリパラメータ**:
- `initialAppId` (任意): 初期選択するアプリID

## 入出力項目

| 項目名 | 項目ID | 入出力 | 必須 | データ型 | 制約・バリデーション |
|--------|--------|--------|------|----------|---------------------|
| 初期アプリID | initialAppId | 入力（クエリパラメータ） | 任意 | string | 有効なAppId |
| アプリ検索キーワード | appSearchQuery | 入力 | 任意 | string | フリーテキスト |
| パラメータ入力 | inputs | 入力 | アプリ依存 | GenerationContextInput[] | アプリのパラメータスキーマに準拠 |

## 表示項目

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| キャッチコピー | 「Have a task? Your agent is on it.」 | 固定テキスト |
| サンプルアプリ一覧 | Giselleチームが提供するサンプルアプリ | loadStageAppsData().sampleApps |
| チームアプリ一覧 | チームが作成したアプリ | loadStageAppsData().apps |
| アプリカード | アプリ名、説明、LLMプロバイダ、作成者 | StageApp型 |
| パラメータ入力フォーム | 選択アプリのパラメータ入力UI | PlaygroundStageInput |

## イベント仕様

### 1-アプリ選択

**トリガー**: アプリカードをクリック

**処理フロー**:
1. selectedAppIdステートを更新
2. PlaygroundStageInputコンポーネントが選択アプリのパラメータ入力UIを表示

### 2-アプリ検索

**トリガー**: 検索フィールドへの入力

**処理フロー**:
1. isSearchActiveをtrueに設定
2. appSearchQueryステートを更新
3. appsをフィルタリング（useMemoで計算）
4. 検索キーワードを含むアプリのみ表示

### 3-タスク実行

**トリガー**: 入力完了後の送信（PlaygroundStageInputのonSubmitAction）

**処理フロー**:
1. handleRunSubmit関数が呼ばれる
2. showOverlayでオーバーレイを表示（アプリ情報と入力パラメータ）
3. runningAppIdを設定
4. createAndStartTaskAction Server Actionを呼び出し
5. giselle.createTaskでタスク作成
6. giselle.startTaskでタスク開始
7. 成功時、/tasks/{taskId}へ遷移
8. エラー時、runningAppIdをリセットしオーバーレイを非表示

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| タスク実行 | tasks | INSERT | 新規タスクの作成 |
| タスク実行 | generations | INSERT | タスク内の生成ステップ作成 |

### テーブル別更新項目詳細

#### tasks（giselle.createTask経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | 自動生成（TaskId） | SDK で生成 |
| INSERT | workspaceId | 選択アプリのworkspaceId | - |
| INSERT | status | "created" | 初期ステータス |
| INSERT | createdAt | 現在日時 | - |

## メッセージ仕様

| 種別 | メッセージID | メッセージ内容 | 表示条件 |
|------|-------------|---------------|----------|
| キャッチコピー | have_task | Have a task? Your agent is on it. | 常時表示 |
| セクションヘッダー | sample_apps | Sample Apps from Giselle | サンプルアプリが存在する場合 |
| セクションヘッダー | your_apps | Your Apps | 常時表示 |
| 空状態 | no_apps | No apps yet | チームアプリが0件の場合 |
| 空状態説明 | build_first | Build your first app in the Studio. Apps you create will appear here, ready to run in the playground. | チームアプリが0件の場合 |

## 例外処理

| 例外状況 | 処理内容 | ユーザーへの通知 |
|---------|---------|----------------|
| タスク作成失敗 | コンソールエラー出力、オーバーレイ非表示 | なし（サイレント） |
| アプリ取得失敗 | 空配列として処理 | アプリなしメッセージ表示 |

## 備考

- initialAppIdクエリパラメータで初期選択アプリを指定可能
- サンプルアプリはmetadata.sample = trueのワークスペースから取得
- アプリカードにはLLMプロバイダアイコン（最大3つ）と作成者名を表示
- 選択中のアプリはハイライト表示（border、ring、shadow）
- TaskOverlayStoreを使用してタスク実行中のオーバーレイ状態を管理

---

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

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

### 推奨読解順序

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

StageApp型とアプリデータの取得方法を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `apps/studio.giselles.ai/app/(main)/playground/types.ts` | StageApp型の定義 |
| 1-2 | stage-apps.ts | `apps/studio.giselles.ai/app/(main)/lib/stage-apps.ts` | loadStageAppsData関数（220-238行目） |

**読解のコツ**: StageAppにはid, name, description, entryNodeId, parameters, workspaceId, isMine, llmProvidersなどが含まれる。

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

Server Componentの構造とクエリパラメータ処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | page.tsx | `apps/studio.giselles.ai/app/(main)/playground/page.tsx` | searchParamsCacheによるクエリパラメータ解析（8-10行目） |

**主要処理フロー**:
1. **8-10行目**: nuqs/serverでsearchParamsをパース
2. **17行目**: initialAppIdを取得
3. **37-41行目**: Pageコンポーネントにpropsを渡す

#### Step 3: クライアントコンポーネントを理解する

アプリ選択、検索、タスク実行の実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | page.client.tsx | `apps/studio.giselles.ai/app/(main)/playground/page.client.tsx` | ステート管理（204-211行目）、handleRunSubmit（230-263行目） |

**主要処理フロー**:
- **204-211行目**: selectedAppId, runningAppId, appSearchQueryなどのステート
- **213-218行目**: useTaskOverlayStoreでオーバーレイ管理
- **220-228行目**: appsフィルタリング（useMemo）
- **230-263行目**: handleRunSubmitでタスク作成・開始・遷移

#### Step 4: Server Actionを理解する

タスク作成・開始の処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | create-and-start-task.ts | `apps/studio.giselles.ai/app/(main)/lib/create-and-start-task.ts` | createAndStartTask関数（7-19行目） |

**主要処理フロー**:
- **14行目**: assertWorkspaceAccessでアクセス権検証
- **16行目**: giselle.createTaskでタスク作成
- **17行目**: giselle.startTaskでタスク開始
- **18行目**: task.idを返す

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

```
page.tsx (Server Component)
    │
    ├─ searchParamsCache.parse() ─── クエリパラメータ解析
    │
    ├─ dataLoader() ─── data-loader.ts
    │      └─ loadStageAppsData() ─── stage-apps.ts
    │             │
    │             ├─ getCurrentUser()
    │             ├─ fetchCurrentTeam()
    │             ├─ getApps() ─── チームアプリ取得
    │             │      └─ getAppsBySampleFlag(false)
    │             └─ getSampleApps() ─── サンプルアプリ取得
    │                    └─ getAppsBySampleFlag(true)
    │
    └─ Page (Client Component) ─── page.client.tsx
           │
           ├─ useTaskOverlayStore() ─── オーバーレイ管理
           │
           ├─ AppListCard / AppCard ─── アプリカード表示
           │
           ├─ PlaygroundStageInput ─── パラメータ入力UI
           │
           └─ handleRunSubmit()
                  └─ createAndStartTaskAction() ─── create-and-start-task.ts
                         │
                         ├─ assertWorkspaceAccess()
                         ├─ giselle.createTask()
                         └─ giselle.startTask()
```

### データフロー図

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

initialAppId(URL) ───────▶ searchParamsCache ─────────▶ 初期選択
                                │
チーム情報 ──────────────▶ loadStageAppsData() ───────▶ apps, sampleApps
                                │
                                ▼
                         Page (Client)
                                │
アプリ選択 ──────────────▶ selectedAppId ─────────────▶ 入力フォーム表示
                                │
パラメータ入力 ──────────▶ PlaygroundStageInput ─────▶ inputs
                                │
                                ▼
                         handleRunSubmit()
                                │
                                ├─ createAndStartTaskAction()
                                │
                                ▼
                         router.push(/tasks/{taskId})
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| page.tsx | `apps/studio.giselles.ai/app/(main)/playground/page.tsx` | ソース | ページエントリーポイント（Server Component） |
| page.client.tsx | `apps/studio.giselles.ai/app/(main)/playground/page.client.tsx` | ソース | クライアントコンポーネント |
| data-loader.ts | `apps/studio.giselles.ai/app/(main)/playground/data-loader.ts` | ソース | データローダー |
| types.ts | `apps/studio.giselles.ai/app/(main)/playground/types.ts` | ソース | StageApp型定義 |
| stage-apps.ts | `apps/studio.giselles.ai/app/(main)/lib/stage-apps.ts` | ソース | アプリデータ取得 |
| create-and-start-task.ts | `apps/studio.giselles.ai/app/(main)/lib/create-and-start-task.ts` | ソース | タスク作成・開始Server Action |
| task-overlay-store.ts | `apps/studio.giselles.ai/app/(main)/stores/task-overlay-store.ts` | ソース | オーバーレイ状態管理（Zustand） |
| playground-stage-input.tsx | `apps/studio.giselles.ai/app/(main)/components/stage-input/playground-stage-input.tsx` | ソース | パラメータ入力コンポーネント |
