# 画面設計書 111-ロケール追加画面

## 概要

本ドキュメントは、Medusa Admin Dashboardにおけるストア設定のロケール追加画面に関する設計書です。この画面により、ストアでサポートする言語・地域設定（ロケール）を追加管理することができます。

### 本画面の処理概要

**業務上の目的・背景**：グローバルなEコマース運営において、多言語対応は必須の機能です。本画面は、ストアがサポートするロケール（言語・地域の組み合わせ）を管理するためのインターフェースを提供します。翻訳機能を活用するための基盤設定として、どの言語・地域に対応するかを管理者が選択できるようにします。

**画面へのアクセス方法**：設定トップ画面からストア詳細画面に遷移し、ロケール設定セクションの「追加」ボタンをクリックすることでアクセスできます。URL直接アクセスも可能です（/settings/store/locales）。なお、翻訳機能（translation）がフィーチャーフラグで有効化されている必要があります。

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

**画面遷移**：
- 遷移元：ストア詳細画面（/settings/store）
- 遷移先：保存成功時はストア詳細画面に戻る、キャンセル時も同様

**権限による表示制御**：管理者権限を持つユーザーのみがアクセス可能です。翻訳機能のフィーチャーフラグが無効の場合は、自動的に前の画面に戻されます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 69 | ストア設定管理 | 主機能 | ストアにロケールを追加 |
| 68 | ストアCRUD | API連携 | ストア情報の更新処理 |

## 画面種別

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

## URL/ルーティング

`/settings/store/locales`

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 説明 |
|--------|--------|------|------|------|
| ロケール選択 | locales | string[] | 必須（1件以上） | 追加するロケールコードの配列 |

## 表示項目

### ロケール一覧テーブル

| 項目名 | 項目ID | 型 | 説明 |
|--------|--------|------|------|
| 選択チェックボックス | select | boolean | ロケールの選択状態 |
| ロケール名 | name | string | ロケールの表示名（例：日本語） |
| ロケールコード | code | string | ロケールコード（例：ja） |

## イベント仕様

### 1-ロケール選択

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

**処理内容**：
1. 選択状態をローカルステート（rowSelection）に反映
2. フォームの`locales`フィールドに選択されたロケールコードを設定
3. 既存のストアロケールは選択不可（disabled）として表示

### 2-検索

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

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

### 3-保存

**トリガー**：「保存」ボタンをクリック

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

### 4-キャンセル

**トリガー**：「キャンセル」ボタンまたはモーダル外クリック

**処理内容**：
1. フォーム状態をリセット
2. モーダルを閉じてストア詳細画面に戻る

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | store | UPDATE | ストアのsupported_localesフィールドを更新 |

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

#### store

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | supported_locales | 既存ロケール + 新規選択ロケールの配列 | locale_codeをキーとしたオブジェクト配列 |
| UPDATE | updated_at | 現在日時 | 自動更新 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| store.toast.localesUpdated | 成功 | ロケールが更新されました | 保存成功時 |
| - | エラー | {エラーメッセージ} | API呼び出し失敗時 |
| store.localeAlreadyAdded | 情報 | このロケールは既に追加されています | 既存ロケール行のツールチップ |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ストア情報取得エラー | エラーをスローしてエラーバウンダリで処理 |
| ロケール一覧取得エラー | エラーをスローしてエラーバウンダリで処理 |
| 翻訳機能が無効 | navigate(-1)で前の画面に戻る |
| 更新API失敗 | エラートーストを表示、フォームは維持 |

## 備考

- 本画面は翻訳機能（translation）のフィーチャーフラグが有効な場合のみ利用可能
- ページサイズは50件固定
- 検索はサーバーサイドフィルタリング
- 既存のロケールは選択不可として表示されるが、一覧には含まれる

---

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

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

### 推奨読解順序

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

まず、ロケールとストアのデータ構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types | `@medusajs/types` | HttpTypes.AdminLocale、HttpTypes.AdminStoreの型定義 |

**読解のコツ**: MedusaのHTTP APIレスポンス型はHttpTypes名前空間に定義されています。AdminLocaleはcode、name等のフィールドを持ちます。

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

処理の起点となるファイル・関数を特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | store-add-locales.tsx | `packages/admin/dashboard/src/routes/store/store-add-locales/store-add-locales.tsx` | コンポーネントのエントリーポイント、フィーチャーフラグチェック |

**主要処理フロー**:
1. **7-14行目**: フィーチャーフラグチェック、無効なら前画面に戻る
2. **16行目**: useStoreフックでストア情報を取得
3. **24-28行目**: RouteFocusModalでフォームコンポーネントをラップ

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

フォームの状態管理とサブミット処理を理解します。

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

**主要処理フロー**:
- **27-29行目**: Zodスキーマ定義（locales配列、最低1件必須）
- **53-58行目**: useFormでフォーム初期化
- **60-74行目**: 行選択状態管理とフォーム値の同期
- **76-77行目**: 既存ロケールの取得（選択不可用）
- **96行目**: useUpdateStoreフックの取得
- **98-119行目**: handleSubmit - 既存と新規をマージして更新API呼び出し

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

データ取得・更新のAPIフックを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | store.tsx | `packages/admin/dashboard/src/hooks/api/store.tsx` | ストア取得・更新フック |

**主要処理フロー**:
- **36-58行目**: useStore - ストア情報取得
- **60-83行目**: useUpdateStore - ストア更新、成功時にキャッシュ無効化

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

```
StoreAddLocales (store-add-locales.tsx)
    │
    ├─ useFeatureFlag("translation")
    │      └─ フィーチャーフラグプロバイダー
    │
    ├─ useStore()
    │      └─ sdk.admin.store.list()
    │
    └─ AddLocalesForm
           │
           ├─ useLocales()
           │      └─ ロケール一覧API
           │
           ├─ useDataTable()
           │      └─ テーブル状態管理
           │
           └─ useUpdateStore()
                  └─ sdk.admin.store.update()
```

### データフロー図

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

ロケール選択 ───────▶ rowSelection状態管理 ───────▶ フォーム値更新
                           │
                           ▼
              既存ロケール + 新規選択マージ
                           │
                           ▼
                 useUpdateStore API呼び出し
                           │
                           ▼
                  [Store APIサーバー]
                           │
                           ▼
              キャッシュ無効化 & 画面更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| store-add-locales.tsx | `packages/admin/dashboard/src/routes/store/store-add-locales/store-add-locales.tsx` | ソース | エントリーポイント |
| add-locales-form.tsx | `packages/admin/dashboard/src/routes/store/store-add-locales/components/add-locales-form/add-locales-form.tsx` | ソース | フォームコンポーネント |
| store.tsx | `packages/admin/dashboard/src/hooks/api/store.tsx` | ソース | ストアAPIフック |
| use-locales-table-query.ts | `packages/admin/dashboard/src/routes/store/common/hooks/use-locales-table-query.ts` | ソース | ロケールテーブルクエリフック |
| use-locales-table-columns.ts | `packages/admin/dashboard/src/routes/store/common/hooks/use-locales-table-columns.ts` | ソース | ロケールテーブルカラム定義 |
| route-focus-modal.tsx | `packages/admin/dashboard/src/components/modals/route-focus-modal/` | ソース | モーダルコンポーネント |
| data-table.tsx | `packages/admin/dashboard/src/components/table/data-table/` | ソース | データテーブルコンポーネント |
