# 機能設計書 3-リレーションシップエッジ表示

## 概要

本ドキュメントは、Liamシステムにおける「リレーションシップエッジ表示」機能の設計を記述したものである。テーブル間の外部キー関係をエッジ（線）として表示し、カーディナリティ（1:1、1:N等）を視覚的に表現する機能である。

### 本機能の処理概要

本機能は、データベーススキーマの外部キー制約から抽出されたリレーションシップ情報をReact Flowのカスタムエッジとして描画する。エッジの両端にはカーディナリティを示すマーカー（IE記法）を表示し、ハイライト時にはパーティクルアニメーションで視覚的フィードバックを提供する。

**業務上の目的・背景**：データベース設計においてテーブル間の関係性を把握することは極めて重要である。カーディナリティの視覚化により、1対1関係か1対多関係かを一目で判別でき、設計レビューや問題発見を効率化する。

**機能の利用シーン**：
- テーブル間のリレーションシップ確認
- カーディナリティ（多重度）の把握
- 外部キー参照の追跡
- スキーマ設計の整合性確認

**主要な処理内容**：
1. Relationship情報からエッジデータを生成
2. ベジェ曲線によるエッジパス計算
3. カーディナリティマーカーの配置（始点・終点）
4. ハイライト状態の視覚的反映
5. パーティクルアニメーション（ハイライト時）

**関連システム・外部連携**：ER図表示機能（No.1）からエッジとして呼び出される。テーブルノード表示機能（No.2）のHandleと接続される。

**権限による制御**：表示のみの機能のため、認証ユーザーであればアクセス可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | スキーマ画面 | 主画面 | テーブル間の外部キー関係をエッジとして表示 |
| 14 | デザインセッション詳細画面 | 主画面 | 設計中スキーマのリレーションシップエッジ表示 |
| 20 | 公開ERD画面 | 主画面 | 公開スキーマのリレーションシップエッジ表示 |

## 機能種別

データ表示 / UIコンポーネント

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| sourceX | number | Yes | ソースノードのX座標 | - |
| sourceY | number | Yes | ソースノードのY座標 | - |
| targetX | number | Yes | ターゲットノードのX座標 | - |
| targetY | number | Yes | ターゲットノードのY座標 | - |
| sourcePosition | Position | Yes | ソースハンドルの位置 | - |
| targetPosition | Position | Yes | ターゲットハンドルの位置 | - |
| id | string | Yes | エッジID（リレーションシップ名） | - |
| data.isHighlighted | boolean | No | ハイライト状態 | - |
| data.cardinality | Cardinality | No | カーディナリティ（ONE_TO_ONE等） | - |

### 入力データソース

- convertSchemaToNodes関数で生成されたEdge配列
- React Flowからの座標・位置情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ReactNode | JSX.Element | エッジのSVG要素 |

### 出力先

React Flow Canvas内のSVG要素

## 処理フロー

### 処理シーケンス

```
1. EdgeProps受信
   └─ React Flowからエッジ描画パラメータを受け取る
2. ベジェパス計算
   └─ getBezierPathで曲線パスを算出
3. BaseEdge描画
   └─ パス、マーカー、スタイルを適用
4. マーカー決定
   ├─ markerStart: zeroOrOneRight（常時）
   └─ markerEnd: カーディナリティに応じて選択
5. ハイライト処理
   └─ isHighlighted時にパーティクルアニメーション追加
```

### フローチャート

```mermaid
flowchart TD
    A[EdgeProps受信] --> B[getBezierPath計算]
    B --> C[BaseEdge描画]
    C --> D{カーディナリティ判定}
    D -->|ONE_TO_ONE| E[zeroOrOneLeftマーカー]
    D -->|ONE_TO_MANY| F[zeroOrManyLeftマーカー]
    E --> G{ハイライト状態?}
    F --> G
    G -->|Yes| H[パーティクルアニメーション追加]
    G -->|No| I[通常表示]
    H --> J[完了]
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | マーカー始点 | 常にzeroOrOneRight（主キー側）を表示 | 全エッジ |
| BR-002 | マーカー終点 | ONE_TO_ONEならzeroOrOneLeft、それ以外はzeroOrManyLeft | カーディナリティに応じて |
| BR-003 | ハイライトマーカー | ハイライト時は*Highlightサフィックス付きマーカーを使用 | isHighlighted=true |
| BR-004 | パーティクル数 | ハイライト時に6個のパーティクルを表示 | isHighlighted=true |

### 計算ロジック

パーティクルアニメーション:
- PARTICLE_COUNT = 6
- ANIMATE_DURATION = 6秒
- 各パーティクルは`-i * (ANIMATE_DURATION / PARTICLE_COUNT)`秒の遅延で開始
- calcMode: spline、keySplines: "0.42, 0, 0.58, 1.0"（イージング）

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

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

本機能はデータベースを直接操作しない。表示専用機能。

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | - | SVG描画エラーはReactで捕捉 |

### リトライ仕様

なし（コンポーネントの再レンダリングで対応）

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

該当なし（表示専用機能）

## パフォーマンス要件

- SVGアニメーションは60fps目標
- 大量エッジ（100+）でもスムーズに描画

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

- エッジID（リレーションシップ名）はサニタイズ不要（内部生成）

## 備考

IE記法（Information Engineering notation）に基づいたカーディナリティマーカーを使用。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | type.ts | `frontend/packages/erd-core/src/features/erd/components/ERDContent/components/RelationshipEdge/type.ts` | RelationshipEdgeType型定義 |
| 1-2 | Schema型 | `frontend/packages/schema/src/schema/index.ts` | Cardinality型を確認 |

**読解のコツ**: RelationshipEdgeTypeはReact FlowのEdgeを拡張し、isHighlightedとcardinalityをdata部分に持つ。

#### Step 2: エッジ描画を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RelationshipEdge.tsx | `frontend/packages/erd-core/src/features/erd/components/ERDContent/components/RelationshipEdge/RelationshipEdge.tsx` | メインの描画ロジック |

**主要処理フロー**:
1. **23-30行目**: getBezierPathでベジェ曲線パスを計算
2. **34-51行目**: BaseEdgeにマーカーを設定
3. **53-71行目**: ハイライト時のパーティクルアニメーション

#### Step 3: カーディナリティマーカーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CardinalityMarkers.tsx | `frontend/packages/erd-core/src/features/erd/components/ERDRenderer/CardinalityMarkers/CardinalityMarkers.tsx` | SVGマーカー定義 |

**主要処理フロー**:
- **12-20行目**: zeroOrOneLeftマーカー（通常/ハイライト）
- **21-29行目**: zeroOrOneRightマーカー（通常/ハイライト）
- **30-38行目**: zeroOrManyLeftマーカー（通常/ハイライト）

#### Step 4: エッジ生成元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | convertSchemaToNodes.ts | `frontend/packages/erd-core/src/features/erd/utils/convertSchemaToNodes.ts` | エッジ配列の生成 |

**主要処理フロー**:
- **83-100行目**: edges配列の生成、カーディナリティとハンドルIDの設定

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

```
ERDRenderer
    │
    ├─ CardinalityMarkers (SVGマーカー定義)
    │      ├─ CardinalityZeroOrOneLeftMarker
    │      ├─ CardinalityZeroOrOneRightMarker
    │      └─ CardinalityZeroOrManyLeftMarker
    │
    └─ ERDContent
           └─ ReactFlow
                  └─ RelationshipEdge (カスタムエッジ)
                         ├─ getBezierPath
                         ├─ BaseEdge
                         └─ ellipse (パーティクル)
```

### データフロー図

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

Relationship[] ────▶ convertSchemaToNodes ───▶ Edge[]
                            │
                            ▼
                     ReactFlow ───────────────▶ RelationshipEdge呼び出し
                            │
                            ▼
EdgeProps ─────────▶ RelationshipEdge ────────▶ SVG要素
     │                   │
     ├─ 座標 ────────────┼─▶ getBezierPath ───▶ edgePath
     │                   │
     └─ cardinality ────┴─▶ markerEnd選択 ────▶ マーカーURL
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RelationshipEdge.tsx | `frontend/packages/erd-core/src/features/erd/components/ERDContent/components/RelationshipEdge/RelationshipEdge.tsx` | ソース | メインエッジコンポーネント |
| type.ts | `frontend/packages/erd-core/src/features/erd/components/ERDContent/components/RelationshipEdge/type.ts` | ソース | 型定義 |
| CardinalityMarkers.tsx | `frontend/packages/erd-core/src/features/erd/components/ERDRenderer/CardinalityMarkers/CardinalityMarkers.tsx` | ソース | SVGマーカー定義 |
| RelationshipEdgeParticleMarker.tsx | `frontend/packages/erd-core/src/features/erd/components/ERDRenderer/RelationshipEdgeParticleMarker/RelationshipEdgeParticleMarker.tsx` | ソース | パーティクルグラデーション |
| convertSchemaToNodes.ts | `frontend/packages/erd-core/src/features/erd/utils/convertSchemaToNodes.ts` | ソース | エッジ生成 |
| RelationshipEdge.module.css | `frontend/packages/erd-core/src/features/erd/components/ERDContent/components/RelationshipEdge/RelationshipEdge.module.css` | スタイル | エッジスタイル |
