# 機能設計書 14-PostgreSQL DDL生成

## 概要

本ドキュメントは、Liam ERDの内部スキーマ形式からPostgreSQL DDL（CREATE TABLE、ALTER TABLE等）を生成する「PostgreSQL DDL生成」機能の設計を記述する。

### 本機能の処理概要

**業務上の目的・背景**：AIエージェントによるスキーマ設計の結果を、実際にPostgreSQLデータベースに適用可能なDDL文として出力する。これにより、設計からデータベース構築までのワークフローをシームレスにつなげることができる。

**機能の利用シーン**：
- デザインセッションで設計したスキーマをDDLとして出力
- スキーマのバージョン管理用にDDLをファイルとして保存
- 開発環境・テスト環境へのスキーマ適用

**主要な処理内容**：
1. CREATE EXTENSION文の生成（拡張機能）
2. CREATE TYPE AS ENUM文の生成（列挙型）
3. CREATE TABLE文の生成（テーブル定義）
4. CREATE INDEX文の生成（インデックス）
5. ALTER TABLE ADD CONSTRAINT文の生成（制約）

**関連システム・外部連携**：
- DB Agentサブグラフ（No.19）でスキーマ変更のDDL出力に使用
- マイグレーション操作生成（No.13）と連携して差分DDLを生成

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面からの直接利用なし（AIエージェント内部で使用） |

## 機能種別

コード生成処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| schema | Schema | Yes | Liam ERDの内部スキーマオブジェクト | Schema型に準拠 |

### 入力データソース

- メモリ上のSchemaオブジェクト（tables, enums, extensionsを含む）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| value | string | 生成されたDDL文字列 |
| errors | { message: string }[] | 生成中に発生したエラーの配列 |

### 出力先

LegacySchemaDeparser型の戻り値として返却される。

## 処理フロー

### 処理シーケンス

```
1. 拡張機能のDDL生成
   └─ 各extensionについてCREATE EXTENSION文を生成
2. ENUM型のDDL生成
   └─ 各enumについてCREATE TYPE ... AS ENUM文を生成
3. テーブルのDDL生成
   └─ 各tableについてCREATE TABLE文を生成（カラム定義含む）
4. インデックスのDDL生成
   └─ 各tableの各indexについてCREATE INDEX文を生成
5. 制約のDDL生成
   └─ 各tableの各constraintについてALTER TABLE ADD CONSTRAINT文を生成
6. 外部キー制約の後処理
   └─ FOREIGN KEY制約を最後に追加（参照先テーブルの存在を保証）
7. DDL文字列の結合
   └─ 全てのDDL文を改行で結合して返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[CREATE EXTENSION生成]
    B --> C[CREATE TYPE AS ENUM生成]
    C --> D[CREATE TABLE生成]
    D --> E[CREATE INDEX生成]
    E --> F[ADD CONSTRAINT生成]
    F --> G{FOREIGN KEY?}
    G -->|Yes| H[後処理用リストに追加]
    G -->|No| I[即座に追加]
    H --> J{次の制約あり?}
    I --> J
    J -->|Yes| F
    J -->|No| K[FOREIGN KEY制約を追加]
    K --> L[DDL文字列を結合]
    L --> M[結果を返却]
    M --> N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 拡張機能優先 | CREATE EXTENSIONは他のDDLより先に出力 | 常に適用 |
| BR-02 | ENUM型優先 | CREATE TYPE AS ENUMはCREATE TABLEより先に出力 | 常に適用 |
| BR-03 | 外部キー後処理 | FOREIGN KEY制約は最後に出力（参照整合性のため） | 常に適用 |
| BR-04 | IF NOT EXISTS使用 | CREATE EXTENSION/TABLEにIF NOT EXISTSを付与 | 常に適用 |

### DDL生成パターン

#### CREATE TABLE文
```sql
CREATE TABLE IF NOT EXISTS "{table_name}" (
  "{column_name}" {type} {NOT NULL} {DEFAULT value}
);
```

#### CREATE INDEX文
```sql
CREATE {UNIQUE} INDEX "{index_name}" ON "{table_name}" ({columns});
```

#### ALTER TABLE ADD CONSTRAINT文
```sql
ALTER TABLE "{table_name}" ADD CONSTRAINT "{constraint_name}"
  PRIMARY KEY ({columns});
-- or
ALTER TABLE "{table_name}" ADD CONSTRAINT "{constraint_name}"
  FOREIGN KEY ({columns}) REFERENCES "{ref_table}" ({ref_columns})
  ON UPDATE {action} ON DELETE {action};
```

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

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

本機能はDDL文字列を生成するのみで、データベースを直接操作しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 生成エラー | 不正なスキーマ構造 | errorsに追加して処理を継続 |

### リトライ仕様

リトライ不要（同期的な文字列生成処理のため）

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

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

## パフォーマンス要件

- 処理時間：100テーブル規模のスキーマで50ミリ秒以内

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

- SQLインジェクション対策：識別子は常にダブルクォートでエスケープ
- 機密情報の除外：コメント以外のユーザー入力値はスキーマ構造内に含まれない

## 備考

- LegacySchemaDeparser型を使用（将来的にResult型への移行予定）
- utils.tsに各種DDL生成ヘルパー関数が定義されている

---

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

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

### 推奨読解順序

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

まず、入出力の型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | type.ts | `frontend/packages/schema/src/deparser/type.ts` | LegacySchemaDeparser型とSchemaDeparser型の定義 |
| 1-2 | schema/index.ts | `frontend/packages/schema/src/schema/index.ts` | Schema, Table, Column等の入力型定義 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `frontend/packages/schema/src/deparser/postgresql/index.ts` | postgresqlSchemaDeparsrのエクスポート |

#### Step 3: DDL生成ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | schemaDeparser.ts | `frontend/packages/schema/src/deparser/postgresql/schemaDeparser.ts` | メインのDDL生成ロジック |
| 3-2 | utils.ts | `frontend/packages/schema/src/deparser/postgresql/utils.ts` | DDL生成ヘルパー関数 |

**主要処理フロー（schemaDeparser.ts）**:
- **22-88行目**: postgresqlSchemaDeparser関数 - メインロジック
- **29-34行目**: CREATE EXTENSION文の生成
- **37-40行目**: CREATE TYPE AS ENUM文の生成
- **43-46行目**: CREATE TABLE文の生成
- **49-55行目**: CREATE INDEX文の生成
- **61-75行目**: ADD CONSTRAINT文の生成（FK制約は分離）
- **79行目**: 外部キー制約を最後に追加
- **82行目**: DDL文字列の結合

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

```
postgresqlSchemaDeparser(schema)
    │
    ├─ generateCreateExtensionStatement(extension) [utils.ts]
    │
    ├─ generateCreateEnumStatement(enum) [utils.ts]
    │
    ├─ generateCreateTableStatement(table) [utils.ts]
    │      └─ generateColumnDefinition(column)
    │
    ├─ generateCreateIndexStatement(tableName, index) [utils.ts]
    │
    └─ generateAddConstraintStatement(tableName, constraint) [utils.ts]
           ├─ PRIMARY KEY
           ├─ UNIQUE
           ├─ FOREIGN KEY
           └─ CHECK
```

### データフロー図

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

Schema ──┬──▶ extensions ──▶ CREATE EXTENSION ──┐
         │                                      │
         ├──▶ enums ──▶ CREATE TYPE AS ENUM ────┼──▶ DDL文字列
         │                                      │
         ├──▶ tables ──▶ CREATE TABLE ──────────┤
         │         │                            │
         │         ├──▶ indexes ──▶ CREATE INDEX
         │         │                            │
         │         └──▶ constraints ──▶ ALTER TABLE ADD CONSTRAINT
         │                                      │
         └──────────────────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| schemaDeparser.ts | `frontend/packages/schema/src/deparser/postgresql/schemaDeparser.ts` | ソース | メインのDDL生成ロジック |
| utils.ts | `frontend/packages/schema/src/deparser/postgresql/utils.ts` | ソース | DDL生成ヘルパー関数 |
| index.ts | `frontend/packages/schema/src/deparser/postgresql/index.ts` | ソース | エクスポート定義 |
| type.ts | `frontend/packages/schema/src/deparser/type.ts` | ソース | Deparser型定義 |
| schemaDeparser.test.ts | `frontend/packages/schema/src/deparser/postgresql/schemaDeparser.test.ts` | テスト | DDL生成の単体テスト |
| migrationOperationDeparser.ts | `frontend/packages/schema/src/deparser/postgresql/migrationOperationDeparser.ts` | ソース | マイグレーション操作のDDL生成 |
| schemaDiffDeparser.ts | `frontend/packages/schema/src/deparser/postgresql/schemaDiffDeparser.ts` | ソース | スキーマ差分のDDL生成 |
