# 機能設計書 57-国・州データ取得

## 概要

本ドキュメントは、住所登録用の国・州リスト取得機能の設計を記述する。

### 本機能の処理概要

本機能は、住所登録・編集画面で使用する国と州のマスターデータをバックエンドAPIから取得する機能を提供する。国リストは全世界の国を含み、各国には関連する州（都道府県、県、省など）のリストが紐づいている。

**業務上の目的・背景**：ECサイトにおける住所入力では、国と州の正確な選択が配送の正確性に直結する。マスターデータをバックエンドで一元管理し、クライアントに提供することで、データの整合性と更新の容易性を確保できる。また、国際的なサービス展開において、多様な国・地域に対応できる。

**機能の利用シーン**：住所追加画面を開いた時、住所編集画面を開いた時、チェックアウト時の住所入力時などに自動的に呼び出される。

**主要な処理内容**：
1. 住所入力画面の初期化時にイベント発行
2. バックエンドAPIへの国・州リスト取得リクエスト
3. 取得したデータを国ドロップダウンに設定
4. 国選択時に対応する州リストをドロップダウンに設定

**関連システム・外部連携**：GraphQL APIを介してバックエンドサーバーから国・州マスターデータを取得。

**権限による制御**：ログイン済みユーザーのみがアクセス可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | 住所追加・編集画面 | 主画面 | 住所登録用の国・州リスト取得 |

## 機能種別

マスターデータ取得（CRUD - Read）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | 本機能は入力パラメータを受け取らない | - |

### 入力データソース

- 住所入力画面の初期化イベント（AddressCountryEvent）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| data | List<Data> | 国リスト |
| data[].id | String | 国ID |
| data[].code | String | 国コード（ISO 3166-1 alpha-2） |
| data[].name | String | 国名 |
| data[].translations | List<Translations> | 国名の翻訳リスト |
| data[].states | List<States> | 州リスト |
| data[].states[].id | String | 州ID |
| data[].states[].countryCode | String | 国コード |
| data[].states[].code | String | 州コード |
| data[].states[].defaultName | String | 州名（デフォルト） |
| data[].states[].translations | List<Translations> | 州名の翻訳リスト |

### 出力先

- 画面表示（国ドロップダウン、州ドロップダウン）
- 状態管理（AddEditAddressBloc内でcountryDataとして保持）

## 処理フロー

### 処理シーケンス

```
1. 画面初期化
   └─ AddEditAddressBloc内でAddressCountryEventを発行
2. API呼び出し
   └─ AddEditAddressRepositoryImp.callCountriesData()でGraphQL APIを呼び出し
3. レスポンス処理
   └─ CountriesDataにデータをマッピング
4. 状態更新
   └─ AddressCountryState.successで成功状態を発行
5. UI更新
   └─ 国ドロップダウンにデータを設定
6. 国選択時処理
   └─ 選択された国の州リストをドロップダウンに設定
```

### フローチャート

```mermaid
flowchart TD
    A[画面初期化] --> B{countryListが空?}
    B -->|Yes| C[AddressCountryEvent発行]
    B -->|No| D[既存データを使用]
    C --> E[API呼び出し]
    E --> F{レスポンス}
    F -->|成功| G[CountriesData取得]
    F -->|失敗| H[エラー画面表示]
    G --> I[国ドロップダウン設定]
    I --> J[ユーザー国選択]
    J --> K{州リストあり?}
    K -->|Yes| L[州ドロップダウン表示]
    K -->|No| M[州テキスト入力表示]
    D --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-57-01 | キャッシュ利用 | countryListが既に取得済みの場合はAPIを呼び出さない | 画面再描画時 |
| BR-57-02 | 州リスト連動 | 国選択時に、その国の州リストを州ドロップダウンに設定 | 国選択時 |
| BR-57-03 | 州なし国対応 | 州リストがない国の場合は、州入力をテキストフィールドに切替 | 州リストが空の国選択時 |
| BR-57-04 | 編集時の初期選択 | 編集モード時は、既存住所の国・州を初期選択状態にする | isEdit=true |

### 計算ロジック

特になし

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 国・州取得 | countries, country_states | SELECT | 国・州マスターデータを取得 |

### テーブル別操作詳細

#### countries

| 操作 | 項目（カラム名） | 取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, code, name | - | 全国リスト |

#### country_states

| 操作 | 項目（カラム名） | 取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, country_code, code, default_name | - | 全州リスト（各国に紐づけ） |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | API通信エラー | ネットワーク障害 | EmptyDataViewを表示 |
| - | データ取得失敗 | バックエンド処理失敗 | エラーメッセージを表示 |

### リトライ仕様

画面を再度開くことで再取得が可能。

## トランザクション仕様

本機能はデータ参照のみのため、トランザクション管理は不要。

## パフォーマンス要件

- 国・州データ取得: 2秒以内
- データはBloc内でキャッシュし、同一セッション内での再取得を抑制

## セキュリティ考慮事項

- ログイン済みユーザーのみアクセス可能
- 認証トークン付きでAPIリクエスト送信
- 国・州データは参照のみで、改ざんリスクは低い

## 備考

- 国リストは多数の国を含むため、スクロール可能なドロップダウンで表示
- 州リストは国によって0件〜多数件まで変動
- 翻訳リストは多言語対応に使用可能だが、現状はdefaultNameを使用

---

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

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

### 推奨読解順序

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

国・州データのモデル構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | country_model.dart | `lib/screens/address_list/data_model/country_model.dart` | CountriesData, Data, States, Translationsクラスの構造 |

**読解のコツ**: CountriesDataはList<Data>を保持。Dataは国情報でstatesリストを持つ。Statesは州情報でcountryCodeで国と紐づく。翻訳リストは多言語対応用だが現状は未使用部分あり。

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

国・州データ取得のトリガーを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | add_edit_address_screen.dart | `lib/screens/add_edit_address/view/add_edit_address_screen.dart` | データ取得のトリガー |

**主要処理フロー**:
1. **312-316行目**: buildUIでcountryListが空の場合にAddressCountryEventを発行
2. **281-311行目**: AddressCountryStateの処理、countryDataとcountryListを設定
3. **439-451行目**: getCountryStringsメソッドで国名リストを取得

#### Step 3: Bloc層を理解する

データ取得処理のロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | add_edit_address_bloc.dart | `lib/screens/add_edit_address/bloc/add_edit_address_bloc.dart` | AddressCountryEventの処理 |
| 3-2 | add_edit_address_event.dart | `lib/screens/add_edit_address/bloc/add_edit_address_event.dart` | イベント定義 |
| 3-3 | add_edit_address_state.dart | `lib/screens/add_edit_address/bloc/add_edit_address_state.dart` | ステート定義 |

**主要処理フロー**:
- **88-96行目** (add_edit_address_bloc.dart): AddressCountryEventの処理
- **13行目** (add_edit_address_event.dart): AddressCountryEventの定義
- **54-67行目** (add_edit_address_state.dart): AddressCountryStateの定義

#### Step 4: Repository層を理解する

API呼び出しのロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | add_edit_address_repository.dart | `lib/screens/add_edit_address/bloc/add_edit_address_repository.dart` | API呼び出し実装 |

**主要処理フロー**:
- **123-133行目**: callCountriesDataメソッドでApiClient().getCountryStateList()を呼び出し

#### Step 5: UIへの反映を理解する

取得データのUIへの反映処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | add_edit_address_screen.dart | `lib/screens/add_edit_address/view/add_edit_address_screen.dart` | ドロップダウン設定 |

**主要処理フロー**:
- **351-359行目**: CommonDropDownFieldで国ドロップダウン表示
- **361-391行目**: 州リストの有無で表示形式を切替
- **453-474行目**: dropdownUpdateメソッドで国・州選択時の処理

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

```
AddNewAddress (add_edit_address_screen.dart)
    │
    └─ buildUI()
           │
           └─ countryList?.length == 0
                  │
                  └─ AddEditAddressBloc.add(AddressCountryEvent)
                         │
                         └─ AddEditAddressRepositoryImp.callCountriesData()
                                │
                                └─ ApiClient.getCountryStateList()
                                       │
                                       └─ GraphQL API
                                              │
                                              ▼
                                       CountriesData
                                              │
                                              ▼
                                AddressCountryState.success
                                              │
                                              ▼
                              countryData / countryList 設定
                                              │
                                              ▼
                              CommonDropDownField 国ドロップダウン
                                              │
                                              ▼ (国選択時)
                              dropdownUpdate()
                                              │
                                              ▼
                              selectedCountry.states → 州ドロップダウン
```

### データフロー図

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

AddressCountryEvent ───▶ AddEditAddressBloc ───▶ AddressCountryState
                                │
                                ▼
                     AddEditAddressRepositoryImp
                                │
                                ▼
                     ApiClient.getCountryStateList()
                                │
                                ▼
                          GraphQL API
                                │
                                ▼
                       CountriesData ───▶ countryData / countryList
                                │
                                ▼
                       国ドロップダウン表示
                                │
                                ▼ (国選択)
                       selectedCountry.states
                                │
                                ▼
                       州ドロップダウン/テキスト表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| add_edit_address_screen.dart | `lib/screens/add_edit_address/view/add_edit_address_screen.dart` | ソース | メイン画面 |
| add_edit_address_bloc.dart | `lib/screens/add_edit_address/bloc/add_edit_address_bloc.dart` | ソース | 状態管理 |
| add_edit_address_repository.dart | `lib/screens/add_edit_address/bloc/add_edit_address_repository.dart` | ソース | API呼び出し |
| add_edit_address_event.dart | `lib/screens/add_edit_address/bloc/add_edit_address_event.dart` | ソース | イベント定義 |
| add_edit_address_state.dart | `lib/screens/add_edit_address/bloc/add_edit_address_state.dart` | ソース | ステート定義 |
| country_model.dart | `lib/screens/address_list/data_model/country_model.dart` | ソース | 国・州データモデル |
