# 通知設計書 40-配送方法未選択警告

## 概要

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

### 本通知の処理概要

配送方法未選択警告は、チェックアウトプロセスにおいて、ユーザーが配送方法（shippingId）を選択しないまま「Proceed」ボタンをタップした際に、必要な選択を促す警告通知を表示する機能である。

**業務上の目的・背景**：チェックアウトプロセスにおいて、配送方法の選択は注文を確定するために必須の情報である。配送方法によって配送料金や到着日が異なるため、ユーザーが意図的に選択を行う必要がある。ユーザーが配送方法を選択せずに先に進もうとした場合、後のステップでエラーが発生する前に、早い段階で明確なフィードバックを提供することで、ユーザー体験を向上させ、注文の離脱率を低減する。

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

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

**通知内容の概要**：黄色（amber）の背景で警告アイコンとともに「配送方法を選択してください」というメッセージを表示する。

**期待されるアクション**：ユーザーは警告を確認し、利用可能な配送方法の中から希望する方法を選択してから再度「Proceed」ボタンをタップする。

## 通知種別

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

## 送信仕様

### 基本情報

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

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

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

## 通知テンプレート

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

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

### 警告時テンプレート

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

```
本文: "Please select shipping method"（StringConstants.pleaseSelectShipping）
```

### 添付ファイル

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

## テンプレート変数

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

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | Proceedボタンタップ | currentIndex == 2 && shippingId == '' | 配送方法選択ステップでの進行操作 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 配送方法選択済み | shippingId != '' の場合は次ステップへ進行 |
| ダウンロード商品のみ | isDownloadable == true の場合は配送不要（配送ステップスキップ） |
| currentIndex != 2 | 配送方法選択ステップ以外では表示されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Proceedボタンタップ] --> B{currentIndex判定}
    B -->|!= 2| C[他のステップの処理]
    B -->|== 2| D{shippingId判定}
    D -->|== ''| E[pleaseSelectShipping警告表示]
    D -->|!= ''| F[次ステップへ進行]
    E --> G[通知表示・処理中断]
    F --> H[currentIndex++]
```

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

### 参照テーブル一覧

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

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

データベース参照は行わない。配送方法の選択状態はチェックアウト画面のローカル状態（shippingId）から取得。

### 更新テーブル一覧

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

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（ユーザーによる配送方法選択後の再操作） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（24時間対応）

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

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

## 備考

- overlay_supportパッケージを使用したオーバーレイ通知を採用
- ShowMessage.warningNotificationメソッドで警告通知を表示
- shippingIdは文字列型で、初期値は空文字列（''）
- 配送方法はCheckoutShippingPageViewコンポーネントで選択され、callbackで親に伝達
- ダウンロード商品のみの場合（isDownloadable == true）は、配送方法選択ステップをスキップして支払方法選択に直接進む

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | checkout_screen.dart | `lib/screens/checkout/view/checkout_screen.dart` | shippingId変数（59行目） |

**読解のコツ**: shippingIdは文字列型で初期値は空文字列（''）。配送方法が選択されると、CheckoutShippingPageViewからのcallbackでIDがセットされる。

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

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

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

**主要処理フロー（snapshot.connectionState == waiting のブランチ）**:
1. **437行目**: `if (currentIndex == 2 && shippingId == '')` - 配送方法チェック
2. **438-440行目**: `ShowMessage.warningNotification(StringConstants.pleaseSelectShipping.localized(), context)` - 警告表示

**主要処理フロー（snapshot.connectionState != waiting のブランチ）**:
1. **550行目**: `if (currentIndex == 2 && shippingId == '')` - 同様のチェック
2. **551-553行目**: 警告表示

#### Step 3: 配送方法選択UIを理解する

配送方法が選択されてshippingIdがセットされる流れを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | checkout_screen.dart | `lib/screens/checkout/view/checkout_screen.dart` | CheckoutShippingPageViewのcallback（310-313行目） |

**主要処理フロー**:
- **310-313行目**: `callBack: (id,) { shippingId = id; }` - 配送方法選択時のコールバック

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-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 == 2 判定
    │                    │      │
    │                    │      ├─ shippingId == ''
    │                    │      │      └─ warningNotification(pleaseSelectShipping)
    │                    │      │
    │                    │      └─ shippingId != '' → currentIndex++
    │                    │
    │                    └─ 他のcurrentIndexの処理
    │
    ├─ CheckoutShippingPageView (配送方法選択UI)
    │      │
    │      └─ callBack: (id) { shippingId = id; }
    │
    └─ ShowMessage.warningNotification()
           │
           └─ showSimpleNotification()
```

### データフロー図

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

User Select Shipping ───▶  callBack(id)              ───▶  shippingId = id
                              │
                              ▼
User Tap Proceed     ───▶  currentIndex判定           ───▶  Validation
                              │
                              ▼
                         shippingIdチェック
                              │
                    ┌─────────┴─────────┐
                    │                   │
                    ▼                   ▼
            shippingId == ''      shippingId != ''
                    │                   │
                    ▼                   ▼
       warningNotification()    currentIndex++
                    │                   │
                    ▼                   ▼
              Overlay Display    次ステップ表示
              (警告メッセージ)   (支払方法選択)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| checkout_screen.dart | `lib/screens/checkout/view/checkout_screen.dart` | ソース | チェックアウト画面、配送方法バリデーション |
| show_message.dart | `lib/widgets/show_message.dart` | ソース | 通知表示ユーティリティ |
| checkout_shipping_view.dart | `lib/screens/checkout/checkout_shipping/view/checkout_shipping_view.dart` | ソース | 配送方法選択UI |
| string_constants.dart | `lib/utils/string_constants.dart` | 設定 | 文字列定数定義（pleaseSelectShipping） |
| checkout_header_view.dart | `lib/screens/checkout/view/widgets/checkout_header_view.dart` | ソース | チェックアウトステップ表示 |
