# 画面設計書 19-タスク一覧画面

## 概要

本ドキュメントは、Giselle Studio の「タスク一覧画面」に関する画面設計書である。実行されたタスクの一覧をページネーション付きで表示し、各タスクの詳細への遷移を提供する画面を定義する。

### 本画面の処理概要

**業務上の目的・背景**：ユーザーが実行したタスクの履歴を一覧形式で確認し、各タスクの実行状況（完了/実行中/失敗）や実行元（アプリ/GitHub）を把握できるようにする。タスクの実行履歴管理と結果確認のハブとなる画面。

**画面へのアクセス方法**：グローバルナビゲーションの「Tasks」メニューからアクセス可能。

**主要な操作・処理内容**：
1. タスク一覧の表示（ページネーション対応）
2. 各タスクのステータス確認
3. タスク詳細画面への遷移
4. ページネーション（Prev/Next）による一覧ナビゲーション

**画面遷移**：
- 遷移元：グローバルナビゲーション、プレイグラウンド画面
- 遷移先：タスク詳細画面（/tasks/[taskId]）、プレイグラウンド画面（/playground）

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 25 | タスク取得 | 主機能 | 実行されたタスクの一覧取得と表示 |
| 26 | ワークスペースタスク一覧 | 補助機能 | ワークスペースに関連するタスクのフィルタリング |

## 画面種別

一覧画面

## URL/ルーティング

`/tasks`

**クエリパラメータ**:
- `limit` (任意): 1ページあたりの表示件数（デフォルト: 50、最大: 100）
- `offset` (任意): 表示開始位置（デフォルト: 0）

## 入出力項目

| 項目名 | 項目ID | 入出力 | 必須 | データ型 | 制約・バリデーション |
|--------|--------|--------|------|----------|---------------------|
| 表示件数 | limit | 入力（クエリパラメータ） | 任意 | number | 1-100 |
| オフセット | offset | 入力（クエリパラメータ） | 任意 | number | 0以上 |

## 表示項目

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| タスクID | タスクの一意識別子（リンク付き） | task.id |
| 開始日時 | タスクの実行開始日時 | task.startedAt (LocalDateTime表示) |
| ステータス | タスクの実行状態（Running/Completed/Failed/Cancelled） | task.status |
| 実行元 | タスクの発生元（アプリ名/GitHub） | task.origin |
| 表示件数 | 現在表示中のタスク件数 | tasks.length |
| ページネーション | Prev/Nextボタン | prevOffset/nextOffset |

## イベント仕様

### 1-タスク詳細遷移

**トリガー**: タスクIDリンクをクリック

**処理フロー**:
1. /tasks/{taskId} へ遷移
2. タスク詳細画面を表示

### 2-次ページ表示

**トリガー**: 「Next」ボタンをクリック

**処理フロー**:
1. URLを ?limit={limit}&offset={offset+limit} に更新
2. 次ページのタスク一覧を取得・表示

### 3-前ページ表示

**トリガー**: 「Prev」ボタンをクリック

**処理フロー**:
1. URLを ?limit={limit}&offset={offset-limit} に更新
2. 前ページのタスク一覧を取得・表示

### 4-プレイグラウンドへ遷移

**トリガー**: 「Get Started」ボタンをクリック（タスクが0件の場合）

**処理フロー**:
1. /playground へ遷移

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 一覧取得 | tasks | SELECT | チームのタスク一覧取得 |
| 一覧取得 | apps | SELECT | タスクに関連するアプリ情報取得 |
| 一覧取得 | workspaces | SELECT | アプリに関連するワークスペース名取得 |

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

#### tasks（SELECT）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, appDbId, createdAt | WHERE teamDbId = 現在チームのdbId AND appDbId IS NOT NULL | ORDER BY createdAt DESC, LIMIT, OFFSET |

#### apps（SELECT、リレーション）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | workspaceDbId | tasks.app リレーション | - |

#### workspaces（SELECT、リレーション）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | name | apps.workspace リレーション | - |

## メッセージ仕様

| 種別 | メッセージID | メッセージ内容 | 表示条件 |
|------|-------------|---------------|----------|
| ヘッダー | tasks_title | Tasks | 常時表示 |
| リンク | about_tasks | About Tasks | 常時表示（ドキュメントリンク） |
| 空状態 | no_tasks | No tasks completed yet | タスクが0件の場合 |
| 空状態説明 | get_started | Get started by running an app from the Playground page. | タスクが0件の場合 |
| ステータス | running | Running | task.status === "inProgress" |
| ステータス | completed | Completed | task.status === "completed" or "created" |
| ステータス | failed | Failed | task.status === "failed" |
| ステータス | cancelled | Cancelled | その他のステータス |

## 例外処理

| 例外状況 | 処理内容 | ユーザーへの通知 |
|---------|---------|----------------|
| タスク取得失敗 | エラーをスロー | Next.jsエラーページ表示 |
| アプリ情報なし | origin.type = "github" として処理 | 「GitHub」と表示 |

## 備考

- limit+1件を取得し、次ページの有無を判定（hasNextPage）
- ステータスはStatusBadgeコンポーネントでカラーコード化して表示
- LocalDateTimeコンポーネントでブラウザのロケールに応じた日時表示
- ドキュメントリンク（DocsLink）でAbout Tasks記事への外部リンクを提供
- テーブルヘッダーにはInput列とModel列のTODOコメントあり（将来実装予定）

---

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

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

### 推奨読解順序

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

UITaskListRow型とタスクデータの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | page.tsx | `apps/studio.giselles.ai/app/(main)/tasks/page.tsx` | UITaskListRow型（14-30行目）、UITaskListOrigin型（14-22行目） |

**読解のコツ**: UITaskListRowにはid, startedAt, status, inputSummary, originが含まれる。originはapp/githubの2種類。

#### Step 2: データ取得処理を理解する

Server Componentでのデータ取得とページネーションを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | page.tsx | `apps/studio.giselles.ai/app/(main)/tasks/page.tsx` | searchParamsCacheでパラメータ解析（32-35行目）、データ取得（81-145行目） |

**主要処理フロー**:
1. **32-35行目**: searchParamsCacheでlimit, offsetを定義
2. **84-88行目**: clampIntでlimitを1-100に制限
3. **90行目**: fetchCurrentTeam()でチーム取得
4. **93-114行目**: db.query.tasks.findManyでタスク一覧取得
5. **116-117行目**: hasNextPageの判定（limit+1件取得）
6. **119-145行目**: giselle.getTaskで各タスクの詳細取得

#### Step 3: UIコンポーネントを理解する

一覧表示とページネーションのUI実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | page.tsx | `apps/studio.giselles.ai/app/(main)/tasks/page.tsx` | getStatusBadge関数（45-72行目）、一覧表示（199-302行目） |

**主要処理フロー**:
- **45-72行目**: getStatusBadge関数でステータスに応じたバッジを返す
- **74-79行目**: buildTasksHref関数でページネーションURL構築
- **166-196行目**: Prev/Nextボタンの表示制御
- **200-224行目**: タスクが0件の場合の空状態表示
- **225-301行目**: タスク一覧テーブルのレンダリング

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

```
page.tsx (Server Component)
    │
    ├─ searchParamsCache.parse() ─── クエリパラメータ解析
    │
    ├─ clampInt() ─── limit値の制限
    │
    ├─ fetchCurrentTeam() ─── 現在チーム取得
    │
    ├─ db.query.tasks.findMany() ─── タスク一覧取得
    │      │
    │      └─ with: app → workspace ─── リレーション
    │
    ├─ giselle.getTask() ─── 各タスクの詳細取得（並列実行）
    │
    └─ JSXレンダリング
           │
           ├─ PageHeading
           ├─ DocsLink
           ├─ StatusBadge
           ├─ LocalDateTime
           └─ Card (テーブル)
```

### データフロー図

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

limit, offset (URL) ─────▶ searchParamsCache ─────────▶ ページネーション設定
                               │
チームID ────────────────▶ fetchCurrentTeam() ────────▶ team.dbId
                               │
                               ▼
                         db.query.tasks.findMany()
                               │
                               ├─ tasks (limit+1件)
                               ├─ apps (リレーション)
                               └─ workspaces (リレーション)
                                      │
                                      ▼
                         giselle.getTask() (並列)
                                      │
                                      ▼
                         UITaskListRow[] ────────────▶ テーブル表示
                                      │
                                      ▼
                         hasNextPage ─────────────────▶ Prev/Next表示制御
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| page.tsx | `apps/studio.giselles.ai/app/(main)/tasks/page.tsx` | ソース | ページエントリーポイント（Server Component） |
| local-date-time.tsx | `apps/studio.giselles.ai/app/(main)/settings/team/components/local-date-time.tsx` | ソース | ローカル日時表示コンポーネント |
| card.tsx | `apps/studio.giselles.ai/app/(main)/settings/components/card.tsx` | ソース | カードコンテナコンポーネント |
| status-badge | `internal-packages/ui/src/status-badge.tsx` | ソース | ステータスバッジコンポーネント |
| page-heading | `internal-packages/ui/src/page-heading.tsx` | ソース | ページヘッディングコンポーネント |
| docs-link | `internal-packages/ui/src/docs-link.tsx` | ソース | ドキュメントリンクコンポーネント |
