# 画面設計書 8-プロジェクト新規作成画面

## 概要

本ドキュメントは、Liam DBアプリケーションのプロジェクト新規作成画面について定義する。

### 本画面の処理概要

プロジェクト新規作成画面は、GitHubリポジトリをインポートして新規プロジェクトを作成するための画面である。2段階のステッパー形式で、まずGitHub Installationsからリポジトリを選択し、次にスキーマファイルのパスとフォーマットを設定する。

**業務上の目的・背景**：Liam DBはGitHubリポジトリ内のデータベーススキーマファイルを解析してER図を生成するツールである。新規プロジェクト作成時にGitHubリポジトリと連携することで、スキーマファイルの自動取得・更新追跡が可能になる。ステッパー形式により、ユーザーは段階的に設定を行える。

**画面へのアクセス方法**：
- プロジェクト一覧画面の「Add New Project」ボタンをクリック
- 組織新規作成後に自動遷移
- 直接`/projects/new`にアクセス

**主要な操作・処理内容**：
1. Step 1: GitHub Installationsの一覧からリポジトリを選択
2. Step 2: スキーマファイルのパスとフォーマットを入力
3. 「Save」ボタンでプロジェクト作成処理を実行
4. 作成成功時、プロジェクト詳細画面へリダイレクト

**画面遷移**：
- プロジェクト作成成功時 → プロジェクト詳細画面（`/projects/[projectId]`）
- キャンセル時 → Step 1に戻る
- 「Back to Projects」クリック時 → プロジェクト一覧画面（`/projects`）
- 未認証時 → ログイン画面（`/login`）

**権限による表示制御**：認証必須。GitHub OAuth認証が必要（トークンリフレッシュ機能あり）。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | プロジェクト管理 | 主機能 | GitHubリポジトリをインポートして新規プロジェクトを作成 |
| 28 | GitHub連携 | 主機能 | GitHub Installationsの取得とリポジトリ選択 |
| 43 | リポジトリ操作 | 補助機能 | GitHubリポジトリ情報の取得 |
| 12 | フォーマット自動検出 | 補助機能 | スキーマファイル形式の選択 |
| 34 | 基本コンポーネント | 補助機能 | Stepper形式のフォーム表示 |

## 画面種別

登録フォーム（ステッパー形式）

## URL/ルーティング

- URL: `/projects/new`
- ファイル: `frontend/apps/app/app/projects/new/page.tsx`
- レンダリング: ハイブリッド（サーバーでデータ取得、クライアントでUI）

## 入出力項目

### 入力項目（Step 1）

| 項目名 | 項目ID | データ型 | 必須 | 備考 |
|--------|--------|----------|------|------|
| Installation選択 | selectedInstallation | Installation | はい | ドロップダウン選択 |
| リポジトリ選択 | selectedRepository | Repository | はい | クリック選択 |

### 入力項目（Step 2）

| 項目名 | 項目ID | データ型 | 必須 | 備考 |
|--------|--------|----------|------|------|
| スキーマファイルパス | schemaFilePath | string | はい | テキスト入力 |
| スキーマフォーマット | schemaFileFormat | FormatType | はい | ドロップダウン選択、デフォルト: postgres |

## 表示項目

| 項目名 | 説明 | 備考 |
|--------|------|------|
| ページタイトル | "Add New Project" | h1要素 |
| ステッパー | 2段階のステップ表示 | Step 1: Import Git Repository, Step 2: Set Watch Schemas |
| Installation一覧 | GitHub App Installationの一覧 | InstallationSelectorコンポーネント |
| リポジトリ一覧 | 選択Installationのリポジトリ一覧 | カード形式 |
| スキーマ設定フォーム | パスとフォーマットの入力 | SetSchemaFormコンポーネント |
| Cancelボタン | Step 1に戻る | Step 2でのみ表示 |
| Saveボタン | プロジェクト作成実行 | Step 2でのみ表示、条件付き有効 |
| Back to Projectsリンク | プロジェクト一覧へ戻る | 常時表示 |

## イベント仕様

### 1-Installation選択

GitHub App Installationを選択。

**トリガー**：Installation ドロップダウン変更

**処理フロー**：
1. 選択されたInstallationをstateに保存
2. 選択Installationに紐づくリポジトリ一覧を表示

### 2-リポジトリ選択

Installationからリポジトリを選択（Step 2へ進む）。

**トリガー**：リポジトリカードクリック

**処理フロー**：
1. 選択されたリポジトリをstateに保存
2. ステッパーをStep 2に進める
3. スキーマ設定フォームを表示

### 3-スキーマ設定

スキーマファイルのパスとフォーマットを設定。

**トリガー**：フォーム入力

**処理フロー**：
1. 入力値をstateに保存
2. パスが空でなければSaveボタンを有効化

### 4-キャンセル

Step 1に戻る。

**トリガー**：「Cancel」ボタンクリック

**処理フロー**：
1. selectedRepositoryをnullにリセット
2. ステッパーをStep 1に戻す

### 5-プロジェクト保存

プロジェクトを作成して保存。

**トリガー**：「Save」ボタンクリック

**処理フロー**：
1. FormDataを構築（projectName, repositoryName, repositoryOwner, installationId, repositoryIdentifier, schemaFilePath, schemaFormat）
2. `addProject`サーバーアクションを呼び出し
3. Supabase RPC関数`add_project`で一括作成
4. 成功時：`/projects/[projectId]`へリダイレクト
5. 失敗時：エラーメッセージを返却

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| プロジェクト保存 | projects | INSERT | 新規プロジェクトレコード作成 |
| プロジェクト保存 | github_repositories | INSERT | GitHubリポジトリ情報登録 |
| プロジェクト保存 | project_repository_mappings | INSERT | プロジェクトとリポジトリのマッピング |
| プロジェクト保存 | schema_file_paths | INSERT | スキーマファイルパス登録 |

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

#### projects

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | リポジトリ名 | - |
| INSERT | organization_id | 現在の組織ID | - |

#### github_repositories

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | repositoryName | - |
| INSERT | owner | repositoryOwner | - |
| INSERT | github_installation_identifier | installationId | - |

#### project_repository_mappings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | project_id | 作成されたプロジェクトID | - |
| INSERT | github_repository_id | 作成されたリポジトリID | - |

#### schema_file_paths

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | project_id | 作成されたプロジェクトID | - |
| INSERT | path | schemaFilePath | - |
| INSERT | format | schemaFormat | - |

## メッセージ仕様

| メッセージID | メッセージ内容 | 表示タイミング | 種別 |
|--------------|---------------|----------------|------|
| ERR-001 | "Failed to create project. Please try again." | 作成処理失敗時 | エラー |

## 例外処理

| 例外ケース | 処理内容 |
|------------|----------|
| 組織ID取得失敗 | `/login`へリダイレクト |
| ユーザー情報取得エラー | `/login`へリダイレクト |
| GitHubトークン未取得/期限切れ | TokenRefreshKickでトークンリフレッシュ |
| Installation取得失敗 | 空配列を返却、needsRefresh=true |
| プロジェクト作成失敗 | エラーメッセージを返却 |
| RPC関数エラー | エラーメッセージを返却 |

## 備考

- Stepper形式で2段階に分けてフォーム入力
- GitHub OAuth認証が必要、トークン期限切れ時は自動リフレッシュ
- `add_project` RPC関数でアトミックにデータ作成
- スキーマフォーマットのデフォルトは`postgres`
- 対応フォーマット: postgres, schemarb, prisma など

---

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

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

### 推奨読解順序

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

GitHub Installation/Repository とプロジェクトの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | addProject.ts | `frontend/apps/app/components/ProjectNewPage/actions/addProject.ts` | プロジェクト作成のスキーマ定義、RPC呼び出し |

**読解のコツ**: `add_project` RPCが返す`addProjectResultSchema`を確認する。

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

プロジェクト新規作成ページのエントリーポイントを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | page.tsx | `frontend/apps/app/app/projects/new/page.tsx` | サーバーサイドでのデータ取得 |
| 2-2 | ProjectNewPage.tsx | `frontend/apps/app/components/ProjectNewPage/ProjectNewPage.tsx` | クライアントサイドのフォームUI |

**主要処理フロー（page.tsx）**:
- **10-16行目**: 組織ID取得、失敗時はログインへリダイレクト
- **18-26行目**: ユーザー情報取得
- **28-49行目**: GitHubトークン取得とInstallations取得
- **51-53行目**: ProjectNewPageに installations と needsRefresh を渡す

**主要処理フロー（ProjectNewPage.tsx）**:
- **16-19行目**: ステップ定義
- **26-39行目**: state定義（installation, repository, schemaPath, format）
- **46-70行目**: handleSaveでプロジェクト作成
- **105-120行目**: Step 1/Step 2の条件分岐表示

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

Installation選択とスキーマ設定のコンポーネント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | InstallationSelector.tsx | `frontend/apps/app/components/ProjectNewPage/components/InstallationSelector/InstallationSelector.tsx` | Installation/リポジトリ選択UI |
| 3-2 | SetSchemaForm.tsx | `frontend/apps/app/components/ProjectNewPage/components/SetSchemaForm/SetSchemaForm.tsx` | スキーマパス/フォーマット入力UI |
| 3-3 | Stepper.tsx | `frontend/apps/app/components/ProjectNewPage/components/Stepper/Stepper.tsx` | ステッパーUI |

#### Step 4: サーバーアクションを理解する

プロジェクト作成のサーバーアクション処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | addProject.ts | `frontend/apps/app/components/ProjectNewPage/actions/addProject.ts` | プロジェクト作成処理 |

**主要処理フロー**:
- **28-37行目**: FormDataから値を抽出
- **40-47行目**: 組織ID取得
- **52-61行目**: `add_project` RPC呼び出し
- **89行目**: 成功時にプロジェクト詳細へリダイレクト

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

```
app/projects/new/page.tsx
    │
    ├─ features/organizations/services/getOrganizationId.ts
    │
    ├─ libs/github/token.ts (getUserAccessToken)
    │
    ├─ @liam-hq/github (getInstallations)
    │
    └─ components/ProjectNewPage/ProjectNewPage.tsx
           │
           ├─ components/TokenRefreshKick.tsx
           │
           ├─ components/Stepper/Stepper.tsx
           │
           ├─ components/InstallationSelector/InstallationSelector.tsx
           │
           ├─ components/SetSchemaForm/SetSchemaForm.tsx
           │
           └─ actions/addProject.ts [Server Action]
                  └─ supabase.rpc('add_project')
```

### データフロー図

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

ページアクセス      ───▶ page.tsx                     ───▶ ProjectNewPage
                         │
                         ├─ getOrganizationId()
                         ├─ getUserAccessToken()
                         └─ getInstallations()

Installation選択   ───▶ InstallationSelector          ───▶ リポジトリ一覧表示

リポジトリ選択     ───▶ state更新                     ───▶ Step 2へ

スキーマ設定       ───▶ SetSchemaForm                 ───▶ state更新

Save クリック      ───▶ addProject                    ───▶ /projects/[id]
                         │
                         └─ RPC: add_project
                                ├─ projects INSERT
                                ├─ github_repositories INSERT
                                ├─ project_repository_mappings INSERT
                                └─ schema_file_paths INSERT
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| page.tsx | `frontend/apps/app/app/projects/new/page.tsx` | ソース | プロジェクト新規作成ページのエントリーポイント |
| ProjectNewPage.tsx | `frontend/apps/app/components/ProjectNewPage/ProjectNewPage.tsx` | ソース | プロジェクト作成フォームコンポーネント |
| addProject.ts | `frontend/apps/app/components/ProjectNewPage/actions/addProject.ts` | ソース | プロジェクト作成サーバーアクション |
| InstallationSelector.tsx | `frontend/apps/app/components/ProjectNewPage/components/InstallationSelector/InstallationSelector.tsx` | ソース | Installation選択コンポーネント |
| SetSchemaForm.tsx | `frontend/apps/app/components/ProjectNewPage/components/SetSchemaForm/SetSchemaForm.tsx` | ソース | スキーマ設定フォーム |
| Stepper.tsx | `frontend/apps/app/components/ProjectNewPage/components/Stepper/Stepper.tsx` | ソース | ステッパーコンポーネント |
| TokenRefreshKick.tsx | `frontend/apps/app/components/TokenRefreshKick/TokenRefreshKick.tsx` | ソース | トークンリフレッシュ処理 |
| ProjectNewPage.module.css | `frontend/apps/app/components/ProjectNewPage/ProjectNewPage.module.css` | スタイル | プロジェクト新規作成ページのスタイル |
| server.ts | `frontend/apps/app/libs/db/server.ts` | ソース | Supabaseクライアント生成 |
| token.ts | `frontend/apps/app/libs/github/token.ts` | ソース | GitHubトークン取得 |
| urlgen.ts | `frontend/apps/app/libs/routes/urlgen.ts` | ソース | URL生成ユーティリティ |
