# 画面設計書 183-返金理由作成画面

## 概要

本ドキュメントは、Medusa Admin Dashboard における返金理由作成画面の設計仕様を定義する。

### 本画面の処理概要

返金理由作成画面は、新規の返金理由を作成するためのモーダル形式の画面である。

**業務上の目的・背景**：
EC運営において、返金処理時に適用する理由をシステムに登録する必要がある。新たな返金理由（例：「配送遅延による返金」「品質不良による返金」など）を追加することで、返金処理の分類精度を向上させ、業務分析や改善活動に活用できる。本画面を通じて返金理由のマスタデータを拡充し、返金業務の標準化を推進する。

**画面へのアクセス方法**：
設定画面 > 返金理由一覧画面 > 「作成」ボタンをクリックすることでアクセスする。

**主要な操作・処理内容**：
1. 返金理由のラベル（label）を入力する - 顧客や管理者に表示される名称
2. 返金理由のコード（code）を入力する - システム内部で使用される一意の識別子（ラベルから自動生成可能）
3. 返金理由の説明（description）を任意で入力する - 返金理由の詳細説明
4. 保存ボタンを押下して新規作成を確定する

**画面遷移**：
- 遷移元：返金理由一覧画面
- 遷移先：保存完了後は返金理由一覧画面に戻る（モーダルが閉じる）

**権限による表示制御**：
管理者権限を持つユーザーのみがアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 35 | 返金理由管理 | 主機能 | 新規返金理由の作成 |

## 画面種別

登録（モーダル/フォーカスモーダル形式）

## URL/ルーティング

`/settings/refund-reasons/create`

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 入力/出力 | バリデーション | 説明 |
|--------|--------|-----|------|-----------|----------------|------|
| ラベル | label | string | 必須 | 入力 | 1文字以上 | 表示名称 |
| コード | code | string | 必須 | 入力 | 1文字以上 | システム識別子 |
| 説明 | description | string | 任意 | 入力 | なし | 詳細説明 |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| ヘッダー | タイトル | "Create Refund Reason" |
| サブタイトル | テキスト | 作成画面の説明 |
| ラベルフィールド | テキスト入力 | 返金理由の表示名を入力 |
| コードフィールド | テキスト入力 | 返金理由のコードを入力（自動生成対応） |
| 説明フィールド | テキストエリア | 詳細説明を入力（任意） |
| キャンセルボタン | ボタン | 作成をキャンセル |
| 保存ボタン | ボタン | 新規作成を実行 |

## イベント仕様

### 1-画面初期表示

空のフォームを表示する。フィールドの初期値はすべて空文字列。

### 2-ラベル入力時のコード自動生成

1. ラベルフィールドに文字を入力
2. コードフィールドがまだ編集されていない場合、ラベルからコードを自動生成
3. 自動生成ルール：
   - 小文字に変換
   - 英数字以外をアンダースコアに置換
   - 連続するアンダースコアを1つに
   - 先頭・末尾のアンダースコアを除去

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

1. フォームバリデーションを実行
2. バリデーション成功時、`useCreateRefundReason` フックを使用してAPIリクエストを送信
3. 成功時：成功トーストを表示し、モーダルを閉じて一覧画面に戻る
4. 失敗時：エラートーストを表示

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

入力内容を破棄し、モーダルを閉じて返金理由一覧画面に戻る。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | refund_reason | INSERT | 返金理由の新規作成 |

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

#### refund_reason

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | UUID自動生成 | プライマリキー |
| INSERT | label | フォーム入力値 | 表示名称 |
| INSERT | code | フォーム入力値 | 一意識別子 |
| INSERT | description | フォーム入力値（nullの場合あり） | 詳細説明 |
| INSERT | created_at | 現在日時 | 自動設定 |
| INSERT | updated_at | 現在日時 | 自動設定 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| refundReasons.create.successToast | 成功 | "Refund reason {label} created successfully" | 作成成功時 |
| - | エラー | APIエラーメッセージ | 作成失敗時 |

## 例外処理

| 例外ケース | 処理内容 |
|-----------|----------|
| API通信エラー | エラートーストを表示 |
| バリデーションエラー | フォームフィールド下部にエラーメッセージを表示 |
| コードの重複 | APIからのエラーメッセージをトーストで表示 |

## 備考

- 本画面はRouteFocusModalコンポーネントを使用したフォーカスモーダル形式で実装されている
- フォームはreact-hook-formとzodによるバリデーションを使用
- ラベル入力時にコードが自動生成されるが、コードを手動で編集した場合は自動生成を停止
- キーボードショートカット（Enter/Escape）に対応

---

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

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

### 推奨読解順序

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

まず、フォームで扱うデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | refund-reason-create-form.tsx | `packages/admin/dashboard/src/routes/refund-reasons/refund-reason-create/components/refund-reason-create-form/refund-reason-create-form.tsx` | 14-18行目: RefundReasonCreateSchemaでフォームのバリデーションスキーマを定義 |

**読解のコツ**: zodスキーマでlabel, code, descriptionの3フィールドを定義し、label/codeは必須、descriptionは任意となっている。

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

処理の起点となるファイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | refund-reason-create.tsx | `packages/admin/dashboard/src/routes/refund-reasons/refund-reason-create/refund-reason-create.tsx` | コンポーネント全体の構造 |

**主要処理フロー**:
1. **4-9行目**: RouteFocusModalでモーダルUIを構築
2. **7行目**: RefundReasonCreateFormコンポーネントを配置

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

フォームの実装詳細を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | refund-reason-create-form.tsx | `packages/admin/dashboard/src/routes/refund-reasons/refund-reason-create/components/refund-reason-create-form/refund-reason-create-form.tsx` | フォームの実装とAPI連携 |

**主要処理フロー**:
- **24-31行目**: useFormでフォーム初期化（空文字列をデフォルト値に設定）
- **33-39行目**: generateCodeFromLabel関数でラベルからコードを自動生成
- **41行目**: useCreateRefundReasonで作成ミューテーションを取得
- **43-57行目**: handleSubmitで送信処理、成功時はトースト表示とモーダルクローズ
- **79-112行目**: ラベルフィールドのonChangeでコード自動生成ロジックを実装
- **94-103行目**: コードフィールドが未編集または空の場合のみ自動生成

#### Step 4: API連携を理解する

APIフックの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | refund-reasons.tsx | `packages/admin/dashboard/src/hooks/api/refund-reasons.tsx` | 返金理由関連のAPIフック |

**主要処理フロー**:
- **58-77行目**: useCreateRefundReasonで作成処理、成功時に一覧キャッシュを無効化

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

```
RefundReasonCreate (refund-reason-create.tsx)
    │
    └─ RefundReasonCreateForm
           │
           ├─ useForm() - フォーム状態管理
           │
           ├─ generateCodeFromLabel() - ラベルからコード自動生成
           │
           ├─ useCreateRefundReason() - 作成ミューテーション
           │      └─ sdk.admin.refundReason.create()
           │
           └─ handleSubmit() - フォーム送信処理
```

### データフロー図

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

ラベル入力 ───▶ generateCodeFromLabel ───▶ コードフィールド自動入力
                 (文字列変換)

フォーム入力 ───▶ useCreateRefundReason ───▶ 返金理由一覧更新
                     (API作成)              トースト通知
                                           モーダルクローズ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| refund-reason-create.tsx | `packages/admin/dashboard/src/routes/refund-reasons/refund-reason-create/refund-reason-create.tsx` | ソース | 作成画面のメインコンポーネント |
| refund-reason-create-form.tsx | `packages/admin/dashboard/src/routes/refund-reasons/refund-reason-create/components/refund-reason-create-form/refund-reason-create-form.tsx` | ソース | 作成フォームコンポーネント |
| refund-reasons.tsx | `packages/admin/dashboard/src/hooks/api/refund-reasons.tsx` | ソース | 返金理由APIフック |
| RouteFocusModal | `packages/admin/dashboard/src/components/modals` | ソース | フォーカスモーダルコンポーネント |
| Form | `packages/admin/dashboard/src/components/common/form` | ソース | フォームコンポーネント |
