# 機能設計書 5-商品コレクション管理

## 概要

本ドキュメントは、Medusaコマースプラットフォームにおける商品コレクション（Product Collection）のグループ化管理機能の設計を記述する。

### 本機能の処理概要

**業務上の目的・背景**：
商品コレクションは、商品をマーケティング目的やテーマでグループ化するための機能である。カテゴリとは異なり、フラットな構造で「夏のセール」「新着商品」「おすすめ」などのキュレーションに使用される。1つの商品は1つのコレクションにのみ属することができる（1対多の関係）。

**機能の利用シーン**：
- 季節限定セールのコレクション作成
- 新着商品のグループ化
- 特集ページ用の商品グループ作成
- コレクションの名前・ハンドル変更
- 不要になったコレクションの削除

**主要な処理内容**：
1. コレクションの新規作成（タイトル、ハンドル設定）
2. コレクションの一覧取得
3. コレクションの個別取得
4. コレクションの更新（タイトル変更、商品追加・削除）
5. コレクションの削除

**関連システム・外部連携**：
- 商品モジュール（Product Module）：商品とコレクションの1対多関連
- ストアフロント：コレクション別商品一覧の表示

**権限による制御**：
- Admin API経由のアクセスには認証が必要（AuthenticatedMedusaRequest）
- コレクションの作成・更新・削除は管理者権限を持つユーザーのみ実行可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | コレクション一覧画面 | 主画面 | コレクションの一覧表示 |
| 18 | コレクション編集画面 | 主画面 | コレクションの作成・更新 |

## 機能種別

CRUD操作（Create / Read / Update / Delete）

## 入力仕様

### 入力パラメータ

#### コレクション作成（POST /admin/collections）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| title | string | Yes | コレクション名 | 必須 |
| handle | string | No | URLスラッグ | ユニーク（deleted_at IS NULL） |
| metadata | object | No | メタデータ | JSON形式 |

#### コレクション更新（POST /admin/collections/:id）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| title | string | No | コレクション名 | - |
| handle | string | No | URLスラッグ | ユニーク |
| metadata | object | No | メタデータ | - |

### 入力データソース

- 管理画面（Admin Dashboard）からのフォーム入力
- REST API経由のJSON/リクエストボディ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | string | コレクションID（pcol_xxx形式） |
| title | string | コレクション名 |
| handle | string | URLスラッグ |
| products | array | 関連商品配列 |
| metadata | object | メタデータ |
| created_at | datetime | 作成日時 |
| updated_at | datetime | 更新日時 |
| deleted_at | datetime | 削除日時 |

### 出力先

- REST APIレスポンス（JSON形式）
- 管理画面への表示

## 処理フロー

### 処理シーケンス

```
1. コレクション作成フロー
   ├─ handle自動生成（未指定時）
   ├─ コレクション作成（createCollectionsStep）
   ├─ フック実行（collectionsCreated）
   └─ イベント発行（ProductCollectionWorkflowEvents.CREATED）

2. コレクション取得フロー
   ├─ フィルタ条件の適用
   ├─ remoteQueryによるデータ取得
   └─ レスポンス整形

3. コレクション更新フロー
   ├─ 既存コレクションの存在確認
   ├─ コレクション更新（updateCollectionsStep）
   ├─ フック実行（collectionsUpdated）
   └─ イベント発行（ProductCollectionWorkflowEvents.UPDATED）

4. コレクション削除フロー
   ├─ コレクション削除（deleteCollectionsStep）
   ├─ リモートリンク削除（removeRemoteLinkStep）
   ├─ フック実行（collectionsDeleted）
   └─ イベント発行（ProductCollectionWorkflowEvents.DELETED）
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-CL01 | ハンドル一意性 | handleは削除されていないコレクション間でユニーク | コレクション作成・更新時 |
| BR-CL02 | ハンドル自動生成 | handle未指定時、titleからkebab-case形式で自動生成 | コレクション作成時 |
| BR-CL03 | 商品単一所属 | 1つの商品は1つのコレクションにのみ属する | 商品追加時 |

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 作成 | product_collection | INSERT | コレクションレコードの挿入 |
| 取得 | product_collection | SELECT | コレクションの取得 |
| 更新 | product_collection | UPDATE | コレクションの更新 |
| 更新 | product | UPDATE | collection_idの更新 |
| 削除 | product_collection | UPDATE | deleted_atの設定（論理削除） |

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

#### product_collection

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | 自動生成（pcol_xxx形式） | generateEntityId使用 |
| INSERT | title | リクエストの値 | 必須 |
| INSERT | handle | リクエストの値 or 自動生成 | ユニーク |
| DELETE | deleted_at | 現在日時 | 論理削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NOT_FOUND | 404 | 指定IDのコレクションが存在しない | 正しいIDを指定 |
| INVALID_DATA | 400 | handleが重複 | ユニークな値を指定 |

## 備考

- コレクションのIDプレフィックスは「pcol」
- 商品はproduct.collection_idでコレクションを参照（belongsTo関係）

---

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | product-collection.ts | `packages/modules/product/src/models/product-collection.ts` | コレクションモデル定義 |

**主要処理フロー（product-collection.ts）**:
- **4-23行目**: ProductCollectionモデル定義
- **6行目**: IDプレフィックス「pcol」
- **7行目**: titleフィールド（searchable, translatable）
- **8行目**: handleフィールド
- **10-12行目**: 商品との1対多リレーション
- **14-21行目**: ユニークインデックス（handle）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | route.ts | `packages/medusa/src/api/admin/collections/route.ts` | 一覧・作成エンドポイント |
| 2-2 | [id]/route.ts | `packages/medusa/src/api/admin/collections/[id]/route.ts` | 詳細・更新・削除 |

#### Step 3: ワークフローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create-collections.ts | `packages/core/core-flows/src/product/workflows/create-collections.ts` | 作成ワークフロー |
| 3-2 | update-collections.ts | `packages/core/core-flows/src/product/workflows/update-collections.ts` | 更新ワークフロー |
| 3-3 | delete-collections.ts | `packages/core/core-flows/src/product/workflows/delete-collections.ts` | 削除ワークフロー |

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| product-collection.ts | `packages/modules/product/src/models/product-collection.ts` | モデル | コレクションエンティティ定義 |
| route.ts | `packages/medusa/src/api/admin/collections/route.ts` | API | 一覧・作成エンドポイント |
| [id]/route.ts | `packages/medusa/src/api/admin/collections/[id]/route.ts` | API | 詳細・更新・削除 |
| create-collections.ts | `packages/core/core-flows/src/product/workflows/create-collections.ts` | ワークフロー | 作成処理 |
| update-collections.ts | `packages/core/core-flows/src/product/workflows/update-collections.ts` | ワークフロー | 更新処理 |
| delete-collections.ts | `packages/core/core-flows/src/product/workflows/delete-collections.ts` | ワークフロー | 削除処理 |
