# 機能設計書 9-ニュースレター登録

## 概要

本ドキュメントは、ECモバイルアプリケーションにおけるニュースレター登録機能の設計仕様を定義する。ユーザーがメールアドレスを入力してニュースレター（メールマガジン）の購読を申し込む。

### 本機能の処理概要

**業務上の目的・背景**：マーケティング施策として、新商品情報やセール情報、クーポン配信等をメールで配信するため、ユーザーのメールアドレスを収集する。購読者リストを構築し、継続的な顧客エンゲージメントを実現する。

**機能の利用シーン**：ホーム画面のフッターセクションに配置されたニュースレター登録フォームで使用される。ユーザーがメールアドレスを入力して「登録」ボタンをタップすると購読登録が完了する。

**主要な処理内容**：
1. メールアドレスの入力
2. 入力値のバリデーション
3. GraphQL APIを通じた購読登録リクエスト
4. 成功/失敗メッセージの表示

**関連システム・外部連携**：Bagisto（Laravel製ECプラットフォーム）のGraphQL APIと連携し、subscribe mutationを呼び出す。

**権限による制御**：本機能は認証不要で呼び出し可能（ゲストユーザーでも利用可能）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | ホーム画面 | 主画面 | ニュースレター登録フォームの表示 |

## 機能種別

データ登録 / バリデーション / API連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| email | String | Yes | 購読者のメールアドレス | 空でないこと、有効なメール形式であること |

### 入力データソース

- 画面入力：ホーム画面のニュースレター登録フォームから取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| success | bool | 登録成功フラグ |
| message | String | 処理結果メッセージ（成功時：登録完了、失敗時：エラー理由） |

### 出力先

- 画面通知：成功/失敗メッセージをSnackBar等で表示

## 処理フロー

### 処理シーケンス

```
1. ユーザーがメールアドレスを入力
   └─ TextEditingControllerで値を保持

2. 登録ボタン押下
   └─ バリデーション実行（メール形式チェック）

3. SubscribeNewsLetterEventをHomePageBlocへ送信
   └─ homePageBloc?.add(SubscribeNewsLetterEvent(email: email))

4. HomePageBlocがHomePageRepositoryを通じてAPI呼び出し
   └─ repository?.subscribeNewsletter(email)

5. ApiClientがGraphQL mutationを実行
   └─ mutation.subscribeNewsletter(email)

6. レスポンス処理
   └─ 成功: SubscribeNewsLetterState.success発行
   └─ 失敗: SubscribeNewsLetterState.fail発行

7. 結果メッセージ表示
   └─ 成功: ShowMessage.successNotification
   └─ 失敗: ShowMessage.errorNotification
```

### フローチャート

```mermaid
flowchart TD
    A[メールアドレス入力] --> B{バリデーション}
    B -->|失敗| C[エラーメッセージ表示]
    C --> A
    B -->|成功| D[SubscribeNewsLetterEvent]
    D --> E[subscribe mutation実行]
    E --> F{API結果}
    F -->|失敗| G[エラー通知表示]
    F -->|成功| H[成功通知表示]
    H --> I[入力フォームクリア]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | メール形式検証 | 入力されたメールアドレスは有効な形式である必要がある | メールアドレス入力時 |
| BR-002 | 重複登録チェック | 既に登録済みのメールアドレスの場合はエラー（またはサイレント成功） | API呼び出し時 |
| BR-003 | ゲスト利用可能 | ログインしていないユーザーでも登録可能 | 常時 |

### 計算ロジック

本機能に計算ロジックは存在しない。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ニュースレター登録 | subscribers | INSERT | 購読者レコード作成 |

※上記はバックエンド側（Bagisto）での操作。モバイルアプリ側ではデータベース操作なし。

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

モバイルアプリ側でのローカルストレージ操作なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バリデーションエラー | メールアドレスが空または不正形式 | 入力フォームにエラーメッセージ表示 |
| - | 重複登録エラー | 既に登録済みのメールアドレス | ShowMessage.errorNotificationでエラー表示 |
| - | ネットワークエラー | API通信失敗 | ShowMessage.errorNotificationでエラー表示 |

### リトライ仕様

本機能にリトライ処理は実装されていない。

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

モバイルアプリ側ではトランザクション管理は行わない。

## パフォーマンス要件

- API応答時間：2秒以内

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

- メールアドレスのみを収集（個人情報最小化）
- スパム対策としてレート制限が推奨される（バックエンド側）
- GDPR準拠のためオプトイン方式を採用

## 備考

- サインアップ時にもニュースレター購読オプションあり（別機能）
- 購読解除はメール内のリンクから行う（アプリ内機能なし）

---

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

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

### 推奨読解順序

#### Step 1: イベント・状態定義を理解する

Blocのイベントと状態を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | home_page_event.dart | `lib/screens/home_page/bloc/home_page_event.dart` | SubscribeNewsLetterEvent定義 |
| 1-2 | home_page_state.dart | `lib/screens/home_page/bloc/home_page_state.dart` | SubscribeNewsLetterState定義 |

#### Step 2: ビジネスロジックを理解する

Blocでのイベント処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | home_page_bloc.dart | `lib/screens/home_page/bloc/home_page_bloc.dart` | SubscribeNewsLetterEvent処理（182-195行目） |

**主要処理フロー**:
- **182行目**: SubscribeNewsLetterEventの判定
- **184-185行目**: repository?.subscribeNewsletter(event.email)呼び出し
- **186-189行目**: 成功/失敗に応じたState発行

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

API呼び出しの実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | home_page_repository.dart | `lib/screens/home_page/bloc/home_page_repository.dart` | subscribeNewsletter()（174-183行目） |

#### Step 4: API通信層を理解する

GraphQL mutation定義を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | mutation_query.dart | `lib/services/mutation_query.dart` | subscribeNewsletter()（2022-2030行目） |
| 4-2 | api_client.dart | `lib/services/api_client.dart` | subscribeNewsletter()メソッド |

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

```
HomePageView (ニュースレターフォーム)
    │
    └─ HomePageBloc
           │
           └─ SubscribeNewsLetterEvent
                  │
                  └─ HomePageRepository.subscribeNewsletter()
                         │
                         └─ ApiClient.subscribeNewsletter()
                                │
                                └─ GraphQlApiCalling
                                       │
                                       └─ MutationsData.subscribeNewsletter()
```

### データフロー図

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

email           ───▶ SubscribeNewsLetterEvent ───▶ HomePageBloc
                                                      │
                                                      ▼
                                              HomePageRepository
                                                      │
                                                      ▼
                                                  ApiClient ───▶ GraphQL API
                                                      │                │
                                                      │                ▼
                                                      │          購読者登録
                                                      │
                                                      ▼
                                                  BaseModel
                                                      │
                                                      ▼
                            SubscribeNewsLetterState.success ───▶ 通知表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| home_page_bloc.dart | `lib/screens/home_page/bloc/home_page_bloc.dart` | ソース | Bloc（イベント処理） |
| home_page_event.dart | `lib/screens/home_page/bloc/home_page_event.dart` | ソース | イベント定義 |
| home_page_state.dart | `lib/screens/home_page/bloc/home_page_state.dart` | ソース | 状態定義 |
| home_page_repository.dart | `lib/screens/home_page/bloc/home_page_repository.dart` | ソース | リポジトリ層 |
| graphql_base_model.dart | `lib/data_model/graphql_base_model.dart` | ソース | 基本レスポンスモデル |
| api_client.dart | `lib/services/api_client.dart` | ソース | API通信クライアント |
| mutation_query.dart | `lib/services/mutation_query.dart` | ソース | GraphQLクエリ定義 |
