# 機能設計書 44-RemoteEvent

## 概要

本ドキュメントは、Symfony RemoteEventコンポーネントの機能設計を記述する。RemoteEventはサードパーティサービスからのリモートイベント受信と処理を容易にする機能を提供するコンポーネントである。

### 本機能の処理概要

RemoteEventコンポーネントは、外部サービスから受信したイベントを統一的なデータ構造（RemoteEvent）で表現し、ConsumerInterfaceを通じて処理する仕組みを提供する。Webhookコンポーネントと連携して、HTTPリクエストとして受信したイベントをMessenger経由で非同期処理する。

**業務上の目的・背景**：現代のマイクロサービスアーキテクチャやSaaS連携では、外部サービスからのイベント通知を受信・処理する必要がある。メール配信サービスのバウンス通知、決済サービスの決済完了通知、CIツールのビルド結果通知など、多様な外部イベントを統一的に処理するための抽象化レイヤーが必要である。

**機能の利用シーン**：Webhookコンポーネント経由で受信したサードパーティイベントの処理、メール配信ステータス（配信成功、バウンス、スパム報告）の処理、決済サービスからの決済ステータス更新、ソーシャルメディアAPIからのイベント受信等。

**主要な処理内容**：
1. RemoteEventオブジェクトによるイベントデータの統一表現（name、id、payload）
2. ConsumerInterfaceによるイベント消費の標準インターフェース定義
3. AsRemoteEventConsumerアトリビュートによるコンシューマーの宣言的登録
4. ConsumeRemoteEventMessageによるMessenger経由の非同期イベント処理
5. PayloadConverterInterfaceによるペイロード変換の拡張ポイント

**関連システム・外部連携**：Webhookコンポーネント（イベント受信のHTTPレイヤー）、Messengerコンポーネント（非同期処理）と密接に連携する。

**権限による制御**：RemoteEventコンポーネント自体には権限制御機構はない。認証・認可はWebhookコンポーネントの署名検証で担保される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | RemoteEventコンポーネントには関連画面はない |

## 機能種別

イベント処理 / データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | Yes | イベント名 | - |
| id | string | Yes | イベントID | - |
| payload | array | Yes | イベントペイロード | - |

### 入力データソース

- Webhookコンポーネント経由のHTTPリクエスト（RequestParser::doParse()の結果）
- Messengerバス経由のConsumeRemoteEventMessage

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| RemoteEvent | RemoteEvent | 統一イベントオブジェクト |
| ConsumeRemoteEventMessage | ConsumeRemoteEventMessage | Messenger用メッセージ |

### 出力先

- ConsumerInterface実装クラス（イベント処理）
- Messengerバス（非同期処理時）

## 処理フロー

### 処理シーケンス

```
1. 外部サービスからのWebhookリクエスト受信
   └─ WebhookController経由でRequestParserが処理
2. RemoteEvent オブジェクトの生成
   └─ name、id、payloadを設定
3. ConsumeRemoteEventMessage の生成
   └─ Webhookのtypeとイベントオブジェクトをラップ
4. Messengerバスへのディスパッチ
   └─ 非同期でConsumerに配信
5. ConsumerInterface::consume(RemoteEvent) の実行
   └─ アプリケーション固有のイベント処理ロジック
```

### フローチャート

```mermaid
flowchart TD
    A[外部サービス] --> B[HTTP POST]
    B --> C[WebhookController]
    C --> D[RequestParser]
    D --> E[RemoteEvent生成]
    E --> F[ConsumeRemoteEventMessage]
    F --> G[MessageBus::dispatch]
    G --> H[ConsumeRemoteEventHandler]
    H --> I[ConsumerInterface::consume]
    I --> J[アプリケーション処理]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-44-01 | イベント不変性 | RemoteEventのname、id、payloadはreadonly | 生成後の変更不可 |
| BR-44-02 | コンシューマー登録 | AsRemoteEventConsumerアトリビュートでコンシューマーを宣言的に登録する | DI設定時 |

### 計算ロジック

特になし。

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

RemoteEventコンポーネント自体はデータベース操作を行わない。ConsumerInterface実装でのDB操作はアプリケーション層の責務。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 例外 | Consumer内での処理エラー | Messengerのリトライ機構で再処理 |

### リトライ仕様

Messenger経由の処理であるため、Messengerのリトライポリシーに従う。

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

該当なし。ConsumerInterface実装でのトランザクション管理はアプリケーション層の責務。

## パフォーマンス要件

- Messenger経由の非同期処理により、Webhookレスポンスの遅延を防止する
- 大量イベント受信時はMessengerワーカーのスケーリングで対応

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

- イベント認証はWebhookコンポーネントの署名検証で担保
- ペイロードの内容検証はConsumerInterface実装で行う

## 備考

- RemoteEventコンポーネントはWebhookコンポーネントと密結合しており、通常はセットで使用する
- PayloadConverterInterfaceにより、サードパーティ固有のペイロード形式を標準形式に変換できる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RemoteEvent.php | `src/Symfony/Component/RemoteEvent/RemoteEvent.php` | イベントのデータ構造（name、id、payload） |

**読解のコツ**: RemoteEventはイミュータブルなValueObjectとして設計されている。コンストラクタで受け取る3つのreadonly プロパティ（**19-23行目**）がすべてのデータを保持する。

#### Step 2: コンシューマーインターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ConsumerInterface.php | `src/Symfony/Component/RemoteEvent/Consumer/ConsumerInterface.php` | イベント消費の標準インターフェース |

**主要処理フロー**:
- **21行目**: consume(RemoteEvent $event): void - イベントを受け取り処理するメソッド

#### Step 3: Messenger統合を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ConsumeRemoteEventMessage | `src/Symfony/Component/RemoteEvent/Messenger/ConsumeRemoteEventMessage.php` | Messenger用メッセージクラス |

#### Step 4: アトリビュート登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AsRemoteEventConsumer | `src/Symfony/Component/RemoteEvent/Attribute/AsRemoteEventConsumer.php` | コンシューマーの宣言的登録 |

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

```
WebhookController::handle()
    |
    └─ RequestParser::parse() → RemoteEvent
           |
           └─ MessageBus::dispatch(ConsumeRemoteEventMessage)
                  |
                  └─ ConsumeRemoteEventHandler::__invoke()
                         |
                         └─ ConsumerInterface::consume(RemoteEvent)
```

### データフロー図

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

HTTP POST           RequestParser                   RemoteEvent
  (JSON payload)    └─ RemoteEvent生成               (name, id, payload)
                         |
                    ConsumeRemoteEventMessage        Consumer処理結果
                    └─ MessageBus                    (アプリケーション依存)
                         |
                    ConsumerInterface
                    └─ consume(RemoteEvent)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RemoteEvent.php | `src/Symfony/Component/RemoteEvent/RemoteEvent.php` | ソース | リモートイベントデータ構造 |
| ConsumerInterface.php | `src/Symfony/Component/RemoteEvent/Consumer/ConsumerInterface.php` | ソース | コンシューマーインターフェース |
| PayloadConverterInterface.php | `src/Symfony/Component/RemoteEvent/PayloadConverterInterface.php` | ソース | ペイロード変換インターフェース |
| Messenger/ | `src/Symfony/Component/RemoteEvent/Messenger/` | ソース | Messenger統合 |
| Attribute/ | `src/Symfony/Component/RemoteEvent/Attribute/` | ソース | PHPアトリビュート定義 |
| Event/ | `src/Symfony/Component/RemoteEvent/Event/` | ソース | イベント関連クラス |
