# 通知設計書 54-ドロワーカテゴリ操作通知

## 概要

本ドキュメントは、Bagisto モバイルアプリにおけるドロワーカテゴリ操作通知の設計を記載する。ドロワーメニュー内のカテゴリ画面およびサブカテゴリ画面での商品操作（カート追加、ウィッシュリスト追加/削除、比較リスト追加）の成否をユーザーに通知する機能の仕様を定義する。

### 本通知の処理概要

ドロワーカテゴリ操作通知は、ドロワーメニューからアクセスするカテゴリ画面やサブカテゴリ画面において、ユーザーが商品に対してカート追加、ウィッシュリスト追加/削除、比較リスト追加などの操作を行った際に、操作結果を成功または失敗として通知する機能である。

**業務上の目的・背景**：ECアプリでは、ユーザーがカテゴリ一覧から直接商品をカートに追加したり、ウィッシュリストに追加したりする操作が頻繁に行われる。これらの操作が正常に完了したか、または何らかの理由で失敗したかを即座にフィードバックすることで、ユーザーは操作結果を確認でき、必要に応じて再試行や問題の対処を行うことができる。特にカート追加は購買行動に直結するため、明確なフィードバックが重要である。

**通知の送信タイミング**：以下の操作完了時（APIレスポンス受信後）に通知が表示される。
1. カート追加（AddToCartState）成功時または失敗時
2. ウィッシュリスト追加（AddWishlistState）成功時または失敗時
3. ウィッシュリスト削除（RemoveWishlistState）成功時または失敗時
4. 比較リスト追加（AddToCompareState）成功時または失敗時
5. 未ログイン状態での操作試行時（警告通知）
6. インターネット接続エラー時（エラー通知）

**通知の受信者**：現在アプリを操作しているユーザー本人。端末上でリアルタイムに通知が表示される。

**通知内容の概要**：成功時は緑色背景の成功通知（チェックアイコン付き）、失敗時は赤色背景のエラー通知（キャンセルアイコン付き）、警告時は黄色背景の警告通知（警告アイコン付き）が画面上部にオーバーレイ表示される。

**期待されるアクション**：成功通知を受けたユーザーは操作が完了したことを確認できる。失敗通知を受けた場合は、エラー内容を確認し再試行する。未ログイン警告を受けた場合はログイン画面へ移動してログインする。インターネット接続エラーの場合はネットワーク接続を確認する。

## 通知種別

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

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（BlocConsumer listener内で即座に表示） |
| 優先度 | 中（操作結果のフィードバック） |
| リトライ | 無（ユーザーによる再操作が必要） |

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

操作を実行したユーザー本人に対してのみ表示される。端末上のローカル通知であり、送信先の決定ロジックは不要。

## 通知テンプレート

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

#### 成功通知
| 項目 | 内容 |
|-----|------|
| 表示位置 | 画面上部オーバーレイ |
| 背景色 | 緑色（Colors.green.shade400） |
| アイコン | チェックアイコン（Icons.check_circle_outline） |
| 表示時間 | 自動消去 |

#### エラー通知
| 項目 | 内容 |
|-----|------|
| 表示位置 | 画面上部オーバーレイ |
| 背景色 | 赤色（Colors.red） |
| アイコン | キャンセルアイコン（Icons.cancel_outlined） |
| 表示時間 | 自動消去 |

#### 警告通知
| 項目 | 内容 |
|-----|------|
| 表示位置 | 画面上部オーバーレイ |
| 背景色 | 黄色（Colors.amber） |
| アイコン | 警告アイコン（Icons.warning_amber） |
| 表示時間 | 自動消去 |

### 本文テンプレート

#### カート追加成功時
```
タイトル: Success
メッセージ: {APIレスポンスのメッセージ}
```

#### カート追加失敗時
```
タイトル: Failed
メッセージ: {GraphQLエラーメッセージ}
```

#### ウィッシュリスト追加/削除成功時
```
タイトル: Success
メッセージ: {APIレスポンスのメッセージ}
```

#### ウィッシュリスト追加/削除失敗時
```
タイトル: Failed
メッセージ: {エラーメッセージ}
```

#### 比較リスト追加成功/失敗時
```
タイトル: Success / Failed
メッセージ: {成功/エラーメッセージ}
```

#### 未ログイン警告時
```
タイトル: Warning
メッセージ: ログインしてください（StringConstants.pleaseLogin）
```

#### オプション選択必要時
```
タイトル: Warning
メッセージ: オプションを追加してください（StringConstants.addOptions）
```

#### インターネット接続エラー時
```
タイトル: Failed
メッセージ: インターネット接続を確認してください（StringConstants.internetIssue）
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| state.graphQlBaseModel?.message | カート追加成功メッセージ | API レスポンス | No |
| state.graphQlBaseModel?.graphqlErrors | カート追加エラーメッセージ | API レスポンス | No |
| state.response?.message | ウィッシュリスト操作成功メッセージ | API レスポンス | No |
| state.message | エラーメッセージ | 例外メッセージ | No |
| state.successMsg | 比較リスト操作メッセージ | API レスポンス | No |
| StringConstants.pleaseLogin | ログイン要求メッセージ | 定数 | Yes |
| StringConstants.addOptions | オプション追加要求メッセージ | 定数 | Yes |
| StringConstants.internetIssue | 接続エラーメッセージ | 定数 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | カート追加ボタン押下 | AddToCartState受信時 | シンプル/仮想商品のカート追加APIレスポンス後 |
| 画面操作 | ウィッシュリストアイコン押下 | AddWishlistState受信時 | ウィッシュリスト追加APIレスポンス後 |
| 画面操作 | ウィッシュリストアイコン押下 | RemoveWishlistState受信時 | ウィッシュリスト削除APIレスポンス後 |
| 画面操作 | 比較アイコン押下 | AddToCompareState受信時 | 比較リスト追加APIレスポンス後 |
| 画面操作 | 各操作ボタン押下 | !isLogin | 未ログイン状態での操作時 |
| 画面操作 | カート追加ボタン押下 | 設定可能商品の場合 | オプション選択が必要な商品の場合 |
| 画面操作 | 各操作ボタン押下 | checkInternetConnection() == false | ネットワーク接続なし |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | すべての操作結果に対して通知を表示 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザー操作] --> B{インターネット接続チェック}
    B -->|接続なし| C[エラー通知: internetIssue]
    B -->|接続あり| D{ログイン状態チェック}
    D -->|未ログイン| E[警告通知: pleaseLogin]
    D -->|ログイン済み| F{商品タイプ判定}
    F -->|シンプル/仮想| G[Bloc.add AddToCartEvent]
    F -->|設定可能等| H[警告通知: addOptions]
    H --> I[商品詳細画面へ遷移]
    G --> J[API呼び出し]
    J --> K{API結果}
    K -->|成功| L[成功通知表示]
    K -->|失敗| M[エラー通知表示]
    L --> N[カート数更新]
```

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

### 参照テーブル一覧

なし（API経由でサーバー側データベースにアクセス）

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| carts（サーバー側） | INSERT/UPDATE | カートへの商品追加 |
| wishlists（サーバー側） | INSERT/DELETE | ウィッシュリストへの商品追加/削除 |
| compare_items（サーバー側） | INSERT | 比較リストへの商品追加 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ネットワークエラー | checkInternetConnection() == false | エラー通知表示 |
| 認証エラー | 未ログイン状態での操作 | 警告通知表示 |
| 商品タイプエラー | 設定可能商品の直接カート追加 | 警告通知 + 商品詳細画面遷移 |
| API通信エラー | サーバーエラー等 | エラー通知表示 |
| バリデーションエラー | 在庫なし等 | GraphQLエラーメッセージ表示 |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

24時間いつでも表示可能

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

- カート操作、ウィッシュリスト操作はログインユーザーのみ実行可能（未ログイン時は警告通知）
- 比較リスト操作もログインユーザーのみ実行可能
- API呼び出し前にインターネット接続チェックを実施
- エラーメッセージに個人情報は含めない

## 備考

- ドロワーカテゴリ画面（drawer_category_item.dart）とサブカテゴリ画面（drawer_sub_categories.dart）の両方で同様の通知機能が実装されている
- カート追加成功時は、appStoragePref.setCartCount() と GlobalData.cartCountController でカート数が同期更新される
- ウィッシュリスト操作後は fetchProducts() で商品一覧が再取得され、ウィッシュリスト状態が更新される
- overlay_support パッケージを使用したオーバーレイ通知
- 多言語対応済み（localized() メソッドで翻訳テキストを取得）

---

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

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

### 推奨読解順序

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

State クラスの構造と通知メッセージの取得元を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | string_constants.dart | `lib/utils/string_constants.dart` | pleaseLogin, addOptions, internetIssue の定義 |

**読解のコツ**: Dart の静的定数として定義されており、localized() メソッドで多言語対応テキストに変換される。

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

ドロワーサブカテゴリ画面のBlocConsumerでのState処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | drawer_sub_categories.dart | `lib/screens/drawer_sub_categories/drawer_sub_categories.dart` | BlocConsumerのlistener実装（76-118行目） |

**主要処理フロー**:
1. **76行目**: BlocConsumer<DrawerSubCategoriesBloc, DrawerSubCategoriesState> でState変化を監視
2. **78-90行目**: AddToCartState の処理（成功/失敗で通知表示、カート数更新）
3. **91-99行目**: AddWishlistState の処理（成功/失敗で通知表示、商品一覧再取得）
4. **100-108行目**: RemoveWishlistState の処理（成功/失敗で通知表示、商品一覧再取得）
5. **110-117行目**: AddToCompareState の処理（成功/失敗で通知表示）

#### Step 3: 操作トリガーを理解する

ウィッシュリストアイコン、比較アイコン、カート追加ボタンの押下処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | drawer_sub_categories.dart | `lib/screens/drawer_sub_categories/drawer_sub_categories.dart` | ウィッシュリストアイコン押下（472-506行目）、比較アイコン押下（515-543行目）、カート追加ボタン（589-641行目） |

**主要処理フロー**:
- **472-506行目**: ウィッシュリストアイコンのonTap処理
  - checkInternetConnection() で接続チェック
  - isLogin で認証チェック
  - isInWishlist で追加/削除を判断
  - 未ログイン時は warningNotification
  - 接続なし時は errorNotification
- **515-543行目**: 比較アイコンのonTap処理
  - 同様の接続・認証チェック
  - AddToCompareEvent を発行
- **589-641行目**: カート追加ボタンのonPressed処理
  - 接続チェック後、商品タイプを判定
  - simple/virtual商品のみ直接カート追加
  - その他は warningNotification + 商品詳細画面遷移

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | show_message.dart | `lib/widgets/show_message.dart` | successNotification（18-36行目）、errorNotification（38-56行目）、warningNotification（58-77行目） |

**主要処理フロー**:
- **18行目**: successNotification - 緑色背景、チェックアイコン
- **38行目**: errorNotification - 赤色背景、キャンセルアイコン
- **58行目**: warningNotification - 黄色背景、警告アイコン

#### Step 5: カテゴリアイテムの処理を理解する

ドロワーカテゴリアイテムでのインターネット接続チェック処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | drawer_category_item.dart | `lib/screens/drawer/widget/drawer_category_item.dart` | ダブルタップ時のcheckInternetConnection処理（31-45行目） |

**主要処理フロー**:
- **31行目**: onDoubleTap でcheckInternetConnection呼び出し
- **32-39行目**: 接続あり時はカテゴリ画面へ遷移
- **42-43行目**: 接続なし時はshowNotificationでエラー表示

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

```
DrawerSubCategoryView
    │
    ├─ ウィッシュリストアイコン onTap
    │      ├─ checkInternetConnection()
    │      ├─ isLogin チェック
    │      │      └─ ShowMessage.warningNotification (未ログイン時)
    │      ├─ DrawerSubCategoriesBloc.add(AddWishlistEvent / RemoveWishlistItemEvent)
    │      │      └─ API呼び出し
    │      │             └─ emit(AddWishlistState / RemoveWishlistState)
    │      └─ ShowMessage.errorNotification (接続なし時)
    │
    ├─ 比較アイコン onTap
    │      ├─ checkInternetConnection()
    │      ├─ isLogin チェック
    │      │      └─ ShowMessage.warningNotification (未ログイン時)
    │      ├─ DrawerSubCategoriesBloc.add(AddToCompareEvent)
    │      │      └─ API呼び出し
    │      │             └─ emit(AddToCompareState)
    │      └─ ShowMessage.errorNotification (接続なし時)
    │
    ├─ カート追加ボタン onPressed
    │      ├─ checkInternetConnection()
    │      ├─ 商品タイプ判定
    │      │      ├─ simple/virtual: DrawerSubCategoriesBloc.add(AddToCartEvent)
    │      │      │      └─ API呼び出し
    │      │      │             └─ emit(AddToCartState)
    │      │      └─ その他: ShowMessage.warningNotification + 商品詳細画面遷移
    │      └─ ShowMessage.errorNotification (接続なし時)
    │
    └─ BlocConsumer.listener
           ├─ AddToCartState
           │      └─ ShowMessage.successNotification / errorNotification
           ├─ AddWishlistState
           │      └─ ShowMessage.successNotification / errorNotification
           ├─ RemoveWishlistState
           │      └─ ShowMessage.successNotification / errorNotification
           └─ AddToCompareState
                  └─ ShowMessage.successNotification / errorNotification
```

### データフロー図

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

ユーザー操作 ───▶ checkInternetConnection() ───▶ bool（接続状態）
                        │
                        ├──接続なし──▶ ShowMessage.errorNotification()
                        │
                        └──接続あり──▶ isLogin チェック
                                            │
                                            ├──未ログイン──▶ ShowMessage.warningNotification()
                                            │
                                            └──ログイン済み──▶ Bloc.add(Event)
                                                                │
                                                                ▼
                                                         API呼び出し
                                                                │
                                                                ▼
                                                       ┌────────┴────────┐
                                                       │                 │
                                                   成功State          失敗State
                                                       │                 │
                                                       ▼                 ▼
                                              successNotification  errorNotification
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| drawer_sub_categories.dart | `lib/screens/drawer_sub_categories/drawer_sub_categories.dart` | ソース | サブカテゴリ画面メインUI |
| drawer_category_item.dart | `lib/screens/drawer/widget/drawer_category_item.dart` | ソース | カテゴリアイテムウィジェット |
| drawer_list_view.dart | `lib/screens/drawer/drawer_list_view.dart` | ソース | ドロワーメニュー画面 |
| show_message.dart | `lib/widgets/show_message.dart` | ソース | 通知表示ユーティリティクラス |
| check_internet_connection.dart | `lib/utils/check_internet_connection.dart` | ソース | インターネット接続チェック |
| string_constants.dart | `lib/utils/string_constants.dart` | ソース | 文字列定数定義 |
| index.dart | `lib/screens/drawer_sub_categories/utils/index.dart` | ソース | サブカテゴリ utils エクスポート |
