# 通知設計書 38-お問い合わせ送信成功/失敗通知

## 概要

本ドキュメントは、ECモバイルアプリケーションにおける「お問い合わせ送信成功/失敗通知」の設計仕様を定義する。ユーザーがお問い合わせフォームから問い合わせを送信した際の処理結果をアプリ内通知で表示する機能について記載する。

### 本通知の処理概要

お問い合わせ送信成功/失敗通知は、ユーザーがお問い合わせ画面から名前、メールアドレス、電話番号、メッセージを入力して送信した際に、その操作結果をリアルタイムでフィードバックする通知機能である。

**業務上の目的・背景**：ユーザーからの問い合わせは、カスタマーサポートにおいて重要なコミュニケーションチャネルである。ユーザーが送信した問い合わせが正常に受け付けられたか、または入力内容の問題等でエラーが発生したかを即座にフィードバックすることで、ユーザーは問い合わせが適切に処理されたことを確認できる。これにより、顧客満足度の向上と、問い合わせ対応の効率化に寄与する。

**通知の送信タイミング**：お問い合わせ画面において、ユーザーが「Submit」ボタンをタップし、APIリクエストが完了した時点で通知が表示される。BlocパターンによりContactUsStateの状態変化を検知してトリガーされる。

**通知の受信者**：問い合わせ操作を実行したユーザー本人のみが通知を受け取る。通知はアプリ内のオーバーレイ表示であり、他のユーザーには影響しない。

**通知内容の概要**：成功時は緑色の背景でチェックマークアイコンとともにサーバーから返されたメッセージを表示する。失敗時は赤色の背景でキャンセルアイコンとともにエラーメッセージを表示する。

**期待されるアクション**：成功通知の場合、ユーザーは問い合わせが受け付けられたことを確認し、カスタマーサポートからの回答を待つ。入力フォームは自動的にクリアされる。失敗通知の場合、ユーザーはエラー原因を確認し、入力内容を修正して再送信する。

## 通知種別

アプリ内通知（オーバーレイ通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ユーザー操作に対する即時レスポンス） |
| 優先度 | 中 |
| リトライ | 無（単発表示、自動消失） |

### 送信先決定ロジック

送信操作を実行したユーザー本人のアプリ画面にのみ表示される。ユーザーIDやセッション情報に基づく送信先決定は不要（ローカル表示のため）。

## 通知テンプレート

### アプリ内通知の場合

| 項目 | 内容 |
|-----|------|
| 表示位置 | 画面上部オーバーレイ |
| 表示時間 | 自動消失（約3秒） |
| スワイプ操作 | 上方向スワイプで即時消去可能 |

### 成功時テンプレート

| 項目 | 内容 |
|-----|------|
| タイトル | "Success"（ローカライズ対応） |
| 背景色 | 緑色（Colors.green.shade400） |
| アイコン | チェックマーク（Icons.check_circle_outline） |

```
本文: {サーバーレスポンスのmessageフィールド または "Updated"}
```

### 失敗時テンプレート

| 項目 | 内容 |
|-----|------|
| タイトル | "Failed"（ローカライズ対応） |
| 背景色 | 赤色（Colors.red） |
| アイコン | キャンセルマーク（Icons.cancel_outlined） |

```
本文: {エラーメッセージ}
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | 本通知には添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| message | 成功/エラーメッセージ | BaseModel.message / error | Yes |
| title | 通知タイトル | StringConstants（ローカライズ） | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | ContactUsEvent発行 | API応答受信後 | 送信ボタンタップ時 |
| Bloc状態変化 | ContactUsState | status == success または fail | BlocConsumerのlistenerで検知 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| フォームバリデーション失敗 | 必須項目未入力の場合はAPI呼び出しされない |
| 画面遷移中 | お問い合わせ画面から離脱している場合は表示されない |
| Bloc未初期化 | ContactUsScreenBlocが初期化されていない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[送信ボタンタップ] --> B{フォームバリデーション}
    B -->|OK| C[ContactUsEvent発行]
    B -->|NG| D[フィールドエラー表示]
    C --> E[ContactUsScreenBloc処理]
    E --> F[Repository.contactUsRepoScreen呼び出し]
    F --> G{API応答}
    G -->|success == true| H[ContactUsState.success発行]
    G -->|success == false/エラー| I[ContactUsState.fail発行]
    H --> J[BlocConsumer.listener検知]
    I --> J
    J --> K{状態判定}
    K -->|success| L[ShowMessage.showNotification 成功]
    K -->|fail| M[ShowMessage.showNotification 失敗]
    L --> N[入力フォームクリア]
    N --> O[オーバーレイ表示]
    M --> O
    O --> P[自動消失/スワイプ消去]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | 問い合わせは新規送信のみ |

### テーブル別参照項目詳細

データベース参照は行わない。

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| contact_us（サーバー側） | INSERT | 問い合わせ内容の登録 |

#### 送信ログテーブル

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| なし | - | - | アプリ内通知のためログ記録なし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| API通信エラー | ネットワーク接続不可 | "SomethingWrong"メッセージ表示 |
| サーバーエラー | バックエンドエラー | graphqlErrorsメッセージ表示 |
| バリデーションエラー | 必須項目未入力 | フィールドエラー表示（API呼び出し前） |
| メールアドレス形式エラー | 無効なメール形式 | バリデーションエラー表示 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（ユーザー操作による再試行） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（ユーザー操作起点） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（24時間対応）

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

- 問い合わせ送信はログイン不要（ゲストユーザーも利用可能）
- 入力データはHTTPS経由で送信
- 通知内容に機密情報は含まない

## 備考

- overlay_supportパッケージを使用したオーバーレイ通知を採用
- ShowMessage.showNotificationメソッドで汎用的な通知表示を使用
- 送信成功後、入力フォーム（name, email, phone, comment）は自動的にクリアされる
- SnackBarによる追加通知「Form submitted successfully!」も表示される
- EmailValidatorミックスインによるメールアドレス検証

---

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

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

### 推奨読解順序

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

通知に関連する状態クラスとイベントクラスを理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | contact_us_state.dart | `lib/screens/contact_us/bloc/contact_us_state.dart` | ContactUsState クラスの構造 |
| 1-2 | contact_us_event.dart | `lib/screens/contact_us/bloc/contact_us_event.dart` | ContactUsEvent の引数（name, email, phone, describe） |

**読解のコツ**: ContactUsStateはBaseModelを保持し、成功時にはsuccessMsgフィールドを通知表示に使用する。

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

処理の起点となる画面ファイルを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | contact_us_view.dart | `lib/screens/contact_us/contact_us_view.dart` | BlocConsumerのlistener部分（47-65行目） |

**主要処理フロー**:
1. **49行目**: `if (state is ContactUsState)` - 状態判定
2. **50行目**: `isLoading = true` - ローディング状態
3. **51-53行目**: 失敗時の`ShowMessage.showNotification`呼び出し
4. **54-63行目**: 成功時の`ShowMessage.showNotification`呼び出し + フォームクリア

#### Step 3: 送信処理を理解する

送信ボタンタップ時の処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | contact_us_view.dart | `lib/screens/contact_us/contact_us_view.dart` | _submitFormメソッド（230-244行目） |

**主要処理フロー**:
- **231行目**: フォームバリデーション
- **232行目**: フォーム状態保存
- **234-237行目**: コントローラーから値取得
- **239行目**: ContactUsEvent発行
- **240-242行目**: SnackBar表示

#### Step 4: Bloc処理を理解する

状態管理とAPI呼び出しのロジックを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | contact_us_bloc.dart | `lib/screens/contact_us/bloc/contact_us_bloc.dart` | ContactUsEventハンドリング（34-48行目） |

**主要処理フロー**:
- **34行目**: `if (event is ContactUsEvent)` - イベント判定
- **36行目**: `repository!.contactUsRepoScreen(...)` - API呼び出し
- **37-40行目**: 成功時の状態発行（success == true）
- **42行目**: 失敗時の状態発行（graphqlErrors）

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

```
contact_us_view.dart (UI Layer)
    │
    ├─ _submitForm()
    │      │
    │      ├─ フォームバリデーション
    │      │
    │      ├─ ContactUsEvent発行
    │      │
    │      └─ SnackBar表示
    │
    ├─ BlocConsumer<ContactUsScreenBloc, ContactUsBaseState>
    │      │
    │      └─ listener: (state is ContactUsState)
    │             │
    │             ├─ success → ShowMessage.showNotification (成功)
    │             │                  │
    │             │                  └─ フォームクリア
    │             │
    │             └─ fail → ShowMessage.showNotification (失敗)
    │
    └─ ContactUsScreenBloc (Business Logic Layer)
           │
           └─ ContactUsEvent handler
                  │
                  └─ ContactUsScreenRepository.contactUsRepoScreen()
                         │
                         └─ GraphQL API Call
```

### データフロー図

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

User Input:
- name               ───▶  ContactUsEvent            ───▶  UI Dispatch
- email
- phone
- describe
                              │
                              ▼
                    ContactUsScreenBloc
                              │
                              ▼
                    ContactUsScreenRepository.contactUsRepoScreen()
                              │
                              ▼
                         GraphQL API
                              │
                              ▼
                         BaseModel
                              │
                              ▼
                    ContactUsState (success/fail)
                              │
                              ▼
BlocConsumer       ───▶  listener検知              ───▶  ShowMessage
                              │
                              ▼
                    success: フォームクリア + 通知表示
                    fail: エラー通知表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| contact_us_view.dart | `lib/screens/contact_us/contact_us_view.dart` | ソース | お問い合わせ画面、通知表示トリガー |
| contact_us_bloc.dart | `lib/screens/contact_us/bloc/contact_us_bloc.dart` | ソース | 状態管理、API呼び出し |
| contact_us_event.dart | `lib/screens/contact_us/bloc/contact_us_event.dart` | ソース | イベント定義 |
| contact_us_state.dart | `lib/screens/contact_us/bloc/contact_us_state.dart` | ソース | 状態定義 |
| contact_us_repository.dart | `lib/screens/contact_us/bloc/contact_us_repository.dart` | ソース | API通信処理 |
| show_message.dart | `lib/widgets/show_message.dart` | ソース | 通知表示ユーティリティ |
| string_constants.dart | `lib/utils/string_constants.dart` | 設定 | 文字列定数定義 |
| common_widgets.dart | `lib/widgets/common_widgets.dart` | ソース | フォームウィジェット |
