# 画面設計書 44-メールアドレス確認エラー画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるメールアドレス確認エラー画面の設計仕様を定義したものです。メールアドレス変更の確認トークンが無効または期限切れの場合に表示されるエラー画面について記載しています。

### 本画面の処理概要

本画面は、メールアドレス変更の確認処理でトークンの検証に失敗した際に表示されるエラー画面です。ユーザーに対して、確認リンクが無効になった理由を説明し、再度メールアドレス変更をリクエストするよう案内します。

**業務上の目的・背景**：セキュリティ上の理由から、メールアドレス変更の確認トークンには30分の有効期限が設けられています。この期限を過ぎた場合や、既に使用されたトークン、改ざんされたトークンなど無効なトークンでアクセスした場合、ユーザーに適切なエラーメッセージを表示し、次のアクションを案内する必要があります。

**画面へのアクセス方法**：メールアドレス確認画面（No.43）でトークン検証に失敗した場合に自動的に遷移します。確認メール内の期限切れリンクをクリックした場合や、無効なトークンでアクセスした場合に表示されます。

**主要な操作・処理内容**：
1. エラーメッセージを表示する
2. 「Change my email address」リンクでメールアドレス追加画面に再遷移する
3. サポートへの連絡方法を案内する

**画面遷移**：
- 遷移元：メールアドレス確認画面（No.43）でのトークン検証失敗時
- 遷移先：メールアドレス追加画面（No.41）

**権限による表示制御**：本画面は認証なしでアクセス可能ですが、表示されるリンクには適切なユーザーコンテキストが必要です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 72 | メールアドレス確認 | 主機能 | 無効なトークンの場合のエラー表示 |

## 画面種別

エラー

## URL/ルーティング

- パス: `/users/:user_id/email_addresses/:token/confirmation`（POSTレスポンス）
- HTTPメソッド: POST（のレスポンスとして表示）
- コントローラ: `Users::EmailAddresses::ConfirmationsController#create`
- ビュー: `app/views/users/email_addresses/confirmations/invalid_token.html.erb`
- HTTPステータス: 422 Unprocessable Entity

## 入出力項目

本画面には入力項目はありません。

## 表示項目

| 項目名 | 説明 | 表示条件 |
|--------|------|----------|
| ページタイトル | "Link expired" | 常時 |
| エラーメッセージ | 確認リンクが期限切れである旨の説明 | 常時 |
| 有効期限情報 | 30分で期限切れになることの説明 | 常時 |
| 再試行リンク | "Change my email address" | 常時 |
| サポート情報 | サポートメールアドレスへのリンク | 常時 |

## イベント仕様

### 1-「Change my email address」リンク押下

メールアドレス追加画面（`new_user_email_address_path`）に遷移します。ユーザーは再度メールアドレス変更をリクエストできます。

### 2-サポートメールリンク押下

デフォルトのメールクライアントが起動し、`support@fizzy.do`宛のメール作成画面が表示されます。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | 本画面ではデータベース更新は行われない |

本画面はエラー表示のみを行い、データベースへの更新は行いません。

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | エラー | That email confirmation link is no longer valid—they expire after 30 minutes. You'll have to try again. | 常時表示 |
| MSG-002 | 案内 | If you get stuck, send us an email and we'll get you back on track. | 常時表示 |

## 例外処理

本画面自体がエラーハンドリング画面のため、追加の例外処理はありません。

## 備考

- 本画面は`render :invalid_token, status: :unprocessable_entity`で表示される
- HTTPステータスコードは422（Unprocessable Entity）
- トークンの有効期限は30分
- サポートメールアドレスは`support@fizzy.do`
- パネルサイズは50ch

---

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

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

### 推奨読解順序

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

本画面で扱うデータ構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | user.rb | `app/models/user.rb` | Userモデルとaccountの関係を確認 |
| 1-2 | email_address_changeable.rb | `app/models/user/email_address_changeable.rb` | トークン有効期限（30分）の定数を確認 |

**読解のコツ**: 本画面はエラー表示のため、直接扱うデータ構造は少ないですが、なぜエラーになるかを理解するためにトークン検証ロジックを確認してください。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | confirmations_controller.rb | `app/controllers/users/email_addresses/confirmations_controller.rb` | createアクションでのエラーハンドリングを確認 |

**主要処理フロー**:
1. **行10-18**: `create`アクション
2. **行11**: `change_email_address_using_token`の戻り値をチェック
3. **行17**: 失敗時に`render :invalid_token, status: :unprocessable_entity`

#### Step 3: トークン検証の失敗条件を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | email_address_changeable.rb | `app/models/user/email_address_changeable.rb` | トークン検証が失敗する条件を確認 |

**主要処理フロー**:
- **行3**: `EMAIL_CHANGE_TOKEN_EXPIRATION = 30.minutes` - 有効期限
- **行7-17**: `change_email_address_using_token` - 検証ロジック
- **行13**: 失敗条件（トークンがnil、ユーザー不一致、旧メールアドレス不一致）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | invalid_token.html.erb | `app/views/users/email_addresses/confirmations/invalid_token.html.erb` | エラー画面の構造を確認 |

**主要処理フロー**:
- **行1**: ページタイトルの設定
- **行7-8**: エラーメッセージ（30分で期限切れ）
- **行11**: 再試行リンク（`new_user_email_address_path`）
- **行13-15**: サポートメールへのリンク

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

```
Users::EmailAddresses::ConfirmationsController#create
    │
    ├─ set_user (before_action)
    │      └─ Current.account.users.active.find(params[:user_id])
    │
    ├─ @user.change_email_address_using_token(token)
    │      │
    │      ├─ SignedGlobalID.parse(token)
    │      │      └─ nil（期限切れ、無効）
    │      │
    │      └─ return false（検証失敗）
    │
    └─ render :invalid_token, status: :unprocessable_entity
           │
           └─ invalid_token.html.erb レンダリング
```

### データフロー図

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

URLパラメータ          ConfirmationsController#create     invalid_token.html.erb
email_address_token ───▶        │                          （エラー画面表示）
（期限切れ/無効）               │                              │
                                ├─▶ SignedGlobalID.parse ───▶ nil / 検証失敗
                                │                              │
                                └─▶ render :invalid_token      │
                                    status: 422                │
                                                               └─▶ @user（再試行リンク用）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| confirmations_controller.rb | `app/controllers/users/email_addresses/confirmations_controller.rb` | コントローラ | エラーハンドリング |
| invalid_token.html.erb | `app/views/users/email_addresses/confirmations/invalid_token.html.erb` | ビュー | エラー画面の表示 |
| email_address_changeable.rb | `app/models/user/email_address_changeable.rb` | Concern | トークン検証ロジック |
| user.rb | `app/models/user.rb` | モデル | ユーザーエンティティ |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（行21-23） |
