# 機能設計書 30-通知管理

## 概要

本ドキュメントは、Laravel Frameworkの通知管理機能（ChannelManager）の設計仕様を記載する。ChannelManagerは、メール、SMS、Slack、データベースなど複数のチャネルを通じた通知の送信を統一的に管理するコンポーネントである。

### 本機能の処理概要

ChannelManagerは、様々な通知チャネル（メール、データベース、ブロードキャスト、SMS等）を管理し、Notificationクラスで定義された通知を適切なチャネルに送信する。キュー経由の非同期送信もサポート。

**業務上の目的・背景**：現代のアプリケーションでは、ユーザーへの通知は単一のチャネルでは不十分である。メール通知、プッシュ通知、SMS、アプリ内通知など、複数のチャネルを使い分けることで、ユーザーに確実に情報を届けることができる。ChannelManagerは、これらの複数チャネルへの通知を統一的なAPIで提供し、開発者の負担を軽減する。

**機能の利用シーン**：ユーザー登録完了通知、注文確認通知、パスワードリセット通知、リアルタイムアラート、スケジュールリマインダー、システム障害通知など。

**主要な処理内容**：
1. send()メソッドで通知を送信
2. sendNow()メソッドで同期的に即時送信
3. Notificationクラスのvia()メソッドで送信チャネルを決定
4. 各チャネルドライバ（mail、database、broadcast等）で実際の送信処理
5. NotificationSentイベントの発火

**関連システム・外部連携**：MailChannel（メール送信）、BroadcastChannel（リアルタイム通知）、DatabaseChannel（DB保存）、外部サービス（Slack、Vonage等）との連携。

**権限による制御**：本機能自体には権限制御はない。通知対象はアプリケーションロジックで制御。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | 内部機能 | 通知送信処理 |

## 機能種別

通知管理 / マルチチャネル通知

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| notifiables | Collection/mixed | Yes | 通知対象のエンティティ | Notifiableトレイト使用 |
| notification | Notification | Yes | 通知内容を定義したクラス | Notificationインスタンス |
| channels | array/null | No | 送信チャネルの指定 | 有効なチャネル名 |

### 入力データソース

- アプリケーションで定義されたNotificationクラス
- 通知対象のユーザーモデル等

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| - | void | 通知は非同期で送信されるため戻り値なし |

### 出力先

- メールサーバー（MailChannel）
- データベース（DatabaseChannel）
- ブロードキャストサーバー（BroadcastChannel）
- 外部サービス（Slack、SMS等）

## 処理フロー

### 処理シーケンス

```
1. Notification::send()またはnotify()で通知を開始
   └─ ChannelManager::send()を呼び出し

2. NotificationSender::send()で送信処理
   └─ queueNotification()でキュー経由送信
   └─ または直接sendNow()で同期送信

3. sendToNotifiable()で各通知対象に送信
   └─ via()で送信チャネルを取得
   └─ 各チャネルに対してsendNotification()

4. チャネルドライバで実際の送信
   └─ MailChannel::send()
   └─ DatabaseChannel::send()
   └─ BroadcastChannel::send()

5. NotificationSentイベント発火
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Notification::send]
    B --> C[ChannelManager::send]
    C --> D[NotificationSender::send]
    D --> E{ShouldQueueを実装?}
    E -->|Yes| F[queueNotification]
    E -->|No| G[sendNow]
    F --> H[キューワーカーで処理]
    H --> G
    G --> I[sendToNotifiable]
    I --> J[Notification::via]
    J --> K[チャネルリスト取得]
    K --> L{各チャネル}
    L --> M[ChannelManager::driver]
    M --> N{チャネル種別}
    N -->|mail| O[MailChannel::send]
    N -->|database| P[DatabaseChannel::send]
    N -->|broadcast| Q[BroadcastChannel::send]
    N -->|custom| R[カスタムチャネル::send]
    O --> S[NotificationSent Event]
    P --> S
    Q --> S
    R --> S
    L -->|次のチャネル| L
    S --> T[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | チャネル選択 | via()メソッドで通知対象ごとにチャネルを選択可能 | Notification送信時 |
| BR-02 | キュー送信 | ShouldQueueを実装した通知はキュー経由で非同期送信 | ShouldQueue実装時 |
| BR-03 | ローカライゼーション | locale()で通知の言語を指定可能 | locale指定時 |
| BR-04 | デフォルトチャネル | デフォルトは'mail'チャネル | via()未指定時 |

### 計算ロジック

- チャネル解決: via($notifiable)の戻り値を使用
- ルーティング: Notifiableのメソッド（routeNotificationFor{Driver}）で宛先を取得

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| DB通知保存 | notifications | INSERT | 通知データを保存 |
| 既読マーク | notifications | UPDATE | read_atを更新 |

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

#### notifications テーブル（DatabaseChannel使用時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | type, notifiable_type, notifiable_id, data | 通知クラス名、対象情報、データ | 通知保存 |
| UPDATE | read_at | 現在時刻 | 既読マーク |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgumentException | 設定エラー | 未定義のチャネル | チャネルクラスを確認 |
| Exception | 送信エラー | チャネルでの送信失敗 | 各チャネルの設定を確認 |

### リトライ仕様

キュー経由送信時、キュードライバの設定に基づきリトライを実行。

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

DatabaseChannel使用時、通知の保存はトランザクション外で実行（通知は副作用として扱う）。

## パフォーマンス要件

- 大量通知: キュー経由送信を推奨
- ブロードキャスト: Redis/Pusherとの接続が必要
- データベース通知: インデックスを適切に設定

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

- **通知内容**: 機密情報は適切にマスキング
- **ルーティング**: 通知先アドレスの検証
- **ブロードキャスト**: 認証済みチャネルを使用
- **外部サービス**: API キーの適切な管理

## 備考

- NotificationServiceProviderで自動登録
- Notification Facadeで簡易アクセス可能
- Notifiableトレイトでモデルに通知機能を追加
- カスタムチャネルはクラス名を直接指定可能

---

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

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

### 推奨読解順序

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

まず、契約インターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Dispatcher.php | `src/Illuminate/Contracts/Notifications/Dispatcher.php` | 通知ディスパッチャーの契約 |
| 1-2 | Factory.php | `src/Illuminate/Contracts/Notifications/Factory.php` | チャネルファクトリの契約 |

**読解のコツ**: send()とsendNow()の違いを確認。

#### Step 2: マネージャクラスを理解する

ChannelManagerでのチャネル管理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ChannelManager.php | `src/Illuminate/Notifications/ChannelManager.php` | チャネル管理 |
| 2-2 | NotificationServiceProvider.php | `src/Illuminate/Notifications/NotificationServiceProvider.php` | サービス登録 |

**主要処理フロー**:
- **45-48行目**: send()でNotificationSenderを呼び出し
- **58-61行目**: sendNow()で同期送信
- **69-72行目**: channel()でドライバを取得（driver()のエイリアス）
- **79-82行目**: createDatabaseDriver()でDatabaseChannel生成
- **89-92行目**: createBroadcastDriver()でBroadcastChannel生成
- **99-102行目**: createMailDriver()でMailChannel生成
- **112-123行目**: createDriver()でカスタムチャネルクラスをサポート
- **130-135行目**: resolveNotificationSender()でNotificationSenderを解決

#### Step 3: 送信処理を理解する

NotificationSenderの送信ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | NotificationSender.php | `src/Illuminate/Notifications/NotificationSender.php` | 送信処理 |

#### Step 4: チャネルドライバを理解する

各チャネルの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | MailChannel.php | `src/Illuminate/Notifications/Channels/MailChannel.php` | メール送信 |
| 4-2 | DatabaseChannel.php | `src/Illuminate/Notifications/Channels/DatabaseChannel.php` | DB保存 |
| 4-3 | BroadcastChannel.php | `src/Illuminate/Notifications/Channels/BroadcastChannel.php` | ブロードキャスト |

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

```
NotificationServiceProvider::register()
    │
    └─ ChannelManager (singleton)

$user->notify($notification)
    │
    └─ Notifiable::notify()
           │
           └─ ChannelManager::send()
                  │
                  └─ NotificationSender::send()
                         │
                         ├─ shouldSendNotification() ─── フィルタ
                         │
                         └─ sendToNotifiable()
                                │
                                ├─ $notification->via($notifiable)
                                │
                                └─ foreach channel
                                       │
                                       └─ sendNotification()
                                              │
                                              ├─ ChannelManager::driver()
                                              │
                                              └─ Channel::send()
                                                     │
                                                     ├─ MailChannel
                                                     ├─ DatabaseChannel
                                                     └─ BroadcastChannel
```

### データフロー図

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

Notifiable（ユーザー）
    │
    └─ notify($notification)
           │
           ▼
Notification::via()
    │
    └─ ['mail', 'database', 'broadcast']
           │
           ▼
NotificationSender
    │
    ├─ MailChannel
    │      └─ toMail() ───▶ メールサーバー
    │
    ├─ DatabaseChannel
    │      └─ toDatabase() ─▶ notifications テーブル
    │
    └─ BroadcastChannel
           └─ toBroadcast() ─▶ WebSocket
                                │
                                ▼
                         NotificationSent Event
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ChannelManager.php | `src/Illuminate/Notifications/ChannelManager.php` | ソース | チャネル管理 |
| NotificationSender.php | `src/Illuminate/Notifications/NotificationSender.php` | ソース | 送信処理 |
| Notification.php | `src/Illuminate/Notifications/Notification.php` | ソース | 通知基底クラス |
| MailChannel.php | `src/Illuminate/Notifications/Channels/MailChannel.php` | ソース | メールチャネル |
| DatabaseChannel.php | `src/Illuminate/Notifications/Channels/DatabaseChannel.php` | ソース | DBチャネル |
| BroadcastChannel.php | `src/Illuminate/Notifications/Channels/BroadcastChannel.php` | ソース | ブロードキャスト |
| NotificationServiceProvider.php | `src/Illuminate/Notifications/NotificationServiceProvider.php` | ソース | サービス登録 |
| Notifiable.php | `src/Illuminate/Notifications/Notifiable.php` | ソース | Notifiableトレイト |
| RoutesNotifications.php | `src/Illuminate/Notifications/RoutesNotifications.php` | ソース | ルーティングトレイト |
| HasDatabaseNotifications.php | `src/Illuminate/Notifications/HasDatabaseNotifications.php` | ソース | DB通知トレイト |
| Dispatcher.php | `src/Illuminate/Contracts/Notifications/Dispatcher.php` | インターフェース | 契約定義 |
| Factory.php | `src/Illuminate/Contracts/Notifications/Factory.php` | インターフェース | 契約定義 |
