# 機能設計書 20-カート明細管理

## 概要

本ドキュメントは、Medusaコマースプラットフォームにおけるカート明細管理機能の設計を記載したものである。カートに追加された商品明細（ラインアイテム）の管理機能について、処理フロー、データ構造、ビジネスルールを定義する。

### 本機能の処理概要

カート明細管理機能は、ECサイトにおけるカート内の商品明細を管理するための機能である。

**業務上の目的・背景**：ECサイトにおいて、顧客が購入を検討している商品をカートに追加・編集・削除することは、購買体験の中核となる機能である。本機能は、カート明細（LineItem）の追加・更新・削除と、関連する税金ライン・調整の管理を提供する。

**機能の利用シーン**：
- 顧客が商品をカートに追加する場面
- 顧客がカート内の商品数量を変更する場面
- 顧客がカートから商品を削除する場面
- プロモーション適用時に調整を追加する場面
- 税金計算時に税金ラインを追加する場面

**主要な処理内容**：
1. 明細（LineItem）の追加・更新・削除
2. 明細の税金ライン（LineItemTaxLine）の管理
3. 明細の調整（LineItemAdjustment）の管理
4. 商品情報の取得と明細への反映
5. 数量・単価の管理

**関連システム・外部連携**：
- 商品モジュール：商品・バリアント情報の取得
- 価格モジュール：単価の取得
- プロモーションモジュール：割引調整の適用
- 税金モジュール：税金計算

**権限による制御**：
- 顧客は自身のカートの明細のみ操作可能
- 管理者は任意のカート明細を操作可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | カート画面 | 主画面 | 明細の追加・数量変更・削除 |
| 2 | チェックアウト画面 | 参照画面 | 明細内容の確認 |

## 機能種別

CRUD操作 / 金額計算

## 入力仕様

### 入力パラメータ（明細追加）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cart_id | string | Yes | カートID | 有効なカートIDであること |
| title | string | Yes | 商品タイトル | 空文字不可 |
| quantity | number | Yes | 数量 | 1以上 |
| unit_price | BigNumber | Yes | 単価 | 0以上 |
| variant_id | string | No | バリアントID | - |
| product_id | string | No | 商品ID | - |
| product_title | string | No | 商品タイトル | - |
| product_description | string | No | 商品説明 | - |
| product_subtitle | string | No | 商品サブタイトル | - |
| product_type | string | No | 商品タイプ | - |
| product_type_id | string | No | 商品タイプID | - |
| product_collection | string | No | コレクション | - |
| product_handle | string | No | 商品ハンドル | - |
| variant_sku | string | No | SKU | - |
| variant_barcode | string | No | バーコード | - |
| variant_title | string | No | バリアントタイトル | - |
| variant_option_values | object | No | オプション値 | JSON形式 |
| requires_shipping | boolean | No | 配送必要フラグ | デフォルトtrue |
| is_discountable | boolean | No | 割引可能フラグ | デフォルトtrue |
| is_giftcard | boolean | No | ギフトカードフラグ | デフォルトfalse |
| is_tax_inclusive | boolean | No | 税込みフラグ | デフォルトfalse |
| is_custom_price | boolean | No | カスタム価格フラグ | デフォルトfalse |
| compare_at_unit_price | BigNumber | No | 比較単価 | - |
| metadata | object | No | メタデータ | JSON形式 |

### 入力パラメータ（明細更新）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | string | Yes | 明細ID | 有効な明細IDであること |
| quantity | number | No | 数量 | 1以上 |
| unit_price | BigNumber | No | 単価 | 0以上 |
| title | string | No | タイトル | - |
| metadata | object | No | メタデータ | JSON形式 |

### 入力データソース

- フロントエンド：顧客のカート操作
- プロモーションモジュール：調整の適用
- 税金モジュール：税金ラインの設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | string | 明細ID（prefix: cali） |
| cart_id | string | カートID |
| title | string | 商品タイトル |
| subtitle | string | サブタイトル |
| thumbnail | string | サムネイル画像URL |
| quantity | number | 数量 |
| unit_price | BigNumber | 単価 |
| compare_at_unit_price | BigNumber | 比較単価 |
| variant_id | string | バリアントID |
| product_id | string | 商品ID |
| requires_shipping | boolean | 配送必要フラグ |
| is_discountable | boolean | 割引可能フラグ |
| is_giftcard | boolean | ギフトカードフラグ |
| is_tax_inclusive | boolean | 税込みフラグ |
| is_custom_price | boolean | カスタム価格フラグ |
| adjustments | LineItemAdjustment[] | 調整一覧 |
| tax_lines | LineItemTaxLine[] | 税金ライン一覧 |
| total | BigNumber | 明細合計（計算値） |
| subtotal | BigNumber | 明細小計（計算値） |
| tax_total | BigNumber | 税金合計（計算値） |
| discount_total | BigNumber | 割引合計（計算値） |

### 出力先

- データベース：cart_line_itemテーブル
- API応答：CartLineItemDTO形式

## 処理フロー

### 処理シーケンス（明細追加）

```
1. 明細追加リクエスト受信
   └─ cart_id、title、quantity、unit_price等を含むリクエストを受信

2. カート存在確認
   └─ 対象カートの存在確認

3. 明細の作成
   └─ LineItemレコードを作成

4. 結果返却
   └─ 作成された明細をシリアライズして返却
```

### フローチャート

```mermaid
flowchart TD
    A[明細追加リクエスト] --> B[カート存在確認]
    B --> C{カートが存在?}
    C -->|No| D[エラー返却]
    C -->|Yes| E[LineItem作成]
    E --> F[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-20-01 | 明細ID生成 | 明細IDは"cali"プレフィックス付きで自動生成 | 明細作成時 |
| BR-20-02 | カスケード削除 | 明細削除時はadjustments、tax_linesも削除 | 明細削除時 |
| BR-20-03 | 割引可能判定 | is_discountable=falseの明細には割引調整を適用しない | 調整追加時 |
| BR-20-04 | ギフトカード判定 | is_giftcard=trueの明細は特別な処理が適用される | - |
| BR-20-05 | 税込み判定 | is_tax_inclusive=trueの場合、unit_priceは税込み価格として扱う | 税金計算時 |

### 計算ロジック

```
line_subtotal = unit_price * quantity
line_discount_total = SUM(adjustments.amount)
line_tax_total = SUM(tax_lines.amount)
line_total = line_subtotal - line_discount_total + line_tax_total  # 税抜きの場合
line_total = line_subtotal - line_discount_total                    # 税込みの場合
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 明細追加 | cart_line_item | INSERT | 明細レコードの作成 |
| 明細更新 | cart_line_item | UPDATE | 明細属性の更新 |
| 明細削除 | cart_line_item | DELETE | 明細の削除 |
| 税金ライン追加 | cart_line_item_tax_line | INSERT | 税金ラインの作成 |
| 調整追加 | cart_line_item_adjustment | INSERT | 調整の作成 |

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

#### cart_line_item

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | 自動生成（prefix: cali） | 主キー |
| INSERT | cart_id | 対象カートID | 外部キー |
| INSERT | title | リクエストのtitle | 必須 |
| INSERT | quantity | リクエストのquantity | 必須 |
| INSERT | unit_price | リクエストのunit_price | 必須 |
| INSERT | variant_id | リクエストのvariant_id | nullable |
| INSERT | product_id | リクエストのproduct_id | nullable |
| INSERT | requires_shipping | リクエストのrequires_shipping | デフォルトtrue |
| INSERT | is_discountable | リクエストのis_discountable | デフォルトtrue |
| INSERT | is_giftcard | リクエストのis_giftcard | デフォルトfalse |
| INSERT | is_tax_inclusive | リクエストのis_tax_inclusive | デフォルトfalse |
| INSERT | is_custom_price | リクエストのis_custom_price | デフォルトfalse |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NOT_FOUND | MedusaError | 指定されたカートIDまたは明細IDが存在しない | 有効なIDを指定 |
| INVALID_DATA | MedusaError | 必須パラメータ（title, quantity, unit_price）が未指定 | 必須項目を入力 |
| INVALID_DATA | MedusaError | quantity が0以下 | 1以上の数量を指定 |

### リトライ仕様

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

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

- `@InjectTransactionManager`デコレータにより、明細追加・更新処理はトランザクション内で実行
- 明細と関連する調整・税金ラインの操作は同一トランザクション内で実行可能
- 処理失敗時は全ての変更がロールバックされる

## パフォーマンス要件

- 明細追加：100ms以内
- 明細更新：100ms以内
- インデックス：cart_id、variant_id、product_id、product_type_idにインデックス設定

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

- 顧客は自身のカートの明細のみ操作可能
- 価格情報の改ざん防止のため、サーバーサイドで価格を検証
- is_custom_price=trueの場合のみ任意の価格設定が可能

## 備考

- LineItemのテーブル名は"cart_line_item"
- 商品関連の属性（product_title, variant_sku等）は非正規化されたスナップショットとして保存
- これにより、商品マスタが変更されても注文履歴の整合性が保たれる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | line-item.ts | `packages/modules/cart/src/models/line-item.ts` | LineItemエンティティ、title/quantity/unit_priceプロパティ、adjustments/tax_linesリレーション |

**読解のコツ**:
- **7-8行目**: テーブル名は"cart_line_item"、IDプレフィックスは"cali"
- **10-35行目**: title、quantity、unit_price、variant_id、product_id等の主要プロパティ
- **27-35行目**: requires_shipping、is_discountable、is_giftcard、is_tax_inclusive、is_custom_priceフラグ
- **36-44行目**: adjustments、tax_lines、cartリレーション

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cart-module.ts | `packages/modules/cart/src/services/cart-module.ts` | addLineItems、updateLineItems、deleteLineItemsメソッド |

**主要処理フロー**:
1. **433-470行目**: `addLineItems` - 明細追加の公開メソッド
2. **472-492行目**: `addLineItems_` - カート指定での明細追加
3. **494-500行目**: `addLineItemsBulk_` - 明細の一括作成

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

```
addLineItems (public)
    ├─ addLineItems_（cart_id指定の場合）
    │      ├─ cartService_.retrieve
    │      └─ addLineItemsBulk_
    │             └─ lineItemService_.create
    │
    └─ addLineItemsBulk_（直接データの場合）
           └─ lineItemService_.create

updateLineItems
    └─ lineItemService_.update

deleteLineItems
    └─ lineItemService_.delete
```

### データフロー図

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

CreateLineItemDTO ───────▶ addLineItems_ ─────────────▶ cart_line_item テーブル
       │                        │
       v                        v
 cart_id, title,          lineItemService_.create       CartLineItemDTO
 quantity, unit_price

調整適用時:
LineItemAdjustmentDTO ───▶ lineItemAdjustmentService_ ─▶ cart_line_item_adjustment テーブル

税金ライン設定時:
LineItemTaxLineDTO ──────▶ lineItemTaxLineService_ ───▶ cart_line_item_tax_line テーブル
```

### 関連ファイル一覧

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