# 機能設計書 12-注文変更管理

## 概要

本ドキュメントは、Medusaコマースプラットフォームにおける注文変更管理機能の設計を記載したものである。注文の変更リクエスト（キャンセル、返品、交換等）の管理機能について、処理フロー、データ構造、ビジネスルールを定義する。

### 本機能の処理概要

注文変更管理機能は、ECサイトにおける注文内容の変更を管理するための中核機能である。

**業務上の目的・背景**：ECサイトにおいて、顧客からの注文変更依頼（商品の追加・削除、数量変更等）や、返品・交換・クレーム対応時の注文修正が発生する。本機能は、これらの変更を「OrderChange」として管理し、変更内容を「OrderChangeAction」としてトラッキングすることで、変更履歴の追跡と適切なバージョン管理を実現する。

**機能の利用シーン**：
- 顧客が注文後に商品の追加・削除を依頼する場面
- 管理者が注文内容を編集する場面（数量変更、配送方法変更等）
- 返品・交換・クレーム処理時に注文変更を記録する場面
- 変更のプレビュー・確認・キャンセルを行う場面

**主要な処理内容**：
1. 注文変更（OrderChange）の作成・取得・削除
2. 注文変更アクション（OrderChangeAction）の追加・削除
3. 注文変更のプレビュー（変更適用前の確認）
4. 注文変更の確認（confirmOrderChange）による変更の確定
5. 注文変更のキャンセル（cancelOrderChange）
6. 注文バージョンのインクリメントと履歴管理

**関連システム・外部連携**：
- 返品モジュール：返品処理時の注文変更
- クレームモジュール：クレーム処理時の注文変更
- 交換モジュール：交換処理時の注文変更
- プロモーションモジュール：割引の再計算

**権限による制御**：
- 注文変更の作成・確認は管理者権限を持つユーザーのみ実行可能
- 変更リクエストの送信は顧客自身または管理者が可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 50 | 注文編集作成画面 | 主画面 | 注文内容の編集・変更アクションの追加 |
| 43 | 注文詳細画面 | 参照画面 | 注文変更履歴の表示 |

## 機能種別

CRUD操作 / 状態管理 / バージョン管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| order_id | string | Yes | 注文ID | 有効な注文IDであること |
| change_type | string | No | 変更種別（edit, return, exchange, claim等） | 有効な変更種別であること |
| description | string | No | 変更の説明 | - |
| internal_note | string | No | 内部メモ | - |
| return_id | string | No | 返品ID | 返品に紐づく場合 |
| claim_id | string | No | クレームID | クレームに紐づく場合 |
| exchange_id | string | No | 交換ID | 交換に紐づく場合 |
| created_by | string | No | 作成者ID | - |
| requested_by | string | No | リクエスト者ID | - |
| carry_over_promotions | boolean | No | プロモーション引継ぎフラグ | v2.12.0以降 |

### OrderChangeActionの入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| action | string | Yes | アクション種別 | ITEM_ADD, ITEM_REMOVE, SHIPPING_ADD等 |
| reference | string | No | 参照種別 | - |
| reference_id | string | No | 参照ID | - |
| details | object | No | アクション詳細（JSON） | アクション種別に応じた構造 |
| amount | BigNumber | No | 金額 | - |
| internal_note | string | No | 内部メモ | - |

### 入力データソース

- 画面入力：管理画面からの注文編集操作
- API呼び出し：返品・交換・クレーム処理からの自動呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | string | 注文変更ID（prefix: ordch） |
| order_id | string | 注文ID |
| version | number | 変更後のバージョン番号 |
| change_type | string | 変更種別 |
| status | OrderChangeStatus | 変更ステータス（pending, requested, confirmed等） |
| description | string | 変更の説明 |
| internal_note | string | 内部メモ |
| return_id | string | 返品ID |
| claim_id | string | クレームID |
| exchange_id | string | 交換ID |
| created_by | string | 作成者ID |
| requested_at | Date | リクエスト日時 |
| confirmed_at | Date | 確認日時 |
| declined_at | Date | 却下日時 |
| canceled_at | Date | キャンセル日時 |
| actions | OrderChangeAction[] | 変更アクションの一覧 |

### 出力先

- データベース：order_change、order_change_actionテーブル
- API応答：OrderChangeDTO形式

## 処理フロー

### 処理シーケンス

```
1. 注文変更作成リクエスト受信
   └─ order_id、change_type等を含むリクエストを受信

2. 既存の注文変更存在確認
   └─ 同一注文に対してPENDINGまたはREQUESTEDの変更が存在しないか確認
   └─ 存在する場合はエラーを返却

3. 注文バージョン取得
   └─ 対象注文の現在のバージョンを取得
   └─ 新しい変更のバージョンは現在のバージョン+1

4. 注文変更の作成
   └─ OrderChangeレコードを作成
   └─ ステータスはPENDINGで初期化

5. 変更アクションの追加（オプション）
   └─ OrderChangeActionを作成
   └─ 順序（ordering）は自動採番

6. 変更のプレビュー（オプション）
   └─ previewOrderChangeで変更適用後の状態を確認

7. 変更の確認（confirmOrderChange）
   └─ 全アクションを適用
   └─ 注文のバージョンをインクリメント
   └─ ステータスをCONFIRMEDに更新

または

7. 変更のキャンセル（cancelOrderChange）
   └─ ステータスをCANCELEDに更新
   └─ アクションは適用されない
```

### フローチャート

```mermaid
flowchart TD
    A[注文変更作成リクエスト] --> B{アクティブな変更が存在?}
    B -->|Yes| C[エラー: 既存の変更あり]
    B -->|No| D[注文バージョン取得]
    D --> E[OrderChange作成 status=PENDING]
    E --> F[変更アクション追加]
    F --> G{変更内容確認}
    G -->|プレビュー| H[previewOrderChange]
    H --> G
    G -->|確認| I[confirmOrderChange]
    G -->|キャンセル| J[cancelOrderChange]
    I --> K[アクション適用・バージョンUP]
    K --> L[status=CONFIRMED]
    J --> M[status=CANCELED]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-12-01 | 単一アクティブ変更 | 同一注文に対してPENDINGまたはREQUESTEDの変更は1つのみ存在可能 | 注文変更作成時 |
| BR-12-02 | バージョン自動インクリメント | 変更作成時にバージョンは注文の現在バージョン+1となる | 注文変更作成時 |
| BR-12-03 | 確認時バージョン更新 | 変更確認時に注文のバージョンが変更のバージョンに更新される | 変更確認時 |
| BR-12-04 | アクション順序保持 | OrderChangeActionのorderingフィールドで適用順序を管理 | アクション追加時 |
| BR-12-05 | カスケード削除 | OrderChange削除時はactionsも削除される | 変更削除時 |

### 計算ロジック

- 変更プレビュー時は、現在の注文に対してアクションを順番に適用し、変更後の合計金額を計算
- 税金・割引の再計算は既存のロジック（decorateCartTotals）を使用

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 注文変更作成 | order_change | INSERT | 変更レコードの作成 |
| アクション追加 | order_change_action | INSERT | 変更アクションの作成 |
| 変更確認 | order_change | UPDATE | status=CONFIRMED、confirmed_at設定 |
| 変更確認 | order | UPDATE | version更新 |
| 変更確認 | order_item, order_shipping等 | INSERT/UPDATE | アクションに応じた変更適用 |
| 変更キャンセル | order_change | UPDATE | status=CANCELED、canceled_at設定 |

### テーブル別操作詳細

#### order_change

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | 自動生成（prefix: ordch） | 主キー |
| INSERT | order_id | 対象注文ID | 外部キー |
| INSERT | version | 注文の現在バージョン+1 | 整数 |
| INSERT | change_type | リクエストのchange_type | nullable |
| INSERT | status | PENDING | OrderChangeStatus |
| UPDATE (confirm) | status | CONFIRMED | - |
| UPDATE (confirm) | confirmed_at | 現在日時 | - |
| UPDATE (confirm) | confirmed_by | 確認者ID | - |
| UPDATE (cancel) | status | CANCELED | - |
| UPDATE (cancel) | canceled_at | 現在日時 | - |

#### order_change_action

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | 自動生成（prefix: ordchact） | 主キー |
| INSERT | order_change_id | 親の注文変更ID | 外部キー |
| INSERT | order_id | 注文ID | 外部キー |
| INSERT | action | アクション種別 | ITEM_ADD, ITEM_REMOVE等 |
| INSERT | ordering | 自動採番 | 適用順序 |
| INSERT | details | アクション詳細 | JSON |
| INSERT | applied | false | 適用済みフラグ |
| UPDATE (apply) | applied | true | 適用完了時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| INVALID_DATA | MedusaError | 指定された注文が存在しない | 有効な注文IDを指定 |
| INVALID_DATA | MedusaError | 同一注文に既存のアクティブな変更が存在する | 既存の変更を確認またはキャンセル |
| NOT_FOUND | MedusaError | 指定された注文変更が存在しない | 有効な注文変更IDを指定 |

### リトライ仕様

データベース操作はトランザクション内で実行されるため、失敗時は自動ロールバックされる。

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

- `@InjectTransactionManager`デコレータにより、変更作成・確認・キャンセル処理はトランザクション内で実行
- confirmOrderChange_では、アクション適用と注文更新が同一トランザクションで実行
- 処理失敗時は全ての変更がロールバックされる

## パフォーマンス要件

- 変更作成：200ms以内
- 変更プレビュー：500ms以内（アクション数に依存）
- 変更確認：1000ms以内（アクション数に依存）

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

- 注文変更の作成・確認は認証済み管理者のみ実行可能
- 変更履歴は監査ログとして保存
- internal_noteフィールドは顧客には公開されない

## 備考

- OrderChangeStatusの値：PENDING, REQUESTED, CONFIRMED, DECLINED, CANCELED
- carry_over_promotionsフラグ（v2.12.0〜）：変更後もプロモーションを引き継ぐかどうかを制御
- 変更アクションの種類（ChangeActionType）：ITEM_ADD, ITEM_REMOVE, ITEM_UPDATE, SHIPPING_ADD, SHIPPING_REMOVE等

---

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

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

### 推奨読解順序

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

まず、注文変更に関するデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | order-change.ts | `packages/modules/order/src/models/order-change.ts` | OrderChangeエンティティ、status/version/change_typeプロパティ、actionsリレーション |
| 1-2 | order-change-action.ts | `packages/modules/order/src/models/order-change-action.ts` | OrderChangeActionエンティティ、action/details/ordering/appliedプロパティ |
| 1-3 | order-change.ts | `packages/modules/order/src/types/order-change.ts` | CreateOrderChangeDTO、OrderChangeDTO等の型定義 |

**読解のコツ**: OrderChangeは注文の変更セッションを表し、複数のOrderChangeActionを持つ。各アクションはorderingで適用順序が管理される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | 2446-2529行：createOrderChange関連メソッド |

**主要処理フロー**:
1. **2478-2485行目**: 既存のPENDING/REQUESTED変更の存在確認
2. **2497-2510行目**: 対象注文の取得とバリデーション
3. **2512-2528行目**: 新バージョン番号設定とOrderChange作成

#### Step 3: 変更プレビューを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | 2531-2591行：previewOrderChangeメソッド |

**主要処理フロー**:
- **2549-2558行目**: アクションをordering順にソート
- **2560-2569行目**: applyChangesToOrderで変更を仮適用
- **2583-2588行目**: 合計金額の再計算

#### Step 4: 変更確認・キャンセルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | 2761-2829行：confirmOrderChange_メソッド |
| 4-2 | order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | 2710-2759行：cancelOrderChangeメソッド |

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

```
createOrderChange (public)
    └─ createOrderChange_
           ├─ orderChangeService_.list (既存変更確認)
           ├─ orderService_.list (注文バージョン取得)
           └─ orderChangeService_.create

previewOrderChange
    ├─ retrieveOrder
    ├─ retrieveOrderChange
    ├─ applyChangesToOrder (変更仮適用)
    └─ decorateCartTotals (合計計算)

confirmOrderChange
    └─ confirmOrderChange_
           ├─ orderChangeService_.list
           └─ applyOrderChanges_ (実際の適用)
                  ├─ 各アクションの適用
                  └─ 注文バージョン更新

cancelOrderChange
    └─ orderChangeService_.update (status=CANCELED)
```

### データフロー図

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

CreateOrderChangeDTO ──▶ createOrderChange_ ─────────▶ order_change テーブル
                               │
                               v
OrderChangeActionDTO ──▶ addOrderChangeAction ───────▶ order_change_action テーブル
                               │
                               v
                         previewOrderChange ─────────▶ プレビュー用注文DTO
                               │
                               v
                         confirmOrderChange_ ────────▶ order テーブル (version更新)
                                                       order_item 等 (変更適用)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | ソース | 注文変更の主要ロジック |
| order-change.ts | `packages/modules/order/src/models/order-change.ts` | ソース | OrderChangeエンティティ定義 |
| order-change-action.ts | `packages/modules/order/src/models/order-change-action.ts` | ソース | OrderChangeActionエンティティ定義 |
| apply-order-changes.ts | `packages/modules/order/src/utils/apply-order-changes.ts` | ソース | 変更適用ユーティリティ |
| calculate-order-change.ts | `packages/modules/order/src/utils/calculate-order-change.ts` | ソース | 変更計算ユーティリティ |
| actions/ | `packages/modules/order/src/services/actions/` | ソース | 各種アクション処理（返品、交換、クレーム等） |
| order-change.ts | `packages/modules/order/src/types/order-change.ts` | ソース | DTO型定義 |
