# 画面設計書 99-在庫メタデータ編集画面

## 概要

本ドキュメントは、Medusa Admin Dashboardの在庫メタデータ編集画面の設計仕様を定義するものです。

### 本画面の処理概要

在庫メタデータ編集画面は、在庫アイテムに関連付けられたカスタムメタデータをキー・バリュー形式で編集するためのドロワー形式の画面です。

**業務上の目的・背景**：在庫アイテムには標準フィールド以外にも、業務固有の情報を保持する必要がある場合があります。メタデータ機能を使用することで、拡張データをJSONオブジェクト形式で柔軟に管理できます。例えば、製造ロット番号、入荷日、保管条件などのカスタム属性を追加可能です。

**画面へのアクセス方法**：在庫詳細画面のアクションメニューから「Edit Metadata」を選択することでドロワー形式で表示されます。URL `/inventory/{id}/metadata` に直接アクセスすることも可能です。

**主要な操作・処理内容**：
1. 現在のメタデータをキー・バリュー形式で表示
2. 行の追加・削除・編集
3. 保存処理の実行

**画面遷移**：
- 遷移元：在庫詳細画面
- 遷移先：保存成功時は在庫詳細画面に戻る（ドロワークローズ）

**権限による表示制御**：認証済みユーザーであれば全機能を利用可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 48 | 在庫アイテム管理 | 主機能 | メタデータの編集 |

## 画面種別

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

## URL/ルーティング

`/inventory/{id}/metadata`

## 入出力項目

### 入力項目

| 項目名 | 項目ID | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| キー | metadata.{index}.key | string | - | メタデータのキー名 |
| 値 | metadata.{index}.value | any | - | メタデータの値（文字列、数値、真偽値） |

## 表示項目

| 項目名 | 項目ID | 型 | 説明 |
|--------|--------|-----|------|
| Key列ヘッダー | - | string | 「Key」 |
| Value列ヘッダー | - | string | 「Value」 |
| キー入力フィールド | metadata.{index}.key | string | メタデータのキー入力 |
| 値入力フィールド | metadata.{index}.value | string | メタデータの値入力 |
| 複雑な値プレースホルダー | - | string | オブジェクト「{ ... }」、配列「[ ... ]」 |

## イベント仕様

### 1-Saveボタン押下

入力内容でバリデーションを実行し、メタデータを更新します。

**処理フロー**:
1. parseValuesでフォームデータを解析
2. 空キーの行はスキップ
3. 削除されたキーは空文字で上書き（削除扱い）
4. 値の型変換（"true"/"false"はboolean、数値文字列はnumber）
5. `useUpdateInventoryItem` で API 呼び出し
6. 成功時、トースト通知（metadata.edit.successToast）を表示しドロワーをクローズ
7. エラー時、エラーメッセージをトースト表示

### 2-Cancelボタン押下

入力内容を破棄してドロワーをクローズします。

### 3-行の追加（Insert Row Above/Below）

アクションメニューから新しい行を指定位置に挿入します。

### 4-行の削除（Delete Row）

アクションメニューから行を削除します。最後の1行を削除した場合は、空の行が自動的に追加されます。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 初期表示 | inventory_item | SELECT | メタデータを含む在庫アイテム情報の取得 |
| Save押下 | inventory_item | UPDATE | メタデータの更新 |

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

#### inventory_item

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | metadata | フォーム入力値（JSONオブジェクト） | nullの場合は空になる |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| metadata.edit.successToast | 成功 | メタデータが正常に更新されました | 更新成功時 |
| - | エラー | エラーメッセージ（API エラー内容） | API 呼び出しエラー時 |
| metadata.edit.complexRow.label | 警告 | 複雑な値 | 編集不可な複雑型がある場合 |
| metadata.edit.complexRow.description | 警告 | オブジェクトや配列は直接編集できません | 編集不可な複雑型がある場合 |
| metadata.edit.complexRow.tooltip | ツールチップ | この行は複雑な値を含むため編集できません | 無効行ホバー時 |

## 例外処理

| 例外条件 | 対応 | 画面表示 |
|---------|------|----------|
| 在庫アイテムが存在しない | エラーをスロー | エラー画面を表示 |
| APIエラー | トースト通知 | エラーメッセージを表示 |

## 備考

- RouteDrawer形式で実装
- MetadataFormコンポーネントを共通利用（他のメタデータ編集画面と共有）
- useFieldArrayで動的な行追加・削除を実現
- オブジェクトや配列などの複雑な値は編集不可（disabled: true）
- 値の型は自動判定（"true"/"false" → boolean、数値文字列 → number）
- キーが空の行は保存時にスキップ
- 元のメタデータから削除されたキーは空文字で上書きして削除扱いとする

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | metadata-form.tsx | `packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx` | MetadataFieldSchemaのkey, value, disabled構造を確認 |

**読解のコツ**: EDITABLE_TYPESで編集可能な型（string, number, boolean）を定義している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | inventory-metadata.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-metadata/inventory-metadata.tsx` | 軽量なエントリーポイント。useInventoryItemとuseUpdateInventoryItemをMetadataFormに渡す |

**主要処理フロー**:
1. **8行目**: `useParams` でidを取得
2. **10行目**: `useInventoryItem` でメタデータを含むアイテム取得
3. **11行目**: `useUpdateInventoryItem` で更新用ミューテーション取得
4. **19-24行目**: MetadataFormコンポーネントに必要なpropsを渡す

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | metadata-form.tsx | `packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx` | 共通メタデータフォーム。useFieldArrayで行管理 |

**主要処理フロー**:
1. **84-89行目**: useFormの設定、getDefaultValuesで初期値構築
2. **91-108行目**: handleSubmitでparseValuesを実行後、hookを呼び出し
3. **110-113行目**: useFieldArrayで行の挿入・削除を管理
4. **115-126行目**: deleteRowで最後の行削除時に空行を追加
5. **128-134行目**: insertRowで指定位置に行を挿入
6. **333-367行目**: getDefaultValuesで既存メタデータを編集可能/不可に分類
7. **369-428行目**: parseValuesで値の型変換と削除キーの処理

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

```
InventoryItemMetadata (inventory-metadata.tsx)
    │
    ├─ useInventoryItem (inventory.tsx)
    │      └─ sdk.admin.inventoryItem.retrieve()
    │
    ├─ useUpdateInventoryItem (inventory.tsx)
    │      └─ sdk.admin.inventoryItem.update()
    │
    └─ MetadataForm (metadata-form.tsx)
           │
           ├─ useFieldArray (react-hook-form)
           │      └─ fields, insert, remove
           │
           ├─ getDefaultValues()
           │      └─ 既存メタデータを編集可能/不可に分類
           │
           └─ parseValues()
                  └─ 型変換、削除キー処理
```

### データフロー図

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

inventory_item.metadata ──────▶ getDefaultValues ──▶ fields配列
                                        │
                                        ▼
                                フォーム表示（Grid）
                                        │
行の編集 ──────────────────────────────┤
行の追加 ──────────────────────────────┤
行の削除 ──────────────────────────────┤
                                        │
                                        ▼
                                handleSubmit
                                        │
                                        ▼
                                parseValues
                                    │
        ┌───────────────────────────┴───────────────────────────┐
        │                           │                           │
        ▼                           ▼                           ▼
  値の型変換                  空キーのスキップ           削除キーの処理
(boolean/number)                                     (空文字で上書き)
        │                           │                           │
        └───────────────────────────┴───────────────────────────┘
                                        │
                                        ▼
                          useUpdateInventoryItem({ metadata })
                                        │
                                        ▼
                                handleSuccess ──▶ ドロワークローズ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| inventory-metadata.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-metadata/inventory-metadata.tsx` | ソース | エントリーポイントコンポーネント |
| metadata-form.tsx | `packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx` | ソース | 共通メタデータフォームコンポーネント |
| inventory.tsx | `packages/admin/dashboard/src/hooks/api/inventory.tsx` | ソース | API フック |
