# 画面設計書 23-バリアント詳細画面

## 概要

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

### 本画面の処理概要

バリアント詳細画面は、商品バリアントの詳細情報を表示するためのフルページ形式の画面である。バリアントの基本情報、メディア、在庫、価格情報を一覧表示し、各種編集操作へのナビゲーションを提供する。

**業務上の目的・背景**：ECサイトでは、同一商品でもサイズ・色・素材などの違いによって複数のバリエーション（バリアント）が存在する。この画面により、特定のバリアントに関するすべての情報を一元的に確認でき、在庫状況や価格設定の確認、編集作業への導線を提供する。運用担当者は個別のバリアントごとに詳細な管理を行える。

**画面へのアクセス方法**：商品詳細画面のバリアント一覧から特定のバリアントをクリックすることでこの画面に遷移する。URLは `/products/:id/variants/:variant_id` の形式となる。

**主要な操作・処理内容**：
1. バリアントの基本情報（タイトル、SKU、オプション値）の表示
2. バリアントに紐付いた画像の表示
3. 在庫アイテム情報の表示（在庫管理が有効な場合）
4. 価格情報の表示（通貨別）
5. 編集・削除アクションの提供
6. JSONデータとメタデータの表示

**画面遷移**：
- 商品詳細画面からバリアント選択で遷移
- 編集ボタンからバリアント編集画面（ドロワー）へ
- 在庫管理ボタンからバリアント在庫管理画面（モーダル）へ
- メディア編集ボタンからバリアントメディア編集画面（モーダル）へ
- 削除実行後は商品詳細画面に戻る

**権限による表示制御**：商品の閲覧権限を持つユーザーが表示可能。編集・削除は編集権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | 商品バリアント管理 | 主機能 | バリアント詳細情報の表示 |
| 48 | 在庫アイテム管理 | 補助機能 | バリアント在庫情報の表示 |

## 画面種別

詳細

## URL/ルーティング

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

## 入出力項目

| 項目名 | 項目ID | データ型 | 必須 | 入力/出力 | 説明 |
|--------|--------|----------|------|-----------|------|
| 商品ID | id | string | 必須 | 入力（URLパラメータ） | 親商品のID |
| バリアントID | variant_id | string | 必須 | 入力（URLパラメータ） | 表示対象のバリアントID |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| バリアントタイトル | string | バリアントの名前 |
| ラベル | string | "商品バリアント" 固定テキスト |
| SKU | string | 在庫管理単位コード |
| オプション値 | Badge[] | サイズ・色などのオプション値をバッジ表示 |
| インベントリキットアイコン | icon | 複数在庫アイテムがある場合にコンポーネントアイコン表示 |
| メディアセクション | section | バリアントに紐付いた画像の一覧 |
| 在庫セクション | section | 在庫アイテムの一覧テーブル |
| 価格セクション | section | 通貨別価格の一覧 |
| JSONセクション | section | 生データのJSON表示 |
| メタデータセクション | section | メタデータの表示と編集リンク |

## イベント仕様

### 1-編集ボタン押下

アクションメニューから「編集」を選択すると、バリアント編集画面（ドロワー）に遷移する。URLは `edit` が追加される。

### 2-削除ボタン押下

アクションメニューから「削除」を選択すると、確認ダイアログが表示される。確認後、バリアントが削除され、商品詳細画面に戻る。

### 3-在庫管理ボタン押下

在庫セクションのアクションメニューから「在庫アイテムを管理」または「インベントリキットを管理」を選択すると、バリアント在庫管理画面（モーダル）に遷移する。

### 4-メディア編集ボタン押下

メディアセクションのアクションメニューから「メディアを編集」を選択すると、バリアントメディア編集画面（モーダル）に遷移する。

### 5-在庫アイテム行クリック

在庫セクションのテーブル行をクリックすると、該当在庫アイテムの詳細画面（`/inventory/:id`）に遷移する。

### 6-翻訳管理ボタン押下（翻訳機能有効時のみ）

アクションメニューから「翻訳を管理」を選択すると、翻訳編集画面に遷移する。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 削除ボタン押下 | product_variant | DELETE | バリアントを削除 |

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

#### product_variant

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | variant_id で指定されたレコードを削除 | 関連する在庫アイテム紐付けも削除 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| general.areYouSure | 確認 | 本当に実行しますか？ | 削除確認ダイアログ |
| products.variant.deleteWarning | 警告 | バリアント "{title}" を削除しますか？ | 削除確認ダイアログ |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| バリアントが見つからない | エラーをthrowし、エラーバウンダリで処理 |
| ローディング中 | TwoColumnPageSkeletonを表示 |

## 備考

- TwoColumnPageレイアウトを使用（メイン領域とサイドバー）
- メイン領域：一般情報セクション、メディアセクション、在庫セクション
- サイドバー：価格セクション
- 在庫管理（manage_inventory）が無効な場合、在庫セクションはプレースホルダー表示
- 拡張ポイント（widgets）をサポート：before/after, sideBefore/sideAfter
- variantLoaderによるサーバーサイドデータローディングをサポート

---

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

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

### 推奨読解順序

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

バリアントデータの取得フィールドと構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | constants.ts | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/constants.ts` | VARIANT_DETAIL_FIELDSで取得するリレーション（在庫、オプション、価格、画像）を確認 |

**読解のコツ**: `*` はリレーション展開、`+` は追加フィールドを示す。inventory_items.inventory.location_levelsまで展開している。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | product-variant-detail.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/product-variant-detail.tsx` | useLoaderDataで初期データ取得（19-21行目） |
| 2-2 | product-variant-detail.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/product-variant-detail.tsx` | useProductVariantでバリアントデータ取得（24-31行目） |
| 2-3 | product-variant-detail.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/product-variant-detail.tsx` | TwoColumnPageでレイアウト構成（51-83行目） |

**主要処理フロー**:
1. **19-21行目**: useLoaderDataでSSR初期データを取得
2. **23行目**: useParamsでURLパラメータを取得
3. **24-31行目**: useProductVariantでバリアントデータをフェッチ
4. **35-44行目**: ローディング中はスケルトンを表示
5. **51-83行目**: TwoColumnPageでMain/Sidebarを構成

#### Step 3: 各セクションコンポーネントを理解する

画面を構成する各セクションの処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | variant-general-section.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/components/variant-general-section/variant-general-section.tsx` | 基本情報とアクションメニューの実装 |
| 3-2 | variant-inventory-section.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/components/variant-inventory-section/variant-inventory-section.tsx` | 在庫テーブルとInventorySectionPlaceholderの実装 |

**主要処理フロー（variant-general-section.tsx）**:
- **16-45行目**: useDeleteVariantで削除処理、handleDeleteで確認ダイアログ表示
- **47-110行目**: Container内にタイトル、アクションメニュー、SectionRowを配置
- **102-109行目**: オプション値をmapでバッジ表示

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

```
ProductVariantDetail (product-variant-detail.tsx:18-85)
    │
    ├─ useLoaderData() → SSR初期データ取得
    │
    ├─ useParams() → URLパラメータ取得
    │
    ├─ useProductVariant(id, variant_id) → バリアントデータ取得
    │      └─ sdk.admin.productVariant.retrieve()
    │
    ├─ useExtension() → 拡張ウィジェット取得
    │
    └─ TwoColumnPage
           │
           ├─ TwoColumnPage.Main
           │      ├─ VariantGeneralSection
           │      │      └─ useDeleteVariant() → 削除処理
           │      ├─ VariantMediaSection
           │      └─ VariantInventorySection / InventorySectionPlaceholder
           │             └─ useDataTable() → テーブル設定
           │
           └─ TwoColumnPage.Sidebar
                  └─ VariantPricesSection
```

### データフロー図

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

URLパラメータ(id, variant_id) ───▶ useProductVariant ───▶ バリアントデータ取得
                                          │
                                          ▼
                                  variant.inventory_items
                                          │
                    ┌─────────────────────┴────────────────────┐
                    ▼                                          ▼
          manage_inventory: true                    manage_inventory: false
                    │                                          │
                    ▼                                          ▼
          VariantInventorySection              InventorySectionPlaceholder
                    │
                    ▼
              useDataTable ───▶ 在庫テーブル表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| product-variant-detail.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/product-variant-detail.tsx` | ソース | 画面のエントリーポイント |
| loader.ts | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/loader.ts` | ソース | SSRデータローダー |
| constants.ts | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/constants.ts` | ソース | フィールド定義定数 |
| breadcrumb.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/breadcrumb.tsx` | ソース | パンくずリスト設定 |
| variant-general-section.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/components/variant-general-section/variant-general-section.tsx` | ソース | 基本情報セクション |
| variant-media-section.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/components/variant-media-section/variant-media-section.tsx` | ソース | メディアセクション |
| variant-inventory-section.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/components/variant-inventory-section/variant-inventory-section.tsx` | ソース | 在庫セクション |
| variant-prices-section.tsx | `packages/admin/dashboard/src/routes/product-variants/product-variant-detail/components/variant-prices-section/variant-prices-section.tsx` | ソース | 価格セクション |
| useProductVariant | `packages/admin/dashboard/src/hooks/api/products.ts` | ソース | バリアント取得フック |
| useDeleteVariant | `packages/admin/dashboard/src/hooks/api/products.ts` | ソース | バリアント削除フック |
| TwoColumnPage | `packages/admin/dashboard/src/components/layout/pages/` | ソース | 2カラムレイアウトコンポーネント |
