# 機能設計書 8-Ruby on Rails schema.rb解析

## 概要

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

### 本機能の処理概要

本機能は、@ruby/prismライブラリを使用してRubyコード（schema.rb）を構文解析し、ActiveRecordのスキーマ定義からテーブル、カラム、制約、インデックス等の情報をLiam内部形式（Schema型）に変換する。Visitorパターンを使用してAST（抽象構文木）を走査する。

**業務上の目的・背景**：Ruby on Railsは広く使用されているWebフレームワークであり、schema.rbはマイグレーション実行後のデータベース構造を記録する標準的なファイルである。本機能により、Railsアプリケーションのデータベース構造を可視化できる。

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

**主要な処理内容**：
1. @ruby/prismによるRuby構文解析
2. SchemaFinderクラスによるAST走査
3. create_table、add_foreign_key等のメソッド呼び出し解析
4. カラム型の変換（Railsマイグレーション型→PostgreSQL型）
5. 外部キー・制約情報の抽出

**関連システム・外部連携**：@ruby/prism（Rubyパーサー）を使用。WebAssembly経由で動作。

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

## 関連画面

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

## 機能種別

データ変換 / パース処理

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- Rails db/schema.rb ファイル
- Schemafileファイル（ridgepoleなど）

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. schema.rb受信
   └─ Rubyコード文字列を受け取る
2. prismパース
   └─ loadPrismでWASMを読み込み、parseを実行
3. AST走査
   └─ SchemaFinderでVisitorパターンによる走査
4. メソッド検出
   ├─ create_table: テーブル定義
   ├─ add_foreign_key: 外部キー制約
   └─ add_check_constraint: チェック制約
5. スキーマ構築
   └─ テーブル、カラム、制約を統合
6. 結果返却
   └─ ProcessResult形式で返却
```

### フローチャート

```mermaid
flowchart TD
    A[schema.rb入力] --> B[loadPrism WASM読み込み]
    B --> C[parse 実行]
    C --> D[AST生成]
    D --> E[SchemaFinder走査]
    E --> F{CallNode検出}
    F -->|create_table| G[handleCreateTable]
    F -->|add_foreign_key| H[handleAddForeignKey]
    F -->|add_check_constraint| I[handleAddCheckConstraint]
    G --> J[テーブル・カラム抽出]
    H --> K[外部キー制約追加]
    I --> L[チェック制約追加]
    J --> M[Schema構築]
    K --> M
    L --> M
    M --> N[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | デフォルトID | id: falseでない場合、bigserial型のidカラムを追加 | create_table時 |
| BR-002 | 外部キーカラム名 | 指定がない場合、{テーブル名の単数形}_id | add_foreign_key時 |
| BR-003 | 型変換 | Railsのt.integerをintegerに変換等 | convertColumnType関数 |
| BR-004 | 参照アクション | on_delete: :cascadeなどを正規化 | normalizeConstraintName関数 |

### 計算ロジック

Railsカラム型の変換例:
- t.string → character varying
- t.integer → integer
- t.bigint → bigint
- t.boolean → boolean
- t.datetime → timestamp without time zone

参照アクションの変換:
- :cascade → CASCADE
- :restrict → RESTRICT
- :nullify → SET_NULL

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

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UnsupportedTokenError | 未対応トークン | 解析できないRuby構文 | 警告として記録 |
| UnexpectedTokenWarningError | 予期しないトークン | 想定外のAST構造 | 警告として記録 |

### リトライ仕様

なし（再パースで対応）

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

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

## パフォーマンス要件

- 大規模schema.rb（数千行）でも高速処理
- WASMによるクロスプラットフォーム対応

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

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

## 備考

@ruby/prismはRuby公式のパーサーであり、最新のRuby構文にも対応している。

---

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

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

### 推奨読解順序

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

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

**主要処理フロー**:
1. **827-838行目**: parseRubySchema関数、prismでパースしSchemaFinderで走査
2. **841行目**: processor関数のエクスポート

#### Step 2: SchemaFinderを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | parser.ts | `frontend/packages/schema/src/parser/schemarb/parser.ts` | SchemaFinderクラス |

**主要処理フロー**:
- **701-770行目**: handleCreateTable - テーブル定義の処理
- **772-800行目**: handleAddForeignKey - 外部キーの処理
- **802-815行目**: handleAddCheckConstraint - チェック制約の処理
- **817-824行目**: visitCallNode - メソッド呼び出しのディスパッチ

#### Step 3: カラム抽出を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | parser.ts extractColumnDetails | `frontend/packages/schema/src/parser/schemarb/parser.ts` | カラム情報抽出 |
| 3-2 | convertColumnType.ts | `frontend/packages/schema/src/parser/schemarb/convertColumnType.ts` | 型変換 |

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

```
processor
    │
    └─ parseRubySchema
           │
           ├─ loadPrism (WASM読み込み)
           │
           ├─ parse (Rubyパース)
           │
           └─ SchemaFinder.accept (AST走査)
                  │
                  ├─ visitCallNode
                  │      ├─ handleCreateTable
                  │      │      ├─ extractTableName
                  │      │      ├─ extractTableComment
                  │      │      ├─ extractIdColumnAndConstraint
                  │      │      └─ extractTableDetails
                  │      │             └─ processCallNode
                  │      │                    ├─ extractColumnDetails
                  │      │                    └─ extractIndexDetails
                  │      │
                  │      ├─ handleAddForeignKey
                  │      │      └─ extractForeignKeyOptions
                  │      │
                  │      └─ handleAddCheckConstraint
                  │
                  └─ getSchema (結果取得)
```

### データフロー図

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

schema.rb ──────────▶ loadPrism ─────────────▶ parse関数
                           │
                           ▼
Rubyコード ─────────▶ parse() ───────────────▶ AST
                           │
                           ▼
AST ────────────────▶ SchemaFinder ──────────▶ tables[]
                           │
                           ├─▶ create_table → Table
                           ├─▶ t.xxx → Column
                           ├─▶ t.index → Index
                           └─▶ add_foreign_key → Constraint

tables[] ───────────▶ getSchema ─────────────▶ Schema
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| parser.ts | `frontend/packages/schema/src/parser/schemarb/parser.ts` | ソース | メインパーサー |
| index.ts | `frontend/packages/schema/src/parser/schemarb/index.ts` | ソース | エクスポート |
| loadPrism.ts | `frontend/packages/schema/src/parser/schemarb/loadPrism.ts` | ソース | WASM読み込み |
| convertColumnType.ts | `frontend/packages/schema/src/parser/schemarb/convertColumnType.ts` | ソース | 型変換 |
| singularize.ts | `frontend/packages/schema/src/parser/schemarb/singularize.ts` | ソース | 複数形→単数形変換 |
