# 画面設計書 15-商品配送プロファイル編集画面

## 概要

本ドキュメントは、Medusa Admin Dashboard における商品配送プロファイル編集画面の設計仕様を定義するものである。

### 本画面の処理概要

商品配送プロファイル編集画面は、商品に適用する配送プロファイル（配送ルール・配送方法のグループ）を設定するための画面である。商品の配送方法を一元管理し、適切な配送オプションを適用する。

**業務上の目的・背景**：ECサイトでは商品の特性（サイズ、重量、取り扱い注意度等）に応じて異なる配送方法を適用する必要がある。本画面は、商品を適切な配送プロファイルに紐付けることで、正確な配送料金計算と配送オプションの表示を実現するために必要である。

**画面へのアクセス方法**：商品詳細画面の配送セクションから「Edit Shipping Profile」ボタンをクリックすることでドロワー形式で表示される。URLパスは `/products/:id/shipping-profile` となる。

**主要な操作・処理内容**：
1. 利用可能な配送プロファイル一覧の表示（Combobox形式）
2. 配送プロファイルの検索
3. 配送プロファイルの選択/クリア
4. 設定の保存

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

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 44 | 配送プロファイル管理 | 主機能 | 商品の配送プロファイル設定 |

## 画面種別

編集（ドロワー形式）

## URL/ルーティング

```
/products/:id/shipping-profile
```

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

## 入出力項目

### 入力項目

| 項目名 | 項目ID | 型 | 必須 | バリデーション | 備考 |
|--------|--------|-----|------|---------------|------|
| 配送プロファイルID | shipping_profile_id | string | 必須 | - | Comboboxで選択 |

### 出力項目

| 項目名 | 項目ID | 型 | 備考 |
|--------|--------|-----|------|
| 配送プロファイル一覧 | shipping_profiles | ShippingProfile[] | Comboboxオプションとして表示 |

## 表示項目

### フォーム

| 項目名 | 表示形式 | 備考 |
|--------|---------|------|
| 配送プロファイル | Combobox | 検索可能、クリア可能 |

### ヘッダー

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

## イベント仕様

### 1-配送プロファイル選択

**トリガー**：Comboboxでのプロファイル選択

**処理フロー**：
1. useComboboxDataフックで配送プロファイル一覧を取得
2. 選択時にフォーム値を更新
3. allowClear: trueでクリア操作も可能

**データ取得**：
- sdk.admin.shippingProfile.listでAPI呼び出し
- getOptionsでラベル/値のマッピング

### 2-クリア

**トリガー**：Comboboxのクリアボタン押下

**処理フロー**：
1. shipping_profile_idをundefinedに設定
2. useEffectで空文字に変換

### 3-保存

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

**処理フロー**：
1. フォームデータを取得（shipping_profile_id）
2. 空文字の場合はnullに変換
3. `useUpdateProduct`ミューテーションでshipping_profile_idを更新
4. 成功時にトースト表示、ドロワーを閉じる

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | product | UPDATE | 商品のshipping_profile_idを更新 |

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

#### product

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | shipping_profile_id | 選択した配送プロファイルID | null可（クリア時） |

## メッセージ仕様

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

## 例外処理

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

## 備考

- RouteDrawerコンポーネントを使用したドロワー形式
- Comboboxコンポーネントで検索可能な選択UI
- useComboboxDataフックでインフィニットスクロール対応
- 空文字とnullの変換処理に注意（空文字=未選択、保存時はnullに変換）

---

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

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

### 推奨読解順序

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

まず、配送プロファイル設定のデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | product-shipping-profile-form.tsx | `packages/admin/dashboard/src/routes/products/product-shipping-profile/components/product-organization-form/product-shipping-profile-form.tsx` | ProductShippingProfileSchemaの定義（24-26行目） |

**読解のコツ**: シンプルなスキーマで、shipping_profile_idのみを管理。zodで必須バリデーション。

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

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

**主要処理フロー**:
- **10行目**: useParamsでidを取得
- **13-17行目**: useProductで商品データを取得（*shipping_profile含む）
- **23-34行目**: RouteDrawer内でProductShippingProfileFormをレンダリング

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

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

**主要処理フロー**:
- **34-42行目**: useComboboxDataで配送プロファイル一覧を取得
- **44-49行目**: useFormの初期化（既存プロファイルIDを初期値に）
- **55-75行目**: handleSubmit - 保存処理
- **77-81行目**: useEffectでundefinedを空文字に変換

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

```
ProductShippingProfile (product-shipping-profile.tsx)
    │
    ├─ useParams
    │      └─ id を取得
    │
    ├─ useProduct (hooks/api/products.tsx)
    │      └─ sdk.admin.product.retrieve
    │             └─ fields: "*shipping_profile,..."
    │
    └─ ProductShippingProfileForm (product-shipping-profile-form.tsx)
           │
           ├─ useComboboxData
           │      └─ sdk.admin.shippingProfile.list
           │
           ├─ useForm (react-hook-form)
           │      └─ zodResolver(ProductShippingProfileSchema)
           │
           ├─ Combobox (inputs/combobox)
           │      └─ 配送プロファイル選択UI
           │
           └─ useUpdateProduct
                  └─ sdk.admin.product.update
```

### データフロー図

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

product.shipping_profile ──▶ defaultValues生成 ─────────────▶ フォーム初期状態
        │
        └─ shipping_profile?.id ?? ""

Combobox選択 ──────────────▶ useForm状態更新 ───────────────▶ shipping_profile_id

クリア操作 ────────────────▶ useEffect ─────────────────────▶ ""に変換
        │
        └─ undefined → ""

保存ボタン ────────────────▶ handleSubmit ──────────────────▶ API更新
        │
        ├─ "" → null 変換
        │
        └─ useUpdateProduct
               └─ { shipping_profile_id }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| product-shipping-profile.tsx | `packages/admin/dashboard/src/routes/products/product-shipping-profile/product-shipping-profile.tsx` | ソース | ルートコンポーネント |
| product-shipping-profile-form.tsx | `packages/admin/dashboard/src/routes/products/product-shipping-profile/components/product-organization-form/product-shipping-profile-form.tsx` | ソース | 編集フォーム本体 |
| index.ts | `packages/admin/dashboard/src/routes/products/product-shipping-profile/index.ts` | ソース | エクスポート定義 |
| products.tsx | `packages/admin/dashboard/src/hooks/api/products.tsx` | ソース | 商品関連APIフック |
| use-combobox-data.ts | `packages/admin/dashboard/src/hooks/use-combobox-data.ts` | ソース | Comboboxデータ取得フック |
| combobox.tsx | `packages/admin/dashboard/src/components/inputs/combobox/combobox.tsx` | ソース | Comboboxコンポーネント |
