# 機能設計書 11-tbls解析

## 概要

本ドキュメントは、tblsツールが出力するschema.json形式のファイルをパースし、Liam ERDの内部スキーマ形式に変換する「tbls解析」機能の設計を記述する。

### 本機能の処理概要

**業務上の目的・背景**：tblsは様々なデータベース（MySQL、SQLite、BigQuery等）からスキーマ情報を抽出し、ドキュメント化するOSSツールである。PostgreSQL DDLを直接出力できないデータベースでもtblsを経由することでLiam ERDでのER図可視化が可能となり、対応データベースの拡張性を大幅に向上させる。

**機能の利用シーン**：MySQL、SQLite、BigQueryなど、PostgreSQL以外のデータベースを使用しているプロジェクトにおいて、tblsで出力したschema.jsonファイルをLiam ERDに読み込ませてER図を生成する場面で利用される。

**主要な処理内容**：
1. 入力されたJSON文字列をパースしてJavaScriptオブジェクトに変換
2. ValibotスキーマによるJSON構造のバリデーション
3. テーブル情報（名前、カラム、制約、インデックス）の抽出と変換
4. 外部キー制約からのリレーションシップ情報の抽出
5. ENUM型情報の抽出と変換
6. Liam ERD内部Schema形式への統合

**関連システム・外部連携**：tblsツール（https://github.com/k1LoW/tbls）が出力するschema.json形式のファイルを入力として受け取る。

**権限による制御**：本機能は認証・認可を必要としないライブラリ機能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | 公開ERD画面 | 補助機能 | tblsのschema.json形式のパース処理 |

## 機能種別

データ変換処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| schemaString | string | Yes | tblsが出力したschema.jsonの内容を文字列として渡す | JSON形式であること、tblsスキーマに準拠していること |

### 入力データソース

- ファイル入力：tblsが生成したschema.jsonファイル
- CLI経由：`npx @liam-hq/cli erd build --input schema.json --format tbls`
- Web UI経由：公開ERD画面でのURL指定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| value.tables | Tables | テーブル定義のマップ（キー：テーブル名） |
| value.enums | Enums | ENUM型定義のマップ（キー：ENUM名） |
| value.extensions | Extensions | 拡張機能定義（空オブジェクト） |
| errors | Error[] | パース中に発生したエラーの配列 |

### 出力先

メモリ上のProcessResult型オブジェクトとして返却される。

## 処理フロー

### 処理シーケンス

```
1. JSON文字列のパース
   └─ JSON.parseでJavaScriptオブジェクトに変換
2. Valibotスキーマによるバリデーション
   └─ schema.generated.jsで定義されたスキーマで検証
3. テーブル情報の処理
   └─ 各テーブルについてprocessTable関数を呼び出し
4. カラム情報の変換
   └─ processColumns関数でカラム定義を内部形式に変換
5. 制約情報の変換
   └─ processConstraints関数でPK/FK/UNIQUE/CHECK制約を変換
6. インデックス情報の変換
   └─ processIndexes関数でインデックス定義を変換
7. ENUM情報の処理
   └─ processEnums関数でENUM型を内部形式に変換
8. 結果オブジェクトの構築
   └─ ProcessResult形式で返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[JSON.parseでパース]
    B --> C{パース成功?}
    C -->|No| D[エラー返却]
    C -->|Yes| E[Valibotスキーマ検証]
    E --> F{検証成功?}
    F -->|No| G[バリデーションエラー返却]
    F -->|Yes| H[テーブル情報の処理]
    H --> I[カラム・制約・インデックス変換]
    I --> J[ENUM情報の処理]
    J --> K[ProcessResult構築]
    K --> L[終了]
    D --> L
    G --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 外部キーアクション正規化 | ON UPDATE/ON DELETEのアクションをNO_ACTION/CASCADE/RESTRICT/SET_NULL/SET_DEFAULTに正規化 | FOREIGN KEY制約処理時 |
| BR-02 | デフォルト値の型変換 | 文字列のデフォルト値を数値・真偽値に適切に変換 | カラムdefault値処理時 |
| BR-03 | ENUM名のスキーマ除去 | "schema.enum_name"形式の場合、スキーマ部分を除去 | ENUM処理時 |
| BR-04 | インデックス一意性判定 | defフィールドに"unique"が含まれる場合、uniqueをtrueに設定 | インデックス処理時 |

### 計算ロジック

外部キー制約のON UPDATE/ON DELETEアクションは、制約定義文字列からの正規表現マッチングで抽出：
- パターン: `ON UPDATE (SET NULL|SET DEFAULT|RESTRICT|CASCADE|NO ACTION)`
- パターン: `ON DELETE (SET NULL|SET DEFAULT|RESTRICT|CASCADE|NO ACTION)`

## データベース操作仕様

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

本機能はデータベースを操作しない（純粋な変換処理）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | JSONパースエラー | 入力文字列が不正なJSON形式 | エラーをerrorsに格納し空のスキーマを返却 |
| - | スキーマ検証エラー | tblsスキーマ形式に準拠していない | エラー詳細をerrorsに格納し空のスキーマを返却 |

### リトライ仕様

リトライ不要（同期的な変換処理のため）

## トランザクション仕様

該当なし（データベース操作を行わない）

## パフォーマンス要件

- 処理時間：1000テーブル程度のスキーマでも1秒以内で処理完了
- メモリ使用量：入力JSONサイズの2-3倍程度

## セキュリティ考慮事項

- 入力JSONのサイズ制限を設けることで、DoS攻撃を防止
- JSON.parseによる安全なパース処理

## 備考

- tblsバージョンによってschema.json形式に差異がある可能性があるため、スキーマ定義は緩めに設計
- schema.generated.jsはtblsのJSONスキーマからzodへの自動変換スクリプトで生成

---

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

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

### 推奨読解順序

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

まず、tblsスキーマ形式と出力形式のデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | schema.generated.js | `frontend/packages/schema/src/parser/tbls/schema.generated.js` | tblsのJSONスキーマをValibotで定義した入力形式 |
| 1-2 | schema/index.ts | `frontend/packages/schema/src/schema/index.ts` | Tables, Columns, Constraints等の出力型定義 |

**読解のコツ**: ValibotはZodに類似したバリデーションライブラリ。v.object(), v.array()などの構文に慣れておくとよい。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `frontend/packages/schema/src/parser/tbls/index.ts` | processorのエクスポート |
| 2-2 | parser/index.ts | `frontend/packages/schema/src/parser/index.ts` | parse関数でformat='tbls'の場合のルーティング |

**主要処理フロー**:
1. **33-35行目**: format='tbls'の場合、tbls/index.jsからprocessorをインポートして実行

#### Step 3: パーサー実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | parser.ts | `frontend/packages/schema/src/parser/tbls/parser.ts` | メインのパース処理実装 |

**主要処理フロー**:
- **368-433行目**: parseTblsSchema関数 - メインのパースエントリーポイント
- **65-89行目**: processColumns関数 - カラム情報の変換
- **217-256行目**: processConstraints関数 - 制約情報の変換
- **261-286行目**: processIndexes関数 - インデックス情報の変換
- **336-363行目**: processEnums関数 - ENUM情報の変換
- **15-43行目**: extractForeignKeyActions関数 - FK制約のON UPDATE/DELETE抽出

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

```
parse(str, 'tbls')
    │
    └─ processor(str) [parser.ts:458]
           │
           └─ parseTblsSchema(schemaString) [parser.ts:368]
                  │
                  ├─ JSON.parse(schemaString)
                  │
                  ├─ schema.safeParse(parsedSchema)
                  │
                  ├─ processTable(tblsTable) [parser.ts:291]
                  │      │
                  │      ├─ processColumns(columns) [parser.ts:65]
                  │      │
                  │      ├─ processConstraints(constraints) [parser.ts:217]
                  │      │      │
                  │      │      ├─ processPrimaryKeyConstraint() [parser.ts:94]
                  │      │      ├─ processForeignKeyConstraint() [parser.ts:123]
                  │      │      │      └─ extractForeignKeyActions() [parser.ts:15]
                  │      │      ├─ processUniqueConstraint() [parser.ts:163]
                  │      │      └─ processCheckConstraint() [parser.ts:192]
                  │      │
                  │      └─ processIndexes(indexes) [parser.ts:261]
                  │
                  └─ processEnums(enums) [parser.ts:336]
```

### データフロー図

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

schema.json ───▶ JSON.parse ───▶ JavaScript Object
     │
     ├───────▶ schema.safeParse ───▶ バリデーション済みデータ
     │                                    │
     │                                    ├─▶ processTable ───▶ Tables{}
     │                                    │
     │                                    └─▶ processEnums ───▶ Enums{}
     │
     └─────────────────────────────────────▶ ProcessResult {
                                                 value: { tables, enums, extensions },
                                                 errors: []
                                             }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| parser.ts | `frontend/packages/schema/src/parser/tbls/parser.ts` | ソース | tbls形式のメインパーサー実装 |
| index.ts | `frontend/packages/schema/src/parser/tbls/index.ts` | ソース | processorのエクスポート |
| schema.generated.js | `frontend/packages/schema/src/parser/tbls/schema.generated.js` | 生成ファイル | tblsスキーマのValibot定義 |
| schema.generated.test.ts | `frontend/packages/schema/src/parser/tbls/schema.generated.test.ts` | テスト | 生成スキーマのテスト |
| index.test.ts | `frontend/packages/schema/src/parser/tbls/index.test.ts` | テスト | パーサーの単体テスト |
| types.ts | `frontend/packages/schema/src/parser/types.ts` | ソース | Processor, ProcessResult型定義 |
| schema/index.ts | `frontend/packages/schema/src/schema/index.ts` | ソース | Tables, Columns等の出力型定義 |
| input/mysql/schema.json | `frontend/packages/schema/src/parser/tbls/input/mysql/schema.json` | テストデータ | MySQLサンプルスキーマ |
| input/sqlite/schema.json | `frontend/packages/schema/src/parser/tbls/input/sqlite/schema.json` | テストデータ | SQLiteサンプルスキーマ |
