# 画面設計書 117-国追加画面

## 概要

本ドキュメントは、Medusa Admin Dashboardにおけるリージョンへの国追加画面に関する設計書です。この画面により、既存のリージョンに対して新しい国を追加することができます。

### 本画面の処理概要

**業務上の目的・背景**：リージョンの販売対象地域を拡大する場合、新たな国をリージョンに追加する必要があります。本画面では、利用可能な国の一覧から選択し、リージョンに追加します。

**画面へのアクセス方法**：リージョン詳細画面（/settings/regions/:id）の国一覧セクションにあるアクションメニューから「国を追加」を選択、またはURL直接アクセス（/settings/regions/:id/countries/add）。

**主要な操作・処理内容**：
1. 利用可能な国一覧をテーブル形式で表示
2. 検索・ソート機能による絞り込み
3. チェックボックスによる複数国の選択
4. 既にリージョンに追加済みの国は選択不可として表示
5. 選択した国をリージョンに追加保存

**画面遷移**：
- 遷移元：リージョン詳細画面（/settings/regions/:id）
- 遷移先：保存成功時・キャンセル時ともにリージョン詳細画面に戻る

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 66 | 地域国設定 | 主機能 | リージョンに国を追加 |

## 画面種別

モーダル形式（RouteFocusModal）の選択・登録画面

## URL/ルーティング

`/settings/regions/:id/countries/add`

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 説明 |
|--------|--------|------|------|------|
| 国選択 | countries | string[] | 必須（1件以上） | 追加する国コード（ISO 3166-1 alpha-2）の配列 |

## 表示項目

### 国一覧テーブル

| 項目名 | 項目ID | 型 | 説明 |
|--------|--------|------|------|
| 選択チェックボックス | select | boolean | 国の選択状態 |
| 国名 | display_name | string | 国の表示名 |
| 国コード | iso_2 | string | ISO 3166-1 alpha-2コード |

## イベント仕様

### 1-国選択

**トリガー**：テーブル行のチェックボックスをクリック

**処理内容**：
1. 選択状態をローカルステート（rowSelection）に反映
2. useEffectでrowSelectionの変更を監視し、フォームのcountriesフィールドに同期
3. 既にリージョンに含まれている国は選択不可（disabled）として表示

### 2-検索

**トリガー**：検索フィールドへの入力

**処理内容**：
1. 入力値で国一覧をフィルタリング
2. ページネーションをリセット

### 3-ソート

**トリガー**：テーブルヘッダーのソートボタンをクリック

**処理内容**：
1. ソート対象：display_name、iso_2
2. ソート順を変更して一覧を再表示

### 4-保存

**トリガー**：「追加」ボタンをクリック

**処理内容**：
1. バリデーション（最低1件以上の国選択）
2. 既存の国コード配列と新規選択国コードをマージ
3. useUpdateRegionフックでリージョン更新APIを呼び出し
4. 成功時：トースト通知を表示し、モーダルを閉じる
5. 失敗時：エラートースト通知を表示

### 5-キャンセル

**トリガー**：「キャンセル」ボタンをクリック

**処理内容**：
1. モーダルを閉じてリージョン詳細画面に戻る

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | region | UPDATE | リージョンのcountriesフィールドを更新 |

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

#### region

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | countries | 既存国コード + 新規選択国コードの配列 | iso_2コードの配列 |
| UPDATE | updated_at | 現在日時 | 自動更新 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| regions.toast.countries | 成功 | 国設定が更新されました | 保存成功時 |
| - | エラー | {エラーメッセージ} | API呼び出し失敗時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| リージョン情報取得エラー | エラーをスローしてエラーバウンダリで処理 |
| 更新API失敗 | エラートーストを表示、フォームは維持 |

## 備考

- ページサイズは50件固定
- 静的な国データ（countries.ts）を使用
- 既にリージョンに含まれている国はチェックボックスがdisabledで表示
- 検索はクライアントサイドフィルタリング（useCountriesフック内）

---

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

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

### 推奨読解順序

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

国追加時のデータ構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | add-countries-form.tsx | `packages/admin/dashboard/src/routes/regions/region-add-countries/components/add-countries-form/add-countries-form.tsx` | AddCountriesSchemaの定義（31-33行目） |

**読解のコツ**: Zodスキーマでcountries配列が最低1件必須であることを確認します。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | region-add-countries.tsx | `packages/admin/dashboard/src/routes/regions/region-add-countries/region-add-countries.tsx` | コンポーネントのエントリーポイント |

**主要処理フロー**:
1. **7行目**: URLパラメータからリージョンIDを取得
2. **9-16行目**: useRegionでリージョン情報を取得
3. **22-26行目**: RouteFocusModalでAddCountriesFormをラップ

#### Step 3: フォームロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | add-countries-form.tsx | `packages/admin/dashboard/src/routes/regions/region-add-countries/components/add-countries-form/add-countries-form.tsx` | メインフォームロジック |

**主要処理フロー**:
- **31-33行目**: Zodバリデーションスキーマ
- **42-49行目**: useFormでフォーム初期化
- **53-60行目**: useEffectでrowSelectionとフォーム値を同期
- **62-78行目**: useCountriesで静的国データをフィルタ・ソート
- **82-100行目**: useDataTableでテーブル設定（既存国は選択不可）
- **102行目**: useUpdateRegionでリージョン更新フック取得
- **104-124行目**: handleSubmit - 既存と新規をマージして更新API呼び出し

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | regions.tsx | `packages/admin/dashboard/src/hooks/api/regions.tsx` | リージョンAPIフック |

**主要処理フロー**:
- **86-111行目**: useUpdateRegion - countriesフィールドを更新

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

```
RegionAddCountries (region-add-countries.tsx)
    │
    ├─ useParams()
    │      └─ リージョンID取得
    │
    ├─ useRegion()
    │      └─ sdk.admin.region.retrieve()
    │
    └─ AddCountriesForm
           │
           ├─ useForm() + useEffect()
           │      └─ フォーム状態とrowSelectionの同期
           │
           ├─ useCountries()
           │      └─ 静的国データのフィルタ・ソート
           │
           ├─ useDataTable()
           │      └─ テーブル状態管理（既存国は選択不可）
           │
           └─ useUpdateRegion()
                  └─ sdk.admin.region.update()
```

### データフロー図

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

静的国データ ──────▶ useCountries() ──────────▶ フィルタ済み国一覧
                           │
                           ▼
region.countries ──▶ enableRowSelection判定 ──▶ 既存国は選択不可
                           │
                           ▼
チェックボックス ───▶ rowSelection ────────────▶ useEffect同期
                           │
                           ▼
                     フォームcountries値
                           │
                           ▼
保存ボタン ────────▶ 既存 + 新規マージ ────────▶ useUpdateRegion()
                           │
                           ▼
                  [Region APIサーバー]
                           │
                           ▼
                  モーダルを閉じる
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| region-add-countries.tsx | `packages/admin/dashboard/src/routes/regions/region-add-countries/region-add-countries.tsx` | ソース | エントリーポイント |
| add-countries-form.tsx | `packages/admin/dashboard/src/routes/regions/region-add-countries/components/add-countries-form/add-countries-form.tsx` | ソース | メインフォームコンポーネント |
| regions.tsx | `packages/admin/dashboard/src/hooks/api/regions.tsx` | ソース | リージョンAPIフック |
| countries.ts | `packages/admin/dashboard/src/lib/data/countries.ts` | データ | 静的国データ |
| use-countries.ts | `packages/admin/dashboard/src/routes/regions/common/hooks/use-countries.ts` | ソース | 国フィルタ・ソートフック |
| use-country-table-columns.ts | `packages/admin/dashboard/src/routes/regions/common/hooks/use-country-table-columns.ts` | ソース | 国テーブルカラム定義 |
| use-country-table-query.ts | `packages/admin/dashboard/src/routes/regions/common/hooks/use-country-table-query.ts` | ソース | 国テーブルクエリフック |
| route-focus-modal.tsx | `packages/admin/dashboard/src/components/modals/route-focus-modal/` | ソース | モーダルコンポーネント |
