# 画面設計書 27-バリアントメタデータ編集画面

## 概要

本ドキュメントは、Medusa Admin Dashboard における「バリアントメタデータ編集画面」の設計仕様を定義するものである。

### 本画面の処理概要

バリアントメタデータ編集画面は、商品バリアントに関連付けられたカスタムメタデータ（キーと値のペア）を編集するためのドロワー形式の画面である。商品メタデータ編集画面と同様の機能を提供するが、対象がバリアントである点が異なる。

**業務上の目的・背景**：商品バリアントにも商品同様にカスタム情報を付与する必要がある場合がある。例えば、バリアント固有の仕入先コード、製造ロット番号、品質管理情報などを管理できる。メタデータを活用することで、標準フィールドでは表現できない業務固有の情報をバリアント単位で柔軟に管理できる。

**画面へのアクセス方法**：バリアント詳細画面のJSONセクション内にある「メタデータを編集」ボタンをクリックすることで、ドロワー形式でこの画面が表示される。URLは `/products/:id/variants/:variant_id/metadata` の形式となる。

**主要な操作・処理内容**：
1. 既存のメタデータキー・値ペアの表示と編集
2. 新規メタデータ行の追加（行の上または下に挿入可能）
3. メタデータ行の削除
4. 複雑なデータ型（オブジェクト、配列）の読み取り専用表示
5. 変更内容の保存とキャンセル

**画面遷移**：バリアント詳細画面からドロワーとして開き、保存またはキャンセル後にバリアント詳細画面に戻る。

**権限による表示制御**：商品の編集権限を持つユーザーのみがメタデータを編集可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | 商品バリアント管理 | 主機能 | バリアントメタデータの編集 |

## 画面種別

編集（モーダル/ドロワー形式）

## URL/ルーティング

`/products/:id/variants/:variant_id/metadata`

## 入出力項目

| 項目名 | 項目ID | データ型 | 必須 | 入力/出力 | 説明 |
|--------|--------|----------|------|-----------|------|
| 商品ID | id | string | 必須 | 入力（URLパラメータ） | 親商品のID |
| バリアントID | variant_id | string | 必須 | 入力（URLパラメータ） | 編集対象のバリアントID |
| メタデータキー | metadata[].key | string | - | 入出力 | メタデータのキー名 |
| メタデータ値 | metadata[].value | string/number/boolean | - | 入出力 | メタデータの値 |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| ドロワーヘッダー | Heading | 「メタデータを編集」 |
| メタデータテーブル | array | キーと値のペアを表形式で表示 |
| キー列ヘッダー | string | "Key" ラベル |
| 値列ヘッダー | string | "Value" ラベル |
| 複雑データ警告 | InlineTip | オブジェクト/配列型の値がある場合に警告表示 |

## イベント仕様

### 1-行メニュー表示

メタデータ行にホバーすると、行の右端にアクションメニュー（縦三点リーダー）が表示される。

### 2-上に行を挿入

行メニューから「上に行を挿入」を選択すると、現在の行の上に新しい空のメタデータ行が追加される。

### 3-下に行を挿入

行メニューから「下に行を挿入」を選択すると、現在の行の下に新しい空のメタデータ行が追加される。

### 4-行を削除

行メニューから「行を削除」を選択すると、該当行が削除される。最後の行を削除した場合は、新しい空の行が自動的に追加される。

### 5-保存ボタン押下

フォームの内容を検証し、APIを呼び出してバリアントのメタデータを更新する。成功時はトースト通知を表示し、ドロワーを閉じる。

### 6-キャンセルボタン押下

変更を破棄し、ドロワーを閉じてバリアント詳細画面に戻る。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | product_variant | UPDATE | バリアントのmetadataフィールドを更新 |

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

#### product_variant

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | metadata | フォーム入力されたキー・値ペアをJSON形式で保存 | 空のキーは除外、削除されたキーは空文字で上書き |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| metadata.edit.successToast | 成功 | メタデータが正常に更新されました | 保存成功時 |
| - | エラー | {エラーメッセージ} | API呼び出し失敗時 |
| metadata.edit.complexRow.label | 警告 | 複雑なデータ | オブジェクト/配列型の値がある場合 |
| metadata.edit.complexRow.description | 情報 | 一部のメタデータフィールドは編集できません | オブジェクト/配列型の値がある場合 |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| バリアントが見つからない | エラーをthrowし、エラーバウンダリで処理 |
| API呼び出し失敗 | トースト通知でエラーメッセージを表示 |

## 備考

- MetadataFormコンポーネントを再利用（商品メタデータ編集画面と共通）
- useProductVariantフックでバリアントデータを取得
- useUpdateProductVariantフックでバリアント更新を実行
- 文字列、数値、真偽値以外の複雑なデータ型は読み取り専用
- 値が "true"/"false" の場合、保存時に真偽値型に変換
- 数値形式の文字列は保存時に数値型に変換

---

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

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

### 推奨読解順序

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

メタデータはJSONオブジェクト形式でバリアントテーブルに保存される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | metadata-form.tsx | `packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx` | MetadataFieldSchema（42-46行目）でフォームの単一行の構造を確認 |
| 1-2 | metadata-form.tsx | `packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx` | MetadataSchema（48-50行目）でフォーム全体の構造を確認 |

**読解のコツ**: 商品メタデータ編集画面と同じMetadataFormコンポーネントを使用。

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

ルートコンポーネントの処理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | product-variant-metadata.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-metadata/product-variant-metadata.tsx` | useParamsでURLパラメータを取得（6行目） |
| 2-2 | product-variant-metadata.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-metadata/product-variant-metadata.tsx` | useProductVariantフックでバリアントデータ取得（8-11行目） |
| 2-3 | product-variant-metadata.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-metadata/product-variant-metadata.tsx` | useUpdateProductVariantフックで更新処理を準備（13-16行目） |

**主要処理フロー**:
1. **6行目**: URLパラメータから商品IDとバリアントIDを取得
2. **8-11行目**: useProductVariantフックでバリアントデータをフェッチ
3. **13-16行目**: useUpdateProductVariantフックでmutateAsync関数を取得
4. **23-28行目**: MetadataFormコンポーネントにpropsを渡して描画

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

```
ProductVariantMetadata (product-variant-metadata.tsx:5-30)
    │
    ├─ useParams() → 商品ID・バリアントID取得
    │
    ├─ useProductVariant(id, variant_id) → バリアントデータ取得
    │      └─ sdk.admin.productVariant.retrieve()
    │
    ├─ useUpdateProductVariant(id, variant_id) → 更新関数取得
    │      └─ sdk.admin.productVariant.update()
    │
    └─ MetadataForm (metadata-form.tsx:52-68)
           │
           ├─ useForm() → フォーム状態管理
           │
           ├─ useFieldArray() → 動的行管理
           │
           ├─ getDefaultValues() → 初期値変換
           │
           └─ handleSubmit()
                  └─ parseValues() → 送信データ変換
                         └─ hook() → mutateAsync呼び出し
```

### データフロー図

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

URLパラメータ(id, variant_id) ───▶ useProductVariant ───▶ バリアントデータ取得
                                          │
                                          ▼
                                    variant.metadata
                                          │
                                          ▼
                                  getDefaultValues
                                          │
                                          ▼
フォーム入力 ──────────────────────▶ useForm/useFieldArray
                                          │
                                          ▼
                                    parseValues
                                          │
                                          ▼
保存ボタン押下 ────────────────────▶ mutateAsync ───▶ API更新
                                          │
                                          ▼
                                  handleSuccess ───▶ ドロワーを閉じる
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| product-variant-metadata.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-metadata/product-variant-metadata.tsx` | ソース | 画面のエントリーポイント |
| index.ts | `packages/admin/dashboard/src/routes/product-variants/product-variant-metadata/index.ts` | ソース | エクスポート定義 |
| metadata-form.tsx | `packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx` | ソース | メタデータ編集フォームの汎用コンポーネント |
| useProductVariant | `packages/admin/dashboard/src/hooks/api/products.ts` | ソース | バリアント取得フック |
| useUpdateProductVariant | `packages/admin/dashboard/src/hooks/api/products.ts` | ソース | バリアント更新フック |
| RouteDrawer | `packages/admin/dashboard/src/components/modals/` | ソース | ドロワーモーダルコンポーネント |
