# 機能設計書 13-注文トランザクション管理

## 概要

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

### 本機能の処理概要

注文トランザクション管理機能は、ECサイトにおける決済情報を管理するための機能である。

**業務上の目的・背景**：ECサイトにおいて、顧客からの支払い（capture）と返金（refund）を追跡することは、財務管理と顧客サービスの両面で不可欠である。本機能は、注文に紐づくすべての金銭の流れをOrderTransactionとして記録し、支払い済み金額、返金可能金額の算出を可能にする。

**機能の利用シーン**：
- 注文作成時に初期トランザクションを記録する場面
- 支払いキャプチャ完了時にトランザクションを追加する場面
- 返品・クレーム処理時に返金トランザクションを記録する場面
- 注文詳細画面で支払い履歴を表示する場面

**主要な処理内容**：
1. 注文トランザクション（OrderTransaction）の追加・削除
2. トランザクション作成時の注文バージョン自動設定
3. 支払い済み金額・返金可能金額の自動更新（OrderSummary）
4. 返品・交換・クレームに紐づくトランザクションの管理

**関連システム・外部連携**：
- 支払いモジュール：支払い処理結果の連携
- 返品モジュール：返金トランザクションの作成
- 注文サマリー：支払い状況の集計

**権限による制御**：
- トランザクションの追加・削除は管理者権限を持つユーザーのみ実行可能
- 支払いプロバイダーからのWebhookによる自動更新も可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 43 | 注文詳細画面 | 参照画面 | 支払い履歴の表示 |
| 46 | 支払いキャプチャ画面 | 主画面 | 支払いキャプチャ実行 |
| 47 | 返金画面 | 主画面 | 返金処理の実行 |

## 機能種別

CRUD操作 / 集計処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| order_id | string | Yes | 注文ID | 有効な注文IDであること |
| amount | BigNumber | Yes | トランザクション金額 | 数値であること |
| currency_code | string | Yes | 通貨コード | 有効な通貨コード |
| reference | string | No | 参照種別（payment, refund等） | - |
| reference_id | string | No | 参照ID（支払いセッションID等） | - |
| return_id | string | No | 返品ID | 返金時に指定 |
| claim_id | string | No | クレームID | クレーム返金時に指定 |
| exchange_id | string | No | 交換ID | 交換処理時に指定 |

### 入力データソース

- 支払いモジュール：支払いキャプチャ完了時
- 返品処理：返金処理時
- 管理画面：手動でのトランザクション追加

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | string | トランザクションID（prefix: ordtrx） |
| order_id | string | 注文ID |
| version | number | 注文バージョン |
| amount | BigNumber | 金額（正:支払い、負:返金） |
| currency_code | string | 通貨コード |
| reference | string | 参照種別 |
| reference_id | string | 参照ID |
| return_id | string | 返品ID |
| claim_id | string | クレームID |
| exchange_id | string | 交換ID |

### 出力先

- データベース：order_transactionテーブル
- API応答：OrderTransactionDTO形式
- OrderSummary：paid_total、refundable_amount等の更新

## 処理フロー

### 処理シーケンス

```
1. トランザクション追加リクエスト受信
   └─ order_id、amount、currency_code等を受信

2. 対象注文の取得
   └─ 注文ID・バージョンを取得

3. バージョンの設定
   └─ トランザクションに注文の現在バージョンを設定

4. トランザクションの作成
   └─ OrderTransactionレコードを作成

5. OrderSummaryの更新
   └─ updateOrderPaidRefundableAmount_を呼び出し
   └─ paid_total、refundable_amountを再計算
```

### フローチャート

```mermaid
flowchart TD
    A[トランザクション追加リクエスト] --> B[対象注文取得]
    B --> C{注文が存在?}
    C -->|No| D[エラー返却]
    C -->|Yes| E[バージョン設定]
    E --> F[OrderTransaction作成]
    F --> G[OrderSummary更新]
    G --> H[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-13-01 | バージョン自動設定 | トランザクション作成時に注文の現在バージョンが自動設定される | トランザクション追加時 |
| BR-13-02 | サマリー自動更新 | トランザクション追加・削除時にOrderSummaryのpaid_total等が自動更新される | トランザクション追加・削除時 |
| BR-13-03 | 金額の符号 | 支払いは正の金額、返金は負の金額で記録 | - |
| BR-13-04 | 論理削除対応 | トランザクション削除時はサマリーから金額を差し引く | トランザクション削除時 |

### 計算ロジック

```
paid_total = SUM(amount) where amount > 0
refunded_total = ABS(SUM(amount)) where amount < 0
refundable_amount = paid_total - refunded_total
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| トランザクション追加 | order_transaction | INSERT | トランザクションの作成 |
| トランザクション追加 | order_summary | UPDATE | paid_total等の更新 |
| トランザクション削除 | order_transaction | UPDATE (soft delete) | 論理削除 |
| トランザクション削除 | order_summary | UPDATE | paid_total等の更新 |

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

#### order_transaction

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | 自動生成（prefix: ordtrx） | 主キー |
| INSERT | order_id | 対象注文ID | 外部キー |
| INSERT | version | 注文の現在バージョン | 整数 |
| INSERT | amount | リクエストのamount | BigNumber |
| INSERT | currency_code | リクエストのcurrency_code | 文字列 |
| INSERT | reference | リクエストのreference | nullable |
| INSERT | reference_id | リクエストのreference_id | nullable |
| INSERT | return_id | リクエストのreturn_id | nullable（外部キー） |
| INSERT | claim_id | リクエストのclaim_id | nullable（外部キー） |
| INSERT | exchange_id | リクエストのexchange_id | nullable（外部キー） |

## エラー処理

### エラーケース一覧

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

### リトライ仕様

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

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

- `@InjectTransactionManager`デコレータにより、トランザクション追加処理はDBトランザクション内で実行
- OrderTransaction作成とOrderSummary更新は同一トランザクション内で実行
- 処理失敗時は全ての変更がロールバックされる

## パフォーマンス要件

- トランザクション追加：200ms以内
- トランザクション一覧取得：100件以下で500ms以内
- インデックス：order_id、reference_id、return_id、claim_id、exchange_idにインデックス設定

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

- トランザクションの追加・削除は認証済み管理者のみ実行可能
- 金額情報は監査ログに記録
- 支払いプロバイダーからの参照情報（reference_id）は適切に保護

## 備考

- トランザクションは返品（Return）、クレーム（Claim）、交換（Exchange）と紐付け可能
- これにより、どの処理に対する支払い・返金かを追跡可能
- 複合インデックス（order_id, version）により、特定バージョン時点のトランザクション取得が効率的

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | transaction.ts | `packages/modules/order/src/models/transaction.ts` | OrderTransactionエンティティ、amount/currency_code/referenceプロパティ、order/return/claim/exchangeリレーション |

**読解のコツ**:
- **11-36行目**: 各リレーション（order, return, exchange, claim）の定義を確認
- **38-87行目**: インデックス定義（order_id, reference_id, return_id等）を確認

#### Step 2: サービス層の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | 3633-3735行：addOrderTransactions、deleteOrderTransactionsメソッド |

**主要処理フロー**:
1. **3668-3705行目**: `addOrderTransactions_` - 注文バージョンの取得・設定、トランザクション作成、サマリー更新
2. **3702行目**: `updateOrderPaidRefundableAmount_`の呼び出し - サマリー更新処理

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

```
addOrderTransactions (public)
    └─ addOrderTransactions_
           ├─ orderService_.list (注文バージョン取得)
           ├─ orderTransactionService_.create (トランザクション作成)
           └─ updateOrderPaidRefundableAmount_ (サマリー更新)

deleteOrderTransactions
    ├─ listOrderTransactions (対象取得)
    ├─ orderTransactionService_.delete (削除)
    └─ updateOrderPaidRefundableAmount_ (サマリー更新)

softDeleteOrderTransactions
    └─ softDeleteOrderTransactions_
           ├─ listOrderTransactions
           ├─ super.softDeleteOrderTransactions
           └─ updateOrderPaidRefundableAmount_
```

### データフロー図

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

CreateOrderTransactionDTO ─▶ addOrderTransactions_ ─────▶ order_transaction テーブル
       │                        │
       │                        v
       │                  updateOrderPaidRefundableAmount_
       │                        │
       v                        v
 order_id, amount,        paid_total,              order_summary テーブル
 currency_code            refundable_amount
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | ソース | トランザクション管理の主要ロジック |
| transaction.ts | `packages/modules/order/src/models/transaction.ts` | ソース | OrderTransactionエンティティ定義 |
| order-summary.ts | `packages/modules/order/src/models/order-summary.ts` | ソース | OrderSummaryエンティティ定義 |
| transaction.ts | `packages/modules/order/src/types/transaction.ts` | ソース | DTO型定義 |
