# 機能設計書 48-アカウント情報表示

## 概要

本ドキュメントは、ECモバイルアプリケーションにおけるアカウント情報表示機能の設計仕様を定義する。ユーザープロフィール情報（名前、メールアドレス、電話番号、生年月日等）を表示する機能である。

### 本機能の処理概要

この機能は、ログイン済みユーザーが自身のアカウント情報を確認するための画面を提供する。プロフィール画像、氏名、性別、生年月日、電話番号、メールアドレス、ニュースレター購読状態などの情報を一覧表示する。

**業務上の目的・背景**：ECサイトにおいて、ユーザーが自身の登録情報を確認できることは重要である。配送先や連絡先が最新であることを確認し、必要に応じて更新することで、注文処理や顧客コミュニケーションの正確性を確保する。

**機能の利用シーン**：ユーザーがダッシュボードまたはナビゲーションメニューから「アカウント情報」にアクセスした際に利用される。住所変更前の確認、パスワード変更の検討、ニュースレター設定の確認などに使用される。

**主要な処理内容**：
1. GraphQL APIを通じてアカウント情報を取得
2. プロフィール画像の表示
3. ユーザー基本情報（名前、性別、生年月日、電話番号）の表示
4. メールアドレスとパスワード変更セクションの表示
5. ニュースレター購読状態の表示

**関連システム・外部連携**：バックエンドのBagisto GraphQL APIと連携し、ユーザー情報を取得する。

**権限による制御**：ログイン済みユーザーのみがアクセス可能。ユーザーは自身のアカウント情報のみを閲覧できる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 22 | アカウント情報画面 | 主画面 | ユーザープロフィール情報の表示 |
| 3 | ダッシュボード画面 | 参照元画面 | ダッシュボードからアカウント情報画面へ遷移 |

## 機能種別

データ取得 / 詳細表示

## 入力仕様

### 入力パラメータ

なし（ログインユーザーの情報を自動取得）

### 入力データソース

- ユーザーセッション：認証トークン（SharedPreferencesから取得）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | String | ユーザーID |
| email | String | メールアドレス |
| firstName | String | 名 |
| lastName | String | 姓 |
| imageUrl | String | プロフィール画像URL |
| dateOfBirth | String | 生年月日 |
| phone | String | 電話番号 |
| subscribedToNewsLetter | bool | ニュースレター購読状態 |

### 出力先

- 画面表示：AccountScreenウィジェットによるプロフィール情報表示
- 入力フィールド：編集用TextEditingControllerへのプリセット

## 処理フロー

### 処理シーケンス

```
1. 画面初期化（initState）
   └─ AccountInfoBlocを取得し、AccountInfoDetailsEventを発行
2. API呼び出し
   └─ AccountInfoRepositoryImpがApiClient経由でGraphQL APIを呼び出し
3. レスポンス処理
   └─ AccountInfoModelにデシリアライズ
4. 状態更新
   └─ AccountInfoDetailStateをemitしてUI更新
5. フォームプリセット
   └─ 取得したデータをTextEditingControllerに設定
6. プロフィール表示
   └─ ProfileDetailViewでユーザー情報を表示
```

### フローチャート

```mermaid
flowchart TD
    A[画面表示開始] --> B[AccountInfoBloc初期化]
    B --> C[AccountInfoDetailsEvent発行]
    C --> D[callAccountDetailsApi呼び出し]
    D --> E{レスポンス成功?}
    E -->|Yes| F[AccountInfoModel生成]
    E -->|No| G[エラー表示 / ローダー継続]
    F --> H[TextEditingControllerに値設定]
    H --> I[ProfileDetailView表示]
    I --> J[プロフィール画像表示]
    I --> K[基本情報フォーム表示]
    I --> L[パスワード変更セクション表示]
    I --> M[ニュースレター設定表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-48-01 | 認証必須 | ログイン済みユーザーのみアカウント情報を閲覧可能 | 常時 |
| BR-48-02 | 自己情報のみ | ユーザーは自身のアカウント情報のみ閲覧可能 | 常時 |
| BR-48-03 | 初回ロードフラグ | 初回ロード時のみControllerに値を設定 | isLoad == true |
| BR-48-04 | 性別選択肢 | Male / Female / Other の3つから選択 | 常時 |

### 計算ロジック

初回ロード判定：
```dart
if (isLoad) {
  isLoad = false;
  firstNameController.text = accountInfoDetails?.firstName ?? "";
  // ... 他のフィールドも同様
}
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| アカウント情報取得 | customers | SELECT | ログインユーザーの情報を取得 |

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

#### customers（GraphQL API経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, email, first_name, last_name, date_of_birth, phone等 | 認証トークンに紐づくユーザー | 単一レコード |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | API通信エラー | ネットワーク接続不可 | ローダー継続表示 |
| - | 認証エラー | セッション切れ | ログイン画面へリダイレクト |

### リトライ仕様

- 自動リトライなし
- 画面再表示で再取得可能

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

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

## パフォーマンス要件

- データロード：2秒以内

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

- 認証トークンを使用したAPI呼び出し
- パスワードフィールドは初期状態で空（表示しない）
- センシティブ情報は適切にマスキング

## 備考

- AccountScreenは表示と編集の両方の機能を持つ
- ProfileDetailViewは表示専用ウィジェットではなく、フォーム入力ウィジェット
- 性別選択はDropdownButtonFormFieldで実装
- プロフィール画像はProfileImageViewで管理

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | account_info_details.dart | `lib/data_model/account_models/account_info_details.dart` | AccountInfoModelの構造 |

**読解のコツ**: シンプルなモデルで、ユーザー基本情報を保持。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | account_screen.dart | `lib/screens/account/view/account_screen.dart` | StatefulWidgetの構造、initStateでのBloc初期化 |

**主要処理フロー**:
- **49-56行目**: initStateでAccountInfoBlocを取得し、AccountInfoDetailsEventを発行
- **97-150行目**: BlocConsumerでstateの変化を監視
- **154-205行目**: buildUIでstate別のUI構築
- **157-168行目**: 初回ロード時にControllerへ値設定

#### Step 3: BLoCパターンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | account_info_event.dart | `lib/screens/account/bloc/account_info_event.dart` | AccountInfoDetailsEventの定義 |
| 3-2 | account_info_state.dart | `lib/screens/account/bloc/account_info_state.dart` | AccountInfoDetailStateの定義 |
| 3-3 | account_info_bloc.dart | `lib/screens/account/bloc/account_info_bloc.dart` | イベントハンドリング |

**主要処理フロー**:
- **account_info_bloc.dart 23-29行目**: AccountInfoDetailsEvent処理、callAccountDetailsApi呼び出し

#### Step 4: リポジトリ層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | account_info_repository.dart | `lib/screens/account/bloc/account_info_repository.dart` | callAccountDetailsApiメソッド |

**主要処理フロー**:
- **35-43行目**: callAccountDetailsApiでApiClient.getCustomerData呼び出し

#### Step 5: UI実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | profile_detail.dart | `lib/screens/account/widget/profile_detail.dart` | フォーム入力UI、バリデーション |
| 5-2 | profile_image_view.dart | `lib/screens/account/widget/profile_image_view.dart` | プロフィール画像表示・変更 |
| 5-3 | change_email_pass_view.dart | `lib/screens/account/widget/change_email_pass_view.dart` | メール・パスワード変更セクション |

**主要処理フロー**:
- **profile_detail.dart 71-86行目**: 名前入力フィールド
- **profile_detail.dart 104-160行目**: 性別ドロップダウン
- **profile_detail.dart 162-167行目**: 生年月日選択

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

```
AccountScreen (Widget)
    │
    ├─ AccountInfoBloc
    │      │
    │      └─ AccountInfoRepositoryImp
    │             │
    │             └─ ApiClient.getCustomerData()
    │
    ├─ AccountInfoDetailState
    │      │
    │      └─ AccountInfoModel
    │
    └─ ProfileDetailView (Widget)
           │
           ├─ ProfileImageView
           ├─ CommonWidgets.getTextField (名前、電話番号)
           ├─ DropdownButtonFormField (性別)
           ├─ CommonDatePicker (生年月日)
           ├─ ChangeEmailAndPassword
           └─ NewsLetterCheckbox
```

### データフロー図

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

画面表示 ───▶ AccountInfoDetailsEvent ───▶ AccountInfoBloc
   │                                             │
   │                                             ▼
   │                                    AccountInfoRepository
   │                                             │
   │                                             ▼
   │                                      ApiClient (GraphQL)
   │                                             │
   │                                             ▼
   │                                    AccountInfoModel
   │                                             │
   │                                             ▼
   └────────────────────────────── AccountInfoDetailState ───▶ UI更新
                                                                │
                                                                ▼
                                                    TextEditingControllerに値設定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| account_screen.dart | `lib/screens/account/view/account_screen.dart` | ソース | メイン画面ウィジェット |
| account_info_bloc.dart | `lib/screens/account/bloc/account_info_bloc.dart` | ソース | 状態管理BLoC |
| account_info_event.dart | `lib/screens/account/bloc/account_info_event.dart` | ソース | イベント定義 |
| account_info_state.dart | `lib/screens/account/bloc/account_info_state.dart` | ソース | 状態定義 |
| account_info_repository.dart | `lib/screens/account/bloc/account_info_repository.dart` | ソース | リポジトリ層 |
| profile_detail.dart | `lib/screens/account/widget/profile_detail.dart` | ソース | プロフィールフォームUI |
| profile_image_view.dart | `lib/screens/account/widget/profile_image_view.dart` | ソース | プロフィール画像UI |
| change_email_pass_view.dart | `lib/screens/account/widget/change_email_pass_view.dart` | ソース | メール・パスワード変更UI |
| account_loader_view.dart | `lib/screens/account/widget/account_loader_view.dart` | ソース | ローディング表示 |
| account_info_details.dart | `lib/data_model/account_models/account_info_details.dart` | ソース | データモデル |
