# 画面設計書 67-キャンペーン編集画面

## 概要

本ドキュメントは、Medusa Admin Dashboard のキャンペーン編集画面について、画面仕様・機能・データ処理を定義した画面設計書です。

### 本画面の処理概要

この画面では、既存キャンペーンの基本情報を編集することができます。キャンペーン名、識別子、説明、開始日、終了日を変更できます。

**業務上の目的・背景**：作成済みのキャンペーンの基本情報を修正するための画面です。キャンペーン名や識別子の変更、説明の追加・修正、期間設定の変更などを行えます。予算関連の設定は別画面（予算編集画面）で行います。

**画面へのアクセス方法**：キャンペーン詳細画面のアクションメニューから「編集」を選択することで、ドロワー形式でこの画面が表示されます。URL: `/campaigns/:id/edit`

**主要な操作・処理内容**：
1. キャンペーン名を編集
2. 識別子を編集
3. 説明を編集
4. 開始日を編集
5. 終了日を編集
6. 保存ボタンで更新を実行

**画面遷移**：
- 遷移元：キャンペーン詳細画面（`/campaigns/:id`）
- 遷移先：更新成功時はドロワーを閉じてキャンペーン詳細画面に戻る、キャンセル時も同様

**権限による表示制御**：認証済みの管理者ユーザーのみがアクセス可能です。キャンペーン管理権限を持つユーザーが操作できます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 38 | キャンペーン管理 | 主機能 | キャンペーン基本情報の編集 |

## 画面種別

編集（ドロワー形式）

## URL/ルーティング

`/campaigns/:id/edit`

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 入力/出力 | 説明 |
|--------|--------|-----|------|-----------|------|
| キャンペーン名 | name | string | - | 入力 | キャンペーン名 |
| 説明 | description | string | - | 入力 | キャンペーンの説明 |
| 識別子 | campaign_identifier | string | - | 入力 | キャンペーン識別子 |
| 開始日 | starts_at | date | - | 入力 | キャンペーン開始日時 |
| 終了日 | ends_at | date | - | 入力 | キャンペーン終了日時 |

## 表示項目

| 項目名 | 説明 |
|--------|------|
| 画面タイトル | 「キャンペーンを編集」 |
| 名前フィールド | キャンペーン名入力 |
| 説明フィールド | キャンペーン説明入力 |
| 識別子フィールド | キャンペーン識別子入力 |
| 開始日フィールド | DatePicker（分単位、12時間制） |
| 終了日フィールド | DatePicker（分単位） |
| キャンセルボタン | ドロワーを閉じる |
| 保存ボタン | 変更を保存 |

## イベント仕様

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

**処理フロー**：
1. フォームバリデーションを実行
2. `useUpdateCampaign` フックを使用してAPIを呼び出し
3. 成功時：トースト通知を表示し、ドロワーを閉じる
4. 失敗時：エラーメッセージをトーストで表示

**API呼び出し**：
- エンドポイント: `POST /admin/campaigns/:id`
- リクエストボディ:
```json
{
  "name": string,
  "description": string,
  "campaign_identifier": string,
  "starts_at": date | null,
  "ends_at": date | null
}
```

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

**処理フロー**：
1. フォームの入力内容を破棄
2. ドロワーを閉じてキャンペーン詳細画面に戻る

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | campaign | UPDATE | キャンペーンの更新 |

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

#### campaign

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | フォームの name | |
| UPDATE | description | フォームの description | |
| UPDATE | campaign_identifier | フォームの campaign_identifier | |
| UPDATE | starts_at | フォームの starts_at | null許可 |
| UPDATE | ends_at | フォームの ends_at | null許可 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | 成功 | キャンペーン「{name}」を更新しました | 更新成功時 |
| MSG-002 | エラー | {エラーメッセージ} | API通信エラー時 |

## 例外処理

| 例外 | 処理内容 |
|------|---------|
| キャンペーンが見つからない | エラーをスローしてエラー画面を表示 |
| API通信エラー | エラーメッセージをtoastで表示 |

## 備考

- ドロワー形式（RouteDrawer）で表示される
- 開始日・終了日を削除することも可能（undefinedに設定可能）
- 予算の編集は別画面（予算編集画面）で行う
- DatePickerは分単位の粒度で設定可能
- 開始日のDatePickerは12時間制（hourCycle: 12）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | edit-campaign-form.tsx | `packages/admin/dashboard/src/routes/campaigns/campaign-edit/components/edit-campaign-form/edit-campaign-form.tsx` | EditCampaignSchema（16-22行目）でフォームの構造を確認 |

**読解のコツ**: name, description, campaign_identifier, starts_at, ends_atの5つのフィールドを持つシンプルな編集フォームです。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | campaign-edit.tsx | `packages/admin/dashboard/src/routes/campaigns/campaign-edit/campaign-edit.tsx` | RouteDrawerレイアウトとキャンペーンデータのロード |

**主要処理フロー**:
1. **12行目**: useParamsでキャンペーンIDを取得
2. **13行目**: useCampaignでキャンペーン詳細を取得
3. **20-32行目**: RouteDrawerでドロワーをレンダリング
4. **30行目**: EditCampaignFormコンポーネントを表示

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit-campaign-form.tsx | `packages/admin/dashboard/src/routes/campaigns/campaign-edit/components/edit-campaign-form/edit-campaign-form.tsx` | フォームロジックと送信処理 |

**主要処理フロー**:
- **28-37行目**: useFormでフォーム初期化（既存データをデフォルト値に設定）
- **39行目**: useUpdateCampaignでミューテーション準備
- **41-65行目**: handleSubmitで送信処理
- **52-56行目**: 成功時のトースト表示
- **60-62行目**: エラー時のトースト表示

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

```
CampaignEdit (campaign-edit.tsx)
    │
    ├─ useCampaign() - キャンペーン詳細取得
    │      └─ sdk.admin.campaign.retrieve()
    │             └─ GET /admin/campaigns/:id
    │
    └─ EditCampaignForm (edit-campaign-form.tsx)
           │
           ├─ useForm() - フォーム状態管理
           │
           └─ useUpdateCampaign() - 更新ミューテーション
                  └─ sdk.admin.campaign.update()
                         └─ POST /admin/campaigns/:id
                                └─ updateCampaignsWorkflow
```

### データフロー図

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

URLパラメータ ────▶ useCampaign() ────▶ キャンペーン詳細
     (id)                                      ↓
                    useForm() ─────────▶ フォーム初期化
                                              ↓
フォーム入力 ────────▶ フォーム状態 ───────▶ 編集データ
                                              ↓
保存ボタン ──────────▶ handleSubmit ───▶ バリデーション
                                              ↓
                    useUpdateCampaign() ▶ API更新
                                              ↓
                    toast.success() ──▶ 成功通知
                                              ↓
                    handleSuccess() ──▶ ドロワー閉じる
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| campaign-edit.tsx | `packages/admin/dashboard/src/routes/campaigns/campaign-edit/campaign-edit.tsx` | ソース | エントリーポイント |
| edit-campaign-form.tsx | `packages/admin/dashboard/src/routes/campaigns/campaign-edit/components/edit-campaign-form/edit-campaign-form.tsx` | ソース | フォームコンポーネント |
| campaigns.tsx | `packages/admin/dashboard/src/hooks/api/campaigns.tsx` | ソース | APIフック |
| route.ts | `packages/medusa/src/api/admin/campaigns/[id]/route.ts` | ソース | APIエンドポイント |
