# 機能設計書 5-ユーザー確認メール

## 概要

本ドキュメントは、Chatwootシステムにおけるユーザー確認メール機能の設計を記載する。メールアドレス確認ワークフローによるアカウント有効化を実現する。

### 本機能の処理概要

本機能は、新規ユーザー登録時にメールアドレスの所有権を確認するための確認メールを送信し、ユーザーがメール内のリンクをクリックすることでアカウントを有効化する機能を提供する。

**業務上の目的・背景**：メールアドレスの所有権確認は、スパムアカウントの作成防止とユーザーへの確実な連絡手段の確保のために重要である。本機能により、正当なメールアドレスを持つユーザーのみがシステムを利用でき、パスワードリセットや重要通知の到達性を保証する。

**機能の利用シーン**：
- 新規ユーザー登録後のメールアドレス確認
- 確認メールの再送要求
- メールアドレス変更時の再確認

**主要な処理内容**：
1. 確認トークンの生成と確認メール送信
2. 確認トークンの検証
3. ユーザーアカウントの有効化（confirmed_at設定）
4. 確認成功後の自動ログイン

**関連システム・外部連携**：
- メール送信システム（Action Mailer / Devise Mailer）
- Active Job（非同期メール送信）

**権限による制御**：メール確認は認証前の操作であり、権限制御は適用されない。確認トークンの有効性のみで操作を許可する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | メール確認画面 | 主画面 | メールアドレス確認トークンの検証 |
| 3 | サインアップ画面 | 参照画面 | 登録後の確認メール送信トリガー |

## 機能種別

認証処理 / アカウント有効化

## 入力仕様

### 入力パラメータ

#### 確認処理（create）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| confirmation_token | String | Yes | 確認トークン | トークン有効性確認 |

### 入力データソース

- URLパラメータ（確認トークン）
- メール内リンク

## 出力仕様

### 出力データ

#### 確認成功

| 項目名 | 型 | 説明 |
|--------|-----|------|
| access-token | String | APIアクセス用トークン（HTTPヘッダー） |
| client | String | クライアント識別子（HTTPヘッダー） |
| uid | String | ユーザー識別子（HTTPヘッダー） |
| data | Object | ユーザー情報 |

#### 確認失敗

| 項目名 | 型 | 説明 |
|--------|-----|------|
| message | String | エラーメッセージ |
| redirect_url | String | リダイレクト先URL |

### 出力先

- HTTPレスポンスヘッダー（認証トークン）
- HTTPレスポンスボディ（JSON形式）
- データベース（usersテーブル - confirmed_at）

## 処理フロー

### 処理シーケンス

```
【確認メール送信フロー】
1. ユーザー登録
   └─ AccountBuilder.performでユーザー作成
   └─ Devise confirmableモジュールが自動的に確認メール送信

2. 確認トークン生成
   └─ confirmation_token生成
   └─ confirmation_sent_at設定

3. 確認メール送信
   └─ DeviseMailer.confirmation_instructions
   └─ deliver_later（非同期送信）

【確認処理フロー】
4. 確認リンククリック
   └─ /auth/confirmationエンドポイントへリクエスト
   └─ ConfirmationsController#createアクション

5. トークン検証
   └─ User.find_by(confirmation_token: token)
   └─ トークン不正の場合: 422エラー

6. アカウント有効化
   └─ user.confirm
   └─ confirmed_atをTime.nowに設定

7. 自動ログイン
   └─ 認証トークン生成
   └─ HTTPヘッダーにトークン設定
   └─ ユーザー情報返却
```

### フローチャート

```mermaid
flowchart TD
    A[ユーザー登録] --> B[確認トークン生成]
    B --> C[確認メール送信]
    C --> D[ユーザーがメール受信]
    D --> E[確認リンククリック]
    E --> F[ConfirmationsController#create]
    F --> G{トークン有効?}
    G -->|No - トークン不正| H[422: Invalid token]
    G -->|No - 確認済み| I[422: Already confirmed]
    G -->|Yes| J[user.confirm]
    J --> K[confirmed_at設定]
    K --> L[認証トークン生成]
    L --> M[200 OK + 認証情報]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 自動メール送信 | ユーザー作成時に確認メールを自動送信 | confirmableモジュール有効時 |
| BR-002 | 確認済みチェック | 既に確認済みの場合はエラー | 確認処理時 |
| BR-003 | 自動ログイン | 確認成功後は自動的にログイン状態に | 確認成功時 |
| BR-004 | OAuth確認スキップ | OAuthログイン時は確認をスキップ可能 | OmniAuth認証時 |

### 計算ロジック

- **確認トークン生成**: Deviseのconfirmableモジュールが自動生成

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| トークン検索 | users | SELECT | confirmation_token条件でユーザー取得 |
| アカウント有効化 | users | UPDATE | confirmed_at設定 |

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

#### users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | WHERE confirmation_token = :token | トークン検証時 |
| UPDATE | confirmed_at | Time.now | 確認成功時 |
| UPDATE | confirmation_token | nil | 確認成功後（任意） |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 422 | Unprocessable Entity | 確認トークンが無効 | 確認メールの再送を要求 |
| 422 | Unprocessable Entity | 既に確認済み | ログイン画面へ誘導 |
| 422 | Unprocessable Entity | その他のエラー | サポートへ連絡 |

### リトライ仕様

- 確認トークンが無効な場合、確認メールの再送を要求可能
- 再送時は新しい確認トークンが生成される

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

- アカウント有効化は単一トランザクション

## パフォーマンス要件

- 確認処理: 500ms以内
- メール送信: 非同期のため即座にレスポンス返却

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

- 確認トークンは推測困難なランダム文字列
- トークンの有効期限はDevise設定で管理
- 確認済みユーザーへの再確認攻撃を防止

## 備考

- 確認メールのテンプレートは`app/views/devise/mailer/confirmation_instructions.html.erb`
- 確認トークンの有効期限は`config/initializers/devise.rb`の`confirm_within`で設定
- メール再送機能は別途プロフィール設定から利用可能

---

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

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

### 推奨読解順序

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

メール確認関連のデータベースカラムを把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | user.rb | `app/models/user.rb` | confirmation_token, confirmed_at, confirmation_sent_at カラム |

**読解のコツ**:
- 8-10行目: confirmation_sent_at, confirmation_token, confirmed_at カラム定義
- 65行目: :confirmable モジュール（メール確認機能）

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

確認コントローラーの処理フローを把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | confirmations_controller.rb | `app/controllers/devise_overrides/confirmations_controller.rb` | create アクション |

**主要処理フロー**:
1. **6-10行目**: createアクションでトークン検証と確認処理
2. **7行目**: User.find_by(confirmation_token: params[:confirmation_token])でユーザー検索
3. **8行目**: @confirmable.confirmでアカウント有効化
4. **15-17行目**: render_confirmation_successで認証トークン付与
5. **20-27行目**: render_confirmation_errorでエラーハンドリング

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

```
DeviseOverrides::ConfirmationsController#create
    │
    ├─ User.find_by(confirmation_token: token)
    │
    ├─ @confirmable.confirm
    │      └─ confirmed_at = Time.now
    │
    ├─ [成功] render_confirmation_success
    │      ├─ send_auth_headers(@confirmable)
    │      │      └─ 認証トークン生成・HTTPヘッダー設定
    │      └─ render partial: 'devise/auth'
    │
    └─ [失敗] render_confirmation_error
           ├─ [トークン不正] "Invalid token"
           ├─ [確認済み] "Already confirmed"
           └─ [その他] "Failure"
```

### データフロー図

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

【確認メール送信】
ユーザー登録 ─────────▶ Devise confirmable
                              │
                              ▼
                       confirmation_token生成 ────────▶ users (confirmation_token)
                              │
                              ▼
                       DeviseMailer ──────────────────▶ Email (確認リンク)

【確認処理】
confirmation_token ───▶ ConfirmationsController#create
                              │
                              ▼
                       User.find_by(token) ───────────▶ [トークン検証]
                              │
                              ▼
                       user.confirm ──────────────────▶ users (confirmed_at)
                              │
                              ▼
                       send_auth_headers ─────────────▶ HTTPヘッダー (認証トークン)
                              │
                              ▼
                       200 OK + user data ────────────▶ JSON Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| confirmations_controller.rb | `app/controllers/devise_overrides/confirmations_controller.rb` | コントローラー | メール確認API |
| user.rb | `app/models/user.rb` | モデル | 確認関連カラム、confirmableモジュール |
| auth_helper.rb | `app/helpers/auth_helper.rb` | ヘルパー | 認証トークン付与 |
| routes.rb | `config/routes.rb` | 設定 | 確認ルート定義（4行目） |
| confirmation_instructions.html.erb | `app/views/devise/mailer/` | ビュー | 確認メールテンプレート |
| devise.rb | `config/initializers/devise.rb` | 設定 | トークン有効期限等の設定 |
