# 画面設計書 132-ロケーション詳細画面

## 概要

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

### 本画面の処理概要

ロケーション詳細画面は、登録された在庫ロケーションの詳細情報を表示し、サービスゾーン、配送オプション、販売チャネル、フルフィルメントプロバイダーの管理を行うための中心的な画面である。

**業務上の目的・背景**：ECサイト運営において、各ロケーション（倉庫、店舗）がどの地域に配送可能か、どの販売チャネルで利用されるか、どの配送プロバイダーを使用するかを一元管理する必要がある。この画面は、ロケーションに関連するすべての設定を俯瞰し、効率的に管理するためのハブとして機能する。

**画面へのアクセス方法**：設定画面 > ロケーション一覧画面 > ロケーション行をクリック、またはロケーション作成完了後に自動遷移。URLパスは `/settings/locations/{location_id}`。

**主要な操作・処理内容**：
1. ロケーション基本情報（名前、住所）の確認と編集画面への遷移
2. 配送/ピックアップのフルフィルメントセットの有効化/無効化
3. サービスゾーンの作成・編集・削除・エリア管理
4. 配送オプション（通常配送・返品配送）の作成・編集・削除・料金設定
5. 販売チャネルの設定
6. フルフィルメントプロバイダーの設定
7. ロケーションの削除

**画面遷移**：
- 遷移元：ロケーション一覧画面、ロケーション作成画面
- 遷移先：ロケーション編集画面、販売チャネル設定画面、フルフィルメントプロバイダー設定画面、サービスゾーン作成画面、サービスゾーン編集画面、エリア管理画面、配送オプション作成画面、配送オプション編集画面、配送オプション料金設定画面、在庫一覧画面

**権限による表示制御**：管理者権限を持つユーザーのみがこの画面にアクセスし、各種設定を変更できる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 79 | 在庫ロケーションCRUD | 主機能 | ロケーション詳細の表示 |
| 42 | サービスゾーン管理 | 補助機能 | サービスゾーンの表示 |

## 画面種別

詳細画面（2カラムレイアウト）

## URL/ルーティング

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

## 入出力項目

この画面は主に情報表示画面のため、直接の入力項目はない。各操作は子画面（モーダル/ドロワー）で行う。

## 表示項目

### メインエリア

#### ロケーション基本情報セクション

| 項目名 | 説明 |
|--------|------|
| ロケーション名 | ロケーションの名称 |
| 住所 | フォーマットされた住所（カンマ区切り） |
| アクションメニュー | 編集、在庫表示、削除 |

#### フルフィルメントセット（配送）セクション

| 項目名 | 説明 |
|--------|------|
| セクションタイトル | 「Shipping」 |
| ステータスバッジ | Enabled/Disabled |
| サービスゾーン一覧 | 各ゾーンの名前、国リスト、配送オプション数、返品オプション数 |

#### フルフィルメントセット（ピックアップ）セクション

| 項目名 | 説明 |
|--------|------|
| セクションタイトル | 「Pickup」 |
| ステータスバッジ | Enabled/Disabled |
| サービスゾーン一覧 | 各ゾーンの名前、国リスト、ピックアップオプション数、返品オプション数 |

#### サービスゾーン内配送オプション

| 項目名 | 説明 |
|--------|------|
| オプション名 | 配送オプションの名称 |
| プロファイル名 | 配送プロファイル名 |
| プロバイダー名 | フルフィルメントプロバイダー名 |
| タイプバッジ | Store/Admin（ストアフロント表示有無） |

### サイドバーエリア

#### 販売チャネルセクション

| 項目名 | 説明 |
|--------|------|
| セクションタイトル | 「Sales Channels」 |
| チャネルリスト | 紐付けられた販売チャネル名 |

#### フルフィルメントプロバイダーセクション

| 項目名 | 説明 |
|--------|------|
| セクションタイトル | 「Fulfillment Providers」 |
| プロバイダーリスト | 有効なフルフィルメントプロバイダー名 |

## イベント仕様

### 1-編集ボタン押下（ロケーション基本情報）

**トリガー**: アクションメニュー > 「Edit」

**処理フロー**:
1. ロケーション編集画面（ドロワー）を開く
2. URLが `/settings/locations/{location_id}/edit` に変更

### 2-在庫表示ボタン押下

**トリガー**: アクションメニュー > 「View Inventory」

**処理フロー**:
1. 在庫一覧画面へ遷移
2. URLが `/inventory?location_id={location_id}` に変更
3. 該当ロケーションでフィルタリングされた在庫一覧を表示

### 3-削除ボタン押下

**トリガー**: アクションメニュー > 「Delete」

**処理フロー**:
1. 確認ダイアログを表示（ロケーション名の入力による確認）
2. 確認後、`useDeleteStockLocation`フックを通じてAPIを呼び出し
3. APIリクエスト: `DELETE /admin/stock-locations/{location_id}`
4. 成功時: トースト通知を表示し、ロケーション一覧画面へ遷移
5. 失敗時: エラーメッセージをトースト通知で表示

### 4-フルフィルメントセット有効化

**トリガー**: フルフィルメントセットのアクションメニュー > 「Enable」

**処理フロー**:
1. `useCreateStockLocationFulfillmentSet`フックを通じてAPIを呼び出し
2. APIリクエスト: `POST /admin/stock-locations/{location_id}/fulfillment-sets`
3. 成功時: トースト通知を表示、セクションが更新される

### 5-フルフィルメントセット無効化

**トリガー**: フルフィルメントセットのアクションメニュー > 「Disable」

**処理フロー**:
1. 確認ダイアログを表示
2. 確認後、`useDeleteFulfillmentSet`フックを通じてAPIを呼び出し
3. 成功時: トースト通知を表示、セクションが更新される

### 6-サービスゾーン作成

**トリガー**: 「Add Service Zone」ボタンまたはリンク

**処理フロー**:
1. サービスゾーン作成画面（モーダル）を開く
2. URLが `/settings/locations/{location_id}/fulfillment-set/{fset_id}/service-zones/create` に変更

### 7-サービスゾーン編集

**トリガー**: サービスゾーンのアクションメニュー > 「Edit」

**処理フロー**:
1. サービスゾーン編集画面（ドロワー）を開く
2. URLが `/settings/locations/{location_id}/fulfillment-set/{fset_id}/service-zone/{zone_id}/edit` に変更

### 8-サービスゾーンエリア管理

**トリガー**: サービスゾーンのアクションメニュー > 「Manage Areas」

**処理フロー**:
1. エリア管理画面（モーダル）を開く
2. URLが `/settings/locations/{location_id}/fulfillment-set/{fset_id}/service-zone/{zone_id}/areas` に変更

### 9-サービスゾーン削除

**トリガー**: サービスゾーンのアクションメニュー > 「Delete」

**処理フロー**:
1. 確認ダイアログを表示
2. 確認後、`useDeleteFulfillmentServiceZone`フックを通じてAPIを呼び出し
3. 成功時: トースト通知を表示

### 10-配送オプション作成

**トリガー**: 「Create Shipping Option」リンク

**処理フロー**:
1. 配送オプション作成画面（モーダル）を開く
2. URLが `/settings/locations/{location_id}/fulfillment-set/{fset_id}/service-zone/{zone_id}/shipping-option/create` に変更
3. 返品オプションの場合は `?is_return` クエリパラメータが追加される

### 11-配送オプション編集

**トリガー**: 配送オプションのアクションメニュー > 「Edit」

**処理フロー**:
1. 配送オプション編集画面（ドロワー）を開く
2. URLが `/settings/locations/{location_id}/fulfillment-set/{fset_id}/service-zone/{zone_id}/shipping-option/{so_id}/edit` に変更

### 12-配送オプション料金設定

**トリガー**: 配送オプションのアクションメニュー > 「Edit Pricing」

**処理フロー**:
1. 配送オプション料金設定画面（モーダル）を開く
2. URLが `/settings/locations/{location_id}/fulfillment-set/{fset_id}/service-zone/{zone_id}/shipping-option/{so_id}/pricing` に変更
3. 「Calculated」タイプの場合は無効化される

### 13-配送オプション削除

**トリガー**: 配送オプションのアクションメニュー > 「Delete」

**処理フロー**:
1. 確認ダイアログを表示（オプション名の入力による確認）
2. 確認後、`useDeleteShippingOption`フックを通じてAPIを呼び出し
3. 成功時: トースト通知を表示

### 14-販売チャネル編集

**トリガー**: 販売チャネルセクションの「Edit」ボタン

**処理フロー**:
1. 販売チャネル設定画面（モーダル）を開く
2. URLが `/settings/locations/{location_id}/sales-channels` に変更

### 15-フルフィルメントプロバイダー編集

**トリガー**: フルフィルメントプロバイダーセクションの「Edit」ボタン

**処理フロー**:
1. フルフィルメントプロバイダー設定画面（モーダル）を開く
2. URLが `/settings/locations/{location_id}/fulfillment-providers` に変更

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 削除ボタン押下 | stock_location | DELETE | ロケーションレコードの削除 |
| フルフィルメントセット有効化 | fulfillment_set | INSERT | フルフィルメントセットの作成 |
| フルフィルメントセット無効化 | fulfillment_set | DELETE | フルフィルメントセットの削除 |
| サービスゾーン削除 | service_zone | DELETE | サービスゾーンの削除 |
| 配送オプション削除 | shipping_option | DELETE | 配送オプションの削除 |

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

#### stock_location（削除時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | WHERE id = {location_id} | 論理削除または物理削除 |

## メッセージ仕様

| メッセージ種別 | メッセージキー | 表示条件 | 表示内容 |
|--------------|---------------|----------|---------|
| 成功 | stockLocations.create.successToast | ロケーション削除成功時 | 「{name} deleted successfully」 |
| 成功 | stockLocations.fulfillmentSets.enable.{type} | フルフィルメントセット有効化成功時 | タイプに応じたメッセージ |
| 成功 | stockLocations.fulfillmentSets.disable.{type} | フルフィルメントセット無効化成功時 | タイプに応じたメッセージ |
| 成功 | stockLocations.serviceZones.delete.successToast | サービスゾーン削除成功時 | 「{name} deleted」 |
| 成功 | stockLocations.shippingOptions.delete.successToast | 配送オプション削除成功時 | 「{name} deleted」 |
| エラー | - | API呼び出し失敗時 | APIから返却されたエラーメッセージ |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| ロケーションが見つからない | `loader`でエラーをスロー、エラー画面を表示 |
| APIエラー | トースト通知でエラーメッセージを表示 |
| 認証エラー（401） | ログイン画面へリダイレクト |

## 備考

- 画面は`TwoColumnPage`レイアウトを使用し、メインエリアとサイドバーで構成
- 拡張ポイント（Widgets）が用意されており、`location.details.before`、`location.details.after`、`location.details.side.before`、`location.details.side.after`でカスタムコンテンツを追加可能
- ローディング中は`TwoColumnPageSkeleton`でスケルトン表示
- JSON表示機能（`showJSON`）でロケーションデータの生データを確認可能
- サービスゾーン内の配送オプションは折りたたみ可能（デフォルトは展開状態）

---

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

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

### 推奨読解順序

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

ロケーションの詳細データ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | constants.ts | `packages/admin/dashboard/src/routes/locations/location-detail/constants.ts` | `LOCATION_DETAILS_FIELD`でAPIから取得するフィールドを定義 |

**読解のコツ**: `fields`パラメータはMedusa APIのセレクトフィールドを指定し、`*`プレフィックスはリレーションの展開を意味する。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | location-detail.tsx | `packages/admin/dashboard/src/routes/locations/location-detail/location-detail.tsx` | L14-64: メインコンポーネントの構造、`TwoColumnPage`レイアウトの使用 |

**主要処理フロー**:
1. **L15-17**: `useLoaderData`でプリロードされたデータを取得
2. **L19-29**: `useStockLocation`でロケーションデータを取得
3. **L33-41**: ローディング/エラー状態のハンドリング
4. **L43-62**: 2カラムレイアウトでセクションを配置

#### Step 3: 各セクションを理解する

メインセクションとサイドバーセクションの詳細を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | location-general-section.tsx | `packages/admin/dashboard/src/routes/locations/location-detail/components/location-general-section/location-general-section.tsx` | L59-94: 基本情報表示とフルフィルメントセットの管理UI |
| 3-2 | locations-sales-channels-section.tsx | `packages/admin/dashboard/src/routes/locations/location-detail/components/location-sales-channels-section/locations-sales-channels-section.tsx` | 販売チャネルセクション |
| 3-3 | location-fulfillment-providers-section.tsx | `packages/admin/dashboard/src/routes/locations/location-detail/components/location-fulfillment-providers-section/location-fulfillment-providers-section.tsx` | フルフィルメントプロバイダーセクション |

**主要処理フロー（location-general-section.tsx）**:
- **L59-94**: `LocationGeneralSection`でロケーション基本情報を表示
- **L76-92**: `FulfillmentSet`コンポーネントでPickupとShippingの各フルフィルメントセットを表示
- **L453-593**: `FulfillmentSet`でセット全体の管理（有効化/無効化、サービスゾーン一覧）
- **L282-443**: `ServiceZone`で各ゾーンの詳細表示と配送オプション管理
- **L103-192**: `ShippingOption`で各配送オプションの表示とアクション

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

```
LocationDetail (location-detail.tsx)
    │
    ├─ TwoColumnPage.Main
    │      └─ LocationGeneralSection
    │             ├─ Actions (編集/在庫表示/削除)
    │             ├─ FulfillmentSet (Pickup)
    │             │      └─ ServiceZone[]
    │             │             └─ ServiceZoneOptions
    │             │                    └─ ShippingOption[]
    │             └─ FulfillmentSet (Shipping)
    │                    └─ ServiceZone[]
    │                           └─ ServiceZoneOptions
    │                                  └─ ShippingOption[]
    │
    └─ TwoColumnPage.Sidebar
           ├─ LocationsSalesChannelsSection
           └─ LocationsFulfillmentProvidersSection
```

### データフロー図

```
[API取得]                    [状態管理]                [表示]

useStockLocation ───▶ stock_location ───▶ LocationGeneralSection
     │                                           │
     │                                           ├─▶ 基本情報表示
     │                                           │
     ├─ fulfillment_sets ───────────────────────▶ FulfillmentSet[]
     │         │                                        │
     │         └─ service_zones ────────────────▶ ServiceZone[]
     │                    │                              │
     │                    └─ shipping_options ──▶ ShippingOption[]
     │
     ├─ sales_channels ─────────────────────────▶ SalesChannelsSection
     │
     └─ fulfillment_providers ──────────────────▶ FulfillmentProvidersSection
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| location-detail.tsx | `packages/admin/dashboard/src/routes/locations/location-detail/location-detail.tsx` | ソース | 画面エントリーポイント |
| loader.ts | `packages/admin/dashboard/src/routes/locations/location-detail/loader.ts` | ソース | データプリロード |
| constants.ts | `packages/admin/dashboard/src/routes/locations/location-detail/constants.ts` | ソース | 定数定義 |
| location-general-section.tsx | `packages/admin/dashboard/src/routes/locations/location-detail/components/location-general-section/location-general-section.tsx` | ソース | 基本情報セクション |
| locations-sales-channels-section.tsx | `packages/admin/dashboard/src/routes/locations/location-detail/components/location-sales-channels-section/locations-sales-channels-section.tsx` | ソース | 販売チャネルセクション |
| location-fulfillment-providers-section.tsx | `packages/admin/dashboard/src/routes/locations/location-detail/components/location-fulfillment-providers-section/location-fulfillment-providers-section.tsx` | ソース | プロバイダーセクション |
| stock-locations.tsx | `packages/admin/dashboard/src/hooks/api/stock-locations.tsx` | ソース | API呼び出しフック |
| fulfillment-sets.tsx | `packages/admin/dashboard/src/hooks/api/fulfillment-sets.tsx` | ソース | フルフィルメントセットAPI |
| shipping-options.tsx | `packages/admin/dashboard/src/hooks/api/shipping-options.tsx` | ソース | 配送オプションAPI |
