# 機能設計書 19-カートCRUD

## 概要

本ドキュメントは、MedusaコマースプラットフォームにおけるカートCRUD機能の設計を記載したものである。カート（買い物かご）の基本的なCRUD操作について、処理フロー、データ構造、ビジネスルールを定義する。

### 本機能の処理概要

カートCRUD機能は、ECサイトにおけるカート（買い物かご）の基本管理機能である。

**業務上の目的・背景**：ECサイトにおいて、カートは顧客が購入を検討している商品を一時的に保存する重要な機能である。本機能は、カートの作成・取得・更新・削除という基本操作を提供し、注文完了までの購入フローを支援する。

**機能の利用シーン**：
- 顧客が初めて商品をカートに追加する場面（カート作成）
- 顧客がカート内容を確認する場面（カート取得）
- 顧客がカート情報（配送先住所、メール等）を更新する場面
- カートを破棄する場面（カート削除）
- 注文完了後のカートクローズ処理

**主要な処理内容**：
1. カート（Cart）の作成
2. カートの取得（単一・一覧・件数付き一覧）
3. カートの更新（属性変更）
4. カートの削除
5. 合計金額の自動計算
6. 配送先・請求先住所の管理

**関連システム・外部連携**：
- 商品モジュール：商品情報の取得
- 価格モジュール：価格計算
- 在庫モジュール：在庫確認
- 顧客モジュール：顧客情報の紐付け
- 地域モジュール：地域・通貨設定
- 注文モジュール：カートから注文への変換

**権限による制御**：
- 顧客は自身のカートのみ操作可能
- ゲストユーザーもカート作成可能（customer_id = null）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | カート画面 | 主画面 | カート内容の表示・編集 |
| 2 | チェックアウト画面 | 主画面 | カート情報の確認・注文確定 |

## 機能種別

CRUD操作 / 金額計算

## 入力仕様

### 入力パラメータ（カート作成）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| currency_code | string | Yes | 通貨コード | 有効な通貨コードであること |
| region_id | string | No | 地域ID | 有効な地域IDであること |
| customer_id | string | No | 顧客ID | 有効な顧客IDであること |
| sales_channel_id | string | No | 販売チャネルID | - |
| email | string | No | メールアドレス | 有効なメール形式 |
| locale | string | No | ロケール（BCP 47形式） | v2.12.3〜 |
| shipping_address | AddressInput | No | 配送先住所 | - |
| billing_address | AddressInput | No | 請求先住所 | - |
| items | LineItemInput[] | No | 初期明細アイテム | - |
| metadata | object | No | メタデータ | JSON形式 |

### 入力パラメータ（カート更新）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | string | Yes | カートID | 有効なカートIDであること |
| region_id | string | No | 地域ID | - |
| customer_id | string | No | 顧客ID | - |
| email | string | No | メールアドレス | 有効なメール形式 |
| locale | string | No | ロケール | - |
| metadata | object | No | メタデータ | JSON形式 |

### 入力データソース

- フロントエンド：顧客のカート操作
- API：外部システムからのカート管理

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | string | カートID（prefix: cart） |
| region_id | string | 地域ID |
| customer_id | string | 顧客ID |
| sales_channel_id | string | 販売チャネルID |
| email | string | メールアドレス |
| currency_code | string | 通貨コード |
| locale | string | ロケール |
| completed_at | Date | 完了日時（注文確定時） |
| shipping_address | Address | 配送先住所 |
| billing_address | Address | 請求先住所 |
| items | LineItem[] | 明細アイテム |
| shipping_methods | ShippingMethod[] | 配送方法 |
| credit_lines | CreditLine[] | クレジットライン |
| total | BigNumber | 合計金額 |
| subtotal | BigNumber | 小計 |
| tax_total | BigNumber | 税金合計 |
| discount_total | BigNumber | 割引合計 |

### 出力先

- データベース：cartテーブル
- API応答：CartDTO形式

## 処理フロー

### 処理シーケンス（カート作成）

```
1. カート作成リクエスト受信
   └─ currency_code、region_id等を含むリクエストを受信

2. カートIDの生成
   └─ prefixが"cart"のIDを生成

3. カートの作成
   └─ Cartレコードを作成

4. 住所の作成（オプション）
   └─ shipping_address、billing_addressが指定されている場合は作成

5. 明細アイテムの作成（オプション）
   └─ itemsが指定されている場合は明細を作成

6. 結果返却
   └─ 作成されたカートをシリアライズして返却
```

### フローチャート

```mermaid
flowchart TD
    A[カート作成リクエスト] --> B[カートID生成]
    B --> C[Cartレコード作成]
    C --> D{住所あり?}
    D -->|Yes| E[Address作成]
    D -->|No| F{明細あり?}
    E --> F
    F -->|Yes| G[LineItem作成]
    F -->|No| H[結果返却]
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-19-01 | カートID生成 | カートIDは"cart"プレフィックス付きで自動生成 | カート作成時 |
| BR-19-02 | 通貨必須 | currency_codeは必須項目 | カート作成時 |
| BR-19-03 | 合計自動計算 | 取得時にselectでtotal系フィールドを指定すると自動計算 | カート取得時 |
| BR-19-04 | カスケード削除 | カート削除時はitems、shipping_methods、shipping_address、billing_addressも削除 | カート削除時 |
| BR-19-05 | completed_at設定 | 注文完了時にcompleted_atが設定される | 注文確定時 |

### 計算ロジック

```
subtotal = SUM(items.unit_price * items.quantity)
discount_total = SUM(items.adjustments.amount) + SUM(shipping_methods.adjustments.amount)
tax_total = SUM(items.tax_lines.amount) + SUM(shipping_methods.tax_lines.amount)
total = subtotal + shipping_total - discount_total + tax_total
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| カート作成 | cart | INSERT | カートレコードの作成 |
| カート作成 | cart_address | INSERT | 住所の作成（オプション） |
| カート作成 | cart_line_item | INSERT | 明細の作成（オプション） |
| カート更新 | cart | UPDATE | カート属性の更新 |
| カート削除 | cart | DELETE | カートとカスケード削除 |

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

#### cart

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | 自動生成（prefix: cart） | 主キー |
| INSERT | region_id | リクエストのregion_id | nullable |
| INSERT | customer_id | リクエストのcustomer_id | nullable |
| INSERT | sales_channel_id | リクエストのsales_channel_id | nullable |
| INSERT | email | リクエストのemail | nullable |
| INSERT | currency_code | リクエストのcurrency_code | 必須 |
| INSERT | locale | リクエストのlocale | nullable（v2.12.3〜） |
| INSERT | metadata | リクエストのmetadata | JSON形式 |
| UPDATE | completed_at | 注文確定日時 | 注文確定時に設定 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NOT_FOUND | MedusaError | 指定されたカートIDが存在しない | 有効なカートIDを指定 |
| INVALID_DATA | MedusaError | currency_code未指定 | 通貨コードを指定 |

### リトライ仕様

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

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

- `@InjectTransactionManager`デコレータにより、カート作成処理はトランザクション内で実行
- カート、住所、明細アイテムの作成は同一トランザクション内で実行
- 処理失敗時は全ての変更がロールバックされる

## パフォーマンス要件

- カート作成：200ms以内
- カート取得：100ms以内
- インデックス：region_id、customer_id、sales_channel_id、currency_codeにインデックス設定

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

- カートIDは推測困難な形式で生成
- 顧客は自身のカートのみ操作可能
- メールアドレス等の個人情報は適切に保護

## 備考

- locale属性はv2.12.3で追加（BCP 47形式、例："en-US"）
- 合計金額計算はdecorateCartTotals関数で実行
- カートから注文への変換は別機能（注文作成）で実行

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cart.ts | `packages/modules/cart/src/models/cart.ts` | Cartエンティティ、region_id/customer_id/currency_codeプロパティ、items/shipping_methods/credit_linesリレーション |

**読解のコツ**:
- **9行目**: IDプレフィックスは"cart"
- **10-24行目**: region_id、customer_id、sales_channel_id、email、currency_code、locale等の主要プロパティ
- **26-46行目**: shipping_address、billing_address、items、credit_lines、shipping_methodsリレーション
- **48-55行目**: カスケード削除の設定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cart-module.ts | `packages/modules/cart/src/services/cart-module.ts` | CartModuleServiceクラス、createCarts、updateCarts、retrieveCart、listCartsメソッド |

**主要処理フロー**:
1. **198-214行目**: `retrieveCart` - カート取得、合計計算オプション
2. **260-290行目**: `createCarts` - カート作成の公開メソッド
3. **292-340行目**: `createCarts_` - カート作成の内部処理、明細アイテムの一括作成
4. **359-381行目**: `updateCarts` - カート更新の公開メソッド

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

```
createCarts (public)
    └─ createCarts_
           ├─ cartService_.create（カート作成）
           ├─ addLineItemsBulk_（明細作成、オプション）
           └─ cartService_.list（作成結果取得）

retrieveCart
    └─ super.retrieveCart
           └─ decorateCartTotals（合計計算、オプション）

updateCarts
    └─ updateCarts_
           └─ cartService_.update

listCarts
    └─ super.listCarts
           └─ decorateCartTotals（合計計算、オプション）
```

### データフロー図

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

CreateCartDTO ────────▶ createCarts_ ──────────────▶ cart テーブル
       │                      │
       │                      ├─▶ addressService_ ─────▶ cart_address テーブル
       │                      │
       │                      └─▶ addLineItemsBulk_ ───▶ cart_line_item テーブル
       │
       v
 currency_code,                                          CartDTO
 region_id, email...

合計計算時:
cart + items + shipping_methods ─▶ decorateCartTotals ─▶ total, subtotal,
                                                          tax_total, discount_total
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cart.ts | `packages/modules/cart/src/models/cart.ts` | ソース | Cartエンティティ定義 |
| cart-module.ts | `packages/modules/cart/src/services/cart-module.ts` | ソース | CartModuleServiceサービス |
| address.ts | `packages/modules/cart/src/models/address.ts` | ソース | Addressエンティティ定義 |
| line-item.ts | `packages/modules/cart/src/models/line-item.ts` | ソース | LineItemエンティティ定義 |
| shipping-method.ts | `packages/modules/cart/src/models/shipping-method.ts` | ソース | ShippingMethodエンティティ定義 |
| cart.ts | `packages/modules/cart/src/types/cart.ts` | ソース | DTO型定義 |
