# 画面設計書 41-メールアドレス追加画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるメールアドレス追加画面の設計仕様を定義したものです。ユーザーが自身のアカウントに新しいメールアドレスを追加するための入力画面について記載しています。

### 本画面の処理概要

本画面は、ユーザーが現在のメールアドレスを変更する際に使用する画面です。ユーザーは新しいメールアドレスを入力し、確認メールの送信を要求することができます。

**業務上の目的・背景**：ユーザーがメールアドレスを変更したい場合、セキュリティを確保しながらスムーズに変更できる仕組みが必要です。本画面はマジックリンク認証を採用しているFizzyにおいて、ユーザーのメールアドレス変更を安全に行うための入り口として機能します。変更後のメールアドレスにも確認メールを送信することで、本人確認を徹底しています。

**画面へのアクセス方法**：プロフィール編集画面（`edit_user_path`）からリンクをクリックしてアクセスします。ヘッダーの戻るリンクからもこの遷移関係が確認できます。

**主要な操作・処理内容**：
1. 新しいメールアドレスを入力フィールドに入力する
2. 「Continue」ボタンをクリックして確認メールの送信を要求する
3. システムは入力されたメールアドレスに確認用のマジックリンクを送信する

**画面遷移**：
- 遷移元：プロフィール編集画面（No.39）
- 遷移先：メールアドレス追加完了画面（No.42）※正常処理時
- 遷移先：メールアドレス追加画面（自画面）※同一アカウント内に既存メールアドレスがある場合

**権限による表示制御**：本画面は認証済みユーザーのみアクセス可能です。また、現在ログイン中のIdentityに紐づくユーザーのみが自身のメールアドレスを変更できます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 71 | メールアドレス変更 | 主機能 | 新しいメールアドレスを追加 |

## 画面種別

登録（フォーム入力）

## URL/ルーティング

- パス: `/users/:user_id/email_addresses/new`
- HTTPメソッド: GET
- ルート名: `new_user_email_address_path`
- コントローラ: `Users::EmailAddressesController#new`

## 入出力項目

| 項目名 | 項目ID | 種別 | 必須 | 形式 | 最大長 | 説明 |
|--------|--------|------|------|------|--------|------|
| メールアドレス | email_address | 入力 | ○ | email | - | 新しいメールアドレス |

## 表示項目

| 項目名 | 説明 | 表示条件 |
|--------|------|----------|
| ページタイトル | "Change your email" | 常時 |
| 戻るリンク | "My profile" | 常時 |
| 説明文 | 確認メール送信の案内文 | 常時 |
| 送信ボタン | "Continue" | 常時 |

## イベント仕様

### 1-戻るリンク押下

ヘッダーの「My profile」リンクをクリックすると、プロフィール編集画面（`edit_user_path`）に遷移します。キーボードショートカット（左矢印キー、Escキー）でも同様の動作が可能です。

### 2-Continueボタン押下

フォームが送信され、以下の処理が実行されます：
1. POSTリクエストが`user_email_addresses_path`に送信される
2. コントローラでレート制限チェック（1時間に5回まで）が行われる
3. 入力されたメールアドレスで既存のIdentityを検索する
4. 同一アカウント内に既にそのメールアドレスを持つユーザーが存在する場合、エラーメッセージを表示して自画面にリダイレクト
5. 存在しない場合、確認用メールを送信し、メールアドレス追加完了画面に遷移

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Continueボタン押下 | identities | SELECT | 入力メールアドレスでIdentity検索 |
| Continueボタン押下 | users | SELECT | 同一アカウント内のユーザー存在確認 |

※ 本画面ではデータベースへの直接的な更新は行われません。メール送信のみが実行され、実際のデータ更新は確認画面（No.43）で行われます。

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

本画面では直接的なデータベース更新はありません。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | 入力案内 | Enter your new email address, then check your email to confirm the change. | 常時表示 |
| MSG-002 | エラー | You already have a user in this account with that email address | 同一アカウント内に既存メールアドレスがある場合 |

## 例外処理

| 例外ケース | 対応 |
|-----------|------|
| レート制限超過（1時間に5回以上） | 429 Too Many Requests応答 |
| ユーザーが見つからない | 404エラー（Current.identityに紐づくユーザーでない場合） |
| 認証されていない | ログイン画面へリダイレクト |

## 備考

- Turboが無効化されており（`data: { turbo: false }`）、従来のフルページリダイレクトが使用される
- フォームにはStimulusコントローラ（`form`）が適用されている
- メールアドレス入力フィールドには`autofocus`が設定されており、画面表示時に自動的にフォーカスされる
- メールアドレスのバリデーションはHTML5のemail型フィールドとrequired属性により行われる

---

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

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

### 推奨読解順序

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

まず、メールアドレス変更に関わるモデルの関係を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | user.rb | `app/models/user.rb` | UserモデルがIdentityに紐づいていること、EmailAddressChangeableモジュールをincludeしていることを確認 |
| 1-2 | identity.rb | `app/models/identity.rb` | Identityがemail_addressを持ち、複数のUsersと関連していることを確認 |
| 1-3 | email_address_changeable.rb | `app/models/user/email_address_changeable.rb` | メールアドレス変更のトークン生成・検証ロジックを理解 |

**読解のコツ**: RailsのConcernパターンでモジュールが分離されています。`include`されているモジュールを追跡することで、機能の全体像を把握できます。

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

処理の起点となるコントローラを特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | email_addresses_controller.rb | `app/controllers/users/email_addresses_controller.rb` | newアクションとcreateアクションの実装を確認 |

**主要処理フロー**:
1. **行3**: `rate_limit to: 5, within: 1.hour, only: :create` - レート制限の設定
2. **行5-6**: `new`アクション - ビューをレンダリング
3. **行8-16**: `create`アクション - メールアドレス重複チェックと確認メール送信
4. **行20-22**: `set_user` - Current.identityに紐づくユーザーの取得

#### Step 3: ビューテンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | new.html.erb | `app/views/users/email_addresses/new.html.erb` | フォーム構造とStimulusコントローラの適用を確認 |

**主要処理フロー**:
- **行14-27**: フォームの構造（POSTでuser_email_addresses_pathに送信）
- **行17**: email_fieldによるメールアドレス入力

#### Step 4: メール送信処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | email_address_changeable.rb | `app/models/user/email_address_changeable.rb` | send_email_address_change_confirmationメソッドの実装 |

**主要処理フロー**:
- **行20-31**: 確認トークンの生成とメール送信処理
- **行41-48**: SignedGlobalIDを使用したトークン生成

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

```
Users::EmailAddressesController#create
    │
    ├─ set_user (before_action)
    │      └─ Current.identity.users.find(params[:user_id])
    │
    ├─ Identity.find_by_email_address(new_email_address)
    │
    ├─ identity.users.exists?(account: @user.account)
    │      └─ 重複チェック
    │
    └─ @user.send_email_address_change_confirmation(new_email_address)
           │
           ├─ generate_email_address_change_token
           │      └─ to_sgid (SignedGlobalID生成)
           │
           └─ UserMailer.email_change_confirmation.deliver_later
```

### データフロー図

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

メールアドレス ───▶ EmailAddressesController#create ───▶ 確認メール送信
(フォーム)                    │                              │
                              ├─▶ Identity検索               ├─▶ create.html.erb
                              │                              │   (成功時)
                              └─▶ 重複チェック               │
                                                             └─▶ new.html.erb + flash
                                                                 (エラー時)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| email_addresses_controller.rb | `app/controllers/users/email_addresses_controller.rb` | コントローラ | 画面制御・ビジネスロジック |
| new.html.erb | `app/views/users/email_addresses/new.html.erb` | ビュー | 入力フォームの表示 |
| create.html.erb | `app/views/users/email_addresses/create.html.erb` | ビュー | 完了画面の表示 |
| user.rb | `app/models/user.rb` | モデル | ユーザーエンティティ |
| identity.rb | `app/models/identity.rb` | モデル | 認証情報エンティティ |
| email_address_changeable.rb | `app/models/user/email_address_changeable.rb` | Concern | メールアドレス変更ロジック |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（行21-23） |
