# 機能設計書 11-注文配送管理

## 概要

本ドキュメントは、Medusaコマースプラットフォームにおける注文配送管理機能の設計を記載したものである。注文に対する配送方法・配送先の設定と管理を行う機能について、処理フロー、データ構造、ビジネスルールを定義する。

### 本機能の処理概要

注文配送管理機能は、ECサイトにおける注文の配送情報を一元管理するための機能である。

**業務上の目的・背景**：ECサイトにおいて、注文した商品を顧客に届けるためには、配送方法と配送先住所の管理が不可欠である。本機能は、注文に紐づく配送方法（送料、配送オプション、配送プロバイダー等）と配送先住所を管理し、フルフィルメント処理と連携することで、効率的な出荷業務を実現する。

**機能の利用シーン**：
- 顧客が注文時に配送方法を選択する場面
- 管理者が注文の配送先住所を確認・編集する場面
- フルフィルメント作成時に配送情報を参照する場面
- 出荷処理時に配送方法と追跡情報を更新する場面

**主要な処理内容**：
1. 注文に対する配送方法（OrderShippingMethod）の作成・更新・削除
2. 配送先住所（OrderAddress）の作成・更新・削除
3. 配送方法に関連する税金ライン・調整の管理
4. 配送オプションとの連携によるバリデーション
5. 返品・交換・クレームに紐づく配送方法の管理

**関連システム・外部連携**：
- フルフィルメントモジュール：配送プロバイダーとの連携
- 税金モジュール：配送に対する税金計算
- 価格モジュール：配送料金の取得

**権限による制御**：
- 管理者権限を持つユーザーのみが配送先住所を変更可能
- フルフィルメント権限を持つユーザーのみが出荷処理を実行可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 43 | 注文詳細画面 | 参照画面 | 注文の配送情報表示 |
| 44 | フルフィルメント作成画面 | 主画面 | フルフィルメント作成時の配送方法選択 |
| 45 | 出荷作成画面 | 主画面 | 出荷情報の作成と配送情報設定 |
| 55 | 配送先住所編集画面 | 主画面 | 配送先住所の編集 |

## 機能種別

CRUD操作 / データ連携 / バリデーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| order_id | string | Yes | 注文ID | 有効な注文IDであること |
| shipping_method | CreateOrderShippingMethodDTO | Yes | 配送方法情報 | name, amountは必須 |
| name | string | Yes | 配送方法名 | 空文字不可 |
| amount | BigNumber | Yes | 配送料金 | 0以上の数値 |
| shipping_option_id | string | No | 配送オプションID | 存在する配送オプションであること |
| is_tax_inclusive | boolean | No | 税込み価格フラグ | デフォルトfalse |
| data | object | No | 配送プロバイダー用データ | JSON形式 |
| return_id | string | No | 返品ID | 返品に紐づく場合のみ |
| claim_id | string | No | クレームID | クレームに紐づく場合のみ |
| exchange_id | string | No | 交換ID | 交換に紐づく場合のみ |
| version | number | No | 注文バージョン | 指定がない場合は現在のバージョン |

### 入力データソース

- 画面入力：管理画面からの配送方法選択・住所入力
- フルフィルメントモジュール：配送オプション情報
- 注文モジュール：注文情報（バージョン等）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | string | 配送方法ID（prefixはordsm） |
| name | string | 配送方法名 |
| description | object | 配送方法の説明（JSON） |
| amount | BigNumber | 配送料金 |
| is_tax_inclusive | boolean | 税込みフラグ |
| is_custom_amount | boolean | カスタム金額フラグ |
| shipping_option_id | string | 配送オプションID |
| data | object | 配送プロバイダーデータ |
| metadata | object | メタデータ |
| tax_lines | OrderShippingMethodTaxLine[] | 税金ライン |
| adjustments | OrderShippingMethodAdjustment[] | 調整情報 |

### 出力先

- データベース：order_shipping_method、order_shippingテーブル
- API応答：OrderShippingMethodDTO形式

## 処理フロー

### 処理シーケンス

```
1. 配送方法作成リクエスト受信
   └─ order_id、shipping_method情報を含むリクエストを受信

2. 注文存在確認
   └─ 指定されたorder_idの注文が存在するか確認
   └─ 注文の現在のバージョンを取得

3. 配送方法データ構築
   └─ shipping_methodデータを整形
   └─ versionが未指定の場合は注文のバージョンを使用

4. OrderShippingの作成
   └─ order_id、version、return_id/claim_id/exchange_idとともに作成
   └─ shipping_method情報を関連付け

5. OrderShippingMethodの永続化
   └─ 配送方法の詳細情報をDBに保存
   └─ 税金ライン、調整情報も併せて保存

6. 結果返却
   └─ 作成された配送方法情報をシリアライズして返却
```

### フローチャート

```mermaid
flowchart TD
    A[配送方法作成リクエスト] --> B{注文が存在するか}
    B -->|No| C[エラー: 注文が見つからない]
    B -->|Yes| D[注文バージョン取得]
    D --> E[配送方法データ構築]
    E --> F[OrderShipping作成]
    F --> G[OrderShippingMethod永続化]
    G --> H{税金ライン/調整あり?}
    H -->|Yes| I[税金ライン・調整を保存]
    H -->|No| J[結果返却]
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-11-01 | バージョン自動設定 | 配送方法作成時にバージョンが未指定の場合、注文の現在バージョンを使用する | 配送方法作成時 |
| BR-11-02 | 関連エンティティ指定 | return_id、claim_id、exchange_idのいずれかが指定された場合、該当の処理に紐づく配送方法として管理する | 返品・クレーム・交換の配送方法作成時 |
| BR-11-03 | 配送方法削除時の連鎖処理 | 配送方法削除時は関連するOrderShippingも論理削除する | 配送方法削除時 |
| BR-11-04 | カスケード削除 | 配送方法削除時は関連する税金ライン、調整も削除する | 配送方法削除時 |

### 計算ロジック

配送料金の税金計算は、税金モジュールと連携して行われる。is_tax_inclusiveフラグにより、税込み・税抜きの計算方式が決定される。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 配送方法作成 | order_shipping_method | INSERT | 配送方法の新規作成 |
| 配送方法作成 | order_shipping | INSERT | 注文と配送方法の関連付け |
| 配送方法更新 | order_shipping_method | UPDATE | 配送方法情報の更新 |
| 配送方法削除 | order_shipping_method | UPDATE (soft delete) | 論理削除 |
| 配送方法削除 | order_shipping | UPDATE (soft delete) | 関連の論理削除 |
| 税金ライン作成 | order_shipping_method_tax_line | INSERT | 税金ラインの作成 |
| 調整作成 | order_shipping_method_adjustment | INSERT | 調整情報の作成 |

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

#### order_shipping_method

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | 自動生成（prefix: ordsm） | 主キー |
| INSERT | name | リクエストのname | 必須 |
| INSERT | description | リクエストのdescription | JSON形式 |
| INSERT | amount | リクエストのamount | BigNumber |
| INSERT | is_tax_inclusive | リクエストのis_tax_inclusive | デフォルトfalse |
| INSERT | is_custom_amount | リクエストのis_custom_amount | デフォルトfalse |
| INSERT | shipping_option_id | リクエストのshipping_option_id | 外部キー |
| INSERT | data | リクエストのdata | JSON形式 |
| INSERT | metadata | リクエストのmetadata | JSON形式 |

#### order_shipping

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | order_id | 注文ID | 外部キー |
| INSERT | version | 注文バージョン | 整数 |
| INSERT | shipping_method_id | 配送方法ID | 外部キー |
| INSERT | return_id | 返品ID | nullable |
| INSERT | claim_id | クレームID | nullable |
| INSERT | exchange_id | 交換ID | nullable |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NOT_FOUND | MedusaError | 指定されたorder_idの注文が存在しない | 有効な注文IDを指定 |
| INVALID_DATA | MedusaError | 必須パラメータ（name, amount）が未指定 | 必須項目を入力 |
| INVALID_DATA | MedusaError | shipping_method_idが注文に存在しない | 有効な配送方法IDを指定 |

### リトライ仕様

データベース操作はトランザクション内で実行されるため、失敗時は自動ロールバックされる。リトライは呼び出し元で制御する。

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

- `@InjectTransactionManager`デコレータにより、配送方法の作成・更新処理はトランザクション内で実行
- OrderShippingとOrderShippingMethodの作成は同一トランザクション内で実行
- 処理失敗時は全ての変更がロールバックされる
- 論理削除時もトランザクション管理下で実行

## パフォーマンス要件

- 配送方法の一覧取得：100件以下で500ms以内
- 配送方法の作成：単一レコードで200ms以内
- インデックス：shipping_option_idにインデックスを設定

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

- 配送方法の作成・更新は認証済みユーザーのみ実行可能
- 配送先住所には個人情報が含まれるため、適切なアクセス制御を実施
- 監査ログにより配送情報の変更履歴を追跡可能
- APIエンドポイントは認証ミドルウェアで保護

## 備考

- 配送方法はOrderShippingを介して注文と関連付けられる設計となっている
- これにより、同一の配送方法詳細（OrderShippingMethod）を異なるバージョンや返品・交換・クレームで再利用可能
- 配送プロバイダー固有のデータはdataフィールドにJSON形式で保存

---

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

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

### 推奨読解順序

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

まず、配送方法に関するデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | shipping-method.ts | `packages/modules/order/src/models/shipping-method.ts` | OrderShippingMethodエンティティの構造、name/amount/is_tax_inclusive等のプロパティ、tax_lines/adjustmentsのリレーション |
| 1-2 | order-shipping-method.ts | `packages/modules/order/src/models/order-shipping-method.ts` | OrderShippingエンティティ（注文と配送方法の中間テーブル）、order_id/version/return_id/claim_id/exchange_idのリレーション |
| 1-3 | shipping-method.ts | `packages/modules/order/src/types/shipping-method.ts` | 配送方法のDTO定義、CreateOrderShippingMethodDTO、UpdateOrderShippingMethodDTO |

**読解のコツ**: Medusaではモデル定義にDMLパターンを使用している。`model.define()`でエンティティを定義し、`.cascades()`でカスケード削除、`.indexes()`でインデックスを設定する。

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

配送方法管理の主要エントリーポイントはOrderModuleServiceである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | 1374-1499行：createOrderShippingMethods関連メソッド、配送方法の作成フロー |

**主要処理フロー**:
1. **1392-1445行目**: `createOrderShippingMethods` - 配送方法作成の公開メソッド。order_idが文字列の場合と配送方法データの配列の場合を分岐
2. **1447-1471行目**: `createOrderShippingMethods_` - order_idから注文を取得し、配送方法データを構築
3. **1473-1485行目**: `createOrderShippingMethodsBulk_` - OrderShippingを作成し、shipping_methodを返却

#### Step 3: 削除・復元処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | 1487-1565行：softDeleteOrderShippingMethods、restoreOrderShippingMethods |

**主要処理フロー**:
- **1502-1527行目**: `softDeleteOrderShippingMethods_` - 配送方法の論理削除時にOrderShippingも同時に論理削除
- **1540-1565行目**: `restoreOrderShippingMethods_` - 配送方法の復元時にOrderShippingも復元

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

```
createOrderShippingMethods (public)
    │
    ├─ createOrderShippingMethods_ (order_idから注文取得)
    │      │
    │      └─ createOrderShippingMethodsBulk_
    │             └─ orderShippingService_.create
    │
    └─ (直接データ配列の場合)
           └─ createOrderShippingMethodsBulk_
                  └─ orderShippingService_.create
```

### データフロー図

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

CreateOrderShippingMethodDTO ─▶ OrderModuleService ─▶ order_shipping_method テーブル
       │                        │                           │
       │                        ├─▶ orderShippingService_ ─▶ order_shipping テーブル
       │                        │
       v                        v
 order_id, name,         バージョン取得、
 amount, data...         データ構築                        OrderShippingMethodDTO
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | ソース | 配送方法の作成・削除・復元処理 |
| shipping-method.ts | `packages/modules/order/src/models/shipping-method.ts` | ソース | OrderShippingMethodエンティティ定義 |
| order-shipping-method.ts | `packages/modules/order/src/models/order-shipping-method.ts` | ソース | OrderShippingエンティティ定義 |
| shipping-method.ts | `packages/modules/order/src/types/shipping-method.ts` | ソース | DTO型定義 |
| shipping-method-tax-line.ts | `packages/modules/order/src/models/shipping-method-tax-line.ts` | ソース | 配送方法の税金ラインエンティティ |
| shipping-method-adjustment.ts | `packages/modules/order/src/models/shipping-method-adjustment.ts` | ソース | 配送方法の調整エンティティ |
| index.ts | `packages/modules/order/src/models/index.ts` | ソース | モデルのエクスポート |
