# 機能設計書 30-ウィッシュリスト全削除

## 概要

本ドキュメントは、ECモバイルアプリにおけるウィッシュリストの全商品を一括削除する機能について設計仕様を定義する。

### 本機能の処理概要

本機能は、ウィッシュリストに登録された全ての商品を一括で削除し、お気に入りリストを空にする機能である。

**業務上の目的・背景**：ECサイトにおいて、ユーザーがウィッシュリストの内容を全てリセットしたい場合がある。長期間更新していないリストの整理、新しいシーズンに向けたリセット、または単純なクリーンアップとして、全商品を一度に削除できる機能は利便性を高める。個別削除を繰り返す手間を省き、効率的なリスト管理を実現する。

**機能の利用シーン**：ユーザーがウィッシュリストを一からやり直したい場合、古い商品を一括でクリアしたい場合に利用される。例えば、セール期間終了後に価格が戻った商品群を全て削除し、新たに商品を選び直す場合などに活用される。

**主要な処理内容**：
1. ウィッシュリスト画面にてFloatingActionButton（削除ボタン）を押下
2. RemoveAllWishlistEventを発行
3. GraphQL API経由でサーバーに全削除リクエストを送信
4. サーバーでウィッシュリストの全商品を削除
5. 成功時はウィッシュリストを空にし、空状態を表示
6. 成功メッセージを表示

**関連システム・外部連携**：Bagisto GraphQL APIとの連携により、`removeAllWishlists` mutationを使用してウィッシュリスト全体を削除する。

**権限による制御**：ログインユーザーのみ利用可能。自身のウィッシュリストのみ操作可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 13 | ウィッシュリスト画面 | 主画面 | お気に入り商品の一括削除 |

## 機能種別

CRUD操作（Delete）/ 一括処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| message | String | No | オプションメッセージ（内部使用） | - |

### 入力データソース

画面操作（FloatingActionButton（ゴミ箱アイコン）押下）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| success | bool | 処理成功可否 |
| message | String | 処理結果メッセージ |

### 出力先

- 画面表示（空ウィッシュリスト画面への遷移）
- 成功/エラーメッセージ表示

## 処理フロー

### 処理シーケンス

```
1. ユーザーがFloatingActionButton（ゴミ箱アイコン）を押下
   └─ WishListScreenのonPressed処理
2. ローダー表示イベントを発行
   └─ OnClickWishListLoaderEvent(isReqToShowLoader: true)
3. RemoveAllWishlistEventを発行
4. WishListBlocがイベントを受信
   └─ repository.removeAllWishListProductsを呼び出し
5. WishListRepositoryがApiClientを経由でAPI呼び出し
   └─ GraphQL mutation removeAllWishlistsを実行
6. 成功時: RemoveAllWishlistProductState.successを発行
7. ローカルのウィッシュリストデータをクリア
8. 空ウィッシュリスト画面を表示
9. 成功メッセージを表示
```

### フローチャート

```mermaid
flowchart TD
    A[FloatingActionButton押下] --> B[ローダー表示]
    B --> C[RemoveAllWishlistEvent発行]
    C --> D[WishListBloc処理]
    D --> E[API呼び出し]
    E --> F{成功?}
    F -->|Yes| G[RemoveAllWishlistProductState.success]
    G --> H[ローカルデータクリア]
    H --> I[wishlistController.sink.add 0]
    I --> J[空ウィッシュリスト表示]
    J --> K[成功メッセージ表示]
    F -->|No| L[RemoveAllWishlistProductState.fail]
    L --> M[エラーメッセージ表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-030-01 | ボタン表示条件 | FloatingActionButtonは商品が1つ以上ある場合のみ表示 | ウィッシュリスト表示時 |
| BR-030-02 | 即座削除 | 確認ダイアログなしで即座に全削除 | ボタン押下時 |
| BR-030-03 | 全商品削除 | ウィッシュリスト内の全商品を一括で削除 | API成功時 |
| BR-030-04 | 空リスト表示 | 削除後は空ウィッシュリスト画面を表示 | 削除成功時 |

### 計算ロジック

特になし

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ウィッシュリスト全削除 | wishlists | DELETE | 当該ユーザーの全ウィッシュリストを削除 |

### テーブル別操作詳細

#### wishlists

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | customer_id = ログインユーザー | 全レコードを削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ネットワークエラー | API通信失敗 | エラーメッセージを表示 |
| - | 認証エラー | セッション切れ | エラー表示 |

### リトライ仕様

自動リトライは行わない。ユーザーに再操作を促す。

## トランザクション仕様

サーバー側でトランザクション管理。全商品の削除は同一トランザクション内で実行される。

## パフォーマンス要件

- API応答時間: 3秒以内を目標（大量商品の場合を考慮）

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

- 認証: ログインユーザーのみ利用可能
- アクセス権限: 自身のウィッシュリストのみ操作可能

## 備考

全削除操作は取り消し不可。削除した商品群を再度追加するには、各商品を個別に検索してウィッシュリストに追加する必要がある。

---

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

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

### 推奨読解順序

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

API応答のデータモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | graphql_base_model.dart | `lib/data_model/graphql_base_model.dart` | BaseModelクラス（success, messageフィールド） |

**読解のコツ**: 全削除APIはBaseModelを返す。

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

FloatingActionButton押下からの流れを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | wishlist_screen.dart | `lib/screens/wishList/view/wishlist_screen.dart` | FloatingActionButtonとイベント発行 |

**主要処理フロー**:
1. **76-95行目**: FloatingActionButtonの定義
2. **79-80行目**: Visibilityでcount > 0の時のみ表示
3. **84-87行目**: onPressedでローダー表示とRemoveAllWishlistEvent発行

#### Step 3: BLoC層を理解する

状態管理とビジネスロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | wishlist_event.dart | `lib/screens/wishList/bloc/wishlist_event.dart` | RemoveAllWishlistEventの定義（28-33行目） |
| 3-2 | wishlist_state.dart | `lib/screens/wishList/bloc/wishlist_state.dart` | RemoveAllWishlistProductStateの定義（64-72行目） |
| 3-3 | wishlist_bloc.dart | `lib/screens/wishList/bloc/wishlist_bloc.dart` | RemoveAllWishlistEventの処理（69-82行目） |

**主要処理フロー**:
- **69-82行目**: RemoveAllWishlistEventを受信し、repository経由でAPI呼び出し、success判定で状態分岐

#### Step 4: リポジトリ層とAPI層を理解する

実際のAPI呼び出し処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | wishlist_repository.dart | `lib/screens/wishList/bloc/wishlist_repository.dart` | removeAllWishListProductsメソッド（65-71行目） |
| 4-2 | api_client.dart | `lib/services/api_client.dart` | removeAllWishlistProducts API呼び出し（613-620行目） |
| 4-3 | mutation_query.dart | `lib/services/mutation_query.dart` | GraphQL mutation定義（832-838行目） |

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

```
WishListScreen (wishlist_screen.dart)
    │
    └─ FloatingActionButton.onPressed
           │
           ├─ OnClickWishListLoaderEvent発行 (ローダー表示)
           │
           └─ RemoveAllWishlistEvent("")発行
                  │
                  └─ WishListBloc.mapEventToState
                         │
                         └─ WishListRepository.removeAllWishListProducts
                                │
                                └─ ApiClient.removeAllWishlistProducts
                                       │
                                       └─ MutationQuery.removeAllWishlistProducts
```

### データフロー図

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

FAB押下 ───▶ RemoveAllWishlistEvent ───▶ WishListBloc
 (UI)        (イベント発行)              (状態管理)
                                              │
                       ┌──────────────────────┘
                       ▼
             WishListRepository
                       │
                       ▼
                  ApiClient
                       │
                       ▼
          GraphQL API (removeAllWishlists)
                       │
                       ▼
               BaseModel ───▶ RemoveAllWishlistProductState ───▶ UI更新
              (応答データ)          (状態通知)              (空リスト表示)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| wishlist_screen.dart | `lib/screens/wishList/view/wishlist_screen.dart` | ソース | ウィッシュリスト画面、FAB |
| wishlist_bloc.dart | `lib/screens/wishList/bloc/wishlist_bloc.dart` | ソース | ウィッシュリストBLoC |
| wishlist_event.dart | `lib/screens/wishList/bloc/wishlist_event.dart` | ソース | BLoCイベント定義 |
| wishlist_state.dart | `lib/screens/wishList/bloc/wishlist_state.dart` | ソース | BLoC状態定義 |
| wishlist_repository.dart | `lib/screens/wishList/bloc/wishlist_repository.dart` | ソース | ウィッシュリストリポジトリ |
| graphql_base_model.dart | `lib/data_model/graphql_base_model.dart` | ソース | API基本応答モデル |
| api_client.dart | `lib/services/api_client.dart` | ソース | API通信クライアント |
| mutation_query.dart | `lib/services/mutation_query.dart` | ソース | GraphQLクエリ定義 |
