# 画面設計書 158-商品タイプ編集画面

## 概要

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

### 本画面の処理概要

商品タイプ編集画面は、既存の商品タイプのタイプ名を変更するための画面である。サイドドロワー形式で表示され、現在のタイプ名を編集して保存することができる。

**業務上の目的・背景**：商品タイプは商品の大分類として機能し、運用中にタイプ名の変更が必要になる場合がある。例えば、商品カテゴリの再編成や、より適切なタイプ名への変更が発生した際に本画面を使用する。

**画面へのアクセス方法**：
1. 商品タイプ詳細画面のアクションメニューから「編集」を選択
2. 商品タイプ一覧画面の行アクションから「編集」を選択
3. 直接URL `/settings/product-types/{id}/edit` にアクセス

**主要な操作・処理内容**：
1. 現在のタイプ名が入力フィールドに表示される
2. タイプ名を編集する
3. 「保存」ボタンをクリックして変更を保存
4. 「キャンセル」ボタンで編集をキャンセルし、ドロワーを閉じる

**画面遷移**：
- 遷移元：商品タイプ詳細画面（No.157）、商品タイプ一覧画面（No.155）
- 遷移先：保存成功時は遷移元に戻る（モーダルクローズ）

**権限による表示制御**：認証済みの管理ユーザーのみがアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 7 | 商品タイプ管理 | 主機能 | 商品タイプの編集 |

## 画面種別

編集（サイドドロワー形式）

## URL/ルーティング

- パス: `/settings/product-types/:id/edit`
- コンポーネント: `ProductTypeEdit`
- ドロワータイプ: `RouteDrawer`

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 最小長 | 最大長 | 備考 |
|--------|--------|-----|------|--------|--------|------|
| タイプ名 | value | string | Yes | 1 | - | Zodスキーマで `z.string().min(1)` として定義 |

## 表示項目

| 項目名 | 説明 | 表示位置 |
|--------|------|----------|
| ヘッダータイトル | 「商品タイプを編集」 | ドロワーヘッダー |
| タイプ名ラベル | 「値」 | 入力フィールド上 |
| キャンセルボタン | 「キャンセル」 | フッター左 |
| 保存ボタン | 「保存」 | フッター右 |

## イベント仕様

### 1-フォーム送信（保存ボタン押下）

1. フォームバリデーションを実行（Zodスキーマによる検証）
2. バリデーション成功時、`useUpdateProductType` フックを通じて API 呼び出し
3. API呼び出し: `sdk.admin.productType.update(id, values)`
4. 成功時:
   - トースト通知「タイプ "{value}" が更新されました」を表示
   - `handleSuccess()` でドロワーを閉じる
5. 失敗時:
   - エラーメッセージをトースト通知で表示

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

1. ドロワーを閉じる
2. 前の画面（遷移元）に戻る

### 3-キーボードショートカット

- `KeyboundForm` コンポーネントにより、Enter キーでフォーム送信が可能

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | product_type | SELECT | タイプ詳細情報の取得 |
| 保存ボタン押下 | product_type | UPDATE | タイプ名の更新 |

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

#### product_type（参照）

| 操作 | 項目（カラム名） | 取得条件 | 備考 |
|-----|-----------------|---------|------|
| SELECT | id, value | WHERE id = :id | 編集前データ取得 |

#### product_type（更新）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | value | 入力された値 | タイプ名 |
| UPDATE | updated_at | システム日時 | 更新日時 |

## メッセージ仕様

| 種別 | メッセージキー | メッセージ内容 | 表示条件 |
|------|---------------|---------------|----------|
| 成功 | productTypes.edit.successToast | タイプ "{value}" が更新されました | 更新成功時 |
| エラー | （APIエラーメッセージ） | APIからのエラーメッセージを表示 | 更新失敗時 |
| バリデーション | （Zodエラー） | 必須項目エラー | value が空の場合 |

## 例外処理

| 例外ケース | 処理内容 |
|-----------|---------|
| タイプが存在しない | エラーをスロー（エラー境界でキャッチ） |
| ネットワークエラー | エラーメッセージをトースト通知で表示、フォームは保持 |
| サーバーエラー | APIからのエラーメッセージをトースト通知で表示 |

## 備考

- ドロワーは `RouteDrawer` コンポーネントを使用しており、画面右側からスライドイン表示
- フォーム状態管理には react-hook-form を使用
- バリデーションには Zod スキーマを使用
- キャッシュ無効化: 更新成功時に `productTypesQueryKeys.detail(id)` と `productTypesQueryKeys.lists()` のキャッシュを無効化
- データ取得完了まで（`ready = !isPending && !!product_type`）はフォームをレンダリングしない
- defaultValues には現在のタイプ名（`productType.value`）を設定

---

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

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

### 推奨読解順序

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

まず、商品タイプのデータ構造とバリデーションスキーマを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | HttpTypes | `@medusajs/types` | `AdminProductType` の型定義 |
| 1-2 | EditProductTypeSchema | `edit-product-type-form.tsx:12-14` | Zodによるバリデーションスキーマの定義 |

**読解のコツ**: Zodスキーマは `z.object({ value: z.string().min(1) })` と定義されており、value フィールドが最小1文字以上の文字列であることが必須条件。

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

処理の起点となるコンポーネントを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ProductTypeEdit | `packages/admin/dashboard/src/routes/product-types/product-type-edit/product-type-edit.tsx` | RouteDrawer でラップされたエントリーポイント |

**主要処理フロー**:
1. **行9**: useParams でURLから id を取得
2. **行12**: useProductType でタイプデータを取得
3. **行14**: ready 状態の判定（`!isPending && !!product_type`）
4. **行16-18**: エラー時はエラーをスロー
5. **行25**: ready 時のみ EditProductTypeForm をレンダリング

#### Step 3: フォームコンポーネントを理解する

実際のフォームロジックを確認する。

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

**主要処理フロー**:
- **行26-31**: useForm による初期化、defaultValues に現在の value を設定
- **行33**: useUpdateProductType フックの呼び出し
- **行35-54**: handleSubmit 関数でフォーム送信処理、成功/失敗時のコールバック定義
- **行56-93**: JSX レンダリング（ドロワー構造、入力フィールド、ボタン）

#### Step 4: APIフックを理解する

バックエンドとの通信を担うフックの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | useUpdateProductType | `packages/admin/dashboard/src/hooks/api/product-types.tsx:109-126` | useMutation によるAPI呼び出しとキャッシュ無効化 |

**主要処理フロー**:
- **行118**: `sdk.admin.productType.update(id, payload)` によるAPI呼び出し
- **行119-124**: 成功時に detail と lists のキャッシュを無効化

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

```
ProductTypeEdit（エントリーポイント）
    │
    ├─ useParams() → id 取得
    │
    ├─ useProductType(id)
    │      └─ sdk.admin.productType.retrieve()
    │
    └─ RouteDrawer
           │
           └─ EditProductTypeForm
                  │
                  ├─ useForm (react-hook-form)
                  │      ├─ defaultValues: { value: productType.value }
                  │      └─ zodResolver (Zod バリデーション)
                  │
                  ├─ useUpdateProductType (API呼び出し)
                  │      └─ useMutation (TanStack Query)
                  │             └─ sdk.admin.productType.update()
                  │
                  └─ handleSubmit
                         ├─ onSuccess → toast.success() + handleSuccess()
                         └─ onError → toast.error()
```

### データフロー図

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

URL params (id) ───▶ ProductTypeEdit ───▶ 遷移元画面に戻る
                          │
                          ├─ useProductType
                          │      │
                          │      └─ GET /admin/product-types/{id}
                          │              │
                          │              └─ product_type データ（現在値）
                          │
                          └─ EditProductTypeForm
                                 │
                                 ├─ 入力: value（編集後）
                                 │
                                 └─ POST /admin/product-types/{id}
                                        │
                                        └─ 更新された product_type データ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| product-type-edit.tsx | `packages/admin/dashboard/src/routes/product-types/product-type-edit/product-type-edit.tsx` | ソース | エントリーポイントコンポーネント |
| edit-product-type-form.tsx | `packages/admin/dashboard/src/routes/product-types/product-type-edit/components/edit-product-type-form/edit-product-type-form.tsx` | ソース | フォームロジックとUI |
| product-types.tsx | `packages/admin/dashboard/src/hooks/api/product-types.tsx` | ソース | 商品タイプ関連APIフック |
| index.ts | `packages/admin/dashboard/src/routes/product-types/product-type-edit/index.ts` | ソース | モジュールエクスポート |
