# 画面設計書 12-スキーマ画面

## 概要

本ドキュメントは、Liam DBアプリケーションにおけるスキーマ画面の設計仕様を定義する。

### 本画面の処理概要

この画面では、プロジェクトに登録されたスキーマファイルを取得し、ER図（Entity-Relationship Diagram）として視覚的に表示する。

**業務上の目的・背景**：
データベース設計の理解と共有を促進するため、スキーマファイルをビジュアルなER図として表示する必要がある。この画面により、開発者やDBアーキテクトはテーブル構造、カラム定義、リレーションシップを直感的に把握できる。GitHubリポジトリと連携し、最新のスキーマ定義を常に確認可能にする。

**画面へのアクセス方法**：
ブランチ詳細画面からスキーマファイルを選択してアクセスする。URLパターンは `/projects/:projectId/ref/:branchOrCommit/schema/:schemaFilePath`。スキーマファイルパスはキャッチオールルートとして複数階層のパスに対応する。

**主要な操作・処理内容**：
1. GitHubリポジトリからスキーマファイルの取得
2. スキーマファイルのパース（PostgreSQL / Rails schema.rb / Prisma 等に対応）
3. ER図としてのビジュアル表示
4. テーブル・カラム・リレーションシップの閲覧
5. サイドバーでのテーブル一覧表示と選択

**画面遷移**：
- 遷移元: ブランチ詳細画面（`/projects/:projectId/ref/:branchOrCommit`）
- 遷移先: デザインセッション新規作成画面（スキーマからセッション開始時）

**権限による表示制御**：
認証済みユーザーのみアクセス可能。プロジェクトへのアクセス権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 30 | スキーマ表示 | 主機能 | スキーマファイルのERD表示 |
| 1 | ER図表示 | 主機能 | データベーススキーマをER図として視覚的に表示 |
| 2 | テーブルノード表示 | 補助機能 | テーブル情報をノードとして表示 |
| 3 | リレーションシップエッジ表示 | 補助機能 | テーブル間の外部キー関係をエッジとして表示 |
| 4 | 自動レイアウト | 補助機能 | ELKアルゴリズムによるER図の自動配置 |
| 44 | ファイル取得 | API連携 | GitHubからスキーマファイルを取得 |
| 7 | PostgreSQL解析 | 補助機能 | PostgreSQL DDLのパース処理 |
| 8 | Ruby on Rails schema.rb解析 | 補助機能 | Rails schema.rbファイルのパース処理 |
| 9 | Prisma解析 | 補助機能 | Prismaスキーマファイルのパース処理 |
| 35 | レイアウトコンポーネント | 補助機能 | Tabs、Resizableパネルによるレイアウト構成 |

## 画面種別

詳細 / ビューア

## URL/ルーティング

```
/projects/:projectId/ref/:branchOrCommit/schema/[...schemaFilePath]
```

動的パラメータ:
- `projectId`: プロジェクトの一意識別子
- `branchOrCommit`: ブランチ名またはコミットハッシュ
- `schemaFilePath`: スキーマファイルのパス（キャッチオールルート、複数階層対応）

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| projectId | string | Yes | URLパラメータ - プロジェクトID |
| branchOrCommit | string | Yes | URLパラメータ - ブランチ名またはコミットハッシュ |
| schemaFilePath | string[] | Yes | URLパラメータ - スキーマファイルパス（配列形式） |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| schema | Schema | パースされたスキーマオブジェクト |
| errorObjects | ErrorObject[] | パースエラー情報 |
| schemaHeader | object | スキーマヘッダー情報（ファイル名、フォーマット、GitHubリンク） |

## 表示項目

### スキーマヘッダー

| 項目名 | 型 | 説明 |
|--------|-----|------|
| schemaName | string | スキーマファイル名 |
| format | FormatType | スキーマフォーマット（postgresql / schemarb / prisma 等） |
| href | string | GitHubファイルへのリンク |

### ERDエディタ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| tables | object | テーブル定義のマップ |
| enums | object | Enum定義のマップ |
| extensions | object | 拡張機能の定義 |

### サイドバー

| 項目名 | 型 | 説明 |
|--------|-----|------|
| defaultSidebarOpen | boolean | サイドバーの初期表示状態（Cookieから取得） |
| defaultPanelSizes | number[] | パネルサイズの初期値（Cookieから取得、デフォルト: [20, 80]） |

## イベント仕様

### 1-スキーマファイル取得

画面表示時にGitHubリポジトリからスキーマファイルを取得する。

**処理フロー**:
1. プロジェクト情報をSupabaseから取得
2. project_repository_mappingsからGitHubリポジトリ情報を取得
3. schema_file_pathsからフォーマット情報を取得
4. `getFileContent`でGitHubからファイルコンテンツを取得
5. `parse`関数でスキーマをパース
6. エラーがあればSentryに報告

### 2-ER図表示

パースされたスキーマをER図として表示する。

**処理フロー**:
1. ERDEditorコンポーネントにスキーマを渡す
2. テーブルをノードとして配置
3. リレーションシップをエッジとして描画
4. ELKアルゴリズムで自動レイアウト

### 3-サイドバー開閉

サイドバーの開閉状態を切り替える。

**処理フロー**:
1. サイドバートグルボタンをクリック
2. 状態をCookieに保存（`sidebar:state`）
3. 次回表示時に状態を復元

### 4-パネルリサイズ

パネルのサイズを変更する。

**処理フロー**:
1. ResizableHandleをドラッグ
2. パネルサイズを更新
3. 状態をCookieに保存（`panels:layout`）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | projects | SELECT | プロジェクト情報とリポジトリマッピングを取得 |
| 画面表示 | schema_file_paths | SELECT | スキーマファイルパスとフォーマット情報を取得 |
| 画面表示 | project_repository_mappings | SELECT | GitHubリポジトリ連携情報を取得 |
| 画面表示 | github_repositories | SELECT | GitHubリポジトリ詳細情報を取得 |

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

#### projects（取得）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | 全カラム | - |
| SELECT | project_repository_mappings | JOINで取得 | - |
| SELECT | github_repositories | JOINで取得 | - |

取得条件:
- `id = :projectId`

#### schema_file_paths（取得）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | path | スキーマファイルパス | - |
| SELECT | format | スキーマフォーマット | postgresql / schemarb / prisma 等 |

取得条件:
- `project_id = :projectId`
- `path = :schemaFilePath`

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 表示条件 |
|------------|------|-----------|---------|
| MSG-001 | エラー | FileNotFound - The specified file could not be found in the repository. | スキーマファイルが見つからない場合 |
| MSG-002 | エラー | FormatError - Record not found | schema_file_pathsにレコードがない場合 |
| MSG-003 | 指示 | Please check the file path and branch/commit reference. | ファイル未発見時の指示 |
| MSG-004 | 指示 | Please make sure that the schema file exists. | フォーマットエラー時の指示 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| パラメータバリデーションエラー | notFound()を呼び出し、404ページを表示 |
| プロジェクト情報取得失敗 | notFound()を呼び出し |
| リポジトリ情報なし | notFound()を呼び出し |
| スキーマファイルコンテンツなし | エラーオブジェクトと空スキーマを返却 |
| フォーマット情報なし | エラーオブジェクトと空スキーマを返却 |
| パースエラー | Sentryにエラー報告、エラーオブジェクトをUIに表示 |

## 備考

- サーバーコンポーネントとして実装されている
- サポートするスキーマフォーマット: postgresql, schemarb, prisma（drizzle, liamは現在UI未対応）
- Prisma WASMファイルはサーバーサイドで解決（`setPrismWasmUrl`）
- サイドバー状態とパネルレイアウトはCookieで永続化
- パースエラーはSentryに自動報告される
- TabsRootでタブ切り替えUIを提供（現在はERDタブのみ）

---

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

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

### 推奨読解順序

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

まず、プログラム間で受け渡されるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Schema型 | `frontend/packages/schema/src/schema/index.ts` | tables, enums, extensionsの構造 |

**読解のコツ**: Schema型はtables, enums, extensionsの3つのオブジェクトで構成。tablesはテーブル名をキーとしたマップ構造。

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

処理の起点となるファイル・関数を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | page.tsx | `frontend/apps/app/app/projects/[projectId]/ref/[branchOrCommit]/schema/[...schemaFilePath]/page.tsx` | キャッチオールルートとパラメータ結合 |

**主要処理フロー**:
1. **行7-11**: paramsSchemaでURLパラメータのバリデーション定義（schemaFilePathは配列）
2. **行13-15**: パラメータ検証、失敗時は404
3. **行17-18**: schemaFilePathを'/'で結合して単一パスに変換
4. **行20-26**: SchemaPageコンポーネントを呼び出し

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SchemaPage.tsx | `frontend/apps/app/components/SchemaPage/SchemaPage.tsx` | スキーマ取得とERD表示ロジック |

**主要処理フロー**:
- **行47-160**: `getERDEditorContent`関数 - スキーマ取得とパースの中核処理
- **行53-67**: プロジェクトとリポジトリマッピング情報の取得
- **行69-74**: schema_file_pathsからフォーマット情報取得
- **行88-93**: `getFileContent`でGitHubからファイル取得
- **行112-113**: `setPrismWasmUrl`と`parse`でスキーマパース
- **行173-177**: `getERDEditorContent`の呼び出し
- **行239-252**: TabsRootとERDEditorのレンダリング

#### Step 4: ERDエディタを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ErdEditor.tsx | `frontend/apps/app/components/SchemaPage/components/ERDEditor/ErdEditor.tsx` | ERDレンダリングコンポーネント |

**読解のコツ**: ERDRendererは@liam-hq/erd-coreパッケージから提供される。schema, defaultSidebarOpen, defaultPanelSizes, errorObjectsをPropsとして受け取る。

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

```
page.tsx (エントリーポイント)
    │
    └─ SchemaPage.tsx
           │
           ├─ getERDEditorContent() (サーバー関数)
           │      │
           │      ├─ createClient() (Supabase接続)
           │      │      └─ projects, schema_file_paths SELECT
           │      │
           │      ├─ getFileContent() (@liam-hq/github)
           │      │      └─ GitHub API呼び出し
           │      │
           │      └─ parse() (@liam-hq/schema/parser)
           │             └─ スキーマパース処理
           │
           ├─ cookies() (レイアウト状態取得)
           │
           └─ ERDEditor.tsx
                  └─ ERDRenderer (@liam-hq/erd-core)
```

### データフロー図

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

URLパラメータ ───▶ page.tsx ───────────────▶ SchemaPage
(projectId,        (バリデーション,
branchOrCommit,     パス結合)
schemaFilePath[])

プロジェクトID ───▶ Supabase ──────────────▶ project情報
                   (projects SELECT)       repository情報

スキーマパス ────▶ Supabase ──────────────▶ format情報
                   (schema_file_paths)

リポジトリ情報 ──▶ getFileContent ─────────▶ ファイルコンテンツ
ブランチ情報       (GitHub API)

コンテンツ ──────▶ parse ─────────────────▶ Schema オブジェクト
フォーマット       (@liam-hq/schema)

Schema ──────────▶ ERDEditor ─────────────▶ ER図表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| page.tsx | `frontend/apps/app/app/projects/[projectId]/ref/[branchOrCommit]/schema/[...schemaFilePath]/page.tsx` | ソース | ページエントリーポイント |
| SchemaPage.tsx | `frontend/apps/app/components/SchemaPage/SchemaPage.tsx` | ソース | メイン画面コンポーネント |
| ErdEditor.tsx | `frontend/apps/app/components/SchemaPage/components/ERDEditor/ErdEditor.tsx` | ソース | ERDレンダリング |
| SchemaHeader.tsx | `frontend/apps/app/components/SchemaPage/components/SchemaHeader/SchemaHeader.tsx` | ソース | スキーマヘッダー表示 |
| constants.ts | `frontend/apps/app/components/SchemaPage/constants.ts` | ソース | 定数定義（SCHEMA_TAB等） |
| SchemaPage.module.css | `frontend/apps/app/components/SchemaPage/SchemaPage.module.css` | スタイル | 画面スタイル定義 |
| parse | `frontend/packages/schema/src/parser/index.ts` | ソース | スキーマパース関数 |
| getFileContent | `frontend/packages/github/src/index.ts` | ソース | GitHubファイル取得 |
| ERDRenderer | `frontend/packages/erd-core/src/components/ERDRenderer/index.tsx` | ソース | ER図レンダリング |
