# 画面設計書 7-商品詳細画面

## 概要

本ドキュメントは、Medusa Admin Dashboard の商品詳細画面の設計仕様を定義するものです。特定の商品の詳細情報を表示し、各種編集操作へのアクセスを提供する画面です。

### 本画面の処理概要

本画面は、商品の詳細情報を2カラムレイアウトで表示する画面です。メインエリアには基本情報、メディア、オプション、バリアントが表示され、サイドバーには販売チャネル、配送プロファイル、組織情報、属性情報が表示されます。

**業務上の目的・背景**：ECサイト運営において、商品情報の確認と管理は日常的な業務です。本画面は、商品に関するすべての情報を一覧できる中心的な画面として機能し、各種編集画面へのナビゲーションを提供します。また、JSON形式でのデータ表示やメタデータの確認機能も備えています。

**画面へのアクセス方法**：
- 商品一覧画面から商品をクリック
- ブラウザで直接 `/products/{id}` へアクセス
- 商品作成成功後の自動遷移

**主要な操作・処理内容**：
1. 商品基本情報の表示（タイトル、説明文、ハンドルなど）
2. メディア（画像）の表示と管理
3. バリアントの一覧表示と操作
4. オプションの表示と管理
5. 販売チャネルの表示と編集
6. 組織情報（タグ、タイプ、コレクション、カテゴリ）の表示
7. 属性情報（サイズ、重量、HSコードなど）の表示
8. 商品の削除

**画面遷移**：
- 遷移元：商品一覧画面、商品作成画面
- 遷移先：商品編集画面、商品属性編集画面、商品組織編集画面、メディア編集画面、バリアント詳細画面、価格編集画面、在庫編集画面

**権限による表示制御**：本画面は認証済みユーザーのみアクセス可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | 商品CRUD | 主機能 | 商品情報の表示・削除 |
| 2 | 商品バリアント管理 | 補助機能 | バリアント一覧表示・編集・削除 |
| 3 | 商品オプション管理 | 補助機能 | オプションの表示・編集 |
| 52 | 価格設定管理 | 補助機能 | 価格編集へのナビゲーション |
| 70 | 販売チャネルCRUD | API連携 | 販売チャネル情報の表示 |

## 画面種別

詳細画面（2カラムレイアウト）

## URL/ルーティング

`/products/:id`

## 入出力項目

本画面は表示専用であり、直接の入力項目はありません。各編集操作は子画面（Drawer）で行われます。

## 表示項目

### メインエリア（左カラム）

#### 基本情報セクション（ProductGeneralSection）

| 項目名 | 表示位置 | データソース | 説明 |
|--------|----------|--------------|------|
| タイトル | ヘッダー | product.title | 商品名 |
| ステータスバッジ | ヘッダー右 | product.status | draft/published/proposed/rejected |
| アクションメニュー | ヘッダー右 | 静的 | 編集・翻訳・削除 |
| 説明文 | コンテンツ | product.description | 商品の説明文 |
| サブタイトル | コンテンツ | product.subtitle | サブタイトル |
| ハンドル | コンテンツ | product.handle | URL用スラッグ（/付き） |
| 素材 | コンテンツ | product.material | 素材情報 |
| 割引可能 | コンテンツ | product.discountable | true/false |

#### メディアセクション（ProductMediaSection）

| 項目名 | 表示位置 | データソース | 説明 |
|--------|----------|--------------|------|
| メディアヘッダー | ヘッダー | i18n | 「メディア」 |
| 画像グリッド | コンテンツ | product.images | サムネイル画像グリッド |
| サムネイルバッジ | 画像上 | product.thumbnail | サムネイル画像の識別 |
| 空状態メッセージ | コンテンツ | i18n | 画像がない場合の案内 |

#### オプションセクション（ProductOptionSection）

| 項目名 | 表示位置 | データソース | 説明 |
|--------|----------|--------------|------|
| オプションヘッダー | ヘッダー | i18n | 「オプション」 |
| オプション一覧 | コンテンツ | product.options | サイズ、色などのオプション |

#### バリアントセクション（ProductVariantSection）

| 項目名 | 表示位置 | データソース | 説明 |
|--------|----------|--------------|------|
| バリアントヘッダー | ヘッダー | i18n | 「バリアント」 |
| バリアントテーブル | コンテンツ | DataTable | サムネイル、タイトル、SKU、オプション、在庫 |
| 作成ボタン | ヘッダー右 | i18n | 新規バリアント作成 |
| アクションメニュー | ヘッダー右 | 静的 | 価格編集、在庫管理、翻訳 |

### サイドバー（右カラム）

#### 販売チャネルセクション（ProductSalesChannelSection）

| 項目名 | 表示位置 | データソース | 説明 |
|--------|----------|--------------|------|
| 販売チャネルヘッダー | ヘッダー | i18n | 「販売チャネル」 |
| チャネル一覧 | コンテンツ | product.sales_channels | 販売チャネルバッジ |

#### 配送プロファイルセクション（ProductShippingProfileSection）

| 項目名 | 表示位置 | データソース | 説明 |
|--------|----------|--------------|------|
| 配送プロファイルヘッダー | ヘッダー | i18n | 「配送プロファイル」 |
| プロファイル情報 | コンテンツ | product.shipping_profile | 配送プロファイル |

#### 組織セクション（ProductOrganizationSection）

| 項目名 | 表示位置 | データソース | 説明 |
|--------|----------|--------------|------|
| 組織ヘッダー | ヘッダー | i18n | 「組織」 |
| タグ | コンテンツ | product.tags | タグバッジ（リンク付き） |
| タイプ | コンテンツ | product.type | タイプバッジ（リンク付き） |
| コレクション | コンテンツ | product.collection | コレクションバッジ（リンク付き） |
| カテゴリ | コンテンツ | product.categories | カテゴリバッジ（リンク付き） |

#### 属性セクション（ProductAttributeSection）

| 項目名 | 表示位置 | データソース | 説明 |
|--------|----------|--------------|------|
| 属性ヘッダー | ヘッダー | i18n | 「属性」 |
| 幅 | コンテンツ | product.width | 商品の幅 |
| 高さ | コンテンツ | product.height | 商品の高さ |
| 長さ | コンテンツ | product.length | 商品の長さ |
| 重量 | コンテンツ | product.weight | 商品の重量 |
| MIDコード | コンテンツ | product.mid_code | MIDコード |
| HSコード | コンテンツ | product.hs_code | HSコード |
| 原産国 | コンテンツ | product.origin_country | 原産国 |

### 共通

| 項目名 | 表示位置 | データソース | 説明 |
|--------|----------|--------------|------|
| JSONデータ | 下部 | product | JSON形式での全データ表示 |
| メタデータ | 下部 | product.metadata | メタデータの表示 |

## イベント仕様

### 1-編集ボタン押下（基本情報）

**トリガー**: アクションメニューの「編集」クリック

**処理フロー**:
1. `/products/{id}/edit` へ遷移
2. RouteDrawerで商品編集フォームを表示

**遷移先**: 商品編集画面（Drawer）

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

**トリガー**: アクションメニューの「削除」クリック

**処理フロー**:
1. `usePrompt` で確認ダイアログを表示
2. 確認時、`useDeleteProduct` フックで削除実行
3. 成功時、商品一覧画面へ遷移（navigate("..")）
4. 失敗時、`toast.error` でエラーメッセージ表示

**遷移先**: 商品一覧画面（成功時）

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

**トリガー**: メディアセクションのアクションメニュー「画像を編集」クリック

**処理フロー**:
1. `/products/{id}/media?view=edit` へ遷移
2. メディア編集画面を表示

**遷移先**: メディア編集画面

### 4-メディア削除

**トリガー**: メディアを選択して削除コマンド実行

**処理フロー**:
1. 画像のチェックボックスで選択
2. CommandBarの削除ボタンまたはショートカット「d」で削除確認
3. `usePrompt` で確認ダイアログ表示
4. 確認時、`useUpdateProduct` で images から対象を除外して更新
5. サムネイルが含まれる場合、thumbnail も空にする

### 5-バリアント作成ボタン押下

**トリガー**: バリアントセクションの「作成」ボタンクリック

**処理フロー**:
1. `/products/{id}/variants/create` へ遷移

**遷移先**: バリアント作成画面

### 6-バリアント行クリック

**トリガー**: バリアントテーブルの行クリック

**処理フロー**:
1. `/products/{id}/variants/{variantId}` へ遷移

**遷移先**: バリアント詳細画面

### 7-バリアント削除

**トリガー**: バリアント行のアクションメニュー「削除」クリック

**処理フロー**:
1. `usePrompt` で確認ダイアログ表示
2. 確認時、`useDeleteVariantLazy` フックで削除実行

### 8-組織編集ボタン押下

**トリガー**: 組織セクションのアクションメニュー「編集」クリック

**処理フロー**:
1. `/products/{id}/organization` へ遷移

**遷移先**: 商品組織編集画面（Drawer）

### 9-属性編集ボタン押下

**トリガー**: 属性セクションのアクションメニュー「編集」クリック

**処理フロー**:
1. `/products/{id}/attributes` へ遷移

**遷移先**: 商品属性編集画面（Drawer）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 商品削除 | product | DELETE（soft） | 商品レコードの論理削除 |
| メディア削除 | product_image | DELETE | 画像紐付けの削除 |
| メディア削除 | product | UPDATE | thumbnail の更新 |
| バリアント削除 | product_variant | DELETE（soft） | バリアントの論理削除 |

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

本画面は主に表示画面であり、削除操作のみがデータベースに影響します。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| products.deleteWarning | 確認 | {title}を削除しますか？ | 商品削除確認時 |
| products.toasts.delete.error | エラー | 削除に失敗しました | 商品削除失敗時 |
| products.deleteVariantWarning | 確認 | {title}を削除しますか？ | バリアント削除確認時 |
| products.media.deleteWarning | 確認 | {count}件のメディアを削除しますか？ | メディア削除確認時 |
| products.media.deleteWarningWithThumbnail | 確認 | サムネイルを含む{count}件のメディアを削除しますか？ | サムネイル含むメディア削除時 |

## 例外処理

| 例外条件 | 処理内容 | ユーザーへの表示 |
|---------|---------|-----------------|
| 商品データ取得失敗 | エラーをスロー | エラー境界でキャッチして表示 |
| 商品削除失敗 | toast.errorで表示 | エラーメッセージをトーストで表示 |
| バリアント取得失敗 | エラーをスロー | エラー境界でキャッチして表示 |
| ローディング中 | TwoColumnPageSkeleton表示 | スケルトンUIを表示 |

## 備考

- 本画面は認証済みユーザーのみアクセス可能なプロテクト画面です
- TwoColumnPageレイアウトを使用し、メイン4セクション、サイドバー4セクションで構成されます
- useExtensionによりウィジェットの追加が可能です（before, after, sideBefore, sideAfter）
- showJSON、showMetadata オプションにより、JSON形式でのデータ表示が可能です
- productLoaderによりSSR/初期データの取得が行われます
- バリアントセクションはDataTableコンポーネントを使用し、フィルタリング、ソート、ページネーションが可能です
- フィーチャーフラグ「translation」が有効な場合、翻訳管理へのリンクが表示されます

---

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

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

### 推奨読解順序

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

ProductDetailコンポーネントから処理の流れを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | product-detail.tsx | `packages/admin/dashboard/src/routes/products/product-detail/product-detail.tsx` | メインコンポーネント |
| 1-2 | loader.ts | `packages/admin/dashboard/src/routes/products/product-detail/loader.ts` | データローダー |
| 1-3 | constants.ts | `packages/admin/dashboard/src/routes/products/product-detail/constants.ts` | フィールド定義 |

**主要処理フロー**:
1. **20-31行目**: useLoaderDataとuseProductでデータ取得
2. **33-38行目**: useExtensionでウィジェット取得
3. **40-48行目**: ローディング中のスケルトン表示
4. **51-53行目**: エラー時のスロー
5. **55-79行目**: TwoColumnPageでUI構築

#### Step 2: メインエリアのセクションを理解する

各セクションコンポーネントを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | product-general-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-general-section/product-general-section.tsx` | 基本情報セクション |
| 2-2 | product-media-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-media-section/product-media-section.tsx` | メディアセクション |
| 2-3 | product-variant-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-variant-section/product-variant-section.tsx` | バリアントセクション |
| 2-4 | product-option-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-option-section/product-option-section.tsx` | オプションセクション |

#### Step 3: サイドバーのセクションを理解する

サイドバーの各セクションを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | product-sales-channel-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-sales-channel-section/product-sales-channel-section.tsx` | 販売チャネルセクション |
| 3-2 | product-shipping-profile-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-shipping-profile-section/product-shipping-profile-section.tsx` | 配送プロファイルセクション |
| 3-3 | product-organization-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-organization-section/product-organization-section.tsx` | 組織セクション |
| 3-4 | product-attribute-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-attribute-section/product-attribute-section.tsx` | 属性セクション |

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

```
ProductDetail (product-detail.tsx)
    │
    ├─ useLoaderData ─▶ productLoader
    ├─ useProduct (初期データ付き)
    └─ useExtension (ウィジェット)
           │
           └─ TwoColumnPage
                  │
                  ├─ Main
                  │     ├─ ProductGeneralSection
                  │     │      ├─ useDeleteProduct
                  │     │      └─ usePrompt
                  │     │
                  │     ├─ ProductMediaSection
                  │     │      ├─ useUpdateProduct
                  │     │      └─ usePrompt
                  │     │
                  │     ├─ ProductOptionSection
                  │     │
                  │     └─ ProductVariantSection
                  │            ├─ useProductVariants
                  │            ├─ useDeleteVariantLazy
                  │            └─ DataTable
                  │
                  └─ Sidebar
                        ├─ ProductSalesChannelSection
                        ├─ ProductShippingProfileSection
                        ├─ ProductOrganizationSection
                        └─ ProductAttributeSection
```

### データフロー図

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

URL /products/:id ───▶ productLoader
                            │
                            ▼
                       useProduct
                            │
                            ▼
                    product データ
                            │
      ┌─────────────────────┼─────────────────────┐
      │                     │                     │
      ▼                     ▼                     ▼
ProductGeneralSection  ProductMediaSection  ProductVariantSection
      │                     │                     │
      │                     │                     ▼
      │                     │              useProductVariants
      │                     │                     │
      ▼                     ▼                     ▼
 [削除操作]           [メディア操作]         [バリアント操作]
      │                     │                     │
      ▼                     ▼                     ▼
useDeleteProduct      useUpdateProduct     useDeleteVariantLazy
      │                     │                     │
      └─────────────────────┼─────────────────────┘
                            │
                            ▼
                    [画面更新/遷移]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| product-detail.tsx | `packages/admin/dashboard/src/routes/products/product-detail/product-detail.tsx` | ソース | メインコンポーネント |
| loader.ts | `packages/admin/dashboard/src/routes/products/product-detail/loader.ts` | ソース | データローダー |
| constants.ts | `packages/admin/dashboard/src/routes/products/product-detail/constants.ts` | ソース | フィールド定義 |
| product-general-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-general-section/product-general-section.tsx` | ソース | 基本情報セクション |
| product-media-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-media-section/product-media-section.tsx` | ソース | メディアセクション |
| product-variant-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-variant-section/product-variant-section.tsx` | ソース | バリアントセクション |
| product-option-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-option-section/product-option-section.tsx` | ソース | オプションセクション |
| product-sales-channel-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-sales-channel-section/product-sales-channel-section.tsx` | ソース | 販売チャネルセクション |
| product-shipping-profile-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-shipping-profile-section/product-shipping-profile-section.tsx` | ソース | 配送プロファイルセクション |
| product-organization-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-organization-section/product-organization-section.tsx` | ソース | 組織セクション |
| product-attribute-section.tsx | `packages/admin/dashboard/src/routes/products/product-detail/components/product-attribute-section/product-attribute-section.tsx` | ソース | 属性セクション |
| breadcrumb.tsx | `packages/admin/dashboard/src/routes/products/product-detail/breadcrumb.tsx` | ソース | パンくずリスト |
