# 画面設計書 16-商品オプション作成画面

## 概要

本ドキュメントは、Medusa Admin Dashboard における商品オプション作成画面の設計仕様を定義するものである。

### 本画面の処理概要

商品オプション作成画面は、商品に新しいオプション（サイズ、色、素材等の選択属性）を追加するための画面である。オプションとそのバリエーション値を設定し、商品バリアントの生成基盤を構築する。

**業務上の目的・背景**：商品バリアントは複数のオプションの組み合わせで構成される。本画面は、新しいオプション種別を追加し、そのオプションが取りうる値（バリエーション）を定義することで、商品の多様性を表現するために必要である。例えば「サイズ」オプションに「S, M, L, XL」の値を設定することで、サイズ別バリアントの作成が可能になる。

**画面へのアクセス方法**：商品詳細画面のオプションセクションから「Add Option」ボタンをクリックすることでドロワー形式で表示される。URLパスは `/products/:id/options/create` となる。

**主要な操作・処理内容**：
1. オプションタイトル（名前）の入力
2. オプション値（バリエーション）の入力（複数可、チップ形式）
3. オプションの作成・保存

**画面遷移**：
- 遷移元：商品詳細画面（No.7）
- 遷移先：商品詳細画面（保存/キャンセル後）

**権限による表示制御**：本画面へのアクセスには商品管理権限が必要。権限がない場合は画面にアクセスできない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 商品オプション管理 | 主機能 | 商品オプションの新規作成 |

## 画面種別

登録（ドロワー形式）

## URL/ルーティング

```
/products/:id/options/create
```

パラメータ：
- `id`：商品ID（必須）

## 入出力項目

### 入力項目

| 項目名 | 項目ID | 型 | 必須 | バリデーション | 備考 |
|--------|--------|-----|------|---------------|------|
| オプションタイトル | title | string | 必須 | 最小1文字 | 例：サイズ、色 |
| オプション値 | values | string[] | - | - | チップ入力形式 |

### 出力項目

| 項目名 | 項目ID | 型 | 備考 |
|--------|--------|-----|------|
| 作成されたオプション | option | ProductOption | APIレスポンス |

## 表示項目

### フォーム

| 項目名 | 表示形式 | 備考 |
|--------|---------|------|
| オプションタイトル | Input | プレースホルダー付き |
| バリエーション | ChipInput | タグ形式で複数入力 |

### ヘッダー

| 項目名 | 表示形式 | 備考 |
|--------|---------|------|
| タイトル | Heading | "Create Product Option" |

## イベント仕様

### 1-オプションタイトル入力

**トリガー**：Inputへの入力

**処理フロー**：
1. react-hook-formでフォーム状態を管理
2. zodバリデーション（最小1文字）

### 2-オプション値入力

**トリガー**：ChipInputへの入力（Enter、カンマ、タブで確定）

**処理フロー**：
1. 入力値を配列に追加
2. チップとして表示
3. チップのクリックで削除可能

### 3-保存

**トリガー**：「Save」ボタン押下

**処理フロー**：
1. フォームバリデーションを実行
2. `useCreateProductOption`ミューテーションでオプションを作成
3. 成功時にトースト表示、ドロワーを閉じる
4. 関連クエリを無効化（optionsQueryKeys.lists、productsQueryKeys.detail）

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | product_option | INSERT | 新規オプションの作成 |
| 保存ボタン押下 | product_option_value | INSERT | オプション値の作成（複数可） |

### テーブル別更新項目詳細

#### product_option

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | product_id | 対象商品ID | 必須 |
| INSERT | title | オプションタイトル | 必須 |

#### product_option_value

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | option_id | 作成されたオプションID | 必須 |
| INSERT | value | オプション値 | 必須 |

## メッセージ仕様

| 種別 | メッセージキー | 表示条件 |
|------|--------------|---------|
| 成功 | products.options.create.successToast | 保存成功時 |
| エラー | (API error message) | API呼び出し失敗時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 商品が見つからない | エラーをスロー（親コンポーネントでハンドリング） |
| バリデーションエラー | フォームエラーを表示 |
| API呼び出し失敗 | エラートースト表示 |

## 備考

- RouteDrawerコンポーネントを使用したドロワー形式
- ChipInputコンポーネントでタグ形式の複数値入力
- オプション値は空配列でも作成可能（後から編集で追加）
- 作成後は商品詳細のクエリキャッシュが自動的に無効化される

---

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

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

### 推奨読解順序

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

まず、オプション作成のデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | create-product-option-form.tsx | `packages/admin/dashboard/src/routes/products/product-create-option/components/create-product-option-form/create-product-option-form.tsx` | CreateProductOptionSchemaの定義（18-21行目） |

**読解のコツ**: シンプルなスキーマで、title（必須、最小1文字）とvalues（オプション、string配列）を管理。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | product-create-option.tsx | `packages/admin/dashboard/src/routes/products/product-create-option/product-create-option.tsx` | ルートコンポーネント、商品データのフェッチ |

**主要処理フロー**:
- **8行目**: useParamsでidを取得
- **12-16行目**: useProductで商品データを取得
- **22-29行目**: RouteDrawer内でCreateProductOptionFormをレンダリング

#### Step 3: 作成フォームを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create-product-option-form.tsx | `packages/admin/dashboard/src/routes/products/product-create-option/components/create-product-option-form/create-product-option-form.tsx` | メインのフォームロジック |

**主要処理フロー**:
- **29-35行目**: useFormの初期化（空のtitle、空のvalues配列）
- **37行目**: useCreateProductOptionミューテーション
- **39-53行目**: handleSubmit - 保存処理

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

```
ProductCreateOption (product-create-option.tsx)
    │
    ├─ useParams
    │      └─ id を取得
    │
    ├─ useProduct (hooks/api/products.tsx)
    │      └─ sdk.admin.product.retrieve
    │
    └─ CreateProductOptionForm (create-product-option-form.tsx)
           │
           ├─ useForm (react-hook-form)
           │      └─ zodResolver(CreateProductOptionSchema)
           │
           ├─ Input (title入力)
           │
           ├─ ChipInput (values入力)
           │
           └─ useCreateProductOption
                  └─ sdk.admin.product.createOption
```

### データフロー図

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

title入力 ────────────────▶ useForm ────────────────────────▶ フォーム状態更新
        │
        └─ zodバリデーション
               └─ 最小1文字

ChipInput ────────────────▶ useForm ────────────────────────▶ values配列更新
        │
        └─ Enter/カンマ/タブで確定
               └─ 配列に追加

保存ボタン ───────────────▶ handleSubmit ───────────────────▶ API更新
        │
        └─ useCreateProductOption
               └─ sdk.admin.product.createOption
                      └─ { title, values }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| product-create-option.tsx | `packages/admin/dashboard/src/routes/products/product-create-option/product-create-option.tsx` | ソース | ルートコンポーネント |
| create-product-option-form.tsx | `packages/admin/dashboard/src/routes/products/product-create-option/components/create-product-option-form/create-product-option-form.tsx` | ソース | 作成フォーム本体 |
| index.ts | `packages/admin/dashboard/src/routes/products/product-create-option/index.ts` | ソース | エクスポート定義 |
| products.tsx | `packages/admin/dashboard/src/hooks/api/products.tsx` | ソース | 商品関連APIフック（useCreateProductOption含む） |
| chip-input.tsx | `packages/admin/dashboard/src/components/inputs/chip-input/chip-input.tsx` | ソース | チップ入力コンポーネント |
