# 画面設計書 17-商品オプション編集画面

## 概要

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

### 本画面の処理概要

商品オプション編集画面は、既存の商品オプション（サイズ、色、素材等の選択属性）を編集するための画面である。オプションタイトルやバリエーション値の変更が可能。

**業務上の目的・背景**：商品のオプション名称の変更や、バリエーション値の追加・修正が必要な場合がある。本画面は、既存オプションを編集することで、商品バリアントの構成を柔軟に変更するために必要である。例えば「Color」オプションに新しい色「Navy」を追加したり、オプション名を「カラー」に変更したりできる。

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

**主要な操作・処理内容**：
1. オプションタイトル（名前）の編集
2. オプション値（バリエーション）の追加・削除
3. 変更の保存

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

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

## 関連機能

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

## 画面種別

編集（ドロワー形式）

## URL/ルーティング

```
/products/:id/options/:option_id/edit
```

パラメータ：
- `id`：商品ID（必須）
- `option_id`：オプションID（必須）

## 入出力項目

### 入力項目

| 項目名 | 項目ID | 型 | 必須 | バリデーション | 備考 |
|--------|--------|-----|------|---------------|------|
| オプションタイトル | title | string | 必須 | 最小1文字 | 既存値で初期化 |
| オプション値 | values | string[] | - | - | 既存値で初期化 |

### 出力項目

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

## 表示項目

### フォーム

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

### ヘッダー

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

## イベント仕様

### 1-オプションタイトル編集

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

**処理フロー**：
1. react-hook-formでフォーム状態を管理
2. zodバリデーション（最小1文字）
3. 既存のtitleが初期値として設定される

### 2-オプション値編集

**トリガー**：ChipInputへの入力・削除

**処理フロー**：
1. 既存のvaluesが初期値として設定
2. 新しい値の追加（Enter、カンマ、タブで確定）
3. 既存値のチップクリックで削除

### 3-保存

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

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

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | product_option | UPDATE | オプションタイトルの更新 |
| 保存ボタン押下 | product_option_value | INSERT/UPDATE/DELETE | オプション値の追加・更新・削除 |

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

#### product_option

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | title | 新しいオプションタイトル | 必須 |

#### product_option_value

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | value | 新規追加されたオプション値 | 新規の場合 |
| DELETE | id | 削除されたオプション値のID | 削除の場合 |

## メッセージ仕様

| 種別 | メッセージキー | 表示条件 |
|------|--------------|---------|
| 成功 | (なし - モーダル遷移) | 保存成功時 |
| エラー | (API error message) | API呼び出し失敗時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 商品が見つからない | エラーをスロー |
| オプションが見つからない | 404 JSONエラーをスロー |
| バリデーションエラー | フォームエラーを表示 |
| API呼び出し失敗 | エラーハンドリング |

## 備考

- RouteDrawerコンポーネントを使用したドロワー形式
- オプションが見つからない場合は404エラーをスローし、適切なエラーページを表示
- ChipInputコンポーネントで既存値の編集が可能
- 既存のバリエーションは option.values.map(v => v.value) で文字列配列に変換

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | edit-product-option-form.tsx | `packages/admin/dashboard/src/routes/products/product-edit-option/components/edit-product-option-form/edit-product-option-form.tsx` | CreateProductOptionSchemaの定義（19-22行目、作成画面と同じスキーマを使用） |

**読解のコツ**: 編集画面も作成画面と同じスキーマを使用。既存データからの初期値設定が重要なポイント。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | product-edit-option.tsx | `packages/admin/dashboard/src/routes/products/product-edit-option/product-edit-option.tsx` | ルートコンポーネント、オプションの取得 |

**主要処理フロー**:
- **9行目**: useParamsでid, option_idを取得
- **12-15行目**: useProductで商品データを取得（optionsを含む）
- **17行目**: product.optionsからoption_idでオプションを検索
- **19-21行目**: オプションが見つからない場合は404エラー

#### Step 3: 編集フォームを理解する

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

**主要処理フロー**:
- **31-37行目**: useFormの初期化（既存のtitleとvaluesを初期値に）
- **34行目**: option.values.map(v => v.value)で文字列配列に変換
- **39-42行目**: useUpdateProductOptionミューテーション
- **44-56行目**: handleSubmit - 保存処理

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

```
ProductEditOption (product-edit-option.tsx)
    │
    ├─ useParams
    │      └─ id, option_id を取得
    │
    ├─ useProduct (hooks/api/products.tsx)
    │      └─ sdk.admin.product.retrieve
    │             └─ fields: "-type,-collection,-tags,..."
    │
    ├─ product.options.find(o => o.id === option_id)
    │      └─ オプションの検索
    │
    └─ CreateProductOptionForm (edit-product-option-form.tsx)
           │
           ├─ useForm (react-hook-form)
           │      └─ zodResolver(CreateProductOptionSchema)
           │      └─ defaultValues: { title, values: [...] }
           │
           ├─ Input (title編集)
           │
           ├─ ChipInput (values編集)
           │
           └─ useUpdateProductOption
                  └─ sdk.admin.product.updateOption
```

### データフロー図

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

option.title ─────────────▶ defaultValues ──────────────────▶ フォーム初期状態
option.values ────────────▶ map(v => v.value) ─────────────▶ string[]に変換

title編集 ────────────────▶ useForm ────────────────────────▶ フォーム状態更新

ChipInput ────────────────▶ useForm ────────────────────────▶ values配列更新

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

### 関連ファイル一覧

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