# 機能設計書 9-Prisma解析

## 概要

本ドキュメントは、Liamシステムにおける「Prisma解析」機能の設計を記述したものである。Prismaスキーマファイル（.prisma）をパースしてスキーマ情報を抽出する機能である。

### 本機能の処理概要

本機能は、@prisma/internalsライブラリのgetDMMF関数を使用してPrismaスキーマを解析し、DMMF（Data Model Meta Format）形式のデータからテーブル、カラム、制約、インデックス、列挙型等の情報をLiam内部形式（Schema型）に変換する。多対多リレーションシップの自動中間テーブル生成にも対応している。

**業務上の目的・背景**：Prismaは現代のTypeScript/JavaScript開発で広く使用されているORMであり、schema.prismaファイルはデータモデルを定義する標準的な方法である。本機能により、Prismaを使用したアプリケーションのデータベース構造を可視化できる。

**機能の利用シーン**：
- 既存Prismaアプリケーションのスキーマ可視化
- schema.prismaファイルの解析
- データベース設計レビュー
- チーム間でのスキーマ共有

**主要な処理内容**：
1. @prisma/internalsによるDMMF生成
2. モデルからテーブルへの変換
3. フィールドからカラムへの変換（型変換含む）
4. リレーションシップから外部キー制約への変換
5. 多対多リレーションの中間テーブル自動生成
6. インデックス情報の抽出
7. 列挙型の抽出

**関連システム・外部連携**：@prisma/internals（Prisma公式内部ライブラリ）を使用。

**権限による制御**：解析自体に認証は不要。解析結果の表示は認証状態に依存。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | スキーマ画面 | 主画面 | Prismaスキーマファイルのパース処理 |
| 20 | 公開ERD画面 | 主画面 | Prismaスキーマファイルのパース処理 |

## 機能種別

データ変換 / パース処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| str | string | Yes | schema.prismaファイル内容 | - |

### 入力データソース

- prisma/schema.prisma ファイル
- マルチファイルPrismaスキーマ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| value | Schema | パース結果のスキーマ |
| errors | ProcessError[] | パース中に発生したエラー/警告 |

### 出力先

スキーマストア / ER図表示機能

## 処理フロー

### 処理シーケンス

```
1. スキーマ受信
   └─ Prismaスキーマ文字列を受け取る
2. DMMF生成
   └─ getDMMFでDMMF形式に変換
3. フィールドリネーミングマップ構築
   └─ @mapアノテーションによるカラム名変換を準備
4. テーブル処理
   └─ processTablesでモデルをテーブルに変換
5. 列挙型処理
   └─ processEnumsでenum定義を変換
6. 制約処理
   └─ processConstraintsで外部キー等を追加
7. インデックス処理
   └─ processIndexesでインデックスを追加
8. 多対多リレーション処理
   └─ processManyToManyRelationshipsで中間テーブル生成
9. 結果返却
   └─ ProcessResult形式で返却
```

### フローチャート

```mermaid
flowchart TD
    A[schema.prisma入力] --> B[getDMMF]
    B --> C[DMMF生成]
    C --> D[buildFieldRenamingMap]
    D --> E[processTables]
    E --> F[processEnums]
    F --> G[processConstraints]
    G --> H[processIndexes]
    H --> I{多対多リレーション?}
    I -->|Yes| J[processManyToManyRelationships]
    I -->|No| K[Schema構築]
    J --> K
    K --> L[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | フィールドリネーミング | @map/@dbアノテーションでDBカラム名を変換 | field.dbNameが存在時 |
| BR-002 | 型変換 | PrismaスカラータイプをPostgreSQL型に変換 | convertToPostgresColumnType |
| BR-003 | autoincrement処理 | Int→serial、BigInt→bigserial等 | @default(autoincrement())時 |
| BR-004 | 多対多中間テーブル | _ModelAToModelB形式で自動生成 | isList && 空のrelationFields時 |
| BR-005 | 外部キーアクション | Cascade→CASCADE等に変換 | normalizeConstraintName |

### 計算ロジック

Prismaスカラー型の変換:
- String → text
- Boolean → boolean
- Int → integer
- BigInt → bigint
- Float → double precision
- DateTime → timestamp(3)
- Json → jsonb
- Decimal → decimal(65,30)
- Bytes → bytea

参照アクションの変換:
- Cascade → CASCADE
- Restrict → RESTRICT
- SetNull → SET_NULL
- SetDefault → SET_DEFAULT
- その他 → NO_ACTION

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

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

本機能はデータベースを直接操作しない。パース処理のみ。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| DMMF_ERROR | DMMF生成エラー | Prismaスキーマ構文エラー | getDMMFがスローする例外をキャッチ |
| TYPE_CONVERSION_ERROR | 型変換エラー | 未知のPrisma型 | デフォルトでそのまま返却 |

### リトライ仕様

なし（再パースで対応）

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

該当なし（メモリ内処理）

## パフォーマンス要件

- 大規模Prismaスキーマ（数百モデル）でも高速処理
- getDMMFの内部パフォーマンスに依存

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

- Prismaコードの実行は行わない（パースのみ）
- 機密情報を含むスキーマは認証後のみ処理

## 備考

@prisma/internalsはPrisma公式の内部ライブラリであり、DMMF形式でスキーマメタデータを提供する。CommonJSモジュールのインポートにはワークアラウンドが必要。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `frontend/packages/schema/src/parser/prisma/index.ts` | processor関数のエクスポート |
| 1-2 | parser.ts | `frontend/packages/schema/src/parser/prisma/parser.ts` | メイン処理ロジック |

**主要処理フロー**:
1. **492-546行目**: parsePrismaSchema関数、DMMF取得と各処理の呼び出し
2. **895行目**: processor関数のエクスポート

#### Step 2: テーブル処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | parser.ts processTables | `frontend/packages/schema/src/parser/prisma/parser.ts` | モデル→テーブル変換 |
| 2-2 | parser.ts processModel | `frontend/packages/schema/src/parser/prisma/parser.ts` | 個別モデル処理 |
| 2-3 | parser.ts processModelField | `frontend/packages/schema/src/parser/prisma/parser.ts` | フィールド→カラム変換 |

**主要処理フロー**:
- **217-228行目**: processTables - 全モデルの処理
- **182-212行目**: processModel - 個別モデルのテーブル化
- **90-177行目**: processModelField - フィールドの変換

#### Step 3: リレーションと制約を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | parser.ts processConstraints | `frontend/packages/schema/src/parser/prisma/parser.ts` | 外部キー制約処理 |
| 3-2 | parser.ts processRelationshipField | `frontend/packages/schema/src/parser/prisma/parser.ts` | リレーション解析 |
| 3-3 | parser.ts processManyToManyRelationships | `frontend/packages/schema/src/parser/prisma/parser.ts` | 多対多中間テーブル |

**主要処理フロー**:
- **343-366行目**: processConstraints - 全モデルの制約処理
- **244-287行目**: processRelationshipField - 外部キー生成
- **405-461行目**: processManyToManyRelationships - 中間テーブル生成

#### Step 4: 型変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | convertToPostgresColumnType.ts | `frontend/packages/schema/src/parser/prisma/convertToPostgresColumnType.ts` | 型変換ロジック |

**主要処理フロー**:
- **45-68行目**: mapPrismaTypeToPostgres - Prisma→PostgreSQL型マッピング
- **71-97行目**: convertToPostgresColumnType - メイン変換関数

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

```
processor
    │
    └─ parsePrismaSchema
           │
           ├─ getDMMF (@prisma/internals)
           │
           ├─ buildFieldRenamingMap
           │
           ├─ processTables
           │      │
           │      └─ processModel
           │             └─ processModelField
           │                    ├─ extractDefaultValue
           │                    └─ convertToPostgresColumnType
           │
           ├─ processEnums
           │
           ├─ processConstraints
           │      │
           │      └─ processModelConstraints
           │             ├─ detectAndStoreManyToManyRelation
           │             └─ processRelationshipField
           │                    └─ normalizeConstraintName
           │
           ├─ processIndexes
           │      └─ extractIndex
           │
           └─ processManyToManyRelationships
                  ├─ getPrimaryKeyInfo
                  └─ createManyToManyJoinTableWithConstraints
```

### データフロー図

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

schema.prisma ──────▶ getDMMF ─────────────▶ DMMF
                           │
                           ▼
DMMF.datamodel.models ──▶ processTables ────▶ tables{}
                           │
                           ├─▶ model → Table
                           └─▶ field → Column
                                   │
                                   └─▶ convertToPostgresColumnType

DMMF.datamodel.enums ───▶ processEnums ─────▶ enums{}

models + tables ────────▶ processConstraints ▶ constraints{}
                           │
                           └─▶ relationName → ForeignKeyConstraint

DMMF.datamodel.indexes ─▶ processIndexes ───▶ indexes{}

manyToManyRelations ────▶ processManyToManyRelationships ─▶ join tables
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| parser.ts | `frontend/packages/schema/src/parser/prisma/parser.ts` | ソース | メインパーサー |
| index.ts | `frontend/packages/schema/src/parser/prisma/index.ts` | ソース | エクスポート |
| convertToPostgresColumnType.ts | `frontend/packages/schema/src/parser/prisma/convertToPostgresColumnType.ts` | ソース | 型変換 |
