# 通知設計書 13-Customer Deleted

## 概要

本ドキュメントは、Shopwareにおける顧客削除通知（Customer Deleted）の設計仕様を記載したものです。顧客アカウントが削除された際に、削除された顧客または関係者に対してその旨を通知するイベント機能について定義します。

### 本通知の処理概要

この通知は、顧客アカウントが削除された際に発火するイベントです。デフォルトではメール送信のFlowは設定されていませんが、`FlowEventAware`および`MailAware`インターフェースを実装しているため、Flowビルダーでメール送信アクションを設定することが可能です。

**業務上の目的・背景**：GDPR（EU一般データ保護規則）等のプライバシー規制に対応するため、顧客は自身のアカウント削除を要求する権利を持っています。アカウント削除時にイベントを発火することで、削除の確認通知を送信したり、関連システムへの通知、監査ログの記録などが可能になります。

**通知の送信タイミング**：顧客エンティティの削除処理が成功した直後（`EntityDeleteEvent`の`addSuccess`コールバック内）に`CustomerDeletedEvent`がディスパッチされます。これにより、削除が確実に完了した後にのみイベントが発火されます。

**通知の受信者**：削除された顧客本人のメールアドレス。ただし、削除後のため受信者情報はイベント発火前に取得されたデータを使用します。

**通知内容の概要**：顧客情報（シリアライズ済み）、削除されたアカウントの確認情報が含まれます。

**期待されるアクション**：顧客はアカウント削除の完了を確認できます。必要に応じて、再登録の手順などを案内することも可能です。

## 通知種別

イベント通知（メール送信はFlowで設定可能）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（Flow経由、設定時のみ） |
| 優先度 | 中 |
| リトライ | Flowの設定に依存 |

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

イベント発生時に`MailRecipientStruct`が構築されます。削除前の顧客情報を使用します。

```php
// CustomerDeletedEvent.php 行67-76
public function getMailStruct(): MailRecipientStruct
{
    if (!$this->mailRecipientStruct instanceof MailRecipientStruct) {
        $this->mailRecipientStruct = new MailRecipientStruct([
            $this->customer->getEmail() => $this->customer->getFirstName() . ' ' . $this->customer->getLastName(),
        ]);
    }

    return $this->mailRecipientStruct;
}
```

## 通知テンプレート

### メール通知の場合

| 項目 | 内容 |
|-----|------|
| 送信元アドレス | ショップ設定に依存 |
| 送信元名称 | ショップ設定に依存 |
| 件名 | カスタム設定（デフォルトテンプレートなし） |
| 形式 | HTML/テキスト |

### 本文テンプレート

デフォルトのメールテンプレートは提供されていません。Flowビルダーでメール送信アクションを設定する際に、カスタムテンプレートを作成する必要があります。

以下は推奨されるテンプレート例です：

**英語版（HTML）例**:
```html
<div style="font-family:arial; font-size:12px;">
    <p>
        Dear {{ customer.firstName }} {{ customer.lastName }},<br/>
        <br/>
        Your account has been successfully deleted from our system.<br/>
        If you did not request this deletion, please contact our support immediately.<br/><br/>

        Thank you for being our customer.
    </p>
</div>
```

### 添付ファイル

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

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| `customer` | 顧客エンティティ（削除前のデータ） | CustomerEntity | Yes |
| `customer.firstName` | 顧客の名 | customer.first_name | Yes |
| `customer.lastName` | 顧客の姓 | customer.last_name | Yes |
| `customer.email` | 顧客のメールアドレス | customer.email | Yes |
| `customer.salutation` | 敬称 | customer.salutation | No |
| `customer.defaultBillingAddress` | デフォルト請求先住所 | customer_address | No |
| `customer.defaultShippingAddress` | デフォルト配送先住所 | customer_address | No |
| `salesChannel` | 販売チャネル | SalesChannelContext | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| データ削除 | `checkout.customer.deleted` | 顧客エンティティ削除成功時 | EntityDeleteEventのsuccessコールバックで発火 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| Flowが設定されていない | Flowビルダーでアクションが設定されていない場合 |
| 削除処理失敗 | EntityDeleteEventが失敗した場合はイベントは発火しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[顧客削除リクエスト] --> B[EntityDeleteEvent発火]
    B --> C[CustomerBeforeDeleteSubscriber::beforeDelete]
    C --> D[削除対象の顧客データ取得]
    D --> E[顧客データのシリアライズ]
    E --> F[addSuccessコールバック登録]
    F --> G{削除処理}
    G -->|成功| H[CustomerDeletedEvent発火]
    G -->|失敗| I[イベント発火なし]
    H --> J[Flowエンジンがイベントを検知]
    J --> K{Flowアクション設定あり?}
    K -->|あり| L[設定されたアクション実行]
    K -->|なし| M[処理終了]
    L --> M
    I --> M
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| customer | 削除対象の顧客情報取得 | 削除前に取得 |
| salutation | 顧客の敬称 | アソシエーション |
| customer_address | 請求先・配送先住所 | アソシエーション |
| country | 住所の国情報 | アソシエーション |
| country_state | 住所の州情報 | アソシエーション |

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

#### customer

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | 顧客識別 | 削除対象のID |
| email | メール送信先 | テンプレート変数 |
| first_name | テンプレート変数 | - |
| last_name | テンプレート変数 | - |
| salutation_id | 敬称取得 | JOIN salutation |
| sales_channel_id | 販売チャネル | コンテキスト構築 |
| language_id | 言語設定 | コンテキスト構築 |
| default_billing_address_id | 請求先住所 | アソシエーション |
| default_shipping_address_id | 配送先住所 | アソシエーション |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| customer | DELETE | 顧客レコード削除（イベント発火のトリガー） |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 顧客未発見 | 削除対象の顧客IDが存在しない | イベント発火なし |
| 削除処理失敗 | データベースエラー等 | イベント発火なし、エラーログ記録 |
| メール送信失敗 | SMTPエラー等（Flow設定時） | ログ記録、例外は抑止 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Flowの設定に依存 |
| リトライ間隔 | Flowの設定に依存 |
| リトライ対象エラー | 一時的なネットワークエラー |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | システム設定に依存 |
| 1日あたり上限 | システム設定に依存 |

### 配信時間帯

制限なし

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

- 削除された顧客のデータはイベント内でシリアライズされて保持されるため、ログ出力時の個人情報漏洩に注意
- GDPR準拠のため、削除確認メールの送信は法的要件を確認の上で設定
- 削除処理のトリガーには適切な認証・認可が必要

## 備考

- このイベントは`ScalarValuesAware`インターフェースを実装しており、シリアライズされた顧客データを`getValues()`メソッドで取得可能
- デフォルトではメール送信Flowは設定されていないため、必要に応じてAdministrationで設定が必要
- 削除処理の`addSuccess`コールバック内でイベントが発火されるため、削除が確実に成功した後にのみ通知される

---

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

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

### 推奨読解順序

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

まず、イベントで扱われるデータ構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CustomerDeletedEvent.php | `src/Core/Checkout/Customer/Event/CustomerDeletedEvent.php` | イベントクラスの構造、シリアライズデータの保持方法 |
| 1-2 | CustomerEntity.php | `src/Core/Checkout/Customer/CustomerEntity.php` | 顧客エンティティの構造 |

**読解のコツ**: `ScalarValuesAware`インターフェースの実装により、`getValues()`メソッドでシリアライズ済み顧客データを取得できる点に注目。

#### Step 2: イベント発火の仕組みを理解する

削除時のイベント発火メカニズムを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CustomerBeforeDeleteSubscriber.php | `src/Core/Checkout/Customer/Subscriber/CustomerBeforeDeleteSubscriber.php` | EntityDeleteEventのハンドリング、addSuccessコールバック |

**主要処理フロー**:
1. **行44-46**: `EntityDeleteEvent`をサブスクライブ
2. **行49-57**: 削除対象の顧客IDを取得
3. **行66-77**: 削除前に顧客データを取得（アソシエーション含む）
4. **行79-103**: `addSuccess`コールバックで削除成功時にイベント発火
5. **行92-101**: `CustomerDeletedEvent`をディスパッチ（シリアライズデータ付き）

#### Step 3: イベント処理を理解する

イベントがどのように処理されるかを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SendMailAction.php | `src/Core/Content/Flow/Dispatching/Action/SendMailAction.php` | Flowでのメール送信アクション |
| 3-2 | BusinessEventRegistry.php | `src/Core/Framework/Event/BusinessEventRegistry.php` | イベントの登録 |

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

```
顧客削除リクエスト
    │
    ▼
EntityDeleteEvent
    │
    ▼
CustomerBeforeDeleteSubscriber::beforeDelete()
    │
    ├─ customerRepository->search()
    │      └─ 削除対象の顧客データ取得（アソシエーション含む）
    │
    ├─ jsonEntityEncoder->encode()
    │      └─ 顧客データをシリアライズ
    │
    └─ event->addSuccess(callback)
           │
           └─ [削除成功時]
                  │
                  ├─ salesChannelContextService->get()
                  │      └─ SalesChannelContext構築
                  │
                  └─ eventDispatcher->dispatch(CustomerDeletedEvent)
                         │
                         └─ FlowExecutor (Subscriber)
                                │
                                └─ [設定されたアクション実行]
```

### データフロー図

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

DELETE Request             EntityDeleteEvent
(customer_id) ────────────▶ CustomerBeforeDeleteSubscriber
                                   │
                                   ▼
                            顧客データ取得
                            (削除前にフェッチ)
                                   │
                                   ▼
                            データシリアライズ
                            (jsonEntityEncoder)
                                   │
                                   ▼
                            [削除処理実行]
                                   │
                          ┌────────┴────────┐
                          │成功             │失敗
                          ▼                 ▼
              CustomerDeletedEvent      処理終了
              (serializedCustomer含む)     (イベントなし)
                          │
                          ▼
                    Flow Engine
                          │
                          ▼
                  [設定されたアクション]
                  (メール送信等)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CustomerDeletedEvent.php | `src/Core/Checkout/Customer/Event/CustomerDeletedEvent.php` | ソース | イベントクラス定義 |
| CustomerBeforeDeleteSubscriber.php | `src/Core/Checkout/Customer/Subscriber/CustomerBeforeDeleteSubscriber.php` | ソース | 削除イベントのサブスクライバー |
| CustomerEntity.php | `src/Core/Checkout/Customer/CustomerEntity.php` | ソース | 顧客エンティティ |
| SendMailAction.php | `src/Core/Content/Flow/Dispatching/Action/SendMailAction.php` | ソース | メール送信アクション |
| BusinessEventRegistry.php | `src/Core/Framework/Event/BusinessEventRegistry.php` | ソース | イベント登録 |
| JsonEntityEncoder.php | `src/Core/Framework/Api/Serializer/JsonEntityEncoder.php` | ソース | エンティティのシリアライズ |
