# 画面設計書 19-メールフォーム作成画面

## 概要

本ドキュメントは、Ruby on Railsフレームワークにおける「メールフォーム作成画面」の設計仕様を定義する。フォーム入力でテストメールを作成し、Action Mailboxのルーティング処理をテストできる開発者向け管理画面である。

### 本画面の処理概要

この画面は、Action Mailboxの開発・テスト用管理インターフェース「Rails Conductor」の一部として、フォーム入力によるテストメールの作成機能を提供する画面である。From、To、CC、BCC、Subject、Body、添付ファイルなどのメールヘッダーと本文を直感的に入力し、InboundEmailを作成することができる。

**業務上の目的・背景**：Action Mailboxを使用したメール受信機能のテストでは、実際のメールサーバーを経由せずにメールを作成・処理する必要がある。この画面は、開発者がGUIフォームで直感的にテストメールを作成できるインターフェースを提供する。RFC822形式のメールソースを手動で記述する必要がなく、簡単にテストメールを作成できる。添付ファイルも追加でき、マルチパートメールのテストも可能。

**画面へのアクセス方法**：開発環境において、`/rails/conductor/action_mailbox/inbound_emails/new`にアクセスすることでこの画面が表示される。または、受信メール一覧画面から"New inbound email by form"リンクをクリックして遷移する。

**主要な操作・処理内容**：
1. 送信者（From）入力 - メールの送信者アドレスを入力
2. 宛先（To）入力 - メールの宛先アドレスを入力
3. CC入力 - CCアドレスを入力
4. BCC入力 - BCCアドレスを入力（ヘッダーに含める設定）
5. X-Original-To入力 - 元の宛先アドレスを入力（転送時などに使用）
6. In-Reply-To入力 - 返信先メッセージIDを入力
7. Subject入力 - 件名を入力
8. Body入力 - 本文を入力
9. 添付ファイル追加 - 複数ファイルの添付が可能
10. メール作成・送信 - フォーム送信でInboundEmailを作成

**画面遷移**：
- 遷移元：受信メール一覧画面（"New inbound email by form"リンク）
- 遷移先：受信メール詳細画面（作成成功後）

**権限による表示制御**：
- 開発環境（`Rails.env.development?`）でのみアクセス可能
- 本番環境ではHTTPステータス403（Forbidden）が返される

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | Action Mailbox | 主機能 | フォーム入力によるテストメール作成処理 |
| 17 | CSRF保護 | 補助機能 | フォーム送信時のCSRFトークン検証 |
| 13 | Active Storage | 補助機能 | 添付ファイルのアップロード処理 |

## 画面種別

登録

## URL/ルーティング

| HTTPメソッド | URL | ルート名 | コントローラー#アクション |
|-------------|-----|---------|------------------------|
| GET | /rails/conductor/action_mailbox/inbound_emails/new | new_rails_conductor_inbound_email | rails/conductor/action_mailbox/inbound_emails#new |
| POST | /rails/conductor/action_mailbox/inbound_emails | rails_conductor_inbound_emails | rails/conductor/action_mailbox/inbound_emails#create |

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | 最大長 | 説明 |
|--------|--------|----------|------|--------|------|
| from | 入力 | String | いいえ | - | 送信者メールアドレス |
| to | 入力 | String | いいえ | - | 宛先メールアドレス |
| cc | 入力 | String | いいえ | - | CCメールアドレス |
| bcc | 入力 | String | いいえ | - | BCCメールアドレス |
| x_original_to | 入力 | String | いいえ | - | X-Original-Toヘッダー |
| in_reply_to | 入力 | String | いいえ | - | In-Reply-Toヘッダー（メッセージID） |
| subject | 入力 | String | いいえ | - | 件名 |
| body | 入力 | Text | いいえ | - | 本文（40x20テキストエリア） |
| attachments | 入力 | File[] | いいえ | - | 添付ファイル（複数選択可） |

## 表示項目

| 項目名 | データ型 | 説明 | ソース |
|--------|----------|------|--------|
| ページタイトル | String | "Deliver new inbound email" | `provide :title` |
| ヘッダー | String | "Deliver new inbound email" | テンプレート固定値 |
| フォーム | HTML | メール作成フォーム | `form_with` |
| 送信ボタン | HTML | "Deliver inbound email" | `form.submit` |

## イベント仕様

### 1-Deliver inbound emailボタン押下

**処理内容**：フォーム入力内容からメールオブジェクトを作成し、InboundEmailを登録する。

**トリガー**："Deliver inbound email"ボタンのクリック

**処理フロー**：
1. フォームがPOSTリクエストを`/rails/conductor/action_mailbox/inbound_emails`に送信
2. CSRFトークンが検証される
3. `InboundEmailsController#create`が実行される
4. `mail_params`でフォームデータを取得
5. `Mail.new`でMailオブジェクトを作成
6. BCCの場合は`include_in_headers = true`を設定
7. 添付ファイルがあれば`mail.add_file`で追加
8. `ActionMailbox::InboundEmail.create_and_extract_message_id!`でInboundEmailを作成
9. 作成したInboundEmailの詳細画面にリダイレクト

**画面遷移**：受信メール詳細画面

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| メール作成 | action_mailbox_inbound_emails | INSERT | InboundEmailレコードを作成 |
| メール作成 | active_storage_blobs | INSERT | メールソースファイルを保存 |
| メール作成 | active_storage_attachments | INSERT | blob関連付けを作成 |

### テーブル別更新項目詳細

#### action_mailbox_inbound_emails

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | 自動採番 | 主キー |
| INSERT | status | 0（pending） | 初期ステータス |
| INSERT | message_id | メールのMessage-IDヘッダー | 自動抽出または生成 |
| INSERT | message_checksum | メールソースのSHA256 | 重複チェック用 |
| INSERT | created_at | 現在時刻 | タイムスタンプ |
| INSERT | updated_at | 現在時刻 | タイムスタンプ |

#### active_storage_blobs

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | key | ランダム生成 | ストレージキー |
| INSERT | filename | "raw_email.eml" | ファイル名 |
| INSERT | content_type | "message/rfc822" | MIMEタイプ |
| INSERT | byte_size | メールソースのバイト数 | ファイルサイズ |
| INSERT | checksum | MD5ハッシュ | チェックサム |

## メッセージ仕様

| メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|-------------|---------------|---------------|----------|
| MSG-001 | 情報 | "Deliver new inbound email" | 常時h1に表示 |

## 例外処理

| 例外種別 | 発生条件 | 処理内容 |
|---------|---------|---------|
| 403 Forbidden | 開発環境以外でのアクセス | HTTPステータス403を返す |
| ActionController::InvalidAuthenticityToken | CSRFトークン不正 | 422エラー |

## 備考

- `form_with`ヘルパーはデフォルトでCSRFトークンを含む
- `local: true`オプションでTurbo/AJAXを無効化し、通常のフォーム送信を使用
- BCCヘッダーは通常メールでは含まれないが、`include_in_headers = true`でテスト用に含める
- 添付ファイルは`multiple: true`で複数選択可能
- `params.expect`メソッドでStrong Parametersを使用

---

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

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

### 推奨読解順序

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

まず、InboundEmailの作成プロセスとMailオブジェクトの関係を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | inbound_email.rb | `actionmailbox/app/models/action_mailbox/inbound_email.rb` | create_and_extract_message_id!メソッド |

**読解のコツ**:
- `create_and_extract_message_id!`はMessageIdモジュールで定義
- メールソースからMessage-IDを抽出し、InboundEmailを作成

#### Step 2: コントローラーを理解する

new/createアクションの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | inbound_emails_controller.rb | `actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller.rb` | newアクション、createアクション |

**主要処理フロー**:
- **11-12行目**: `new`アクションは空のビューを表示
- **18-21行目**: `create`アクションでnew_mailを作成し、InboundEmailを登録
- **24-30行目**: `new_mail`メソッドでMailオブジェクトを構築
- **26行目**: BCCの`include_in_headers`設定
- **27-28行目**: 添付ファイルの追加
- **32-34行目**: `mail_params`でStrong Parametersを定義
- **36-38行目**: `create_inbound_email`でInboundEmailを作成

#### Step 3: テンプレート構造を理解する

フォーム画面のテンプレートを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | new.html.erb | `actionmailbox/app/views/rails/conductor/action_mailbox/inbound_emails/new.html.erb` | フォームテンプレート |

**主要処理フロー**:
- **1行目**: `provide :title`でページタイトルを設定
- **3行目**: h1で"Deliver new inbound email"を表示
- **5行目**: `form_with`でフォームを生成、`scope: :mail`でパラメータをネスト
- **6-8行目**: Fromフィールド（`params[:from]`で初期値設定可能）
- **10-13行目**: Toフィールド
- **14-24行目**: CC、BCC、X-Original-To、In-Reply-To、Subjectフィールド
- **41-44行目**: Bodyテキストエリア（40x20サイズ）
- **46-49行目**: 添付ファイル（multiple: true）
- **51行目**: 送信ボタン

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

```
HTTPリクエスト（GET /rails/conductor/action_mailbox/inbound_emails/new）
    │
    └─ Rails::Conductor::ActionMailbox::InboundEmailsController#new
           │
           └─ render new.html.erb
                  │
                  └─ form_with フォーム表示

HTTPリクエスト（POST /rails/conductor/action_mailbox/inbound_emails）
    │
    ├─ CSRFトークン検証
    │
    └─ Rails::Conductor::ActionMailbox::InboundEmailsController#create
           │
           ├─ mail_params
           │      └─ params.expect(mail: [...])
           │
           ├─ new_mail
           │      │
           │      ├─ Mail.new(mail_params.except(:attachments).to_h)
           │      │
           │      ├─ mail[:bcc]&.include_in_headers = true
           │      │
           │      └─ mail_params[:attachments]&.each do |attachment|
           │             └─ mail.add_file(filename: ..., content: ...)
           │
           ├─ create_inbound_email(mail)
           │      │
           │      └─ ActionMailbox::InboundEmail.create_and_extract_message_id!(mail.to_s)
           │             │
           │             ├─ Message-ID抽出
           │             ├─ Active Storage にメールソース保存
           │             └─ InboundEmail INSERT
           │
           └─ redirect_to rails_conductor_inbound_email_url(inbound_email)
```

### データフロー図

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

フォーム入力 ──────────▶ InboundEmailsController#create
  │                            │
  ├─ from: "user@example.com"  │
  ├─ to: "app@example.com"     ├─ mail_params
  ├─ subject: "Test"           │      │
  ├─ body: "Hello"             │      ▼
  └─ attachments: [file.pdf]   ├─ Mail.new
                               │      │
                               │      ├─ From: user@example.com
                               │      ├─ To: app@example.com
                               │      ├─ Subject: Test
                               │      ├─ Body: Hello
                               │      └─ Attachment: file.pdf
                               │
                               ├─ mail.to_s (RFC822形式)
                               │
                               └─ create_and_extract_message_id!
                                      │
                                      ├─ Message-ID: <xxx@xxx>
                                      │
                                      └─ InboundEmail
                                             │
                                             ├─ INSERT action_mailbox_inbound_emails
                                             ├─ INSERT active_storage_blobs
                                             └─ INSERT active_storage_attachments
                                                    │
                                                    ▼
                                             redirect_to show ──▶ 詳細画面
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| inbound_emails_controller.rb | `actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller.rb` | コントローラー | new/createアクション |
| new.html.erb | `actionmailbox/app/views/rails/conductor/action_mailbox/inbound_emails/new.html.erb` | テンプレート | フォーム表示テンプレート |
| inbound_email.rb | `actionmailbox/app/models/action_mailbox/inbound_email.rb` | モデル | InboundEmailモデル |
| message_id.rb | `actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb` | Concern | create_and_extract_message_id!メソッド |
| routes.rb | `actionmailbox/config/routes.rb` | ルーティング | Action Mailboxルーティング定義 |
| conductor.html.erb | `actionmailbox/app/views/layouts/rails/conductor.html.erb` | レイアウト | Conductorレイアウト |
