# 画面設計書 82-住所作成画面

## 概要

本ドキュメントは、Medusa Admin Dashboard における住所作成画面の設計仕様を定義したものである。顧客に新しい住所を追加するためのモーダル形式の画面について記述する。

### 本画面の処理概要

住所作成画面は、特定の顧客に対して新しい住所情報を登録するためのフルスクリーンモーダル形式の画面である。

**業務上の目的・背景**：ECサイト運営において、顧客は複数の配送先住所を持つことが一般的である。自宅、勤務先、ギフト送付先など、用途に応じた住所を管理できることで、顧客の注文プロセスが円滑になる。本画面は、管理者が顧客の代わりに住所を登録する機能を提供し、電話注文対応やカスタマーサポート業務を支援する。また、住所の正確な管理は配送エラーの削減と顧客満足度向上に直結する。

**画面へのアクセス方法**：顧客詳細画面の住所セクションから「住所を追加」アクションを選択するか、URLパス `/customers/:id/create-address` に直接アクセスすることで本画面を開く。画面はフルスクリーンモーダル形式で表示される。

**主要な操作・処理内容**：
1. 住所名（ラベル）の入力（必須）
2. 住所1行目の入力（必須）
3. 住所2行目の入力（任意）
4. 国の選択（必須）
5. 市区町村の入力（任意）
6. 郵便番号の入力（任意）
7. 都道府県/州の入力（任意）
8. 会社名の入力（任意）
9. 電話番号の入力（任意）
10. 保存ボタンで住所を登録

**画面遷移**：顧客詳細画面から遷移してくる。保存成功後またはキャンセル時に顧客詳細画面に戻る。

**権限による表示制御**：認証済みの管理者ユーザーのみがアクセス可能。特定の権限による表示制御は実装されていない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | 顧客住所管理 | 主機能 | 顧客住所の新規作成 |

## 画面種別

登録（モーダル/フルスクリーンモーダル形式）

## URL/ルーティング

`/customers/:id/create-address`

## 入出力項目

| 項目名 | 項目ID | データ型 | 必須 | 最大長 | 入力/出力 | バリデーション | 備考 |
|--------|--------|----------|------|--------|-----------|----------------|------|
| 住所名 | address_name | string | 必須 | - | 入力 | 最小1文字（zod.string().min(1)） | ラベルとして使用 |
| 住所1 | address_1 | string | 必須 | - | 入力 | 最小1文字（zod.string().min(1)） | 番地・建物名など |
| 住所2 | address_2 | string | 任意 | - | 入力 | なし | 補足住所 |
| 国コード | country_code | string | 必須 | 2 | 入力 | 2文字固定（zod.string().min(2).max(2)） | ISO 3166-1 alpha-2 |
| 市区町村 | city | string | 任意 | - | 入力 | なし | |
| 郵便番号 | postal_code | string | 任意 | - | 入力 | なし | |
| 都道府県/州 | province | string | 任意 | - | 入力 | なし | |
| 会社名 | company | string | 任意 | - | 入力 | なし | |
| 電話番号 | phone | string | 任意 | - | 入力 | なし | |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| ヘッダータイトル | モーダルヘッダー | 「住所を作成」（customers.addresses.create.header） |
| 説明テキスト | タイトル下部 | 「住所を作成するための情報を入力」（customers.addresses.create.hint） |
| フィールドラベル | 各入力フィールド | 各フィールドのラベル表示 |
| optionalラベル | 任意項目 | 任意項目には「任意」ラベルが表示 |
| キャンセルボタン | フッター | モーダルを閉じる |
| 保存ボタン | フッター | 住所を登録 |

## イベント仕様

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

ユーザーが保存ボタンを押下すると、以下の処理が実行される：
1. フォームのバリデーションを実行
2. バリデーション成功時、`useCreateCustomerAddress` フックを通じて API を呼び出し
3. 成功時：成功トーストを表示し、顧客詳細画面 `/customers/:id` に遷移
4. 失敗時：エラートーストを表示

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

モーダルを閉じて顧客詳細画面に戻る。

### 3-国選択

CountrySelect コンポーネントを使用した国選択。選択した国の ISO 3166-1 alpha-2 コードがフォームに設定される。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | customer_address | INSERT | 顧客住所の新規作成 |

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

#### customer_address

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | customer_id | URL パラメータの id | 関連顧客 |
| INSERT | address_name | フォーム入力値 | 住所ラベル |
| INSERT | address_1 | フォーム入力値 | 主住所 |
| INSERT | address_2 | フォーム入力値 | 補足住所 |
| INSERT | country_code | フォーム入力値 | 国コード |
| INSERT | city | フォーム入力値 | 市区町村 |
| INSERT | postal_code | フォーム入力値 | 郵便番号 |
| INSERT | province | フォーム入力値 | 都道府県/州 |
| INSERT | company | フォーム入力値 | 会社名 |
| INSERT | phone | フォーム入力値 | 電話番号 |

## メッセージ仕様

| 種別 | メッセージキー | 表示条件 | メッセージ内容（参考） |
|------|---------------|----------|----------------------|
| 成功 | customers.addresses.create.successToast | 保存成功時 | 住所を作成しました |
| エラー | (動的) | API エラー時 | エラーメッセージを表示 |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| API 作成エラー | エラートーストを表示 |
| バリデーションエラー | 各フィールドにエラーメッセージを表示 |
| 国コード不正 | バリデーションエラー表示 |

## 備考

- モーダルは RouteFocusModal コンポーネントを使用しており、フルスクリーン形式で表示
- フォームは KeyboundForm を使用しており、キーボードショートカットによる操作が可能
- 国選択には CountrySelect コンポーネントを使用し、全世界の国から選択可能
- フォームレイアウトは 2 カラムのグリッド構成
- 住所名は住所を識別するためのラベルとして使用（例：「自宅」「勤務先」）

---

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

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

### 推奨読解順序

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

住所データの型定義と作成スキーマを把握することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | create-customer-address-form.tsx | `packages/admin/dashboard/src/routes/customers/customer-create-address/components/create-customer-address-form/create-customer-address-form.tsx` | CreateCustomerAddressSchema（16-26行目）で定義されるフォームのバリデーションスキーマ |

**読解のコツ**: zod ライブラリによるスキーマ定義。`min(1)` で必須項目、`min(2).max(2)` で国コードの2文字制約を定義。

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

ルートコンポーネントの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | customer-create-address.tsx | `packages/admin/dashboard/src/routes/customers/customer-create-address/customer-create-address.tsx` | CustomerCreateAddress コンポーネント（4-10行目）。RouteFocusModal でフォームをラップ |

**主要処理フロー**:
1. **6行目**: RouteFocusModal でフルスクリーンモーダルを表示
2. **7行目**: CreateCustomerAddressForm コンポーネントを描画

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

フォームの実装詳細を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create-customer-address-form.tsx | `packages/admin/dashboard/src/routes/customers/customer-create-address/components/create-customer-address-form/create-customer-address-form.tsx` | フォームの実装全体（28-282行目） |

**主要処理フロー**:
- **30行目**: `useParams()` で URL から顧客 ID を取得
- **33-46行目**: useForm でフォーム初期化、空文字をデフォルト値として設定
- **48行目**: useCreateCustomerAddress フックで作成用ミューテーションを取得
- **50-74行目**: handleSubmit で保存処理を実装
- **94-116行目**: 住所名フィールドの実装
- **193-208行目**: CountrySelect による国選択の実装

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | customers.tsx | `packages/admin/dashboard/src/hooks/api/customers.tsx` | useCreateCustomerAddress フック（155-176行目） |

**主要処理フロー**:
- **164行目**: sdk.admin.customer.createAddress(id, payload) で API 呼び出し
- **165-170行目**: 成功時にキャッシュを無効化（顧客一覧、詳細、住所リスト）

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

```
CustomerCreateAddress (customer-create-address.tsx)
    │
    └─ RouteFocusModal
           │
           └─ CreateCustomerAddressForm (create-customer-address-form.tsx)
                  │
                  ├─ useParams() ─── URL から顧客 ID 取得
                  │
                  ├─ useForm() ─── フォーム状態管理
                  │
                  ├─ useCreateCustomerAddress(id)
                  │      └─ sdk.admin.customer.createAddress()
                  │             └─ queryClient.invalidateQueries()
                  │
                  ├─ Form.Field × 9 ─── 各入力フィールド
                  │
                  └─ CountrySelect ─── 国選択コンポーネント
```

### データフロー図

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

URL パラメータ (id) ───▶ useParams() ───▶ 顧客ID
                              │
                              ▼
フォーム入力値 ───────▶ useForm() ───▶ バリデーション済みデータ
                              │
国選択 ────────────▶ CountrySelect ───▶ country_code
                              │
                              ▼
                        useCreateCustomerAddress() ───▶ API 作成リクエスト
                              │
                              ▼
                        成功/エラー ───▶ トースト通知 + 画面遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| customer-create-address.tsx | `packages/admin/dashboard/src/routes/customers/customer-create-address/customer-create-address.tsx` | ソース | ルートコンポーネント |
| create-customer-address-form.tsx | `packages/admin/dashboard/src/routes/customers/customer-create-address/components/create-customer-address-form/create-customer-address-form.tsx` | ソース | フォームコンポーネント |
| index.ts | `packages/admin/dashboard/src/routes/customers/customer-create-address/index.ts` | ソース | エクスポート定義 |
| customers.tsx | `packages/admin/dashboard/src/hooks/api/customers.tsx` | ソース | 顧客 API フック |
| RouteFocusModal | `packages/admin/dashboard/src/components/modals/` | ソース | フルスクリーンモーダルコンポーネント |
| Form | `packages/admin/dashboard/src/components/common/form/` | ソース | フォームコンポーネント |
| CountrySelect | `packages/admin/dashboard/src/components/inputs/country-select/` | ソース | 国選択コンポーネント |
