# 画面設計書 14-商品販売チャネル編集画面

## 概要

本ドキュメントは、Medusa Admin Dashboard における商品販売チャネル編集画面の設計仕様を定義するものである。

### 本画面の処理概要

商品販売チャネル編集画面は、商品を販売する販売チャネル（オンラインストア、モバイルアプリ、マーケットプレイス等）との紐付けを管理するための画面である。商品の販売範囲を制御し、マルチチャネル販売戦略を実現する。

**業務上の目的・背景**：現代のECビジネスでは、複数の販売チャネルを通じて商品を販売することが一般的である。本画面は、商品ごとにどの販売チャネルで販売するかを制御し、チャネル別の商品ラインナップを最適化するために必要である。特定チャネル限定商品や、段階的な販売展開などの施策を実現できる。

**画面へのアクセス方法**：商品詳細画面の販売チャネルセクションから「Edit」ボタンをクリックすることでモーダル形式で表示される。URLパスは `/products/:id/sales-channels` となる。

**主要な操作・処理内容**：
1. 利用可能な販売チャネル一覧の表示
2. チャネルの検索・フィルタリング
3. チャネルの選択/選択解除（チェックボックス）
4. 複数チャネルの一括選択
5. 選択状態の保存

**画面遷移**：
- 遷移元：商品詳細画面（No.7）
- 遷移先：商品詳細画面（保存/キャンセル後）

**権限による表示制御**：本画面へのアクセスには商品管理権限が必要。権限がない場合は画面にアクセスできない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 71 | 販売チャネル商品紐付け | 主機能 | 商品と販売チャネルの紐付け |
| 70 | 販売チャネルCRUD | API連携 | 販売チャネル一覧の取得 |

## 画面種別

編集（モーダル形式・フルスクリーン）

## URL/ルーティング

```
/products/:id/sales-channels
```

パラメータ：
- `id`：商品ID（必須）

## 入出力項目

### 入力項目

| 項目名 | 項目ID | 型 | 必須 | バリデーション | 備考 |
|--------|--------|-----|------|---------------|------|
| 販売チャネルID配列 | sales_channels | string[] | - | - | 選択されたチャネルIDの配列 |

### 出力項目

| 項目名 | 項目ID | 型 | 備考 |
|--------|--------|-----|------|
| 販売チャネル一覧 | sales_channels | SalesChannel[] | ページネーション付き |
| 総件数 | count | number | フィルタ適用後の件数 |

## 表示項目

### 販売チャネルテーブル（DataTable）

| 項目名 | 表示形式 | 備考 |
|--------|---------|------|
| 選択チェックボックス | チェックボックス | 行選択用 |
| チャネル名 | テキスト | メインカラム |
| 説明 | テキスト | サブ情報 |

### フィルタ・検索

| 項目名 | 表示形式 | 備考 |
|--------|---------|------|
| 検索ボックス | テキスト入力 | 自動フォーカス |
| フィルタ | ドロップダウン | useSalesChannelTableFiltersで定義 |

## イベント仕様

### 1-販売チャネル選択

**トリガー**：テーブル行のチェックボックス操作

**処理フロー**：
1. RowSelectionStateを更新
2. useEffectでrowSelectionの変更を監視
3. setValue("sales_channels", ids)でフォーム値を更新

### 2-検索・フィルタリング

**トリガー**：検索ボックスへの入力またはフィルタ選択

**処理フロー**：
1. useSalesChannelTableQueryでクエリパラメータを管理
2. useSalesChannelsフックでAPIリクエスト
3. keepPreviousDataでスムーズなページ遷移

### 3-保存

**トリガー**：「Save」ボタン押下

**処理フロー**：
1. フォームデータを取得（sales_channels配列）
2. IDの配列をオブジェクト配列に変換（{id: string}[]）
3. `useUpdateProduct`ミューテーションでsales_channelsを更新
4. 成功時にモーダルを閉じる

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | product_sales_channel | REPLACE | 商品と販売チャネルの紐付けを置換 |

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

#### product_sales_channel

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| REPLACE | product_id | 対象商品ID | 必須 |
| REPLACE | sales_channel_id | 選択された販売チャネルID | 必須 |

## メッセージ仕様

| 種別 | メッセージキー | 表示条件 |
|------|--------------|---------|
| 成功 | (なし - モーダル遷移) | 保存成功時 |
| エラー | (API error message) | API呼び出し失敗時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 商品が見つからない | エラーをスロー（親コンポーネントでハンドリング） |
| 販売チャネル取得失敗 | エラーをスロー |
| API呼び出し失敗 | エラーハンドリング（RouteFocusModalで処理） |

## 備考

- DataTableコンポーネントを使用した一覧表示
- PAGE_SIZE: 50件でページネーション
- PREFIX: "sc" でクエリパラメータを管理
- autoFocusSearch: trueで検索ボックスに自動フォーカス
- layout: "fill"でモーダル全体にフィット
- 初期選択状態は商品の既存sales_channelsから生成

---

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

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

### 推奨読解順序

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

まず、販売チャネル選択のデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | edit-sales-channels-form.tsx | `packages/admin/dashboard/src/routes/products/product-sales-channels/components/edit-sales-channels-form/edit-sales-channels-form.tsx` | EditSalesChannelsSchemaの定義（24-26行目） |

**読解のコツ**: スキーマはシンプルで、sales_channelsはstring配列（チャネルID）として管理される。RowSelectionStateは{[id: string]: boolean}形式。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | product-sales-channels.tsx | `packages/admin/dashboard/src/routes/products/product-sales-channels/product-sales-channels.tsx` | ルートコンポーネント、商品データのフェッチ |

**主要処理フロー**:
- **8行目**: useParamsでidを取得
- **9-12行目**: useProductで商品データを取得（sales_channels除外なし）
- **18-23行目**: RouteFocusModal内でEditSalesChannelsFormをレンダリング

#### Step 3: 編集フォームを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit-sales-channels-form.tsx | `packages/admin/dashboard/src/routes/products/product-sales-channels/components/edit-sales-channels-form/edit-sales-channels-form.tsx` | メインのフォームロジック |

**主要処理フロー**:
- **37-42行目**: useFormの初期化（既存チャネルIDを初期値に）
- **46-50行目**: 初期選択状態の生成（RowSelectionState）
- **55-61行目**: rowSelection変更時にフォーム値を更新
- **63-74行目**: useSalesChannelTableQuery、useSalesChannelsでデータ取得
- **82-101行目**: handleSubmit - 保存処理

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

```
ProductSalesChannels (product-sales-channels.tsx)
    │
    ├─ useParams
    │      └─ id を取得
    │
    ├─ useProduct (hooks/api/products.tsx)
    │      └─ sdk.admin.product.retrieve
    │
    └─ EditSalesChannelsForm (edit-sales-channels-form.tsx)
           │
           ├─ useForm (react-hook-form)
           │      └─ zodResolver(EditSalesChannelsSchema)
           │
           ├─ useSalesChannelTableQuery (hooks)
           │      └─ クエリパラメータ管理
           │
           ├─ useSalesChannels (hooks/api/sales-channels.tsx)
           │      └─ sdk.admin.salesChannel.list
           │
           ├─ DataTable
           │      └─ 販売チャネル一覧UI
           │
           └─ useUpdateProduct
                  └─ sdk.admin.product.update
```

### データフロー図

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

product.sales_channels ────▶ initialState生成 ─────────────▶ RowSelectionState
                                   │
                                   └─ {[id]: true} 形式

rowSelection変更 ──────────▶ useEffect ─────────────────────▶ フォーム状態更新
                                   │
                                   └─ Object.keys(rowSelection)
                                          └─ setValue("sales_channels", ids)

保存ボタン ────────────────▶ handleSubmit ──────────────────▶ API更新
                                   │
                                   ├─ ids.map(id => ({id}))
                                   │
                                   └─ useUpdateProduct
                                          └─ { sales_channels }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| product-sales-channels.tsx | `packages/admin/dashboard/src/routes/products/product-sales-channels/product-sales-channels.tsx` | ソース | ルートコンポーネント |
| edit-sales-channels-form.tsx | `packages/admin/dashboard/src/routes/products/product-sales-channels/components/edit-sales-channels-form/edit-sales-channels-form.tsx` | ソース | 編集フォーム本体 |
| index.ts | `packages/admin/dashboard/src/routes/products/product-sales-channels/index.ts` | ソース | エクスポート定義 |
| products.tsx | `packages/admin/dashboard/src/hooks/api/products.tsx` | ソース | 商品関連APIフック |
| sales-channels.tsx | `packages/admin/dashboard/src/hooks/api/sales-channels.tsx` | ソース | 販売チャネル関連APIフック |
| sales-channels (helpers) | `packages/admin/dashboard/src/components/data-table/helpers/sales-channels` | ソース | テーブルヘルパー関数群 |
