# 帳票設計書 17-Mermaidワークフロー図

## 概要

本ドキュメントは、Symfony Workflowコンポーネントにおけるワークフロー定義のMermaid記法出力機能（`MermaidDumper`）の設計仕様を定義する。ワークフロー定義をMermaid記法で出力し、Markdownドキュメント等に埋め込み可能にする。

### 本帳票の処理概要

MermaidDumperは、Symfonyのワークフロー定義をMermaidフローチャート記法で出力する。Mermaid記法はGitHub、GitLab等のMarkdownレンダラーで直接表示できるため、別途画像変換ツールを必要としない。

**業務上の目的・背景**：ワークフローの可視化をドキュメントに直接埋め込むニーズに対応する。Graphviz形式は専用ツールが必要だが、Mermaid記法はMarkdownファイルに直接記述でき、GitHubやGitLab等のプラットフォームで即座にレンダリングされる。開発者がREADMEやWiki等にワークフロー図を簡単に埋め込めるようにする。

**帳票の利用シーン**：ドキュメント生成、README.mdへのワークフロー図埋め込み、Markdownベースの設計書への図の組み込み、CI/CDパイプラインでの自動ドキュメント生成に使用される。

**主要な出力内容**：
1. Mermaidグラフ宣言（`graph {direction}`）
2. プレース（状態）ノード定義（丸括弧やスタジアム形状）
3. トランジション定義（矢印接続）
4. スタイル定義（背景色、マーキング強調）

**帳票の出力タイミング**：`workflow:dump --dump-format=mermaid`コマンド実行時、またはプログラム内でDumperを直接呼び出した場合。

**帳票の利用者**：アプリケーション開発者、テクニカルライター、業務設計者。

## 帳票種別

Mermaid記法テキスト出力（フローチャート形式）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | CLIコマンド | `bin/console workflow:dump {name} --dump-format=mermaid` | コマンド実行 |
| N/A | プログラム呼び出し | API呼び出し | MermaidDumper::dump() |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | Mermaid（テキスト） |
| 用紙サイズ | N/A |
| 向き | 設定可能（TB, TD, BT, RL, LR） |
| ファイル名 | 任意 |
| 出力方法 | 文字列として返却 |
| 文字コード | UTF-8 |

### Mermaid固有設定

| 項目 | 内容 |
|-----|------|
| チャートタイプ | graph（フローチャート） |
| デフォルト方向 | LR（左から右） |
| トランジションタイプ | statemachine / workflow |
| プレース形状（初期） | スタジアム型 `([...])` |
| プレース形状（通常） | 二重丸 `((...))` |

## 帳票レイアウト

### レイアウト概要

Mermaidフローチャートとして、プレースノードとトランジションが記述される。

```
┌─────────────────────────────────────┐
│  graph LR                           │
├─────────────────────────────────────┤
│    place0(["initial"])              │
│    place1(("state1"))               │
│    (プレースノード定義)              │
├─────────────────────────────────────┤
│  [workflowモード]                   │
│    transition0["action"]            │
│    place0-->transition0             │
│    transition0-->place1             │
│  [statemachineモード]               │
│    place0-->|"action"|place1        │
├─────────────────────────────────────┤
│    style place0 fill:...,stroke-... │
│    (スタイル定義)                    │
│    linkStyle 0 stroke:...           │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | graph宣言 | フローチャートの開始と方向 | コンストラクタ引数 | `graph LR` |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | プレースノード | 状態の定義 | Definition.getPlaces() | `place0(["name"])` / `place0(("name"))` | N/A |
| 2 | トランジションノード | 遷移の定義（workflowモード） | Definition.getTransitions() | `transition0["name"]` | N/A |
| 3 | エッジ | プレース-トランジション間接続 | Transition.getFroms/getTos | `place0-->transition0` | N/A |
| 4 | ノードスタイル | 背景色、ストローク幅 | metadata, marking | `style place0 fill:...` | N/A |
| 5 | リンクスタイル | エッジの色 | metadata.color | `linkStyle 0 stroke:...` | N/A |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| N/A | N/A | Mermaid記法には明示的なフッターなし | N/A | N/A |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| Definition | ワークフロー定義 | Yes |
| transitionType | statemachine / workflow | Yes（コンストラクタ） |
| direction | グラフの方向 | No（デフォルト: LR） |
| Marking | 現在のマーキング状態 | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | プレース | 定義順（placeId順） |
| 2 | トランジション | 定義順（transitionId順） |

### 改ページ条件

N/A

## データベース参照仕様

### 参照テーブル一覧

本帳票はデータベースを直接参照しない。

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| N/A | N/A | N/A |

### テーブル別参照項目詳細

N/A

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| プレースノード名 | `'place' + placeId` | N/A | 連番によるノードID生成（行143） |
| トランジションノード名 | `'transition' + transitionId` | N/A | workflowモード時（行218） |
| プレース形状 | 初期→`([%s])`、通常→`((%s))` | N/A | 初期プレースはスタジアム型（行139-141） |
| リンクカウント | linkCount変数でトラッキング | N/A | linkStyleの適用番号（行47） |
| トークンカウント表示 | `$tokenCount > 1` の場合ラベルに付加 | N/A | 複数トークン時に数量表示（行132-134） |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[dump呼び出し] --> B[linkCount初期化]
    B --> C[プレース処理ループ]
    C --> D[preparePlace - 各プレースのノード生成]
    D --> E[トランジション処理ループ]
    E --> F{transitionType?}
    F -->|statemachine| G[styleStateMachineTransition]
    F -->|workflow| H[styleWorkflowTransition]
    G --> I[出力配列に追加]
    H --> I
    I --> J[改行で結合]
    J --> K[Mermaid文字列返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| InvalidArgumentException | 不正なdirection値 | "Direction \"{dir}\" is not valid, valid directions are: ..." | 有効な方向値を指定 |
| InvalidArgumentException | 不正なtransitionType値 | "Transition type \"{type}\" is not valid, valid types are: ..." | statemachine または workflow を指定 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数十プレース、数十トランジション |
| 目標出力時間 | 1秒以内 |
| 同時出力数上限 | 制限なし |

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

- ダブルクォートは`#quot;`にエスケープされる（行180-181）
- ワークフロー名、プレース名が出力に含まれるため、公開時には名称の適切性を確認する

## 備考

- statemachineモードではプレース間を直接`-->`で接続し、ラベルにトランジション名を表示
- workflowモードではトランジションを独立ノード（`["name"]`）として表示し、プレース-トランジション間をエッジで接続
- 重複するエッジは自動的にスキップされる（行108-115）
- Arcのweight > 1の場合、エッジにweight数値がラベル表示される（行227-228, 240-241）

---

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

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

### 推奨読解順序

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

MermaidDumperのコンストラクタ引数と定数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MermaidDumper.php | `src/Symfony/Component/Workflow/Dumper/MermaidDumper.php` | 方向定数（行21-25）とトランジションタイプ定数（行35-36） |
| 1-2 | MermaidDumper.php | `src/Symfony/Component/Workflow/Dumper/MermaidDumper.php` | コンストラクタ（行49-55）でバリデーション |

**読解のコツ**: statemachineモードとworkflowモードの出力差異を理解することがこのクラスの核心。

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

dump()メソッドが処理の起点。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MermaidDumper.php | `src/Symfony/Component/Workflow/Dumper/MermaidDumper.php` | dump()メソッド（行57-124）がエントリーポイント |

**主要処理フロー**:
1. **行59-61**: linkCount初期化、placeNameMap初期化
2. **行63**: graph方向の出力
3. **行67-86**: 各プレースのノード生成
4. **行88-121**: 各トランジションのエッジ生成
5. **行123**: 改行で結合して返却

#### Step 3: プレース生成を理解する

preparePlace()で各プレースのノード表現を生成する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MermaidDumper.php | `src/Symfony/Component/Workflow/Dumper/MermaidDumper.php` | preparePlace()（行126-150）でノード名、ノード定義、スタイルの3要素を返す |

#### Step 4: トランジションスタイルを理解する

statemachineモードとworkflowモードの出力差異を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | MermaidDumper.php | `src/Symfony/Component/Workflow/Dumper/MermaidDumper.php` | styleStateMachineTransition()（行199-211）でプレース間直接接続 |
| 4-2 | MermaidDumper.php | `src/Symfony/Component/Workflow/Dumper/MermaidDumper.php` | styleWorkflowTransition()（行213-254）でトランジションノード経由接続 |

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

```
MermaidDumper::dump()
    |
    +-- preparePlace() [各プレース]
    |       +-- escape()
    |       +-- styleNode()
    |
    +-- [statemachineモード]
    |   +-- styleStateMachineTransition()
    |           +-- escape()
    |           +-- styleLink()
    |
    +-- [workflowモード]
        +-- styleWorkflowTransition()
                +-- escape()
                +-- styleNode()
                +-- styleLink()
```

### データフロー図

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

Definition ──────────> MermaidDumper::dump() ──────> Mermaid文字列
  |-- Places                |                          |-- graph LR
  |-- Transitions           |-- preparePlace()         |--   place0([...])
  |-- MetadataStore         |-- styleXxxTransition()   |--   place0-->place1
Marking (optional) ──> +-- 行結合                 |-- (or transition nodes)
transitionType ───────>
direction ────────────>
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MermaidDumper.php | `src/Symfony/Component/Workflow/Dumper/MermaidDumper.php` | ソース | メインのMermaidダンプ処理 |
| DumperInterface.php | `src/Symfony/Component/Workflow/Dumper/DumperInterface.php` | ソース | ダンパーインターフェース |
| Definition.php | `src/Symfony/Component/Workflow/Definition.php` | ソース | ワークフロー定義 |
| Marking.php | `src/Symfony/Component/Workflow/Marking.php` | ソース | マーキング状態 |
| Arc.php | `src/Symfony/Component/Workflow/Arc.php` | ソース | アーク（重み付きエッジ） |
| InvalidArgumentException.php | `src/Symfony/Component/Workflow/Exception/InvalidArgumentException.php` | ソース | バリデーションエラー |
