# 画面設計書 5-サインアップ画面

## 概要

本ドキュメントは、Bagisto eコマースモバイルアプリのサインアップ画面に関する設計書です。新規ユーザー登録を行うための画面であり、名前、メールアドレス、パスワードなどの基本情報を入力して会員登録を行います。

### 本画面の処理概要

**業務上の目的・背景**：サインアップ画面は、新規ユーザーがアプリケーションに会員登録するための画面です。eコマースアプリでは、会員登録によりユーザーは注文履歴の管理、ウィッシュリスト、住所の保存などのパーソナライズされた機能を利用できるようになります。また、ニュースレター購読オプションにより、マーケティング活動との連携も実現します。

**画面へのアクセス方法**：
- サインイン画面の「CREATE AN ACCOUNT」ボタンをタップ
- ドロワーメニューの「サインアップ」をタップ

**主要な操作・処理内容**：
1. 名（First Name）の入力
2. 姓（Last Name）の入力
3. メールアドレスの入力とバリデーション
4. パスワードの入力（6文字以上）
5. パスワード確認の入力と一致チェック
6. ニュースレター購読のチェックボックス
7. 利用規約同意のチェックボックス（必須）
8. アカウント作成ボタン押下による登録処理

**画面遷移**：
- 遷移元：サインイン画面
- 遷移先：ホーム画面（登録成功後）、サインイン画面（戻る）

**権限による表示制御**：なし（未ログインユーザー向け画面）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | サインアップ | 主機能 | 新規ユーザー登録処理（メール・名前・パスワード入力） |

## 画面種別

認証画面（新規登録）

## URL/ルーティング

- ルート名: `signUp`
- パス: `/signup`

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | バリデーション | 説明 |
|--------|--------|----------|------|----------------|------|
| 名（First Name） | 入力 | String | Yes | 必須 | ユーザーの名 |
| 姓（Last Name） | 入力 | String | Yes | 必須 | ユーザーの姓 |
| メールアドレス | 入力 | String | Yes | 必須、メール形式 | ログイン用メールアドレス |
| パスワード | 入力 | String | Yes | 必須、6文字以上 | ログイン用パスワード |
| パスワード確認 | 入力 | String | Yes | 必須、パスワードと一致 | パスワードの確認入力 |
| ニュースレター | 入力 | Boolean | No | - | ニュースレター購読希望 |
| 利用規約同意 | 入力 | Boolean | Yes | 必須（同意必要） | 利用規約への同意 |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 画面タイトル | String | 「Create an Account」 |
| 名入力フィールド | TextField | 名の入力欄 |
| 姓入力フィールド | TextField | 姓の入力欄 |
| メールアドレス入力フィールド | TextField | メールアドレス入力欄 |
| パスワード入力フィールド | TextField | パスワード入力欄（マスク表示切り替え可能） |
| パスワード確認入力フィールド | TextField | パスワード確認入力欄（マスク表示切り替え可能） |
| ニュースレターチェックボックス | Checkbox | ニュースレター購読オプション |
| 利用規約チェックボックス | Checkbox | 利用規約同意チェック |
| パスワード警告メッセージ | Text | パスワード要件の説明 |
| アカウント作成ボタン | MaterialButton | 登録実行ボタン |
| ローディングダイアログ | Dialog | 処理中に表示されるダイアログ |

## イベント仕様

### 1-画面初期化イベント（initState）

**トリガー**: 画面がマウントされたタイミング

**処理フロー**:
1. `SignUpBloc`をcontext.readで取得
2. 各TextEditingControllerの初期化

### 2-アカウント作成ボタン押下イベント

**トリガー**: 「CREATE ACCOUNT」ボタンタップ

**処理フロー**:
1. 利用規約同意チェック確認
   - 未同意の場合：`showAgreementError`をtrueにしてエラー表示、処理中断
2. `_signUpFormKey.currentState!.validate()`でフォームバリデーション
3. バリデーション成功時：
   - ローディングダイアログ表示
   - `SignUpBloc`に`FetchSignUpEvent`を送信
4. API応答処理：
   - 成功時：
     - 成功メッセージを表示
     - SharedPreferencesに認証情報を保存
     - 1秒後にホーム画面へ遷移（pushNamedAndRemoveUntil）
   - 失敗時：
     - エラーメッセージを表示
     - 2秒後にダイアログを閉じる

### 3-パスワード表示切り替えイベント

**トリガー**: パスワードフィールドのvisibilityアイコンタップ

**処理フロー**:
1. `setState()`で`showPassword`または`showConfirmPassword`フラグを反転
2. 対応するパスワードフィールドの表示/非表示を切り替え

### 4-ニュースレターチェックボックス変更イベント

**トリガー**: ニュースレターチェックボックスの状態変更

**処理フロー**:
1. コールバックで`isNewsLetterSelected`を更新
2. 登録時にこの値がAPIに送信される

### 5-利用規約チェックボックス変更イベント

**トリガー**: 利用規約チェックボックスの状態変更

**処理フロー**:
1. コールバックで`agreement`を更新
2. チェック時にエラー表示をクリア（`showAgreementError = false`）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| アカウント作成 | users (サーバー側) | INSERT | 新規ユーザー登録 |
| ニュースレター購読 | subscribers (サーバー側) | INSERT | 購読者リストに追加（チェック時） |

### SharedPreferences更新項目

| 操作 | 項目 | 更新値 | 備考 |
|-----|------|--------|------|
| 登録成功 | customerLoggedIn | true | ログイン状態フラグ |
| 登録成功 | customerName | ユーザー名 | 表示用名前 |
| 登録成功 | customerEmail | メールアドレス | ユーザーメール |
| 登録成功 | customerToken | "tokenType token" | 認証トークン |
| 登録成功 | customerId | ユーザーID | 数値ID |

## メッセージ仕様

| メッセージID | メッセージ種別 | 表示条件 | メッセージ内容 |
|-------------|--------------|----------|--------------|
| MSG-001 | エラー | 名未入力 | 「Please fill First Name」 |
| MSG-002 | エラー | 姓未入力 | 「Please fill Last Name」 |
| MSG-003 | エラー | メール未入力 | 「Please fill Email」 |
| MSG-004 | エラー | メール形式不正 | 「Please enter valid email」 |
| MSG-005 | エラー | パスワード未入力 | 「Please fill Password」 |
| MSG-006 | エラー | パスワード6文字未満 | 「Please enter valid password」 |
| MSG-007 | エラー | パスワード確認未入力 | 「Please fill Confirm Password」 |
| MSG-008 | エラー | パスワード不一致 | 「Password mismatch」 |
| MSG-009 | エラー | 利用規約未同意 | 「Agreement field is required」 |
| MSG-010 | 成功 | 登録成功 | APIから返却されるメッセージ |
| MSG-011 | エラー | 登録失敗 | APIから返却されるエラーメッセージ |
| MSG-012 | 情報 | 処理中 | 「Please wait...」 |

## 例外処理

| 例外ケース | 処理内容 | ユーザーへの影響 |
|-----------|---------|----------------|
| 登録API失敗 | エラーメッセージを表示、2秒後にダイアログを閉じる | 登録できない |
| メールアドレス重複 | APIからのエラーメッセージを表示 | 別のメールアドレスで再試行が必要 |
| ネットワークエラー | エラーメッセージを表示 | 登録できない |

## 備考

- パスワードは6文字以上が必要
- 登録成功後は自動的にログイン状態となる
- ニュースレター購読はオプション
- 利用規約への同意は必須
- `NewsLetterCheckbox`ウィジェットは再利用可能なコンポーネント

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sign_in_model.dart | `lib/screens/sign_in/data_model/sign_in_model.dart` | 登録APIレスポンスの構造（サインインと共通） |

**読解のコツ**: SignInModelは登録とログインで共通。status, data, token, tokenTypeフィールドを確認。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sign_up.dart | `lib/screens/sign_up/view/sign_up.dart` | サインアップ画面のメインウィジェット |

**主要処理フロー**:
1. **47-51行目**: `initState()`でSignUpBlocを取得
2. **54-67行目**: `build()`でScaffoldを構築
3. **70-99行目**: `_signInBloc()`でBlocConsumerを構築
4. **122-305行目**: `_form()`で登録フォームUI構築
5. **308-357行目**: `_onPressCreateAccount()`で登録処理実行
6. **360-367行目**: `_updateSharedPreferences()`でSharedPreferences更新

#### Step 3: Blocレイヤーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | sign_up_bloc.dart | `lib/screens/sign_up/bloc/sign_up_bloc.dart` | 状態管理Bloc |
| 3-2 | sign_up_event.dart | `lib/screens/sign_up/bloc/sign_up_event.dart` | イベント定義 |

**主要処理フロー**:
- `FetchSignUpEvent`で登録API呼び出し
- 成功時にSignInModelを返却

#### Step 4: ウィジェットコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | news_letter_checkbox.dart | `lib/screens/sign_up/widgets/news_letter_checkbox.dart` | チェックボックスコンポーネント |

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

```
SignUpScreen (StatefulWidget)
    │
    ├─ initState()
    │      └─ SignUpBloc (context.read)
    │
    ├─ build()
    │      └─ Scaffold
    │             ├─ AppBar(title: "Create an Account")
    │             └─ _signInBloc() → BlocConsumer<SignUpBloc>
    │                    └─ buildUI() → _form()
    │                           ├─ TextField (firstName)
    │                           ├─ TextField (lastName)
    │                           ├─ TextField (email)
    │                           ├─ TextField (password)
    │                           ├─ TextField (confirmPassword)
    │                           ├─ NewsLetterCheckbox (newsletter)
    │                           ├─ NewsLetterCheckbox (agreement)
    │                           └─ MaterialButton ("CREATE ACCOUNT")
    │                                  └─ _onPressCreateAccount()
    │                                         ├─ agreement check
    │                                         ├─ validate()
    │                                         ├─ showDialog()
    │                                         └─ SignUpBloc.add(FetchSignUpEvent)
    │
    └─ SignUpBloc
           └─ FetchSignUpEvent
                  └─ repository.callSignUpApi()
                         └─ FetchSignUpState (success/fail)
                                ├─ 成功: _updateSharedPreferences() → home遷移
                                └─ 失敗: エラーメッセージ表示
```

### データフロー図

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

firstName ──────────────┐
lastName ───────────────┼──▶ FetchSignUpEvent ─────────▶ SignUpBloc
email ──────────────────┤           │
password ───────────────┤           ▼
confirmPassword ────────┤    repository.callSignUpApi()
newsLetter ─────────────┤           │
agreement ──────────────┘           ▼
                              SignInModel (APIレスポンス)
                                    │
                             ┌──────┴──────┐
                             ▼             ▼
                        status=true   status=false
                             │             │
                             ▼             ▼
                  _updateSharedPreferences()  エラー表示
                             │
                             ▼
                      ホーム画面へ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sign_up.dart | `lib/screens/sign_up/view/sign_up.dart` | ソース | サインアップ画面のメインウィジェット |
| sign_up_bloc.dart | `lib/screens/sign_up/bloc/sign_up_bloc.dart` | ソース | 状態管理Bloc |
| sign_up_event.dart | `lib/screens/sign_up/bloc/sign_up_event.dart` | ソース | イベント定義 |
| sign_up_state.dart | `lib/screens/sign_up/bloc/sign_up_state.dart` | ソース | 状態定義 |
| sign_up_repository.dart | `lib/screens/sign_up/bloc/sign_up_repository.dart` | ソース | API通信処理 |
| news_letter_checkbox.dart | `lib/screens/sign_up/widgets/news_letter_checkbox.dart` | ソース | チェックボックスウィジェット |
| sign_in_model.dart | `lib/screens/sign_in/data_model/sign_in_model.dart` | ソース | レスポンスモデル（共通） |
| index.dart | `lib/screens/sign_up/utils/index.dart` | ソース | エクスポート集約 |
| route_constants.dart | `lib/utils/route_constants.dart` | ソース | ルーティング定数 |
