# 画面設計書 92-在庫作成画面

## 概要

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

### 本画面の処理概要

在庫作成画面は、新規の在庫アイテム（Inventory Item）を作成するためのモーダル形式の画面です。2ステップのプログレスタブ形式で、詳細情報と各ロケーションでの在庫数量を設定できます。

**業務上の目的・背景**：商品バリアントに紐づかない独立した在庫アイテムを作成する必要がある場合や、在庫管理の粒度を細かく設定したい場合に使用します。配送に必要な物理属性（サイズ・重量など）や、税関関連の情報（HSコード・原産国など）を設定でき、各ロケーションでの初期在庫数量も同時に設定可能です。

**画面へのアクセス方法**：在庫一覧画面から「Create」ボタンをクリックすることでモーダル形式で表示されます。URL `/inventory/create` に直接アクセスすることも可能です。

**主要な操作・処理内容**：
1. Step 1（Details）: 基本情報の入力
   - タイトル、SKU、説明の入力
   - 配送要否の設定
   - 属性情報の入力（幅、奥行き、高さ、重量、MIDコード、HSコード、原産国、素材）
2. Step 2（Availability）: 在庫数量の設定
   - 各ロケーションでの初期在庫数量を入力
3. 保存処理の実行

**画面遷移**：
- 遷移元：在庫一覧画面（Createボタン押下）
- 遷移先：作成成功時は在庫一覧画面に戻る（モーダルクローズ）

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 48 | 在庫アイテム管理 | 主機能 | 新規在庫アイテムの作成 |

## 画面種別

登録（モーダル形式）

## URL/ルーティング

`/inventory/create`

## 入出力項目

### Step 1: Details（詳細情報）

| 項目名 | 項目ID | 型 | 必須 | バリデーション | 説明 |
|--------|--------|-----|------|--------------|------|
| タイトル | title | string | - | - | 在庫アイテムのタイトル |
| SKU | sku | string | - | - | 在庫管理単位コード |
| 説明 | description | string | - | - | 在庫アイテムの説明 |
| 配送必要 | requires_shipping | boolean | - | デフォルト: true | 配送が必要かどうか |
| 幅 | width | number | - | 0以上 | 製品の幅 |
| 奥行き | length | number | - | 0以上 | 製品の奥行き |
| 高さ | height | number | - | 0以上 | 製品の高さ |
| 重量 | weight | number | - | 0以上 | 製品の重量 |
| MIDコード | mid_code | string | - | - | 製造者識別コード |
| HSコード | hs_code | string | - | - | 関税分類コード |
| 原産国 | origin_country | string | - | - | 原産国コード |
| 素材 | material | string | - | - | 製品の素材 |
| サムネイル | thumbnail | string | - | - | サムネイル画像URL |

### Step 2: Availability（在庫数量）

| 項目名 | 項目ID | 型 | 必須 | バリデーション | 説明 |
|--------|--------|-----|------|--------------|------|
| ロケーション別在庫数 | locations[location_id] | number | - | 0以上の整数 | 各ロケーションでの初期在庫数量 |

## 表示項目

### Step 1: Details

- フォームヘッダー（「Create inventory item」）
- 基本情報入力フォーム
- 配送設定スイッチボックス
- 属性情報入力フォーム

### Step 2: Availability

- ロケーション一覧（在庫数量入力フィールド付き）

## イベント仕様

### 1-Nextボタン押下（Step 1）

Step 1のバリデーションを実行し、成功時にStep 2に遷移します。

**処理フロー**:
1. フォームのtrigger()でバリデーション実行
2. バリデーション成功時、タブをAvailabilityに切り替え
3. プログレスステータスを更新

### 2-Saveボタン押下（Step 2）

在庫アイテムを作成し、各ロケーションの在庫レベルを設定します。

**処理フロー**:
1. フォームデータを取得
2. `createInventoryItem` APIで在庫アイテムを作成
3. 各ロケーションの在庫数量が設定されている場合、`batchUpdateLevels` APIで在庫レベルを一括作成
4. 成功時、トースト通知を表示しモーダルをクローズ
5. エラー時、エラーメッセージをトースト表示

### 3-Cancelボタン押下

入力内容を破棄してモーダルをクローズします。

### 4-タブ切り替え

ProgressTabsのタブをクリックして、Step 1とStep 2を切り替えます。

**処理フロー**:
1. 現在のタブのバリデーションを実行
2. バリデーション成功時、指定タブに切り替え

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ロケーション一覧取得 | stock_location | SELECT | 在庫ロケーションの一覧取得 |
| 在庫アイテム作成 | inventory_item | INSERT | 新規在庫アイテムの作成 |
| 在庫レベル作成 | inventory_level | INSERT | 各ロケーションの在庫レベル作成 |

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

#### inventory_item

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | title | フォーム入力値 | - |
| INSERT | sku | フォーム入力値 | - |
| INSERT | description | フォーム入力値 | - |
| INSERT | requires_shipping | フォーム入力値（デフォルト: true） | - |
| INSERT | width | フォーム入力値 | - |
| INSERT | length | フォーム入力値 | - |
| INSERT | height | フォーム入力値 | - |
| INSERT | weight | フォーム入力値 | - |
| INSERT | mid_code | フォーム入力値 | - |
| INSERT | hs_code | フォーム入力値 | - |
| INSERT | origin_country | フォーム入力値 | - |
| INSERT | material | フォーム入力値 | - |
| INSERT | thumbnail | フォーム入力値 | - |

#### inventory_level

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | inventory_item_id | 作成された在庫アイテムのID | - |
| INSERT | location_id | 選択されたロケーションID | - |
| INSERT | stocked_quantity | フォーム入力値 | - |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| inventory.create.successToast | 成功 | 在庫アイテムが正常に作成されました | 作成成功時 |
| - | エラー | エラーメッセージ（API エラー内容） | API 呼び出しエラー時 |

## 例外処理

| 例外条件 | 対応 | 画面表示 |
|---------|------|----------|
| ロケーション取得エラー | エラーをスロー | エラー画面を表示 |
| 在庫アイテム作成エラー | トースト通知 | エラーメッセージを表示 |
| 在庫レベル作成エラー | トースト通知 | エラーメッセージを表示（アイテムは作成済みのためモーダルクローズ） |

## 備考

- モーダルはRouteFocusModal形式で実装
- 2ステップのProgressTabsを使用
- 在庫レベル作成はアイテム作成成功後に実行されるため、レベル作成エラー時もアイテムは作成される
- ロケーション一覧は初期表示時に取得（limit: 9999）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | schema.ts | `packages/admin/dashboard/src/routes/inventory/inventory-create/components/inventory-create-form/schema.ts` | フォームスキーマの定義。CreateInventoryItemSchemaの構造を確認 |
| 1-2 | inventory-item.ts | `packages/modules/inventory/src/models/inventory-item.ts` | InventoryItemエンティティの定義 |

**読解のコツ**: zodスキーマでバリデーションルールを定義している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | inventory-create.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-create/inventory-create.tsx` | ページエントリーポイント。useStockLocationsでロケーション一覧取得、RouteFocusModalでモーダル表示 |
| 2-2 | inventory-create-form.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-create/components/inventory-create-form/inventory-create-form.tsx` | メインフォームコンポーネント。ProgressTabsで2ステップ実装 |

**主要処理フロー**:
1. **5-11行目**: `useStockLocations` でロケーション一覧取得
2. **16-20行目**: RouteFocusModalでフォームをラップ
3. **54-79行目**: useFormでフォーム状態管理
4. **89-143行目**: handleSubmitで作成処理実行
5. **202-515行目**: ProgressTabsで2ステップフォームを実装

#### Step 3: 在庫数量設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | inventory-availability-form.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-create/components/inventory-create-form/inventory-availability-form.tsx` | ロケーション別在庫数量入力フォーム |

#### Step 4: API呼び出しを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | inventory.tsx | `packages/admin/dashboard/src/hooks/api/inventory.tsx` | useCreateInventoryItemフックの実装 |

**主要処理フロー**:
- **69-87行目**: `useCreateInventoryItem` - 在庫アイテム作成
- **116-127行目**: `sdk.admin.inventoryItem.batchUpdateLevels` - 在庫レベル一括更新

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

```
InventoryCreate (inventory-create.tsx)
    │
    ├─ useStockLocations (stock-locations.tsx)
    │      └─ sdk.admin.stockLocation.list()
    │
    └─ InventoryCreateForm (inventory-create-form.tsx)
           │
           ├─ useCreateInventoryItem (inventory.tsx)
           │      └─ sdk.admin.inventoryItem.create()
           │
           ├─ sdk.admin.inventoryItem.batchUpdateLevels()
           │
           └─ InventoryAvailabilityForm (inventory-availability-form.tsx)
```

### データフロー図

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

基本情報入力 ───────────────┐
                            │
属性情報入力 ───────────────┼──▶ useForm (react-hook-form)
                            │         │
ロケーション別在庫数 ──────┘         │
                                      ▼
                              createInventoryItem API ──▶ inventory_item INSERT
                                      │
                                      ▼
                              batchUpdateLevels API ──▶ inventory_level INSERT
                                      │
                                      ▼
                              handleSuccess ──▶ モーダルクローズ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| inventory-create.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-create/inventory-create.tsx` | ソース | ページエントリーポイント |
| inventory-create-form.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-create/components/inventory-create-form/inventory-create-form.tsx` | ソース | メインフォームコンポーネント |
| inventory-availability-form.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-create/components/inventory-create-form/inventory-availability-form.tsx` | ソース | 在庫数量入力フォーム |
| schema.ts | `packages/admin/dashboard/src/routes/inventory/inventory-create/components/inventory-create-form/schema.ts` | ソース | フォームスキーマ |
| inventory.tsx | `packages/admin/dashboard/src/hooks/api/inventory.tsx` | ソース | API フック |
| inventory-item.ts | `packages/modules/inventory/src/models/inventory-item.ts` | ソース | エンティティモデル |
| inventory-level.ts | `packages/modules/inventory/src/models/inventory-level.ts` | ソース | エンティティモデル |
