# 画面設計書 20-公開ERD画面

## 概要

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

### 本画面の処理概要

この画面では、外部URLからスキーマファイルを取得し、ER図（Entity-Relationship Diagram）として表示する。認証不要でアクセス可能な公開画面である。

**業務上の目的・背景**：
データベーススキーマの可視化ツールとして、GitHubなどの外部リポジトリに格納されたスキーマファイルをER図として表示する。これにより、開発者やDBアーキテクトがスキーマ構造を直感的に理解し、チーム間で共有できる。OSSプロジェクトや公開リポジトリのスキーマを誰でも閲覧可能にする。

**画面へのアクセス方法**：
- 外部URLをエンコードしてアクセス（例: `/erd/p/github.com/user/repo/blob/main/schema.sql`）
- GitHubのファイルURLまたはフォルダURLに対応
- URLパターンは `/erd/p/[...slug]`

**主要な操作・処理内容**：
1. 外部URL（GitHub等）からスキーマファイルを取得
2. スキーマフォーマットの自動検出（またはクエリパラメータで指定）
3. スキーマファイルのパース（PostgreSQL / Rails schema.rb / Prisma / tbls等）
4. ER図としてのビジュアル表示
5. サイドバーでのテーブル一覧表示
6. OGメタデータの動的生成

**画面遷移**：
- 遷移元: 外部リンク、直接URL入力
- 遷移先: なし（単独ビューア）

**権限による表示制御**：
認証不要でアクセス可能。公開リポジトリのスキーマファイルのみ取得可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | ER図表示 | 主機能 | 外部URLからスキーマを取得しER図を表示 |
| 2 | テーブルノード表示 | 補助機能 | テーブル情報をノードとして表示 |
| 3 | リレーションシップエッジ表示 | 補助機能 | テーブル間の外部キー関係をエッジとして表示 |
| 4 | 自動レイアウト | 補助機能 | ELKアルゴリズムによるER図の自動配置 |
| 12 | フォーマット自動検出 | 補助機能 | 入力ファイルの形式を自動検出 |
| 7 | PostgreSQL解析 | 補助機能 | PostgreSQL DDLのパース処理 |
| 8 | Ruby on Rails schema.rb解析 | 補助機能 | Rails schema.rbファイルのパース処理 |
| 9 | Prisma解析 | 補助機能 | Prismaスキーマファイルのパース処理 |
| 11 | tbls解析 | 補助機能 | tblsのschema.json形式のパース処理 |

## 画面種別

ビューア（公開）

## URL/ルーティング

```
/erd/p/[...slug]
```

動的パラメータ:
- `slug`: 外部URLパス（キャッチオールルート）

クエリパラメータ:
- `format`: スキーマフォーマット（オプション、postgresql / schemarb / prisma / tbls等）

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| slug | string[] | Yes | URLパラメータ - 外部URLパス（配列形式） |
| format | SupportedFormat | No | クエリパラメータ - スキーマフォーマット |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| schema | Schema | パースされたスキーマオブジェクト |
| errorObjects | ErrorObject[] | エラー情報 |
| defaultSidebarOpen | boolean | サイドバーの初期表示状態 |
| defaultPanelSizes | number[] | パネルサイズの初期値 |

## 表示項目

### ERDビューア

| 項目名 | 型 | 説明 |
|--------|-----|------|
| tables | object | テーブル定義のマップ |
| enums | object | Enum定義のマップ |
| extensions | object | 拡張機能の定義 |
| errorObjects | ErrorObject[] | エラー情報（表示用） |

### サイドバー

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

### OGメタデータ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| title | string | "{プロジェクト名} - Liam ERD" |
| description | string | "Generate ER diagrams effortlessly..." |
| openGraph.url | string | 公開URL |
| openGraph.images | string | OG画像パス |

## イベント仕様

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

画面表示時に外部URLからスキーマファイルを取得する。

**処理フロー**:
1. URLパラメータからパスを結合（`https://` + joinedPath）
2. GitHubフォルダURLかどうかを判定（`isGitHubFolderUrl`）
3. フォルダの場合: `handleGitHubFolderUrl`で複数ファイル取得
4. ファイルの場合: `handleSingleFileUrl`で単一ファイル取得
5. GitHub URLをraw.githubusercontent.comに変換
6. fetchでコンテンツ取得

### 2-フォーマット検出

スキーマファイルのフォーマットを検出する。

**処理フロー**:
1. クエリパラメータ`format`をチェック
2. 指定がなければ`detectFormat`で自動検出
3. GitHubフォルダの場合はファイル名から検出
4. 検出失敗時はエラー表示

### 3-スキーマパース

取得したコンテンツをパースする。

**処理フロー**:
1. `setPrismWasmUrl`でWASMファイルパス設定
2. `parse`関数でスキーマをパース
3. エラーがあればSentryに報告
4. パース結果をERDViewerに渡す

### 4-OGメタデータ生成

`generateMetadata`関数でOGメタデータを動的生成する。

**処理フロー**:
1. 外部URLのHTMLを取得
2. og:titleまたはtitleタグからプロジェクト名を抽出
3. メタデータオブジェクトを構築

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | データベースアクセスなし（外部URLのみ参照） |

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 表示条件 |
|------------|------|-----------|---------|
| MSG-001 | エラー | Our signal's lost in the void! No access at this time.. | 外部URLにアクセスできない場合 |
| MSG-002 | 指示 | Double-check the transmission link {url} and initiate contact again. | URLアクセスエラー時 |
| MSG-003 | 指示 | Please specify the format in the URL query parameter `format` | フォーマット検出失敗時 |
| MSG-004 | エラー | NetworkError | ネットワークエラー発生時 |
| MSG-005 | エラー | No schema files found in the specified folder | フォルダ内にスキーマファイルがない場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| パラメータバリデーションエラー | notFound()を呼び出し、404ページを表示 |
| URL解析失敗 | エラーオブジェクトと空スキーマをERDViewerに渡す |
| ネットワークエラー | エラーメッセージを表示、指示を付与 |
| フォーマット検出失敗 | フォーマット指定の指示メッセージを表示 |
| パースエラー | Sentryにエラー報告、エラーオブジェクトをUIに表示 |
| GitHubフォルダ取得エラー | エラーメッセージと指示を表示 |

## 備考

- サーバーコンポーネントとクライアントコンポーネントのハイブリッド実装
- ERDViewerはクライアントコンポーネント（'use client'）
- サポートするスキーマフォーマット: postgresql, schemarb, prisma, tbls等
- GitHubの単一ファイルURL（/blob/）とフォルダURL（/tree/）の両方に対応
- GitHubフォルダの場合はセキュリティ制限あり（最大深度5、最大ファイル数100等）
- Prisma WASMファイルはサーバーサイドで解決（`setPrismWasmUrl`）
- サイドバー状態とパネルレイアウトはCookieで永続化
- パースエラーはSentryに自動報告
- CookieConsentを表示（iframe内でない場合のみ）
- VersionProviderでバージョン情報を提供

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Schema型 | `frontend/packages/schema/src/schema/index.ts` | tables, enums, extensionsの構造 |
| 1-2 | SupportedFormat | `frontend/packages/schema/src/parser/index.ts` | サポートするフォーマット一覧 |

**読解のコツ**: Schema型はtables, enums, extensionsの3つのオブジェクトで構成。SupportedFormatはpostgresql, schemarb, prisma等のリテラル型。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | page.tsx | `frontend/apps/app/app/erd/p/[...slug]/page.tsx` | メイン処理ロジック |

**主要処理フロー**:
1. **行22-27**: paramsSchema, searchParamsSchemaでバリデーション定義
2. **行29-43**: resolveContentUrl - GitHub URLをraw URLに変換
3. **行46-72**: handleGitHubFolderUrl - フォルダURLからスキーマ取得
4. **行75-124**: handleSingleFileUrl - 単一ファイル取得
5. **行127-156**: determineSchemaFormat - フォーマット決定
6. **行159-183**: renderErrorView - エラー表示
7. **行185-222**: generateMetadata - OGメタデータ生成
8. **行224-302**: Page関数 - メインレンダリング

#### Step 3: GitHub URL処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | githubUrlHandler.ts | `frontend/apps/app/app/erd/p/[...slug]/utils/githubUrlHandler.ts` | GitHubフォルダ処理 |

**主要処理フロー**:
- **行11-18**: SECURITY_LIMITS - セキュリティ制限定数
- **行38-44**: isGitHubFolderUrl - /tree/を含むか判定
- **行46-110**: isSchemaFile - スキーマファイル判定
- **行112-188**: parseGitHubFolderUrl - URL解析とブランチ検出
- **行309-339**: collectSchemaFilesFromFolder - 再帰的ファイル収集
- **行385-424**: fetchSchemaFromGitHubFolder - フォルダからスキーマ取得

#### Step 4: ERDビューアを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | erdViewer.tsx | `frontend/apps/app/app/erd/p/[...slug]/erdViewer.tsx` | クライアントサイドビューア |

**主要処理フロー**:
- **行29-33**: isShowCookieConsentの判定（iframe内かどうか）
- **行35-42**: versionDataの構築
- **行44-58**: VersionProvider, ErdRendererProvider, ERDRendererの階層

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

```
page.tsx (エントリーポイント)
    │
    ├─ generateMetadata() (OGメタデータ生成)
    │      └─ fetch外部URL → cheerioでHTML解析
    │
    ├─ URL処理分岐
    │      ├─ isGitHubFolderUrl() 判定
    │      │      └─ handleGitHubFolderUrl()
    │      │             └─ fetchSchemaFromGitHubFolder()
    │      │                    ├─ parseGitHubFolderUrl()
    │      │                    ├─ collectSchemaFilesFromFolder()
    │      │                    └─ downloadAndCombineFiles()
    │      │
    │      └─ handleSingleFileUrl()
    │             └─ resolveContentUrl() + fetch()
    │
    ├─ determineSchemaFormat()
    │      └─ detectFormat() (@liam-hq/schema)
    │
    ├─ parse() (@liam-hq/schema)
    │      └─ スキーマパース処理
    │
    └─ ERDViewer.tsx (クライアントコンポーネント)
           ├─ VersionProvider
           ├─ ErdRendererProvider
           └─ ERDRenderer (@liam-hq/erd-core)
```

### データフロー図

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

URLパラメータ ───▶ page.tsx ───────────────▶ joinedPath
(slug[])           (結合処理)                  (https:// + path)

URL ─────────────▶ isGitHubFolderUrl ──────▶ true/false
                   (/tree/ 判定)

フォルダURL ─────▶ handleGitHubFolderUrl ──▶ content + format
                   (複数ファイル取得)

ファイルURL ─────▶ handleSingleFileUrl ────▶ content
                   (単一ファイル取得)

content ─────────▶ determineSchemaFormat ──▶ format
                   (フォーマット検出)

content + format ▶ parse ─────────────────▶ Schema + errors
                   (@liam-hq/schema)

Schema ──────────▶ ERDViewer ─────────────▶ ER図表示
                   (クライアント)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| page.tsx | `frontend/apps/app/app/erd/p/[...slug]/page.tsx` | ソース | ページエントリーポイント |
| erdViewer.tsx | `frontend/apps/app/app/erd/p/[...slug]/erdViewer.tsx` | ソース | ERDビューアクライアントコンポーネント |
| githubUrlHandler.ts | `frontend/apps/app/app/erd/p/[...slug]/utils/githubUrlHandler.ts` | ソース | GitHubフォルダ処理ユーティリティ |
| parse | `frontend/packages/schema/src/parser/index.ts` | ソース | スキーマパース関数 |
| detectFormat | `frontend/packages/schema/src/parser/index.ts` | ソース | フォーマット検出関数 |
| ERDRenderer | `frontend/packages/erd-core/src/components/ERDRenderer/index.tsx` | ソース | ER図レンダリング |
| CookieConsent | `frontend/apps/app/components/CookieConsent/CookieConsent.tsx` | ソース | Cookie同意コンポーネント |
