# 通知設計書 3-Notification（基底クラス）

## 概要

本ドキュメントは、Laravel フレームワークにおける通知基底クラス（Notification）の設計仕様を定義する。このクラスはすべての通知クラスの親クラスとして機能し、通知 ID、ロケール設定、ブロードキャストチャネル設定などの共通機能を提供する。

### 本通知の処理概要

Notification クラスは、Laravel の通知システムにおけるすべての通知クラスの基盤となる抽象的な基底クラスである。具体的な通知機能は提供せず、共通のプロパティとメソッドを定義する。

**業務上の目的・背景**：アプリケーションで送信されるすべての通知に共通の機能（一意識別子、多言語対応、シリアライズ機能）を提供する必要がある。この基底クラスにより、各通知クラスはこれらの共通機能を継承し、一貫した通知処理が可能となる。また、キュー処理時のモデルシリアライズにも対応している。

**通知の送信タイミング**：基底クラス自体は直接使用されない。具体的な通知クラス（ResetPassword、VerifyEmail など）がこのクラスを継承し、それぞれのトリガーに応じて送信される。

**通知の受信者**：基底クラス自体は受信者を決定しない。継承先の通知クラスで via() メソッドを実装し、チャネルを指定する。受信者は Notifiable トレイトを使用するモデル（通常は User モデル）が担当する。

**通知内容の概要**：基底クラス自体は通知内容を持たない。継承先の通知クラスで toMail()、toDatabase()、toBroadcast() などのメソッドを実装して内容を定義する。

**期待されるアクション**：開発者はこのクラスを継承して具体的な通知クラスを作成する。via() メソッドで配信チャネルを指定し、各チャネル用のメソッド（toMail 等）で通知内容を定義する。

## 通知種別

基底クラスのため、通知種別は継承先で決定される。broadcastOn() メソッドはデフォルトで空の配列を返す。

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 継承先で ShouldQueue を実装するかどうかで決定 |
| 優先度 | 継承先で指定 |
| リトライ | 継承先で指定 |

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

基底クラスでは送信先を決定しない。継承先の via() メソッドでチャネルを指定し、Notifiable のルーティングメソッドで送信先を決定する。

## 通知テンプレート

### 基底クラスの機能

| 項目 | 内容 |
|-----|------|
| テンプレート | 継承先で定義 |
| ロケール設定 | $locale プロパティと locale() メソッドで設定可能 |
| 通知 ID | $id プロパティで一意識別子を保持 |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| id | 通知の一意識別子 | NotificationSender で UUID 自動生成 | No |
| locale | 通知送信時のロケール | locale() メソッドで設定 | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 継承先依存 | 継承先で定義 | 継承先で定義 | 基底クラス自体はトリガーを持たない |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| shouldSend() が false を返す | 継承先で shouldSend() メソッドを実装した場合 |
| NotificationSending イベントで false を返す | イベントリスナーで送信を抑止可能 |

## 処理フロー

### 通知システム全体のフロー

```mermaid
flowchart TD
    A[Notifiable::notify 呼び出し] --> B[NotificationSender::send]
    B --> C{ShouldQueue 実装?}
    C -->|Yes| D[queueNotification]
    C -->|No| E[sendNow]
    D --> F[SendQueuedNotifications ジョブ]
    F --> E
    E --> G[formatNotifiables]
    G --> H[各 notifiable をループ]
    H --> I[via メソッドでチャネル取得]
    I --> J[withLocale でロケール設定]
    J --> K[UUID で通知 ID 生成]
    K --> L[各チャネルへ送信]
    L --> M[ChannelManager::driver]
    M --> N[Channel::send]
    N --> O[NotificationSent イベント発火]
    O --> P[終了]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | 基底クラス自体はデータベースを参照しない |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | 基底クラス自体はデータベースを更新しない |

**補足**: database チャネルを使用する場合、notifications テーブルへの INSERT が発生するが、これは DatabaseChannel の責務である。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| シリアライズ失敗 | キュー投入時にモデルがシリアライズできない | SerializesModels トレイトの機能で自動対応 |
| チャネル未定義 | via() メソッドが空を返す | 送信処理がスキップされる |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 継承先で ShouldQueue 実装時に指定可能 |
| リトライ間隔 | 継承先で指定可能 |
| リトライ対象エラー | キュー処理の設定に依存 |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限なし | 基底クラスではレート制限を設けない |

### 配信時間帯

継承先で ShouldQueue と delay を組み合わせて制御可能

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

- SerializesModels トレイトにより、キュー処理時にモデルの主キーのみを保存し、処理時に再取得する
- ロケール設定により、ユーザーの言語設定に応じた通知が可能
- 通知 ID (UUID) により、各通知を一意に識別可能

## 備考

- すべてのカスタム通知クラスはこのクラスを継承する必要がある
- php artisan make:notification コマンドで生成されるスケルトンがこのクラスを継承
- broadcastOn() メソッドをオーバーライドしてブロードキャストチャネルを指定可能
- SerializesModels トレイトにより、Eloquent モデルのシリアライズが最適化される

---

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

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

### 推奨読解順序

#### Step 1: 基底クラスの構造を理解する

まず、Notification 基底クラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Notification.php | `src/Illuminate/Notifications/Notification.php` | クラス全体の構造、$id と $locale プロパティ（16-23行目）を確認 |

**読解のコツ**: このクラスは非常にシンプルで、47行しかない。SerializesModels トレイトの使用が重要なポイント。

#### Step 2: SerializesModels トレイトを理解する

キュー処理時のモデルシリアライズの仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SerializesModels.php | `src/Illuminate/Queue/SerializesModels.php` | __serialize() と __unserialize() メソッドの実装を確認 |

**主要処理フロー**:
1. **19-65行目**: __serialize() でプロパティをシリアライズ
2. **30-32行目**: static プロパティはスキップ
3. **35-37行目**: 未初期化プロパティはスキップ
4. **73-100行目**: __unserialize() でプロパティを復元

#### Step 3: NotificationSender での通知 ID 生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | NotificationSender.php | `src/Illuminate/Notifications/NotificationSender.php` | sendNow() と sendToNotifiable() メソッドで通知 ID が設定される仕組みを確認 |

**主要処理フロー**:
- **112行目**: `$notificationId = (string) Str::uuid();` で UUID 生成
- **152-154行目**: `if (! $notification->id) { $notification->id = $id; }` で通知に ID を設定

#### Step 4: ロケール設定の仕組みを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Notification.php | `src/Illuminate/Notifications/Notification.php` | locale() メソッド（41-46行目）でロケールを設定する仕組みを確認 |
| 4-2 | NotificationSender.php | `src/Illuminate/Notifications/NotificationSender.php` | preferredLocale() メソッド（130-137行目）でロケールの優先順位を確認 |

**主要処理フロー**:
- **Notification.php 41-46行目**: locale() メソッドでチェーン可能なロケール設定
- **NotificationSender.php 132行目**: 通知の locale > NotificationSender の locale > notifiable の preferredLocale の順で優先

#### Step 5: ブロードキャスト設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Notification.php | `src/Illuminate/Notifications/Notification.php` | broadcastOn() メソッド（30-33行目）のデフォルト実装を確認 |

**主要処理フロー**:
- **30-33行目**: デフォルトで空の配列を返す。継承先でオーバーライドしてチャネルを指定可能

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

```
Notifiable::notify($notification)
    │
    └─ NotificationSender::send()
           │
           ├─ ShouldQueue 判定
           │      │
           │      └─ queueNotification()
           │             │
           │             └─ SendQueuedNotifications::handle()
           │
           └─ sendNow()
                  │
                  ├─ formatNotifiables()
                  │
                  └─ 各 notifiable をループ
                         │
                         ├─ $notification->via($notifiable) ... チャネル取得
                         │
                         ├─ preferredLocale() ... ロケール決定
                         │      │
                         │      ├─ $notification->locale
                         │      ├─ $this->locale
                         │      └─ $notifiable->preferredLocale()
                         │
                         ├─ Str::uuid() ... 通知 ID 生成
                         │
                         └─ sendToNotifiable()
                                │
                                ├─ $notification->id = $id ... ID 設定
                                │
                                ├─ shouldSendNotification() ... 送信判定
                                │
                                └─ ChannelManager::driver($channel)->send()
```

### データフロー図

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

$notification             ───▶  NotificationSender::send()
(Notification インスタンス)           │
                                    ▼
                            ShouldQueue 判定
                                    │
                    ┌───────────────┴───────────────┐
                    ▼                               ▼
            queueNotification()              sendNow()
                    │                               │
                    ▼                               ▼
            キューへ投入                    各 notifiable ループ
                    │                               │
                    ▼                               ▼
            SerializesModels で            UUID 生成 → $notification->id
            モデルをシリアライズ                     │
                    │                               ▼
                    └──────────▶  sendToNotifiable()
                                        │
                                        ▼
                                Channel::send()  ───▶  通知送信完了
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Notification.php | `src/Illuminate/Notifications/Notification.php` | ソース | 通知基底クラス |
| SerializesModels.php | `src/Illuminate/Queue/SerializesModels.php` | ソース | モデルシリアライズトレイト |
| SerializesAndRestoresModelIdentifiers.php | `src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php` | ソース | モデル識別子の保存・復元 |
| NotificationSender.php | `src/Illuminate/Notifications/NotificationSender.php` | ソース | 通知送信エンジン |
| ChannelManager.php | `src/Illuminate/Notifications/ChannelManager.php` | ソース | チャネル管理 |
| SendQueuedNotifications.php | `src/Illuminate/Notifications/SendQueuedNotifications.php` | ソース | キュー処理ジョブ |
| NotificationServiceProvider.php | `src/Illuminate/Notifications/NotificationServiceProvider.php` | ソース | サービスプロバイダー |
| Notifiable.php | `src/Illuminate/Notifications/Notifiable.php` | ソース | 通知可能トレイト |
| RoutesNotifications.php | `src/Illuminate/Notifications/RoutesNotifications.php` | ソース | 通知ルーティングトレイト |
| HasDatabaseNotifications.php | `src/Illuminate/Notifications/HasDatabaseNotifications.php` | ソース | DB通知トレイト |
