# 通知設計書 47-サブカテゴリ商品操作通知

## 概要

本ドキュメントは、サブカテゴリ画面（ドロワーメニューから遷移するカテゴリ詳細画面）において商品のカート追加、ウィッシュリスト追加/削除、比較リスト追加の操作結果として表示される通知の設計について記述する。

### 本通知の処理概要

本通知は、サブカテゴリ画面（DrawerSubCategoryView）において商品に対して各種操作（カート追加、ウィッシュリスト追加/削除、比較リスト追加）を行った際に、その処理結果を通知するものである。

**業務上の目的・背景**：ECアプリにおいて、ドロワーメニューから遷移するサブカテゴリ画面では、親カテゴリの子カテゴリ一覧と、そのカテゴリに属する商品が表示される。ユーザーは商品カードから直接商品をカートやウィッシュリストに追加することができる。これらの操作に対して即座にフィードバックを提供することで、ユーザーは操作が成功したか失敗したかを認識でき、スムーズな購買体験を実現できる。

**通知の送信タイミング**：サブカテゴリ画面において以下の操作が完了した際に即時表示される。
- カートへの商品追加（AddToCartState）
- ウィッシュリストへの商品追加（AddWishlistState）
- ウィッシュリストからの商品削除（RemoveWishlistState）
- 比較リストへの商品追加（AddToCompareState）

**通知の受信者**：サブカテゴリ画面を操作している現在のユーザー（アプリ操作者）。ログイン済みユーザーおよびゲストユーザーの両方が対象（ただし一部操作はログイン必須）。

**通知内容の概要**：成功時は緑色の背景でサーバーから返却されたメッセージを表示。失敗時は赤色の背景でエラーメッセージを表示する。

**期待されるアクション**：成功時はユーザーは操作が完了したことを確認し、買い物を継続する。失敗時は表示されたエラーに応じて対処（ログイン、再試行等）する。

## 通知種別

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

## 送信仕様

### 基本情報

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

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

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

## 通知テンプレート

### 成功通知

| 項目 | 内容 |
|-----|------|
| タイトル | Success（StringConstants.success のローカライズ値） |
| 背景色 | Colors.green.shade400（緑色） |
| アイコン | Icons.check_circle_outline（チェックマークアイコン） |
| 形式 | オーバーレイ通知 |

### 失敗通知

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

### 本文テンプレート

**カート追加成功時:**
```
[タイトル]: Success
[メッセージ]: {サーバーから返却されたメッセージ}（state.graphQlBaseModel.message）
```

**ウィッシュリスト追加成功時:**
```
[タイトル]: Success
[メッセージ]: {サーバーから返却されたメッセージ}（state.response.message）
```

**比較リスト追加成功時:**
```
[タイトル]: Success
[メッセージ]: {サーバーから返却されたメッセージ}（state.successMsg）
```

**失敗時:**
```
[タイトル]: Failed
[メッセージ]: {サーバーから返却されたエラーメッセージ}（state.graphQlBaseModel.graphqlErrors または state.message または state.successMsg）
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| message | 成功メッセージ | state.graphQlBaseModel.message / state.response.message | No（成功時） |
| successMsg | 成功/エラーメッセージ | state.successMsg | No |
| graphqlErrors | GraphQLエラーメッセージ | state.graphQlBaseModel.graphqlErrors | No（失敗時） |
| success | 成功タイトル | StringConstants.success | Yes |
| failed | 失敗タイトル | StringConstants.failed | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API応答 | AddToCartState | status == Status.success | カート追加成功時に成功通知 |
| API応答 | AddToCartState | status == Status.fail | カート追加失敗時にエラー通知 |
| API応答 | AddWishlistState | status == Status.success | ウィッシュリスト追加成功時に成功通知 |
| API応答 | AddWishlistState | status == Status.fail | ウィッシュリスト追加失敗時にエラー通知 |
| API応答 | RemoveWishlistState | status == Status.success | ウィッシュリスト削除成功時に成功通知 |
| API応答 | RemoveWishlistState | status == Status.fail | ウィッシュリスト削除失敗時にエラー通知 |
| API応答 | AddToCompareState | status == Status.success | 比較リスト追加成功時に成功通知 |
| API応答 | AddToCompareState | status == Status.fail | 比較リスト追加失敗時にエラー通知 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ネットワーク未接続 | checkInternetConnection が false の場合は API を呼び出さず、インターネットエラー通知を表示 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[商品操作ボタンタップ] --> B{インターネット接続確認}
    B -->|未接続| C[インターネットエラー通知]
    B -->|接続済| D{ログイン確認}
    D -->|未ログイン| E[ログイン要求警告通知]
    D -->|ログイン済| F[API呼び出し]
    F --> G[状態更新受信]
    G --> H{status == success?}
    H -->|Yes| I[ShowMessage.successNotification]
    H -->|No| J[ShowMessage.errorNotification]
    I --> K[カート数更新（カート追加時）]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| products | 商品情報 | カテゴリ内商品一覧表示 |
| categories | カテゴリ情報 | サブカテゴリ階層表示 |

### 更新テーブル一覧（サーバー側）

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| cart_items | INSERT/UPDATE | カート商品追加 |
| wishlist | INSERT/DELETE | ウィッシュリスト操作 |
| compare_items | INSERT | 比較リスト追加 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ネットワークエラー | インターネット未接続 | インターネットエラー通知を表示 |
| 未ログインエラー | ログインが必要な操作で未ログイン | ログイン要求警告通知を表示 |
| 在庫エラー | 商品の在庫がない | エラー通知でメッセージを表示 |
| API呼び出し失敗 | サーバーエラー | エラー通知でメッセージを表示 |
| オプション必須エラー | 商品にオプション選択が必要 | 警告通知を表示して商品詳細画面へ遷移 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（自動リトライなし） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし（ユーザーによる手動リトライ） |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（24時間）

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

- 商品操作は一部ログイン必須（ウィッシュリスト、比較リスト）
- カート数量はグローバル状態（GlobalData.cartCountController）で管理される
- SharedPreferences にカート数が保存される

## 備考

- カート追加成功時はカート数量がリアルタイムで更新される（86-89行目）
- ウィッシュリスト操作後は商品一覧を再取得する（fetchProducts呼び出し）
- 商品がsimple/virtualタイプ以外、またはカスタマイズオプションがある場合は商品詳細画面に遷移する（612-631行目）
- サブカテゴリが存在する場合は再帰的にサブカテゴリ画面に遷移する

---

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

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

### 推奨読解順序

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

まず、サブカテゴリ画面で使用される状態クラスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | drawer_sub_categories_bloc.dart | `lib/screens/drawer_sub_categories/bloc/drawer_sub_categories_bloc.dart` | 各種State（AddToCartState等）の定義を確認 |

**読解のコツ**: Status enum と各State の status フィールドの関係に注目する。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | drawer_sub_categories.dart | `lib/screens/drawer_sub_categories/drawer_sub_categories.dart` | _subCategoriesList メソッド内の BlocConsumer listener（77-118行目）を確認 |

**主要処理フロー**:
1. **78-91行目**: AddToCartState の処理（カート追加）
2. **91-99行目**: AddWishlistState の処理（ウィッシュリスト追加）
3. **100-109行目**: RemoveWishlistState の処理（ウィッシュリスト削除）
4. **110-117行目**: AddToCompareState の処理（比較リスト追加）

#### Step 3: 各操作の呼び出し元を理解する

商品カードからの操作トリガーを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | drawer_sub_categories.dart | `lib/screens/drawer_sub_categories/drawer_sub_categories.dart` | productsView メソッド（313-661行目）内の各操作を確認 |

**主要処理フロー**:
- **472-509行目**: ウィッシュリストアイコンのタップ処理
- **511-544行目**: 比較アイコンのタップ処理
- **588-643行目**: カート追加ボタンのタップ処理

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | string_constants.dart | `lib/utils/string_constants.dart` | success（132行目）, failed（133行目）, pleaseLogin（195行目）, addOptions（136行目）, internetIssue（126行目）の定義を確認 |

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

```
DrawerSubCategoryView
    │
    ├─ _subCategoriesList
    │      └─ BlocConsumer.listener
    │             ├─ AddToCartState
    │             │      ├─ success → successNotification + カート数更新
    │             │      └─ fail → errorNotification
    │             ├─ AddWishlistState
    │             │      ├─ success → successNotification + fetchProducts
    │             │      └─ fail → errorNotification
    │             ├─ RemoveWishlistState
    │             │      ├─ success → successNotification + fetchProducts
    │             │      └─ fail → errorNotification
    │             └─ AddToCompareState
    │                    ├─ success → successNotification
    │                    └─ fail → errorNotification
    │
    └─ productsView (商品カード)
           ├─ ウィッシュリストアイコンタップ
           │      └─ checkInternetConnection
           │             ├─ isLogin → AddWishlistEvent / RemoveWishlistItemEvent
           │             └─ !isLogin → warningNotification (pleaseLogin)
           ├─ 比較アイコンタップ
           │      └─ checkInternetConnection
           │             ├─ isLogin → AddToCompareEvent
           │             └─ !isLogin → warningNotification (pleaseLogin)
           └─ カート追加ボタンタップ
                  └─ checkInternetConnection
                         ├─ simple/virtual商品 → AddToCartEvent
                         └─ 他の商品タイプ → warningNotification (addOptions)
```

### データフロー図

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

商品操作ボタン ───▶ checkInternetConnection
                              │
                       ┌──────┴──────┐
                       ▼             ▼
                    未接続        接続済
                       │             │
                       ▼             ▼
                  エラー通知    ログイン確認
                                     │
                              ┌──────┴──────┐
                              ▼             ▼
                          未ログイン     ログイン済
                              │             │
                              ▼             ▼
                          警告通知     商品タイプ確認
                                           │
                                    ┌──────┴──────┐
                                    ▼             ▼
                              simple/virtual   その他
                                    │             │
                                    ▼             ▼
                              API呼び出し   警告通知+詳細遷移
                                    │
                                    ▼
                                状態更新
                                    │
                              ┌──────┴──────┐
                              ▼             ▼
                           成功          失敗
                              │             │
                              ▼             ▼
                        成功通知     エラー通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| drawer_sub_categories.dart | `lib/screens/drawer_sub_categories/drawer_sub_categories.dart` | ソース | サブカテゴリ画面のWidget、通知トリガーの発火元 |
| drawer_sub_categories_bloc.dart | `lib/screens/drawer_sub_categories/bloc/drawer_sub_categories_bloc.dart` | ソース | サブカテゴリ画面のBLoC |
| show_message.dart | `lib/widgets/show_message.dart` | ソース | 通知表示ユーティリティクラス |
| string_constants.dart | `lib/utils/string_constants.dart` | ソース | 文字列定数の定義 |
| wishlist_compare_widget.dart | `lib/widgets/wishlist_compare_widget.dart` | ソース | ウィッシュリスト・比較アイコンウィジェット |
