# 画面設計書 38-コレクション編集画面

## 概要

本ドキュメントは、Medusa Admin Dashboard におけるコレクション編集画面の設計を記述したものです。

### 本画面の処理概要

商品コレクションの基本情報（タイトル、ハンドル）を編集するための画面です。

**業務上の目的・背景**：ECサイト運営において、コレクション名の変更やURLの調整が必要になることがあります。キャンペーン名の変更、SEO対策でのURL最適化、ブランディングの統一など、様々な理由でコレクションの基本情報を更新する必要があります。この画面では、コレクションのタイトルとハンドルをシンプルに編集できます。

**画面へのアクセス方法**：コレクション詳細画面のアクションメニューから「編集」を選択、またはURL直接アクセスで、右側からドロワー形式で表示されます。

**主要な操作・処理内容**：
1. タイトルの編集 - コレクション名の変更（必須）
2. ハンドルの編集 - URL識別子の変更（必須）
3. 保存ボタン押下で変更内容を確定

**画面遷移**：コレクション詳細画面から遷移してきます。保存完了後またはキャンセル時にコレクション詳細画面に戻ります。

**権限による表示制御**：管理者権限を持つユーザーのみがコレクションを編集できます。認証されていないユーザーはログイン画面にリダイレクトされます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | 商品コレクション管理 | 主機能 | コレクション情報の編集 |

## 画面種別

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

## URL/ルーティング

`/collections/:id/edit`

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 最大長 | 入力/出力 | 説明 |
|--------|--------|-----|------|--------|-----------|------|
| コレクションID | id | string | - | - | 入力(URL) | 編集対象のコレクションID |
| タイトル | title | string | 必須 | - | 入出力 | コレクション名（最低1文字） |
| ハンドル | handle | string | 必須 | - | 入出力 | URL識別子（最低1文字） |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| ヘッダータイトル | Heading | "Edit Collection"（i18n: collections.editCollection） |
| タイトルラベル | フォームラベル | "Title"（i18n: fields.title） |
| ハンドルラベル | フォームラベル（tooltip付き） | "Handle"（i18n: fields.handle） |
| ハンドルプレフィックス | Text | "/"（スラッシュ表示） |
| キャンセルボタン | Button | "Cancel"（i18n: actions.cancel） |
| 保存ボタン | Button | "Save"（i18n: actions.save） |

## イベント仕様

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

フォームのバリデーションを実行し、成功した場合はAPIを呼び出してコレクション情報を更新します。

**処理フロー**:
1. Zodスキーマによるバリデーション実行
2. `useUpdateCollection` フックを使用してAPI呼び出し
3. 成功時: モーダルを閉じる（handleSuccess）
4. 失敗時: エラー処理（特にカスタム処理なし）

**API呼び出し**:
- エンドポイント: `POST /admin/collections/:id`
- リクエストボディ:
  ```json
  {
    "title": "string",
    "handle": "string"
  }
  ```

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

フォームの変更を破棄し、ドロワーを閉じてコレクション詳細画面に戻ります。

### 3-ハンドル入力

ハンドル入力欄の左側に"/"プレフィックスが固定表示され、実際の入力値にはスラッシュは含まれません。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | product_collection | UPDATE | コレクションの基本情報を更新 |

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

#### product_collection

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | title | フォーム入力値 | コレクション名 |
| UPDATE | handle | フォーム入力値 | URL識別子 |
| UPDATE | updated_at | 現在日時 | 自動更新 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示タイミング |
|------------|------|--------------|--------------|
| - | バリデーションエラー | フィールド別エラーメッセージ | 入力値不正時 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| コレクションが見つからない | エラーをスローし、エラーバウンダリで処理 |
| API通信エラー | エラー処理（カスタム処理なし） |
| バリデーションエラー | 各フィールドの下にエラーメッセージを表示 |
| ハンドル重複 | APIエラーとして処理 |
| 認証エラー | ログイン画面にリダイレクト |

## 備考

- ドロワー形式（RouteDrawer）で表示
- キーボードショートカット対応（KeyboundForm）
- フォームの状態管理にはreact-hook-formを使用
- バリデーションにはZodスキーマを使用
- titleとhandleの両方が必須で最低1文字
- ハンドル入力欄に"/"プレフィックスを視覚的に表示
- handleフィールドにtooltipでヒントを表示（collections.handleTooltip）
- 保存成功時のトースト通知は実装されていない

---

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

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

### 推奨読解順序

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

フォームのスキーマを理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | edit-collection-form.tsx | `packages/admin/dashboard/src/routes/collections/collection-edit/components/edit-collection-form/edit-collection-form.tsx` | EditCollectionSchema（17-20行目）でフォームのバリデーションルールを確認 |

**読解のコツ**: titleとhandleの両方が`z.string().min(1)`で必須です。

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

ルートコンポーネントから画面がどのように構成されるかを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | collection-edit.tsx | `packages/admin/dashboard/src/routes/collections/collection-edit/collection-edit.tsx` | useParamsでID取得、useCollectionでデータフェッチ、RouteDrawerでドロワー表示 |

**主要処理フロー**:
1. **9行目**: useParamsでURLからコレクションIDを取得
2. **11行目**: useCollectionでコレクションデータをフェッチ
3. **13-15行目**: エラー時の例外スロー
4. **17-26行目**: RouteDrawerでドロワー表示、EditCollectionFormを配置

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

編集フォームの実装詳細を把握します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit-collection-form.tsx | `packages/admin/dashboard/src/routes/collections/collection-edit/components/edit-collection-form/edit-collection-form.tsx` | useForm、useUpdateCollection、handleSubmitの実装を確認 |

**主要処理フロー**:
- **26-32行目**: useFormでフォーム初期化、既存データをdefaultValuesに設定
- **34行目**: useUpdateCollectionでミューテーションフック取得
- **36-42行目**: handleSubmitで送信処理を定義
- **37-41行目**: mutateAsyncでAPI呼び出し、成功時はhandleSuccessのみ
- **49-62行目**: titleフィールドの定義
- **63-91行目**: handleフィールドの定義（プレフィックス"/"表示付き）

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | collections.tsx | `packages/admin/dashboard/src/hooks/api/collections.tsx` | useUpdateCollection（91-111行目）の実装を確認 |

**主要処理フロー**:
- **100行目**: sdk.admin.productCollection.updateでAPI呼び出し
- **101-105行目**: 成功時にクエリキャッシュを無効化

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

```
CollectionEdit (collection-edit.tsx)
    │
    ├─ useParams() → コレクションID取得
    │
    ├─ useCollection(id) → コレクションデータ取得
    │      └─ sdk.admin.productCollection.retrieve()
    │
    └─ RouteDrawer
           │
           ├─ RouteDrawer.Header
           │      └─ Heading → "Edit Collection"
           │
           └─ EditCollectionForm (edit-collection-form.tsx)
                  │
                  ├─ useForm() → フォーム状態管理
                  │
                  ├─ useRouteModal() → モーダル制御
                  │      └─ handleSuccess() → モーダルクローズ
                  │
                  ├─ useUpdateCollection(id) → 更新ミューテーション
                  │      └─ sdk.admin.productCollection.update()
                  │
                  └─ handleSubmit() → フォーム送信処理
                         └─ mutateAsync() → API呼び出し
```

### データフロー図

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

URLパラメータ(:id) ───▶ useCollection ───▶ コレクションデータ表示
                              │
                              ▼
フォーム入力 ─────────▶ Zodバリデーション
(title, handle)               │
                              ▼
                        useUpdateCollection
                              │
                              ▼
                        SDK API呼び出し ───▶ product_collection更新
                              │
                              ▼
                        クエリキャッシュ無効化
                              │
                              ▼
                        handleSuccess() ───▶ モーダルクローズ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| collection-edit.tsx | `packages/admin/dashboard/src/routes/collections/collection-edit/collection-edit.tsx` | ソース | ルートコンポーネント |
| edit-collection-form.tsx | `packages/admin/dashboard/src/routes/collections/collection-edit/components/edit-collection-form/edit-collection-form.tsx` | ソース | 編集フォームコンポーネント |
| index.ts | `packages/admin/dashboard/src/routes/collections/collection-edit/index.ts` | ソース | エクスポート定義 |
| collections.tsx | `packages/admin/dashboard/src/hooks/api/collections.tsx` | ソース | コレクションAPI フック |
| RouteDrawer | `packages/admin/dashboard/src/components/modals/` | ソース | ドロワーモーダル |
| Form | `packages/admin/dashboard/src/components/common/form/` | ソース | フォームコンポーネント |
| KeyboundForm | `packages/admin/dashboard/src/components/utilities/keybound-form/` | ソース | キーバインド対応フォーム |
