# 機能設計書 10-Action Mailbox

## 概要

本ドキュメントは、Ruby on RailsフレームワークにおけるAction Mailboxの機能設計を記述する。Action Mailboxは、受信メール処理フレームワークとしてRailsアプリケーション内で受信メールを受け取り処理するコンポーネントである。

### 本機能の処理概要

Action Mailboxは、外部メールサービスからの受信メールをRailsアプリケーション内でルーティング・処理するためのフレームワークである。

**業務上の目的・背景**：Webアプリケーションでは、メール返信によるチケット更新、メールによるタスク作成、メールベースのコマンド処理等、受信メールをトリガーとした処理が必要となることがある。Action Mailboxは、様々な外部メールサービス（Mailgun、Mandrill、Postmark、SendGrid等）からの受信メールを統一的なインターフェースで処理する基盤を提供する。メールのルーティング、処理状態の追跡、自動削除（incineration）等の機能により、メール処理の実装を簡素化する。

**機能の利用シーン**：
- メール返信によるサポートチケットの更新
- メールによるタスク・イシューの作成
- メールベースのボットコマンド処理
- メールによるドキュメントアップロード
- 受信メールのログ・監査

**主要な処理内容**：
1. 外部メールサービス（Ingress）からのメール受信
2. InboundEmailモデルでのメール永続化
3. ApplicationMailboxでのルーティング定義
4. Mailboxクラスでのメール処理
5. 処理状態の追跡（pending、processing、delivered、bounced、failed）
6. 処理済みメールの自動削除（incineration）
7. コールバックによるメール処理前後のフック

**関連システム・外部連携**：
- Mailgun: メール受信Ingress
- Mandrill: メール受信Ingress
- Postmark: メール受信Ingress
- SendGrid: メール受信Ingress
- Active Storage: 添付ファイル保存
- Active Record: InboundEmailモデル

**権限による制御**：Ingressエンドポイントは各サービス固有の認証（パスワード、API署名等）で保護される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | 受信メール一覧画面 | 主機能 | InboundEmail一覧の取得・表示処理 |
| 18 | 受信メール詳細画面 | 主機能 | InboundEmailの詳細情報取得・表示処理 |
| 19 | メールフォーム作成画面 | 主機能 | フォーム入力によるテストメール作成処理 |
| 20 | メールソース作成画面 | 主機能 | RFC822形式メールソースからのInboundEmail作成処理 |

## 機能種別

受信メール処理フレームワーク / メールルーティング

## 入力仕様

### 入力パラメータ

#### Ingress（メール受信）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| raw_email | String | Yes | RFC822形式のメールソース | 有効なメール形式 |
| password | String | Yes（一部） | Ingress認証パスワード | 設定値と一致 |

#### routing（ルーティング定義）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| matcher | Regexp/String/Proc | Yes | マッチング条件 | - |
| mailbox | Symbol | Yes | 処理先Mailboxクラス名 | 存在するMailbox |

### 入力データソース

- 外部メールサービスからのWebhook
- Rails Conductorからの手動入力
- リレーサーバーからの転送

## 出力仕様

### 出力データ

#### InboundEmail

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | レコードID |
| status | String | 処理状態（pending/processing/delivered/bounced/failed） |
| message_id | String | メールのMessage-ID |
| message_checksum | String | メール内容のチェックサム |

#### process

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | void | 処理完了（例外時はfailed状態） |

### 出力先

- action_mailbox_inbound_emails テーブル
- Active Storageブロブ（メール本体）
- アプリケーション固有のデータストア

## 処理フロー

### 処理シーケンス（メール受信・処理）

```
1. Ingressでメール受信
   └─ 各サービス固有のコントローラでWebhookを受信
2. InboundEmail作成
   └─ メールをActive Storageに保存し、レコード作成
3. ルーティング実行
   └─ ApplicationMailboxでマッチングルールを評価
4. Mailbox特定
   └─ マッチしたMailboxクラスを特定
5. before_processingコールバック
   └─ 処理前のフック実行
6. processメソッド実行
   └─ メール内容に基づいた処理
7. after_processingコールバック
   └─ 処理後のフック実行
8. 状態更新
   └─ delivered/bounced/failedに更新
9. incineration（自動削除）
   └─ 設定期間後にメールデータを削除
```

### フローチャート

```mermaid
flowchart TD
    A[Webhook受信] --> B[Ingress認証]
    B --> C{認証成功?}
    C -->|Yes| D[InboundEmail作成]
    C -->|No| E[401 Unauthorized]
    D --> F[RoutingJob]
    F --> G{ルートマッチ?}
    G -->|Yes| H[Mailbox.receive]
    G -->|No| I[delivered状態]
    H --> J[before_processing]
    J --> K{継続?}
    K -->|Yes| L[process実行]
    K -->|No| M[bounced状態]
    L --> N{成功?}
    N -->|Yes| O[delivered状態]
    N -->|No| P[failed状態]
    O --> Q[IncinerationJob]
    M --> Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ルーティング優先順位 | 先に定義されたルートが優先 | ルーティング時 |
| BR-002 | :all ルート | すべてのメールにマッチするフォールバック | 他のルートにマッチしない場合 |
| BR-003 | 自動削除 | incinerate_after期間（デフォルト30日）後に削除 | delivered/bounced後 |
| BR-004 | 重複防止 | message_idで同一メールの重複処理を防止 | メール受信時 |
| BR-005 | 状態遷移 | pending -> processing -> delivered/bounced/failed | 処理中 |

### 計算ロジック

**メッセージチェックサム**：
```ruby
Digest::SHA256.hexdigest(mail.raw_source)
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 受信 | action_mailbox_inbound_emails | INSERT | InboundEmail作成 |
| 処理 | action_mailbox_inbound_emails | UPDATE | status更新 |
| 削除 | action_mailbox_inbound_emails | DELETE | incineration時 |
| 添付 | active_storage_blobs | INSERT | メール本体保存 |

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

#### action_mailbox_inbound_emails テーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | status | 'pending' | 初期状態 |
| UPDATE | status | 'processing'/'delivered'/'bounced'/'failed' | 処理状態更新 |
| DELETE | - | incinerateメソッド実行時 | 関連するActive Storageブロブも削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | Unauthorized | Ingress認証失敗 | パスワード/認証設定を確認 |
| - | ActiveRecord::RecordInvalid | InboundEmail作成失敗 | バリデーションエラーを確認 |
| - | 各種例外 | process内でのエラー | rescue_fromでハンドリング |

### リトライ仕様

RoutingJobはActive Jobのリトライ機能を利用可能。processメソッド内での例外はfailed状態となり、手動での再処理（reroute）が可能。

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

InboundEmailの状態更新はトランザクション内で行われる。processメソッド内のトランザクションはアプリケーション側で制御。

## パフォーマンス要件

- メール受信は非同期ジョブで処理
- 大量メール処理時はキューのスケーリングを検討
- 添付ファイルのサイズ制限を設定推奨

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

- Ingressエンドポイントの認証（パスワード/API署名）
- HTTPS必須（SSL/TLS）
- スパムメールのフィルタリング
- 添付ファイルのウイルスチェック検討
- 機密メールの適切な削除期間設定

## 備考

Action Mailboxは `actionmailbox` gem として提供される。Mailgun、Mandrill、Postmark、SendGridなどと連携可能。

---

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

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

### 推奨読解順序

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

Action Mailboxのモジュール構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | action_mailbox.rb | `actionmailbox/lib/action_mailbox.rb` | モジュール定義と設定オプション |

**読解のコツ**: `mattr_accessor` で定義された設定オプションを把握する。

**主要処理フロー**:
- **13-26行目**: ActionMailboxモジュールの定義
- **20行目**: ingressの設定
- **22行目**: incinerateの設定（デフォルトtrue）
- **23行目**: incinerate_afterの設定（デフォルト30日）

#### Step 2: InboundEmailモデルを理解する

受信メールのデータモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | inbound_email.rb | `actionmailbox/app/models/action_mailbox/inbound_email.rb` | InboundEmailモデルの実装 |

#### Step 3: Baseクラスを理解する

Mailboxの基底クラスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | base.rb | `actionmailbox/lib/action_mailbox/base.rb` | ActionMailbox::Baseの構成 |

**主要処理フロー**:
- **9-65行目**: クラスドキュメント。ルーティングとMailbox定義の説明
- **66-68行目**: include文。Rescuable、Callbacks、Routingのinclude
- **75-77行目**: receiveメソッド。Mailboxの受信処理エントリーポイント
- **83-94行目**: perform_processing。処理実行と状態追跡
- **104-108行目**: bounce_withメソッド。バウンスメール送信

#### Step 4: Routerを理解する

メールルーティングを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | router.rb | `actionmailbox/lib/action_mailbox/router.rb` | Routerクラス |
| 4-2 | routing.rb | `actionmailbox/lib/action_mailbox/routing.rb` | Routingモジュール |

#### Step 5: Ingressを理解する

外部サービスからのメール受信を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | base_controller.rb | `actionmailbox/app/controllers/action_mailbox/base_controller.rb` | Ingress基底コントローラ |

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

```
ActionMailbox::Ingresses
    │
    ├─ Mailgun::InboundEmailsController
    ├─ Mandrill::InboundEmailsController
    ├─ Postmark::InboundEmailsController
    ├─ SendGrid::InboundEmailsController
    └─ Relay::InboundEmailsController
           │
           ▼
ActionMailbox::InboundEmail
    │
    ├─ create_and_extract_message_id!
    ├─ route
    │      └─ ActionMailbox::Router
    │             └─ マッチング評価
    │
    └─ ActionMailbox::RoutingJob
           │
           ▼
ApplicationMailbox
    │
    └─ routing 定義
           │
           ▼
CustomMailbox < ApplicationMailbox
    │
    ├─ before_processing
    ├─ process
    └─ after_processing
```

### データフロー図

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

Webhook ───▶ Ingress Controller ───▶ 認証チェック
       │                                  │
       ▼                                  ▼
RFC822メール ───▶ InboundEmail.create ───▶ Active Storage
       │                                  │
       ▼                                  ▼
メールヘッダ ───▶ Router.route ───▶ Mailbox選択
       │                            │
       ▼                            ▼
メール本文 ───▶ Mailbox.process ───▶ アプリケーション処理
       │
       ▼
status更新 ───▶ delivered/bounced/failed ───▶ Incineration
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| action_mailbox.rb | `actionmailbox/lib/action_mailbox.rb` | ソース | モジュールエントリーポイント |
| base.rb | `actionmailbox/lib/action_mailbox/base.rb` | ソース | Mailbox基底クラス |
| router.rb | `actionmailbox/lib/action_mailbox/router.rb` | ソース | ルーティングエンジン |
| routing.rb | `actionmailbox/lib/action_mailbox/routing.rb` | ソース | ルーティングDSL |
| callbacks.rb | `actionmailbox/lib/action_mailbox/callbacks.rb` | ソース | コールバック |
| inbound_email.rb | `actionmailbox/app/models/action_mailbox/inbound_email.rb` | ソース | InboundEmailモデル |
| routing_job.rb | `actionmailbox/app/jobs/action_mailbox/routing_job.rb` | ソース | ルーティングジョブ |
| incineration_job.rb | `actionmailbox/app/jobs/action_mailbox/incineration_job.rb` | ソース | 削除ジョブ |
| base_controller.rb | `actionmailbox/app/controllers/action_mailbox/base_controller.rb` | ソース | Ingress基底コントローラ |
| routes.rb | `actionmailbox/config/routes.rb` | 設定 | Ingressルーティング |
