# 機能設計書 56-デフォルト住所設定

## 概要

本ドキュメントは、住所をデフォルトに設定する機能の設計を記述する。

### 本機能の処理概要

本機能は、ログイン済みユーザーが登録した複数の住所の中から、デフォルト（既定）として使用する住所を設定する機能を提供する。デフォルト住所はチェックアウト時に自動的に選択される住所として使用される。

**業務上の目的・背景**：ユーザーが複数の住所を登録している場合、チェックアウト時に毎回住所を選択する手間を省くため、よく使う住所をデフォルトとして設定できることが重要である。これにより、購入プロセスの効率化と、ユーザーエクスペリエンスの向上が実現できる。

**機能の利用シーン**：住所一覧画面で特定の住所カードの「Set Default」ボタンをタップした時、メインで使用する住所を変更したい時などにユーザーが利用する。

**主要な処理内容**：
1. 「Set Default」ボタンタップの検知
2. ローディング表示
3. バックエンドAPIへのデフォルト住所設定リクエスト
4. 設定成功後の住所一覧再取得
5. 設定結果の通知表示

**関連システム・外部連携**：GraphQL APIを介してバックエンドサーバーにデフォルト住所設定リクエストを送信。

**権限による制御**：ログイン済みユーザーのみがアクセス可能。自身の住所データのみ設定可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 23 | 住所一覧画面 | 主画面 | 住所をデフォルトに設定する処理 |

## 機能種別

データ更新（CRUD - Update）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| addressId | String | Yes | デフォルトに設定する住所ID | 存在する住所ID |

### 入力データソース

- 住所一覧画面の住所カード: AddressData.id

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| success | bool | 処理成功/失敗 |
| message | String | 処理結果メッセージ |
| address | AddressData | 更新された住所データ |

### 出力先

- バックエンドデータベース（GraphQL API経由で更新）
- 画面更新（住所一覧を再取得して表示）
- 通知表示（成功/失敗メッセージ）

## 処理フロー

### 処理シーケンス

```
1. Set Defaultボタンタップ
   └─ 住所カードの「Set Default」ボタンをユーザーがタップ
2. ローディング表示
   └─ ShowLoaderStateを発行してローダーを表示
3. API呼び出し
   └─ SetDefaultAddressEventを発行してAPIを呼び出し
4. レスポンス処理
   └─ 成功時は住所一覧を再取得、失敗時はエラーメッセージを表示
5. 住所一覧更新
   └─ FetchAddressEventを発行して最新の住所一覧を取得
6. 通知表示
   └─ 成功/失敗メッセージを表示
```

### フローチャート

```mermaid
flowchart TD
    A[Set Defaultボタンタップ] --> B{既にデフォルト?}
    B -->|Yes| C[処理終了]
    B -->|No| D[SetDefaultAddressEvent発行]
    D --> E[ShowLoaderState]
    E --> F[API呼び出し]
    F --> G{レスポンス}
    G -->|成功| H[FetchAddressEvent発行]
    H --> I[住所一覧再取得]
    I --> J[成功通知]
    G -->|失敗| K[エラー通知]
    J --> C
    K --> C
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-56-01 | デフォルト住所は1つ | デフォルト住所は常に1つのみ。新たに設定すると、以前のデフォルトは解除される | 常時 |
| BR-56-02 | 既デフォルト時は処理スキップ | 既にデフォルトの住所をタップしても処理は実行されない | isDefault=trueの住所タップ時 |
| BR-56-03 | 設定後に一覧再取得 | デフォルト設定成功後は住所一覧を再取得してデフォルト状態を反映 | 設定成功時 |
| BR-56-04 | ボタン表示切替 | デフォルト住所は「Default」、それ以外は「Set Default」を表示 | 常時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| デフォルト設定 | customer_addresses | UPDATE | 指定住所のdefault_addressをtrueに設定 |
| 旧デフォルト解除 | customer_addresses | UPDATE | 以前のデフォルト住所のdefault_addressをfalseに設定 |

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

#### customer_addresses

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | default_address | true | id = 指定住所ID |
| UPDATE | default_address | false | customer_id = ログインユーザーID AND id != 指定住所ID AND default_address = true | バックエンド側で自動処理 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | API通信エラー | ネットワーク障害 | エラー通知を表示 |
| - | 住所不存在エラー | 指定IDの住所が存在しない | エラー通知を表示 |
| - | サーバーエラー | バックエンド処理失敗 | graphqlErrorsメッセージを表示 |

### リトライ仕様

エラー発生時は、ユーザーが再度「Set Default」ボタンを押すことで再試行可能。

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

デフォルト住所の設定は、旧デフォルトの解除と新デフォルトの設定が同一トランザクションで実行される必要がある（バックエンド側で管理）。

## パフォーマンス要件

- デフォルト設定API呼び出し: 2秒以内
- 住所一覧再取得: 2秒以内

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

- ログイン済みユーザーのみアクセス可能
- 認証トークン付きでAPIリクエスト送信
- 自身の住所データのみ設定可能（バックエンドで権限チェック）

## 備考

- デフォルト住所はチェックアウト時に自動選択される
- ダッシュボード画面からはデフォルト設定ボタンが非表示（isFromDashboard=true時）

---

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

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

### 推奨読解順序

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

デフォルト住所設定で使用するイベントとレスポンスを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | address_event.dart | `lib/screens/address_list/bloc/address_event.dart` | SetDefaultAddressEventの構造 |
| 1-2 | address_state.dart | `lib/screens/address_list/bloc/address_state.dart` | SetDefaultAddressStateの構造 |
| 1-3 | default_address_model.dart | `lib/screens/address_list/data_model/default_address_model.dart` | SetDefaultAddressレスポンスモデル |

**読解のコツ**: SetDefaultAddressEventは設定対象のidをString型で保持。SetDefaultAddressはBaseModelを継承し、successフラグとmessageを保持する。

#### Step 2: UIコンポーネントを理解する

デフォルト設定ボタンの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | saved_address_list.dart | `lib/screens/address_list/view/widget/saved_address_list.dart` | デフォルト設定ボタンの実装 |

**主要処理フロー**:
1. **49-71行目**: デフォルト設定ボタンの表示とタップ処理
2. **60-64行目**: isDefaultに応じたボタンテキストとスタイルの切替
3. **66-69行目**: isDefault=false時のみSetDefaultAddressEventを発行

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

デフォルト設定処理のロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | address_bloc.dart | `lib/screens/address_list/bloc/address_bloc.dart` | SetDefaultAddressEventの処理 |

**主要処理フロー**:
- **40-55行目**: SetDefaultAddressEventの処理
- **41行目**: ShowLoaderStateでローディング表示
- **43-44行目**: setDefaultAddress API呼び出し
- **45-49行目**: 成功/失敗時のステート発行

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

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

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

**主要処理フロー**:
- **51-61行目**: setDefaultAddressメソッドでApiClient().setDefaultAddress()を呼び出し

#### Step 5: 画面更新を理解する

デフォルト設定後の一覧更新処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | address_screen.dart | `lib/screens/address_list/view/address_screen.dart` | 設定後の一覧更新 |

**主要処理フロー**:
- **71-78行目**: SetDefaultAddressStateのリスナーで住所一覧を再取得

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

```
SavedAddressList (saved_address_list.dart)
    │
    └─ GestureDetector.onTap()
           │
           └─ isDefault == false の場合
                  │
                  └─ AddressBloc.add(SetDefaultAddressEvent)
                         │
                         ├─ emit(ShowLoaderState)
                         │
                         └─ AddressRepositoryImp.setDefaultAddress()
                                │
                                └─ ApiClient.setDefaultAddress()
                                       │
                                       └─ GraphQL API
                                              │
                                              ▼
AddressScreen (address_screen.dart)
    │
    └─ BlocConsumer listener
           │
           └─ SetDefaultAddressState
                  │
                  ├─ success → AddressBloc.add(FetchAddressEvent)
                  │                   └─ 住所一覧再取得
                  │
                  └─ fail → ShowMessage.errorNotification()
```

### データフロー図

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

Set Defaultタップ ───▶ isDefault確認
                              │
                              ▼ (isDefault == false)
SetDefaultAddressEvent ───▶ AddressBloc ───▶ ShowLoaderState
(addressId)                   │
                              ▼
                   AddressRepositoryImp
                              │
                              ▼
                   ApiClient.setDefaultAddress()
                              │
                              ▼
                       GraphQL API
                              │
                              ▼
               SetDefaultAddress ───▶ SetDefaultAddressState
                              │
                              ▼
               FetchAddressEvent ───▶ 住所一覧再取得
                              │
                              ▼
                       成功/失敗通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| saved_address_list.dart | `lib/screens/address_list/view/widget/saved_address_list.dart` | ソース | デフォルト設定ボタン |
| address_screen.dart | `lib/screens/address_list/view/address_screen.dart` | ソース | 設定後の一覧更新 |
| address_bloc.dart | `lib/screens/address_list/bloc/address_bloc.dart` | ソース | 状態管理 |
| address_repository.dart | `lib/screens/address_list/bloc/address_repository.dart` | ソース | API呼び出し |
| address_event.dart | `lib/screens/address_list/bloc/address_event.dart` | ソース | イベント定義 |
| address_state.dart | `lib/screens/address_list/bloc/address_state.dart` | ソース | ステート定義 |
| default_address_model.dart | `lib/screens/address_list/data_model/default_address_model.dart` | ソース | レスポンスモデル |
