# 画面設計書 5-セッション転送画面

## 概要

本ドキュメントは、Fizzyアプリケーションのセッション転送画面（`app/views/sessions/transfers/show.html.erb`）の設計仕様を記述したものです。

### 本画面の処理概要

セッション転送画面は、別のデバイスやブラウザから現在のセッションを引き継ぐための中間画面です。転送IDを含むURLにアクセスすると、自動的にフォームが送信され、新しいセッションが開始されます。主にモバイルアプリとWebブラウザ間のセッション共有などに使用されます。

**業務上の目的・背景**：ユーザーが複数のデバイスやブラウザでFizzyを利用する際、再度ログイン操作を行わずにセッションを引き継ぐ仕組みを提供します。転送IDは署名付きで有効期限（4時間）が設定されており、セキュリティを確保しながら利便性を提供しています。QRコードや共有リンクを使用して、認証済みのデバイスから未認証のデバイスへセッションを転送できます。

**画面へのアクセス方法**：転送IDを含むURL（`/session/transfers/:id`）に直接アクセスします。通常、認証済みデバイスで生成された転送リンク（QRコードまたはURL）をスキャン/クリックすることでアクセスします。

**主要な操作・処理内容**：
1. ページ読み込み時に自動的にフォームが送信される（auto-submit）
2. 転送IDが有効な場合、対応するIdentityでセッションが開始される
3. セッションメニュー画面にリダイレクトされる
4. 転送IDが無効な場合は400 Bad Requestが返される

**画面遷移**：
- 遷移元：転送リンク（QRコード、URL）からの直接アクセス
- 遷移先：セッションメニュー画面（`/session/menu`）、エラー時は400レスポンス

**権限による表示制御**：
- 未認証ユーザーのみアクセス可能（認証済みの場合はルートにリダイレクト）
- アカウントスコープは無効化されている

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | サインイン（マジックリンク） | 主機能 | セッション転送処理の実行 |

## 画面種別

処理中間画面（自動送信）

## URL/ルーティング

| 項目 | 値 |
|------|-----|
| URL | `/session/transfers/:id` |
| HTTPメソッド | GET（表示・自動送信）、PUT（セッション作成） |
| コントローラー | `Sessions::TransfersController` |
| アクション | `show`（表示）、`update`（セッション作成） |
| レイアウト | デフォルト（application） |

## 入出力項目

### 入力項目

| No | 項目名 | 物理名 | データ型 | 必須 | 最大長 | 入力形式 | バリデーション | 備考 |
|----|--------|--------|---------|------|--------|----------|---------------|------|
| 1 | 転送ID | :id | string | 必須 | - | URL path | 署名付きID検証 | signed_idで生成・検証 |

### 出力項目

なし（リダイレクトまたはエラー応答）

## 表示項目

| No | 項目名 | 表示条件 | データソース | 備考 |
|----|--------|----------|-------------|------|
| 1 | 自動送信フォーム | 常時 | - | auto_submit_form_withヘルパーで生成 |

## イベント仕様

### 1-ページ読み込み時の自動フォーム送信

**トリガー**: ページ読み込み完了時（auto-submitコントローラーにより自動実行）

**処理フロー**:
1. `Sessions::TransfersController#show`で画面が表示される
2. `auto_submit_form_with`ヘルパーにより、auto-submit Stimulusコントローラーが適用されたフォームが出力される
3. Stimulusコントローラーがページ読み込み時に自動的にフォームを送信（PUT）
4. `Sessions::TransfersController#update`が呼び出される
5. `Identity.find_by_transfer_id(params[:id])`で転送IDを検証
6. 成功時：
   - `start_new_session_for(identity)`でセッション開始
   - セッションメニュー画面（`/session/menu`）にリダイレクト
7. 失敗時：
   - 400 Bad Requestを返却

**レスポンス**:
- 成功時: セッションメニュー画面（`/session/menu`）にリダイレクト
- 失敗時: HTTP 400 Bad Request

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| セッション転送成功 | sessions | INSERT | 新規セッションレコード作成 |

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

#### sessions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | identity_id | 転送IDに紐づくIdentityのID | 外部キー |
| INSERT | user_agent | request.user_agent | ブラウザ情報 |
| INSERT | ip_address | request.remote_ip | IPアドレス |
| INSERT | created_at | 現在日時 | 自動設定 |
| INSERT | updated_at | 現在日時 | 自動設定 |

## メッセージ仕様

| No | メッセージ種別 | メッセージ内容 | 表示条件 |
|----|--------------|---------------|---------|
| なし | - | - | エラー時はHTTPステータスコードのみ |

## 例外処理

| 例外パターン | 対応内容 | 備考 |
|------------|---------|------|
| 無効な転送ID | HTTP 400 Bad Request | find_signedで検証失敗 |
| 期限切れ転送ID | HTTP 400 Bad Request | 4時間で期限切れ |
| 改ざんされた転送ID | HTTP 400 Bad Request | 署名検証失敗 |
| 認証済みユーザーのアクセス | ルートにリダイレクト | require_unauthenticated_access |

## 備考

- 本画面は極めてシンプルで、自動送信フォームのみを表示する
- `auto_submit_form_with`ヘルパーは`auto-submit` Stimulusコントローラーを適用する
- 転送IDは`Identity#transfer_id`メソッドで生成され、`signed_id`を使用して署名される
- 転送IDの有効期限は`TRANSFER_LINK_EXPIRY_DURATION`（4時間）で設定される
- `find_by_transfer_id`は`find_signed`を使用して署名検証と有効期限チェックを行う
- セキュリティ上、転送IDはワンタイムではなく、有効期限内であれば複数回使用可能
- 主にモバイルアプリ連携やクロスデバイス認証に使用される

---

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

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

### 推奨読解順序

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

まず、セッション転送に関わるデータモデルの構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | transferable.rb | `app/models/identity/transferable.rb` | transfer_id生成、find_by_transfer_id、有効期限 |
| 1-2 | identity.rb | `app/models/identity.rb` | IdentityモデルとTransferable concernのinclude |

**読解のコツ**: `signed_id`はRails標準の機能で、IDに署名を付与して有効期限を設定できます。`find_signed`で検証と取得を同時に行います。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | transfers_controller.rb | `app/controllers/sessions/transfers_controller.rb` | show/updateアクション、セッション開始処理 |

**主要処理フロー**:
1. **5-6行目**: `show`アクション - 自動送信フォーム表示のみ
2. **8-15行目**: `update`アクション - 転送ID検証とセッション開始
3. **9行目**: `Identity.find_by_transfer_id(params[:id])` - 署名検証
4. **10行目**: `start_new_session_for identity` - セッション作成
5. **11行目**: `redirect_to session_menu_path` - リダイレクト

#### Step 3: ビューとヘルパーを理解する

画面表示とフォーム自動送信の仕組みを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.erb | `app/views/sessions/transfers/show.html.erb` | 自動送信フォーム |
| 3-2 | forms_helper.rb | `app/helpers/forms_helper.rb` | auto_submit_form_withヘルパー |

**主要処理フロー**:
- **1行目（show.html.erb）**: `auto_submit_form_with method: :put` - 自動送信フォーム
- **2-10行目（forms_helper.rb）**: `auto_submit_form_with` - auto-submitコントローラー適用

#### Step 4: 認証モジュールを理解する

セッション開始処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | authentication.rb | `app/controllers/concerns/authentication.rb` | start_new_session_for、セッションCookie設定 |

**主要処理フロー**:
- **88-92行目**: `start_new_session_for` - 新規セッション作成とCookie設定

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

```
Sessions::TransfersController#show
    │
    └─ auto_submit_form_with (view)
           │
           └─ [auto-submit Stimulus] 自動フォーム送信
                  │
                  └─ Sessions::TransfersController#update
                         │
                         ├─ Identity.find_by_transfer_id(params[:id])
                         │      │
                         │      ├─ find_signed(id, purpose: :transfer)
                         │      │      │
                         │      │      ├─ [検証失敗] return nil
                         │      │      │
                         │      │      └─ [検証成功] return identity
                         │      │
                         │      └─ [nil] head :bad_request
                         │
                         └─ [identity]
                                │
                                ├─ start_new_session_for(identity)
                                │      └─ Session.create!
                                │
                                └─ redirect_to session_menu_path
```

### データフロー図

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

transfer_id ────────▶ TransfersController#show
  (URL param)               │
                            └─▶ 自動送信フォーム表示
                                       │
                                       └─▶ [auto-submit]
                                                  │
                                                  └─▶ TransfersController#update
                                                             │
                                                             ├─▶ find_by_transfer_id
                                                             │        │
                                                             │        ├─[nil]─▶ 400 Bad Request
                                                             │        │
                                                             │        └─[identity]
                                                             │                 │
                                                             │                 └─▶ Session作成
                                                             │
                                                             └─▶ リダイレクト ─▶ /session/menu
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| transfers_controller.rb | `app/controllers/sessions/transfers_controller.rb` | コントローラー | セッション転送の制御 |
| show.html.erb | `app/views/sessions/transfers/show.html.erb` | ビュー | 自動送信フォーム表示 |
| transferable.rb | `app/models/identity/transferable.rb` | Concern | 転送ID生成・検証 |
| identity.rb | `app/models/identity.rb` | モデル | ユーザー識別情報の管理 |
| forms_helper.rb | `app/helpers/forms_helper.rb` | ヘルパー | 自動送信フォームヘルパー |
| authentication.rb | `app/controllers/concerns/authentication.rb` | Concern | 認証共通処理 |
| auto_submit_controller.js | `app/javascript/controllers/auto_submit_controller.js` | Stimulus | 自動送信制御 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
