# 通知設計書 39-住所未入力警告

## 概要

本ドキュメントは、ECモバイルアプリケーションにおける「住所未入力警告」の設計仕様を定義する。チェックアウト画面でユーザーが配送先または請求先住所を入力せずに次のステップに進もうとした際に、警告通知を表示する機能について記載する。

### 本通知の処理概要

住所未入力警告は、チェックアウトプロセスにおいて、ユーザーが配送先住所（shippingAddress）または請求先住所（billingAddress）を入力しないまま「Proceed」ボタンをタップした際に、必要な情報の入力を促す警告通知を表示する機能である。

**業務上の目的・背景**：チェックアウトプロセスにおいて、配送先と請求先の住所は注文を確定するために必須の情報である。ユーザーがこれらの情報を入力せずに先に進もうとした場合、後のステップでエラーが発生する前に、早い段階で明確なフィードバックを提供することで、ユーザー体験を向上させ、注文の離脱率を低減する。配送先と請求先が異なる場合も考慮し、それぞれの入力状態を個別にチェックする。

**通知の送信タイミング**：チェックアウト画面（currentIndex == 1）において、ユーザーが「Proceed」ボタンをタップした時点で住所の入力状態をチェックし、未入力の場合に即座に通知が表示される。

**通知の受信者**：チェックアウト操作を実行しているユーザー本人のみが通知を受け取る。通知はアプリ内のオーバーレイ表示であり、他のユーザーには影響しない。

**通知内容の概要**：黄色（amber）の背景で警告アイコンとともに、未入力の項目に応じたメッセージを表示する。両方未入力、配送先のみ未入力、請求先のみ未入力の3パターンのメッセージがある。

**期待されるアクション**：ユーザーは警告を確認し、不足している住所情報を入力してから再度「Proceed」ボタンをタップする。

## 通知種別

アプリ内通知（オーバーレイ通知）- 警告タイプ

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ユーザー操作に対する即時レスポンス） |
| 優先度 | 高（チェックアウトフロー継続に必須） |
| リトライ | 無（単発表示、自動消失） |

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

チェックアウト操作を実行しているユーザー本人のアプリ画面にのみ表示される。クライアント側のバリデーションによりAPI呼び出し前に判定。

## 通知テンプレート

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

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

### 警告時テンプレート（共通設定）

| 項目 | 内容 |
|-----|------|
| タイトル | "Warning"（ローカライズ対応） |
| 背景色 | 黄色/琥珀色（Colors.amber） |
| アイコン | 警告マーク（Icons.warning_amber） |

### メッセージパターン

| パターン | 条件 | メッセージ |
|---------|------|----------|
| 両方未入力 | billingAddress == null && shippingAddress == null | StringConstants.pleaseFillAddress |
| 請求先のみ未入力 | billingAddress == null | StringConstants.pleaseFillBillingAddress |
| 配送先のみ未入力 | shippingAddress == null | StringConstants.pleaseFillShippingAddress |

### 添付ファイル

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

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| message | 警告メッセージ | StringConstants（条件分岐） | Yes |
| title | 通知タイトル | StringConstants.warning | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | Proceedボタンタップ | currentIndex == 1 && (billingAddress == null または shippingAddress == null) | 住所入力ステップでの進行操作 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 住所入力済み | billingAddress != null && shippingAddress != null の場合は次ステップへ進行 |
| ダウンロード商品のみ | isDownloadable == true の場合は配送先不要（別ロジック） |
| currentIndex != 1 | 住所入力ステップ以外では表示されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Proceedボタンタップ] --> B{currentIndex判定}
    B -->|!= 1| C[他のステップの処理]
    B -->|== 1| D{billingAddress判定}
    D -->|null| E{shippingAddress判定}
    D -->|not null| F{shippingAddress判定}
    E -->|null| G[pleaseFillAddress警告表示]
    E -->|not null| H[pleaseFillBillingAddress警告表示]
    F -->|null| I[pleaseFillShippingAddress警告表示]
    F -->|not null| J[次ステップへ進行]
    G --> K[通知表示・処理中断]
    H --> K
    I --> K
    J --> L[currentIndex++]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | クライアント側の状態チェックのみ |

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

データベース参照は行わない。住所情報はチェックアウト画面のローカル状態（billingAddress, shippingAddress）から取得。

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | 警告表示のみのためDB更新なし |

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

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

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| なし | - | 本通知はバリデーションチェックの結果表示であり、エラー処理は不要 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（ユーザーによる住所入力後の再操作） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（24時間対応）

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

- 住所情報はクライアント側のメモリにのみ保持（この時点ではサーバーに未送信）
- 通知内容に個人情報は含まない
- チェックアウトプロセスの整合性を保護

## 備考

- overlay_supportパッケージを使用したオーバーレイ通知を採用
- ShowMessage.warningNotificationメソッドで警告通知を表示
- StreamBuilderの2つのブランチで同様のバリデーションロジックが実装されている
- ゲストユーザーの場合はGuestAddAddressFormコンポーネントが使用される
- ログインユーザーの場合はCheckoutAddressViewコンポーネントが使用される

---

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

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

### 推奨読解順序

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

通知に関連する状態変数を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | checkout_screen.dart | `lib/screens/checkout/view/checkout_screen.dart` | 住所関連の状態変数（36-58行目） |

**読解のコツ**: billingAddress、shippingAddressは文字列型で、nullの場合は未入力を意味する。

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

処理の起点となるボタンタップ処理を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | checkout_screen.dart | `lib/screens/checkout/view/checkout_screen.dart` | StreamBuilderのonPressedハンドラ（436-476行目、548-573行目） |

**主要処理フロー（snapshot.connectionState == waiting のブランチ）**:
1. **436行目**: `onPressed: () {` - ボタンタップ
2. **437行目**: `if (currentIndex == 2 && shippingId == '')` - 配送方法チェック
3. **442-443行目**: `if (currentIndex == 3 && paymentId == '')` - 支払方法チェック
4. **448-470行目**: 住所チェックの条件分岐
   - **452-455行目**: 両方null → pleaseFillAddress
   - **459-461行目**: billingAddressのみnull → pleaseFillBillingAddress
   - **464-467行目**: shippingAddressのみnull → pleaseFillShippingAddress

**主要処理フロー（snapshot.connectionState != waiting のブランチ）**:
1. **548-573行目**: 同様のバリデーションロジック（シンプル版）

#### Step 3: 通知表示ロジックを理解する

実際の通知表示処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show_message.dart | `lib/widgets/show_message.dart` | warningNotificationメソッド（58-77行目） |

**主要処理フロー**:
- **58行目**: `static warningNotification(String msg, BuildContext context, {String? title})` - メソッドシグネチャ
- **64行目**: 背景色（Colors.amber）
- **65-68行目**: アイコン（Icons.warning_amber）

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

```
checkout_screen.dart (UI Layer)
    │
    ├─ StreamBuilder
    │      │
    │      └─ MaterialButton (Proceed)
    │             │
    │             └─ onPressed
    │                    │
    │                    ├─ currentIndex == 1 判定
    │                    │      │
    │                    │      ├─ billingAddress == null && shippingAddress == null
    │                    │      │      └─ warningNotification(pleaseFillAddress)
    │                    │      │
    │                    │      ├─ billingAddress == null
    │                    │      │      └─ warningNotification(pleaseFillBillingAddress)
    │                    │      │
    │                    │      ├─ shippingAddress == null
    │                    │      │      └─ warningNotification(pleaseFillShippingAddress)
    │                    │      │
    │                    │      └─ 両方入力済み → currentIndex++
    │                    │
    │                    └─ 他のcurrentIndexの処理
    │
    └─ ShowMessage.warningNotification()
           │
           └─ showSimpleNotification()
```

### データフロー図

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

User Tap Proceed   ───▶  currentIndex判定           ───▶  Validation
                              │
                              ▼
                         住所チェック
                              │
                    ┌─────────┴─────────┐
                    │                   │
                    ▼                   ▼
              未入力あり           入力済み
                    │                   │
                    ▼                   ▼
       warningNotification()    currentIndex++
                    │                   │
                    ▼                   ▼
              Overlay Display    次ステップ表示
              (警告メッセージ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| checkout_screen.dart | `lib/screens/checkout/view/checkout_screen.dart` | ソース | チェックアウト画面、住所バリデーション |
| show_message.dart | `lib/widgets/show_message.dart` | ソース | 通知表示ユーティリティ |
| checkout_address_view.dart | `lib/screens/checkout/checkout_address/view/checkout_address_view.dart` | ソース | 住所入力UI（ログインユーザー） |
| guest_add_address_form.dart | `lib/screens/checkout/checkout_guest_address/view/guest_add_address_form.dart` | ソース | 住所入力UI（ゲストユーザー） |
| string_constants.dart | `lib/utils/string_constants.dart` | 設定 | 文字列定数定義 |
| checkout_header_view.dart | `lib/screens/checkout/view/widgets/checkout_header_view.dart` | ソース | チェックアウトステップ表示 |
