# 画面設計書 58-プロモーション一覧画面

## 概要

本ドキュメントは、Medusa Admin Dashboard における「プロモーション一覧画面」の設計仕様を定義するものである。

### 本画面の処理概要

**業務上の目的・背景**：EC運営において、各種プロモーション（割引クーポン、キャンペーン等）を効率的に管理する必要がある。本画面は、登録されているプロモーションの一覧を表示し、検索・フィルタリング・作成・編集・削除等の操作を行うためのインターフェースを提供する。

**画面へのアクセス方法**：サイドナビゲーションから「プロモーション」メニューを選択することでアクセスする。

**主要な操作・処理内容**：
1. プロモーション一覧を確認する
2. 検索・フィルタリングで目的のプロモーションを絞り込む
3. 新規作成ボタンから新しいプロモーションを作成する
4. 一覧から特定のプロモーションを選択して詳細画面に遷移する
5. アクションメニューから編集・削除を実行する

**画面遷移**：
- 遷移元：サイドナビゲーション
- 遷移先：プロモーション作成画面（`/promotions/create`）、プロモーション詳細画面（`/promotions/:id`）

**権限による表示制御**：認証済みの管理者ユーザーのみアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 36 | プロモーション管理 | 主機能 | プロモーションの一覧表示・削除 |

## 画面種別

一覧

## URL/ルーティング

```
/promotions
```

## 入出力項目（検索・フィルター）

| 項目名 | 項目ID | データ型 | 必須 | 入力形式 | バリデーション | 説明 |
|--------|--------|----------|------|----------|----------------|------|
| 検索 | q | string | - | テキスト | - | プロモーションコード・名称での検索 |
| 作成日ソート | orderBy | string | - | セレクト | created_at, updated_at | ソート項目 |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| プロモーションコード | テキスト | プロモーションのコード |
| タイプ | テキスト | standard / buyget |
| ステータス | StatusBadge | active / expired / scheduled / draft |
| 適用方法 | テキスト | Code / Automatic |
| キャンペーン | テキスト | 紐づくキャンペーン名 |
| アクションメニュー | ActionMenu | 編集・削除 |

## イベント仕様

### 1-新規作成ボタン押下

新規作成ボタンが押下された場合：
- プロモーション作成画面（`/promotions/create`）に遷移

### 2-行クリック

一覧の行がクリックされた場合：
- プロモーション詳細画面（`/promotions/:id`）に遷移

### 3-編集アクション

アクションメニューから「編集」を選択した場合：
- プロモーション編集画面（`/promotions/:id/edit`）に遷移

### 4-削除アクション

アクションメニューから「削除」を選択した場合：
1. 確認ダイアログを表示（プロモーションコードの入力確認）
2. 確認後、`useDeletePromotion`フックを使用してAPI呼び出し
3. APIエンドポイント：`DELETE /admin/promotions/:id`
4. 成功時：一覧を更新
5. 失敗時：エラーをスロー

### 5-検索入力

検索フィールドに入力があった場合：
- クエリパラメータを更新
- 一覧を再取得（debounce適用）

### 6-ソート変更

ソート項目を変更した場合：
- クエリパラメータを更新
- 一覧を再取得

### 7-ページネーション

ページを変更した場合：
- クエリパラメータを更新
- 一覧を再取得

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 削除アクション | promotion | DELETE | プロモーションの削除 |

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

#### promotion

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | id = 指定されたプロモーションID | - |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| areYouSure | 確認 | 「本当に削除しますか？」 | 削除確認時 |
| deleteWarning | 確認 | 「プロモーション{code}を削除します」 | 削除確認時 |
| error | エラー | 「プロモーション{code}を削除できませんでした」 | 削除失敗時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| API取得エラー | エラーをスロー |
| 削除失敗 | エラーをスロー |
| ネットワークエラー | エラーをスロー |

## 備考

- ページサイズは20件固定
- 拡張機能（widgets）によるカスタマイズポイントあり（before/after）
- keepPreviousDataオプションでページ遷移時のちらつきを防止
- loaderでサーバーサイドの初期データをプリフェッチ

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | PromotionsList | `packages/admin/dashboard/src/routes/promotions/promotion-list/promotions-list.tsx` | 画面コンポーネント |

**主要処理フロー**:
1. **6行目**: useExtensionでウィジェット取得
2. **8-16行目**: SingleColumnPageコンポーネントでレイアウト構築

#### Step 2: テーブルコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | PromotionListTable | `packages/admin/dashboard/src/routes/promotions/promotion-list/components/promotion-list-table/promotion-list-table.tsx` | 一覧テーブルの実装 |

**主要処理フロー**:
- **22行目**: PAGE_SIZE定数（20件）
- **26-28行目**: useLoaderDataで初期データ取得
- **30行目**: usePromotionTableQueryでクエリパラメータ管理
- **31-37行目**: usePromotionsでデータ取得
- **39行目**: usePromotionTableFiltersでフィルター構築
- **40行目**: useColumnsでカラム定義
- **42-49行目**: useDataTableでテーブル構築
- **86-117行目**: PromotionActionsコンポーネント（削除ロジック含む）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | usePromotions | `packages/admin/dashboard/src/hooks/api/promotions.tsx` | プロモーション一覧取得フック（85-104行目） |
| 3-2 | useDeletePromotion | `packages/admin/dashboard/src/hooks/api/promotions.tsx` | プロモーション削除フック（166-186行目） |

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

```
PromotionsList (promotions-list.tsx)
    │
    ├─ useExtension (ウィジェット取得)
    │
    └─ PromotionListTable (promotion-list-table.tsx)
           │
           ├─ useLoaderData (初期データ)
           │
           ├─ usePromotionTableQuery (クエリパラメータ)
           │
           ├─ usePromotions (promotions.tsx)
           │      └─ sdk.admin.promotion.list
           │             └─ GET /admin/promotions
           │
           ├─ usePromotionTableFilters (フィルター)
           │
           ├─ usePromotionTableColumns (カラム定義)
           │
           ├─ useDataTable (テーブル構築)
           │
           └─ PromotionActions
                  └─ useDeletePromotion
                         └─ sdk.admin.promotion.delete
                                └─ DELETE /admin/promotions/:id
```

### データフロー図

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

初期データ（loader）────▶ useLoaderData ────┐
                                            │
検索入力 ─────────────┐                     │
                      │                     ▼
フィルター ───────────┼───▶ usePromotionTableQuery ───▶ usePromotions ───▶ テーブル表示
                      │                                      │
ソート選択 ───────────┤                                      │
                      │                                      ▼
ページネーション ─────┘                              プロモーション一覧

行クリック ────────────────────────────────────────────────▶ 詳細画面遷移

削除アクション ───▶ 確認ダイアログ ───▶ useDeletePromotion ───▶ 一覧更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| promotions-list.tsx | `packages/admin/dashboard/src/routes/promotions/promotion-list/promotions-list.tsx` | ソース | 画面コンポーネント |
| promotion-list-table.tsx | `packages/admin/dashboard/src/routes/promotions/promotion-list/components/promotion-list-table/promotion-list-table.tsx` | ソース | テーブルコンポーネント |
| loader.ts | `packages/admin/dashboard/src/routes/promotions/promotion-list/loader.ts` | ソース | データローダー |
| promotions.tsx | `packages/admin/dashboard/src/hooks/api/promotions.tsx` | ソース | プロモーションAPIフック |
| use-promotion-table-query.tsx | `packages/admin/dashboard/src/hooks/table/query/use-promotion-table-query.tsx` | ソース | クエリフック |
| use-promotion-table-filters.tsx | `packages/admin/dashboard/src/hooks/table/filters/use-promotion-table-filters.tsx` | ソース | フィルターフック |
| use-promotion-table-columns.tsx | `packages/admin/dashboard/src/hooks/table/columns/use-promotion-table-columns.tsx` | ソース | カラム定義フック |
