# 機能設計書 34-比較リストから削除

## 概要

本ドキュメントは、比較リストから個別の商品を削除する機能の設計を記述する。

### 本機能の処理概要

本機能は、ユーザーが比較画面で不要になった商品を個別に削除するための機能である。

**業務上の目的・背景**：比較検討の過程で、ユーザーは特定の商品を比較対象から除外したいケースがある。本機能により、比較リストを柔軟に管理し、本当に比較したい商品のみを残すことができる。これにより、効率的な購入意思決定を支援する。

**機能の利用シーン**：ユーザーが比較画面で特定の商品カードの「×」（削除）ボタンをタップした際に本機能が実行される。

**主要な処理内容**：
1. 商品カードの削除ボタンタップを検知
2. GraphQL APIで比較リストからの削除リクエストを送信
3. 削除成功時に成功通知を表示し、一覧を再取得
4. 失敗時にエラー通知を表示

**関連システム・外部連携**：GraphQL APIを介したBagistoバックエンドとの通信

**権限による制御**：自身の比較リストのみ削除可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | 商品比較画面 | 主画面 | 比較リストから個別商品を削除 |

## 機能種別

データ削除処理（DELETE操作）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| productId | String | Yes | 削除対象の商品ID | 有効な商品IDであること |

### 入力データソース

- 比較画面の商品カードUIから取得

## 出力仕様

### 出力データ

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

### 出力先

- 画面表示: 成功/失敗通知トースト
- 比較リスト: 削除後の一覧再表示

## 処理フロー

### 処理シーケンス

```
1. ユーザーが削除ボタン（×）をタップ
   └─ CompareList.onTap実行
2. ローディング表示開始
   └─ OnClickCompareLoaderEvent発火
3. RemoveFromCompareListEventを発火
   └─ CompareScreenBloc.add実行
4. BlocがAPIを呼び出し
   └─ CompareScreenRepository.removeFromCompareList実行
5. ApiClient.removeFromCompareでGraphQL通信
   └─ removeFromCompareProduct mutationを実行
6. レスポンス処理
   └─ 成功: 成功通知表示、一覧再取得
   └─ 失敗: エラー通知表示
```

### フローチャート

```mermaid
flowchart TD
    A[削除ボタンタップ] --> B[ローディング表示]
    B --> C[RemoveFromCompareListEvent発火]
    C --> D[GraphQL API呼び出し]
    D --> E{API結果}
    E -->|成功| F[成功通知表示]
    E -->|失敗| G[エラー通知表示]
    F --> H[ページング初期化]
    H --> I[比較一覧再取得]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-34-01 | 自己所有確認 | 自身の比較リストの商品のみ削除可能 | 削除処理時 |
| BR-34-02 | 一覧再取得 | 削除成功後、ページを1に戻して再取得 | 削除成功時 |

### 計算ロジック

特になし。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 削除 | compare_items | DELETE | 比較リストから商品削除 |

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

#### compare_items

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | product_id | 指定された商品ID | バックエンドで処理 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | graphqlErrors | API通信失敗 | エラー通知表示 |
| - | 権限エラー | 他ユーザーのデータ削除試行 | エラー通知表示 |

### リトライ仕様

自動リトライなし。

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

バックエンドAPIでトランザクション管理。

## パフォーマンス要件

- API応答時間: 2秒以内

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

- 認証トークンまたはセッションでユーザー識別
- 自身のデータのみ削除可能

## 備考

- 削除後はページングをリセットして最新データを取得

---

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

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

### 推奨読解順序

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

削除ボタンのUI部分を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | compare_list.dart | `lib/screens/compare/view/widget/compare_list.dart` | 削除ボタンのonTap処理 |

**主要処理フロー**:
- **89-97行目**: 削除ボタンタップ時の処理

#### Step 2: Bloc（状態管理層）を理解する

イベント処理の流れを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | compare_screen_event.dart | `lib/screens/compare/bloc/compare_screen_event.dart` | RemoveFromCompareListEventの定義 |
| 2-2 | compare_screen_bloc.dart | `lib/screens/compare/bloc/compare_screen_bloc.dart` | イベント処理 |

**主要処理フロー**:
- **63-79行目**: RemoveFromCompareListEventの処理

#### Step 3: Repository（データアクセス層）を理解する

API呼び出しの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | compare_screen_repository.dart | `lib/screens/compare/bloc/compare_screen_repository.dart` | removeFromCompareListメソッド |

**主要処理フロー**:
- **36-41行目**: removeFromCompare呼び出し

#### Step 4: APIクライアントを理解する

GraphQL通信の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | api_client.dart | `lib/services/api_client.dart` | removeFromCompareメソッド |

**主要処理フロー**:
- **1165-1181行目**: removeFromCompareProduct mutation実行

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

```
CompareList (UI)
    │
    ├─ OnClickCompareLoaderEvent（ローディング表示）
    │
    ├─ RemoveFromCompareListEvent
    │      │
    │      └─ CompareScreenRepository.removeFromCompareList(productId)
    │             │
    │             └─ ApiClient.removeFromCompare(productId)
    │                    │
    │                    └─ GraphQL mutation: removeFromCompareProduct
    │
    └─ 状態更新
           ├─ RemoveFromCompareState.success
           │      └─ CompareScreenFetchEvent（一覧再取得）
           │
           └─ 通知表示
```

### データフロー図

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

商品ID ─────────────▶ CompareScreenBloc ──────▶ 成功通知
                          │
                    CompareScreenRepository
                          │
                    ApiClient
                          │
                    GraphQL Server ───────────▶ 比較リスト更新
                                                  │
                                            一覧再取得
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| compare_list.dart | `lib/screens/compare/view/widget/compare_list.dart` | ソース | 商品カードUI（削除ボタン） |
| compare_screen_bloc.dart | `lib/screens/compare/bloc/compare_screen_bloc.dart` | ソース | 状態管理Bloc |
| compare_screen_event.dart | `lib/screens/compare/bloc/compare_screen_event.dart` | ソース | イベント定義 |
| compare_screen_repository.dart | `lib/screens/compare/bloc/compare_screen_repository.dart` | ソース | リポジトリ層 |
| api_client.dart | `lib/services/api_client.dart` | ソース | API通信クライアント |
