# 画面設計書 47-データエクスポート画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるデータエクスポート画面の設計仕様を定義したものです。ユーザーが自身のデータをエクスポートしたファイルをダウンロードするための画面について記載しています。

### 本画面の処理概要

本画面は、ユーザーが自身のデータエクスポートをリクエストした後、エクスポートファイルが準備できた際にダウンロードするための画面です。エクスポートの状態に応じて、ダウンロードリンクの表示または期限切れメッセージの表示を行います。

**業務上の目的・背景**：GDPRなどのプライバシー規制に対応するため、ユーザーは自身のデータをエクスポートする権利を持っています。本画面は、非同期で生成されたエクスポートファイル（ZIPファイル形式）をユーザーがダウンロードするためのインターフェースを提供します。エクスポートファイルには、ユーザーがアクセス可能なすべてのカードとその関連データ（コメント、添付ファイルなど）が含まれます。

**画面へのアクセス方法**：エクスポート完了通知メール内のリンク、またはユーザープロフィール画面（No.38）からアクセスします。URLには特定のエクスポートIDが含まれます。

**主要な操作・処理内容**：
1. エクスポートファイルが存在する場合、自動的にダウンロードが開始される
2. エクスポートファイルが期限切れの場合、再エクスポートへのリンクが表示される
3. 「Download your data」リンクをクリックしてダウンロード（自動ダウンロードが動作しない場合のフォールバック）

**画面遷移**：
- 遷移元：エクスポート完了通知メール / ユーザープロフィール画面（No.38）
- 遷移先：ユーザープロフィール画面（No.38）

**権限による表示制御**：本画面は自分自身のデータエクスポートのみ閲覧可能です（`ensure_current_user`で制御）。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 79 | ユーザーデータエクスポート | 主機能 | 個人のユーザーデータのエクスポート状況を表示 |

## 画面種別

詳細（ダウンロード）

## URL/ルーティング

- パス: `/users/:user_id/data_exports/:id`
- HTTPメソッド: GET
- ルート名: `user_data_export_path`
- コントローラ: `Users::DataExportsController#show`

## 入出力項目

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

## 表示項目

| 項目名 | 説明 | 表示条件 |
|--------|------|----------|
| ページタイトル（成功時） | "Download Export" | エクスポートが存在する場合 |
| ページタイトル（期限切れ時） | "Download Expired" | エクスポートが存在しない場合 |
| 戻るリンク | ユーザー名（user_path） | 常時 |
| ダウンロード案内文 | エクスポート準備完了の案内 | エクスポートが存在する場合 |
| ダウンロードリンク | "Download your data" | エクスポートが存在する場合 |
| 期限切れメッセージ | 再エクスポートへの案内 | エクスポートが存在しない場合 |
| 再エクスポートリンク | "request a new export" | エクスポートが存在しない場合 |

## イベント仕様

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

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

### 2-ダウンロードリンク押下（自動クリック）

エクスポートが存在する場合、画面表示時に`auto-click`コントローラにより自動的にダウンロードが開始されます。手動でクリックすることも可能です。

### 3-再エクスポートリンク押下

エクスポートが期限切れの場合、ユーザープロフィール画面（`user_path`）に遷移し、再度エクスポートをリクエストできます。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | exports | SELECT | エクスポートデータの取得 |

本画面ではデータベースへの更新は行いません。

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | 案内 | Your export is ready. The download should start automatically. | エクスポート存在時 |
| MSG-002 | 案内 | That download link has expired. You'll need to request a new export. | エクスポート期限切れ時 |

## 例外処理

| 例外ケース | 対応 |
|-----------|------|
| 認証されていない | ログイン画面へリダイレクト |
| 他のユーザーのエクスポートにアクセス | 403 Forbidden |
| エクスポートが見つからない | @exportがnilとなり、期限切れ画面を表示 |

## 備考

- エクスポートファイルはActive Storageを使用して保存される
- ダウンロードリンクには`disposition: "attachment"`が設定され、ファイルとして保存される
- `auto-click`コントローラにより自動ダウンロードが試行される
- Turboは無効化されている（`data: { turbo: false }`）
- エクスポートは完了状態（`completed`）のもののみ表示される
- エクスポートファイルの有効期限は24時間

---

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

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

### 推奨読解順序

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

エクスポートに関わるモデルの構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | export.rb | `app/models/export.rb` | Exportモデルの基本構造とステータス管理を確認 |
| 1-2 | data_export.rb | `app/models/user/data_export.rb` | User::DataExportの継承関係とエクスポート内容を確認 |

**読解のコツ**: `Export`は基底クラスで、`User::DataExport`が継承しています。STI（Single Table Inheritance）パターンが使用されています。

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

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

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

**主要処理フロー**:
1. **行2**: `before_action :set_user` - ユーザーの取得
2. **行3**: `before_action :ensure_current_user` - 本人確認
3. **行5**: `before_action :set_export, only: :show` - エクスポートの取得
4. **行9-10**: `show`アクション - ビューをレンダリング
5. **行30-32**: `set_export` - completedステータスのエクスポートを取得

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.erb | `app/views/users/data_exports/show.html.erb` | 条件分岐による表示切り替えを確認 |

**主要処理フロー**:
- **行1-5**: ページタイトルの条件分岐
- **行16-22**: エクスポート存在時のダウンロードリンク
- **行23-24**: 期限切れ時の再エクスポートリンク

#### Step 4: エクスポートモデルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | export.rb | `app/models/export.rb` | ステータス管理とActive Storage連携を確認 |
| 4-2 | data_export.rb | `app/models/user/data_export.rb` | エクスポート対象データの定義を確認 |

**主要処理フロー**:
- **行5**: `has_one_attached :file` - Active Storageでファイルを添付
- **行7**: `enum :status` - pending/processing/completed/failedのステータス
- **行9-10**: `current`/`expired`スコープ - 24時間で期限切れ

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

```
Users::DataExportsController#show
    │
    ├─ set_user (before_action)
    │      └─ Current.account.users.find(params[:user_id])
    │
    ├─ ensure_current_user (before_action)
    │      └─ @user == Current.user チェック
    │
    ├─ set_export (before_action)
    │      └─ @user.data_exports.completed.find_by(id: params[:id])
    │
    └─ show.html.erb レンダリング
           │
           ├─ @export.present?
           │      │
           │      ├─ true ──▶ ダウンロードリンク表示
           │      │              └─ rails_blob_path(@export.file)
           │      │
           │      └─ false ──▶ 期限切れメッセージ表示
           │                     └─ user_path(@user)
```

### データフロー図

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

URL パラメータ         DataExportsController#show         show.html.erb
:user_id, :id ───▶          │                              │
                            ├─▶ User 取得                  ├─ ダウンロードリンク
                            │                              │   （@export存在時）
                            ├─▶ 本人確認                   │
                            │                              └─ 期限切れメッセージ
                            └─▶ Export 取得                    （@export非存在時）
                                 └─ completed のみ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| data_exports_controller.rb | `app/controllers/users/data_exports_controller.rb` | コントローラ | 画面制御・認可チェック |
| show.html.erb | `app/views/users/data_exports/show.html.erb` | ビュー | ダウンロード画面の表示 |
| export.rb | `app/models/export.rb` | モデル | エクスポート基底クラス |
| data_export.rb | `app/models/user/data_export.rb` | モデル | ユーザーデータエクスポート |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（行25） |
