# 機能設計書 48-Nodemailerアダプター

## 概要

本ドキュメントは、Payload CMSにおけるNodemailerメールアダプター（email-nodemailer）の設計を記載する。本パッケージは、Nodemailerを使用してPayloadからのメール送信を実現するアダプターを提供する。

### 本機能の処理概要

**業務上の目的・背景**：Payloadはユーザーパスワードリセットやカスタムメール通知などでメール送信が必要となる。本アダプターは、広く使われているNodemailerライブラリを統合し、SMTP、SendGrid、SESなど多様なメールサービスとの連携を可能にする。

**機能の利用シーン**：
- パスワードリセットメールの送信
- アカウント確認メールの送信
- カスタム通知メールの送信
- 開発環境でのテストメール（Ethereal）

**主要な処理内容**：
1. SMTPトランスポートの設定
2. カスタムトランスポートの受け入れ
3. トランスポート未設定時のEtherealテストアカウント自動生成
4. トランスポートの検証（verify）
5. メール送信（sendMail）

**関連システム・外部連携**：
- Nodemailer
- SMTPサーバー
- Ethereal（テストメール）
- SendGrid、SES等（Nodemailerサポートサービス）

**権限による制御**：
- 特になし（メール送信自体に権限制御なし）

## 関連画面

本機能は管理画面との直接的な関連はない（バックエンド処理）。

## 機能種別

外部連携 / メール送信

## 入力仕様

### 入力パラメータ（nodemailerAdapter設定）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| defaultFromAddress | string | Yes* | 送信元メールアドレス | *設定時必須 |
| defaultFromName | string | Yes* | 送信元名 | *設定時必須 |
| transport | Transporter | No | カスタムNodemailerトランスポート | - |
| transportOptions | SMTPConnection.Options | No | SMTP接続オプション | - |
| skipVerify | boolean | No | トランスポート検証のスキップ | デフォルト: false |

### 入力パラメータ（sendEmail）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| to | string | Yes | 宛先 | 必須 |
| subject | string | Yes | 件名 | 必須 |
| html | string | No | HTMLボディ | - |
| text | string | No | テキストボディ | - |
| from | string | No | 送信元（デフォルト使用） | - |

### 入力データソース

- Payload設定ファイルでのアダプター設定
- Payloadからのメール送信リクエスト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| response | object | Nodemailerの送信結果 |

### 出力先

- SMTPサーバー（メール送信）
- Ethereal（テスト環境）
- コンソール（Etherealアカウント情報）

## 処理フロー

### 処理シーケンス

```
1. nodemailerAdapter呼び出し
   └─ buildEmail実行
2. トランスポートの設定
   ├─ transportが渡された場合 → そのまま使用
   ├─ transportOptionsが渡された場合 → nodemailer.createTransport
   └─ どちらも未設定 → createMockAccount（Ethereal）
3. トランスポートの検証
   └─ skipVerify=falseの場合 → transport.verify()
4. EmailAdapterオブジェクトの返却
5. sendEmail呼び出し時
   └─ transport.sendMail実行
```

### フローチャート

```mermaid
flowchart TD
    A[nodemailerAdapter呼び出し] --> B{emailConfig設定済み?}
    B -->|No| C[createMockAccount]
    B -->|Yes| D{transport設定済み?}
    D -->|Yes| E[transportを使用]
    D -->|No| F{transportOptions設定済み?}
    F -->|Yes| G[nodemailer.createTransport]
    F -->|No| C
    C --> H[Etherealアカウント生成]
    H --> I[アカウント情報をログ出力]
    E --> J{skipVerify?}
    G --> J
    I --> J
    J -->|No| K[transport.verify]
    J -->|Yes| L[EmailAdapterオブジェクト返却]
    K --> L
    L --> M[sendEmailメソッド提供]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | デフォルト送信元 | defaultFromNameとdefaultFromAddressから送信元を構成 | from未指定時 |
| BR-02 | Ethereal自動生成 | トランスポート未設定時はEtherealテストアカウントを自動生成 | 開発環境 |
| BR-03 | トランスポート検証 | skipVerify=falseの場合はverify()を実行 | デフォルト動作 |
| BR-04 | Etherealログ出力 | テストアカウントのURLとCredentialをコンソール出力 | Ethereal使用時 |

### 計算ロジック

送信元アドレスの構成:
```typescript
`${defaultFromName} <${defaultFromAddress}>`
```

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

本アダプターはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvalidConfiguration | Etherealアカウント作成失敗 | ネットワーク接続を確認 |
| - | Error | トランスポート検証失敗 | SMTP設定を確認 |
| - | Error | メール送信失敗 | SMTPサーバー/認証情報を確認 |

### リトライ仕様

アダプターレベルでのリトライは未実装。Nodemailerまたは呼び出し側でのリトライを推奨。

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

該当なし

## パフォーマンス要件

- 非同期でのメール送信
- transport.verify()はアプリ起動時のみ実行

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

- SMTP認証情報は環境変数等でセキュアに管理
- Etherealは開発環境専用（本番使用禁止）
- SSL/TLSの使用推奨

## 備考

- Ethereal（ethereal.email）はテスト用のフェイクSMTPサービス
- 本番環境では実際のSMTPサーバーまたはメールサービスの設定が必要

---

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

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

### 推奨読解順序

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

アダプターの全体構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/email-nodemailer/src/index.ts` | nodemailerAdapter関数 |

**主要処理フロー**:
1. **9-15行目**: NodemailerAdapterArgsの型定義
2. **24-41行目**: nodemailerAdapter関数
3. **27行目**: buildEmailの呼び出し
4. **29-39行目**: EmailAdapterオブジェクトの返却
5. **43-80行目**: buildEmail関数
6. **82-88行目**: verifyTransport関数
7. **93-126行目**: createMockAccount関数

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

```
nodemailerAdapter (index.ts)
    │
    └─ buildEmail
           ├─ (引数なし) createMockAccount
           │      └─ nodemailer.createTestAccount
           │      └─ nodemailer.createTransport
           │
           ├─ (transport指定) → そのまま使用
           │
           ├─ (transportOptions指定)
           │      └─ nodemailer.createTransport
           │
           └─ verifyTransport (skipVerify=false時)
                  └─ transport.verify
```

### データフロー図

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

アダプター設定 ──────────▶ nodemailerAdapter ─────────▶ buildEmail
                              │                              │
                              ▼                              ▼
                         トランスポート生成 ────────▶ EmailAdapterオブジェクト

[メール送信時]
sendEmailリクエスト ─────▶ transport.sendMail ────────▶ SMTPサーバー
                              │
                              ▼
                         送信結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/email-nodemailer/src/index.ts` | ソース | エントリーポイント |
