# 通知設計書 31-住所削除成功/失敗通知

## 概要

本ドキュメントは、ECモバイルアプリケーションにおける「住所削除成功/失敗通知」の設計仕様を定義する。ユーザーが登録済みの配送先住所を削除した際の処理結果をアプリ内通知で表示する機能について記載する。

### 本通知の処理概要

住所削除成功/失敗通知は、ユーザーがマイページの住所一覧画面から登録済みの配送先住所を削除した際に、その操作結果をリアルタイムでフィードバックする通知機能である。

**業務上の目的・背景**：ユーザーが複数の配送先住所を管理する際、不要になった住所を削除する操作が必要となる。この操作結果を即座にフィードバックすることで、ユーザーは削除が正常に完了したか、または何らかのエラーが発生したかを明確に認識できる。これにより、ユーザーの操作に対する不安を解消し、スムーズな住所管理体験を提供する。

**通知の送信タイミング**：住所一覧画面において、ユーザーが特定の住所の削除ボタンをタップし、削除確認後にAPIリクエストが完了した時点で通知が表示される。BlocパターンによりRemoveAddressStateの状態変化を検知してトリガーされる。

**通知の受信者**：削除操作を実行したユーザー本人のみが通知を受け取る。通知はアプリ内のオーバーレイ表示であり、他のユーザーには影響しない。

**通知内容の概要**：成功時は緑色の背景でチェックマークアイコンとともにサーバーから返されたメッセージを表示する。失敗時は赤色の背景でキャンセルアイコンとともにエラーメッセージを表示する。

**期待されるアクション**：成功通知の場合、ユーザーは削除完了を確認し、必要に応じて他の住所操作を継続する。失敗通知の場合、ユーザーはエラー原因を確認し、再度削除操作を試みるか、カスタマーサポートに問い合わせる。

## 通知種別

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

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ユーザー操作に対する即時レスポンス） |
| 優先度 | 中 |
| リトライ | 無（単発表示、自動消失） |

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

削除操作を実行したユーザー本人のアプリ画面にのみ表示される。ユーザーIDやセッション情報に基づく送信先決定は不要（ローカル表示のため）。

## 通知テンプレート

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

| 項目 | 内容 |
|-----|------|
| 表示位置 | 画面上部オーバーレイ |
| 表示時間 | 自動消失（約3秒） |
| スワイプ操作 | 上方向スワイプで即時消去可能 |

### 成功時テンプレート

| 項目 | 内容 |
|-----|------|
| タイトル | "Success"（ローカライズ対応） |
| 背景色 | 緑色（Colors.green.shade400） |
| アイコン | チェックマーク（Icons.check_circle_outline） |

```
本文: {サーバーレスポンスのmessageフィールド}
```

### 失敗時テンプレート

| 項目 | 内容 |
|-----|------|
| タイトル | "Failed"（ローカライズ対応） |
| 背景色 | 赤色（Colors.red） |
| アイコン | キャンセルマーク（Icons.cancel_outlined） |

```
本文: {エラーメッセージ}
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | 本通知には添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| message | 成功/エラーメッセージ | BaseModel.message / error | Yes |
| title | 通知タイトル | StringConstants（ローカライズ） | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | RemoveAddressEvent発行 | API応答受信後 | 住所削除ボタンタップ時 |
| Bloc状態変化 | RemoveAddressState | status == success または fail | BlocConsumerのlistenerで検知 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 画面遷移中 | 住所一覧画面から離脱している場合は表示されない |
| Bloc未初期化 | AddressBlocが初期化されていない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[削除ボタンタップ] --> B[RemoveAddressEvent発行]
    B --> C[AddressBloc処理]
    C --> D[Repository.callRemoveAddressApi呼び出し]
    D --> E{API応答}
    E -->|成功| F[RemoveAddressState.success発行]
    E -->|失敗| G[RemoveAddressState.fail発行]
    F --> H[BlocConsumer.listener検知]
    G --> H
    H --> I{状態判定}
    I -->|success| J[ShowMessage.successNotification]
    I -->|fail| K[ShowMessage.errorNotification]
    J --> L[オーバーレイ表示]
    K --> L
    L --> M[自動消失/スワイプ消去]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| customer_addresses | 削除対象住所の確認 | GraphQL API経由 |

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

#### customer_addresses

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | 削除対象識別 | RemoveAddressEvent.id |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| customer_addresses | DELETE | 指定された住所レコードの削除 |

#### 送信ログテーブル

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| なし | - | - | アプリ内通知のためログ記録なし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| API通信エラー | ネットワーク接続不可 | "Something went wrong"メッセージ表示 |
| サーバーエラー | バックエンドエラー | サーバーレスポンスのエラーメッセージ表示 |
| 住所不存在 | 既に削除済みの住所を削除試行 | エラー通知表示 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（ユーザー操作による再試行） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（ユーザー操作起点） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（24時間対応）

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

- 削除操作はログイン済みユーザーのみ実行可能
- 自身の住所のみ削除可能（他ユーザーの住所は削除不可）
- 通知内容に個人情報（住所詳細）は含まない

## 備考

- overlay_supportパッケージを使用したオーバーレイ通知を採用
- 通知のローカライズはStringConstantsおよびlocalized()メソッドで対応
- 削除成功後、住所一覧は自動的に更新される（リストからの即時反映）

---

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

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

### 推奨読解順序

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

通知に関連するモデルクラスと状態クラスを理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | address_state.dart | `lib/screens/address_list/bloc/address_state.dart` | RemoveAddressState クラスの構造、success/fail の状態定義 |
| 1-2 | address_event.dart | `lib/screens/address_list/bloc/address_event.dart` | RemoveAddressEvent の引数（削除対象ID） |

**読解のコツ**: Dartのfactory constructorパターン（`RemoveAddressState.success`、`RemoveAddressState.fail`）に注目する。

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

処理の起点となる画面ファイルを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | address_screen.dart | `lib/screens/address_list/view/address_screen.dart` | BlocConsumerのlistener部分（63-70行目） |

**主要処理フロー**:
1. **63行目**: `if (state is RemoveAddressState)` - 状態判定
2. **64-65行目**: 失敗時の`ShowMessage.errorNotification`呼び出し
3. **66-69行目**: 成功時の`ShowMessage.successNotification`呼び出し

#### Step 3: Bloc処理を理解する

状態管理とAPI呼び出しのロジックを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | address_bloc.dart | `lib/screens/address_list/bloc/address_bloc.dart` | RemoveAddressEventハンドリング（31-39行目） |

**主要処理フロー**:
- **31行目**: `else if (event is RemoveAddressEvent)` - イベント判定
- **33行目**: `repository?.callRemoveAddressApi(event.id)` - API呼び出し
- **34-35行目**: 成功時の状態発行
- **37-39行目**: 失敗時の状態発行

#### Step 4: 通知表示ロジックを理解する

実際の通知表示処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | show_message.dart | `lib/widgets/show_message.dart` | successNotification/errorNotificationメソッド |

**主要処理フロー**:
- **18-36行目**: `successNotification` - 成功通知の表示ロジック
- **38-56行目**: `errorNotification` - エラー通知の表示ロジック

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

```
address_screen.dart (UI Layer)
    │
    ├─ BlocConsumer<AddressBloc, AddressBaseState>
    │      │
    │      └─ listener: (state is RemoveAddressState)
    │             │
    │             ├─ success → ShowMessage.successNotification()
    │             │                  └─ showSimpleNotification()
    │             │
    │             └─ fail → ShowMessage.errorNotification()
    │                          └─ showSimpleNotification()
    │
    └─ AddressBloc (Business Logic Layer)
           │
           └─ RemoveAddressEvent handler
                  │
                  └─ AddressRepository.callRemoveAddressApi()
                         │
                         └─ GraphQL API Call
```

### データフロー図

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

User Tap Delete    ───▶  RemoveAddressEvent        ───▶  UI Dispatch
                              │
                              ▼
                         AddressBloc
                              │
                              ▼
                    AddressRepository.callRemoveAddressApi()
                              │
                              ▼
                         GraphQL API
                              │
                              ▼
                    RemoveAddressState (success/fail)
                              │
                              ▼
BlocConsumer       ───▶  listener検知              ───▶  ShowMessage
                              │
                              ▼
                    showSimpleNotification()       ───▶  Overlay Display
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| address_screen.dart | `lib/screens/address_list/view/address_screen.dart` | ソース | 住所一覧画面、通知表示トリガー |
| address_bloc.dart | `lib/screens/address_list/bloc/address_bloc.dart` | ソース | 状態管理、API呼び出し |
| address_event.dart | `lib/screens/address_list/bloc/address_event.dart` | ソース | イベント定義 |
| address_state.dart | `lib/screens/address_list/bloc/address_state.dart` | ソース | 状態定義 |
| address_repository.dart | `lib/screens/address_list/bloc/address_repository.dart` | ソース | API通信処理 |
| show_message.dart | `lib/widgets/show_message.dart` | ソース | 通知表示ユーティリティ |
| string_constants.dart | `lib/utils/string_constants.dart` | 設定 | 文字列定数定義 |
| saved_address_list.dart | `lib/screens/address_list/view/widget/saved_address_list.dart` | ソース | 住所リストアイテム、削除ボタン |
