# 画面設計書 133-ロケーション編集画面

## 概要

本ドキュメントは、Medusa Admin Dashboardにおけるロケーション編集画面の設計仕様を定義するものである。

### 本画面の処理概要

ロケーション編集画面は、既存の在庫ロケーションの基本情報（名前、住所）を更新するための画面である。

**業務上の目的・背景**：ECサイト運営において、倉庫や店舗の情報が変更された場合（移転、名称変更、電話番号変更など）に、登録済みのロケーション情報を最新の状態に保つ必要がある。正確なロケーション情報は、配送先の決定や顧客への情報提供において重要である。

**画面へのアクセス方法**：ロケーション詳細画面 > アクションメニュー > 「Edit」をクリックすることでアクセスできる。URLパスは `/settings/locations/{location_id}/edit`。

**主要な操作・処理内容**：
1. ロケーション名の編集（必須）
2. 住所情報の編集（住所1、住所2、郵便番号、市区町村、国、都道府県、会社名、電話番号）
3. 「保存」ボタンでロケーション情報を更新
4. 「キャンセル」ボタンで操作を中断し、前の画面に戻る

**画面遷移**：
- 遷移元：ロケーション詳細画面（`/settings/locations/{location_id}`）
- 遷移先：保存完了後、ロケーション詳細画面へ自動的に戻る

**権限による表示制御**：管理者権限を持つユーザーのみがこの画面にアクセスし、ロケーション情報を編集できる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 79 | 在庫ロケーションCRUD | 主機能 | ロケーション情報の編集 |
| 80 | ロケーション住所管理 | 補助機能 | 住所情報の編集 |

## 画面種別

編集画面（ドロワー形式）

## URL/ルーティング

- パス: `/settings/locations/:location_id/edit`
- コンポーネント: `LocationEdit`
- ルートファイル: `packages/admin/dashboard/src/routes/locations/location-edit/location-edit.tsx`

## 入出力項目

| 項目名 | 項目ID | 入出力 | 型 | 必須 | バリデーション | 説明 |
|--------|--------|--------|-----|------|---------------|------|
| ロケーション名 | name | 入力 | string | Yes | 1文字以上 | ロケーションの名称 |
| 住所1 | address.address_1 | 入力 | string | Yes | 1文字以上 | 主要な住所 |
| 住所2 | address.address_2 | 入力 | string | No | - | 補足住所 |
| 郵便番号 | address.postal_code | 入力 | string | No | - | 郵便番号 |
| 市区町村 | address.city | 入力 | string | No | - | 市区町村名 |
| 国 | address.country_code | 入力 | string | Yes | 2文字（ISO 3166-1 alpha-2） | 国コード |
| 都道府県 | address.province | 入力 | string | No | - | 都道府県名 |
| 会社名 | address.company | 入力 | string | No | - | 会社名 |
| 電話番号 | address.phone | 入力 | string | No | - | 電話番号 |

## 表示項目

| 項目名 | 説明 |
|--------|------|
| ヘッダータイトル | 「Edit Location」（翻訳キー: `locations.editLocation`） |

## イベント仕様

### 1-保存ボタン押下

**トリガー**: 「Save」ボタンのクリック、または `Cmd/Ctrl + Enter` キーボードショートカット

**処理フロー**:
1. フォームバリデーションを実行
2. バリデーション成功時、`useUpdateStockLocation`フックを通じてAPIを呼び出し
3. APIリクエスト: `POST /admin/stock-locations/{location_id}`
4. 成功時: トースト通知を表示し、ドロワーを閉じてロケーション詳細画面に戻る
5. 失敗時: エラーメッセージをトースト通知で表示

**送信データ**:
```typescript
{
  name: string,
  address: {
    address_1: string,
    address_2?: string,
    country_code: string,
    city?: string,
    postal_code?: string,
    province?: string,
    company?: string,
    phone?: string
  }
}
```

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

**トリガー**: 「Cancel」ボタンのクリック

**処理フロー**:
1. ドロワーを閉じる
2. ロケーション詳細画面に戻る

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | stock_location | UPDATE | ロケーションレコードの更新 |
| 保存ボタン押下 | stock_location_address | UPDATE | ロケーション住所レコードの更新 |

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

#### stock_location

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | フォーム入力値 | ロケーション名 |
| UPDATE | updated_at | システム自動設定 | 更新日時 |

#### stock_location_address

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | address_1 | フォーム入力値 | 住所1 |
| UPDATE | address_2 | フォーム入力値（任意） | 住所2 |
| UPDATE | city | フォーム入力値（任意） | 市区町村 |
| UPDATE | country_code | フォーム入力値 | 国コード |
| UPDATE | postal_code | フォーム入力値（任意） | 郵便番号 |
| UPDATE | province | フォーム入力値（任意） | 都道府県 |
| UPDATE | company | フォーム入力値（任意） | 会社名 |
| UPDATE | phone | フォーム入力値（任意） | 電話番号 |

## メッセージ仕様

| メッセージ種別 | メッセージキー | 表示条件 | 表示内容 |
|--------------|---------------|----------|---------|
| 成功 | stockLocations.edit.successToast | ロケーション更新成功時 | 「{name} updated successfully」 |
| エラー | - | API呼び出し失敗時 | APIから返却されたエラーメッセージ |
| バリデーション | - | 必須項目未入力時 | 該当フィールドにエラー表示 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| ロケーションが見つからない | エラーをスロー、エラー画面を表示 |
| ネットワークエラー | トースト通知でエラーメッセージを表示、フォーム状態は維持 |
| サーバーエラー（5xx） | トースト通知でエラーメッセージを表示 |
| バリデーションエラー（4xx） | トースト通知でエラーメッセージを表示、該当フィールドにエラー表示 |
| 認証エラー（401） | ログイン画面へリダイレクト |

## 備考

- 画面はドロワー（`RouteDrawer`）として実装されている
- フォームは`react-hook-form`と`zod`によるバリデーションを使用
- 国の選択は`CountrySelect`コンポーネントを使用し、ISO 3166-1 alpha-2形式の国コードを選択
- キーボードショートカット（Cmd/Ctrl + Enter）でフォーム送信が可能
- 既存データはAPIから取得してフォームの初期値として設定される
- ローディング中（データ取得中）はフォームを表示しない（`ready`状態を確認）

---

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

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

### 推奨読解順序

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

フォームの入力値とAPIリクエストの型定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | edit-location-form.tsx | `packages/admin/dashboard/src/routes/locations/location-edit/components/edit-location-form/edit-location-form.tsx` | L17-29: `EditLocationSchema`でフォームのバリデーションスキーマを定義。作成画面と同様の構造 |

**読解のコツ**: zodスキーマは作成画面と同様だが、編集画面では既存データで初期化される点が異なる。

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

画面コンポーネントの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | location-edit.tsx | `packages/admin/dashboard/src/routes/locations/location-edit/location-edit.tsx` | L8-33: URLパラメータからlocation_idを取得し、既存データをフェッチ |

**主要処理フロー**:
1. **L10**: `useParams`でURL からlocation_idを取得
2. **L12-17**: `useStockLocation`でロケーションデータを取得（`*address`フィールドを含む）
3. **L19**: `ready`変数でデータ取得完了を確認
4. **L26-31**: `RouteDrawer`でドロワーUIをレンダリング、データ取得完了時のみフォームを表示

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

フォームの状態管理とAPI呼び出しの流れを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit-location-form.tsx | `packages/admin/dashboard/src/routes/locations/location-edit/components/edit-location-form/edit-location-form.tsx` | L31-72: フォーム初期化、API呼び出し、成功/エラーハンドリングの実装 |

**主要処理フロー**:
- **L35-50**: `useForm`でフォーム状態を初期化、既存のロケーションデータをデフォルト値として設定
- **L52**: `useUpdateStockLocation`フックでAPI呼び出し関数を取得
- **L54-72**: `handleSubmit`でフォーム送信時の処理を定義。成功時は`handleSuccess`でドロワーを閉じる

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

バックエンドとの通信処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | stock-locations.tsx | `packages/admin/dashboard/src/hooks/api/stock-locations.tsx` | L84-106: `useUpdateStockLocation`フックの実装。`sdk.admin.stockLocation.update`でAPIを呼び出し |

**主要処理フロー**:
- **L92**: `mutationFn`で`sdk.admin.stockLocation.update(id, payload)`を実行
- **L93-100**: 成功時にクエリキャッシュを無効化してリスト表示と詳細表示を更新

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

```
LocationEdit (location-edit.tsx)
    │
    ├─ useStockLocation (既存データ取得)
    │      └─ sdk.admin.stockLocation.retrieve
    │
    └─ EditLocationForm (edit-location-form.tsx)
           │
           ├─ useForm (react-hook-form)
           │      └─ zodResolver (EditLocationSchema)
           │      └─ defaultValues (既存ロケーションデータ)
           │
           ├─ useUpdateStockLocation (stock-locations.tsx)
           │      └─ sdk.admin.stockLocation.update
           │             └─ POST /admin/stock-locations/{id}
           │
           └─ handleSuccess (useRouteModal)
                  └─ close drawer
```

### データフロー図

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

既存データ取得 ───▶ useStockLocation ───▶ フォーム初期値設定
                                               │
フォーム編集 ───▶ zodバリデーション ───▶ バリデーションエラー表示
      │
      └─(valid)──▶ useUpdateStockLocation ───▶ POST /admin/stock-locations/{id}
                          │
                          ├─(success)──▶ toast.success + ドロワーclose
                          │
                          └─(error)──▶ toast.error
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| location-edit.tsx | `packages/admin/dashboard/src/routes/locations/location-edit/location-edit.tsx` | ソース | 画面エントリーポイント |
| edit-location-form.tsx | `packages/admin/dashboard/src/routes/locations/location-edit/components/edit-location-form/edit-location-form.tsx` | ソース | フォームコンポーネント |
| index.ts | `packages/admin/dashboard/src/routes/locations/location-edit/index.ts` | ソース | エクスポート定義 |
| stock-locations.tsx | `packages/admin/dashboard/src/hooks/api/stock-locations.tsx` | ソース | API呼び出しフック |
| country-select.tsx | `packages/admin/dashboard/src/components/inputs/country-select/` | ソース | 国選択コンポーネント |
