# 通知設計書 42-配送方法なし通知

## 概要

本ドキュメントは、チェックアウト画面において利用可能な配送方法が存在しない場合に表示されるエラー通知の設計について記述する。

### 本通知の処理概要

本通知は、チェックアウトプロセスにおいて住所情報を保存した後、サーバーから取得した配送方法リストが空である場合に表示されるエラー通知である。

**業務上の目的・背景**：ECアプリにおいて、物理商品の配送には配送方法の選択が必須である。しかし、配送先住所や商品の組み合わせによっては、利用可能な配送方法が存在しない場合がある（例：離島への配送不可、重量制限超過など）。本通知により、ユーザーに配送方法が利用できないことを明示し、別の住所の入力や商品の変更を促すことを目的とする。

**通知の送信タイミング**：チェックアウト画面のステップ2（配送方法選択画面）において、住所情報をサーバーに保存した後、CheckOutFetchShippingState の状態更新時に shippingMethods リストが空であり、かつダウンロード商品でない場合に即時表示される。

**通知の受信者**：チェックアウト操作を行っている現在のユーザー（アプリ操作者）。ログイン済みユーザーおよびゲストユーザーの両方が対象となる。

**通知内容の概要**：エラーメッセージとして「失敗」というタイトルと「利用可能な配送方法がありません」という趣旨のローカライズされたテキストが表示される。画面上部に赤色の背景色でオーバーレイ表示され、キャンセルアイコン付きでエラーを通知する。

**期待されるアクション**：ユーザーは通知を確認後、配送先住所を変更するか、カートの商品を見直すか、カスタマーサポートに連絡して対応を検討する。

## 通知種別

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

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（即時表示） |
| 優先度 | 高 |
| リトライ | 無し（即時1回表示） |

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

操作中のユーザーに対して即時表示。特定の送信先決定ロジックは不要。

## 通知テンプレート

### アプリ内通知

| 項目 | 内容 |
|-----|------|
| タイトル | Failed（StringConstants.failed のローカライズ値） |
| 背景色 | Colors.red（赤色） |
| アイコン | Icons.cancel_outlined（キャンセルアイコン） |
| 形式 | オーバーレイ通知 |

### 本文テンプレート

```
[タイトル]: Failed
[メッセージ]: 利用可能な配送方法がありません（StringConstants.noShippingMsg のローカライズ値）
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| failed | 失敗タイトル | StringConstants.failed | Yes |
| noShippingMsg | 配送方法なしメッセージ | StringConstants.noShippingMsg | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API応答 | CheckOutFetchShippingState 受信 | shippingMethods.isEmpty && isDownloadable == false | 配送方法リストが空で、ダウンロード商品でない場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| shippingMethods.isNotEmpty | 配送方法が存在する場合は通知を表示しない |
| isDownloadable == true | ダウンロード商品の場合は配送が不要なため通知を表示しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[住所情報をサーバーに送信] --> B[CheckOutFetchShippingState 受信]
    B --> C{isDownloadable == false?}
    C -->|No| D[配送不要のため処理終了]
    C -->|Yes| E{shippingMethods.isEmpty?}
    E -->|No| F[配送方法選択画面を表示]
    E -->|Yes| G[ShowMessage.showNotification呼び出し]
    G --> H[オーバーレイエラー通知表示]
    H --> I[ユーザーが対応を検討]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| shipping_methods | 配送方法マスタ | サーバー側で参照、APIレスポンスで返却 |

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

#### shipping_methods（サーバー側）

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | 配送方法ID | 配送先住所・商品に対して有効な配送方法 |
| title | 配送方法名 | 同上 |
| price | 配送料金 | 同上 |

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 配送方法なし | 配送先住所・商品の組み合わせで利用可能な配送方法がない | 本通知を表示し、ユーザーに対応を促す |
| ローカライズエラー | 言語ファイルに該当キーが存在しない | デフォルト言語（英語）のメッセージを表示 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（24時間）

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

- 本通知は個人情報を含まないため、特別なセキュリティ対策は不要
- 配送方法の詳細情報は通知に含まれない

## 備考

- 本通知は ShowMessage.showNotification メソッドを使用して実装されている
- 通知は自動的にスライドして消えるか、ユーザーが上方向にスワイプして消すことができる
- ダウンロード商品のみのカートの場合は配送が不要なため、本通知は発生しない

---

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

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

### 推奨読解順序

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

まず、配送方法データの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | checkout_save_address_model.dart | `lib/screens/checkout/data_model/checkout_save_address_model.dart` | SaveCheckoutAddresses クラスと shippingMethods フィールドを確認 |

**読解のコツ**: GraphQL API レスポンスのデータモデルがどのように定義されているかに注目する。

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

処理の起点となる BlocListener を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | checkout_shipping_view.dart | `lib/screens/checkout/checkout_shipping/view/checkout_shipping_view.dart` | BlocConsumer の listener（122-143行目）を確認 |

**主要処理フロー**:
1. **121-143行目**: BlocConsumer の listener で状態変化を監視
2. **123行目**: CheckOutFetchShippingState の判定
3. **129-131行目**: shippingMethods が空かつ isDownloadable == false の条件チェック
4. **130-131行目**: ShowMessage.showNotification の呼び出し

#### Step 3: 通知表示処理を理解する

ShowMessage クラスの showNotification メソッドの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show_message.dart | `lib/widgets/show_message.dart` | showNotification メソッド（79-94行目）の実装詳細を確認 |

**主要処理フロー**:
- **79行目**: showNotification メソッドの定義（title, message, color, icon パラメータ）
- **81-93行目**: showSimpleNotification の呼び出しとパラメータ設定
- **84行目**: 引数で渡された color（Colors.red）を背景色として設定

#### Step 4: 文字列定数を理解する

通知に使用される文字列定数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | string_constants.dart | `lib/utils/string_constants.dart` | noShippingMsg（340行目）と failed（133行目）の定義を確認 |

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

```
CheckoutShippingPageView
    │
    ├─ _shippingBloc
    │      └─ BlocConsumer.listener
    │             ├─ 条件判定: state is CheckOutFetchShippingState
    │             ├─ 条件判定: shippingMethods.isEmpty && isDownloadable == false
    │             └─ ShowMessage.showNotification
    │                    └─ showSimpleNotification (overlay_support)
    │
    └─ CheckOutShippingBloc
           └─ CheckOutFetchShippingEvent → CheckOutFetchShippingState
```

### データフロー図

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

住所情報送信 ───▶ API呼び出し ───▶ レスポンス受信
                                         │
                                         ▼
                              shippingMethods判定
                                         │
                                   ┌─────┴─────┐
                                   ▼           ▼
                              空でない      空である
                                   │           │
                                   ▼           ▼
                              配送方法表示   エラー通知表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| checkout_shipping_view.dart | `lib/screens/checkout/checkout_shipping/view/checkout_shipping_view.dart` | ソース | 配送方法選択画面のWidget、通知トリガーの発火元 |
| show_message.dart | `lib/widgets/show_message.dart` | ソース | 通知表示ユーティリティクラス |
| string_constants.dart | `lib/utils/string_constants.dart` | ソース | 文字列定数の定義 |
| checkout_save_address_model.dart | `lib/screens/checkout/data_model/checkout_save_address_model.dart` | ソース | 住所保存APIレスポンスのデータモデル |
| checkout_shipping_bloc.dart | `lib/screens/checkout/checkout_shipping/bloc/checkout_shipping_bloc.dart` | ソース | 配送方法取得のBLoC |
