# 画面設計書 54-エクスポート状況画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるエクスポート状況画面の設計仕様を記述したものである。

### 本画面の処理概要

本画面は、アカウントデータのエクスポート処理が完了した後に、ユーザーがエクスポートファイルをダウンロードするための画面である。

**業務上の目的・背景**：アカウントデータのエクスポートはバックグラウンドジョブで処理されるため、完了後にユーザーにダウンロードリンクを提供する必要がある。本画面はメール通知に含まれるリンクから到達し、ZIPファイル形式のエクスポートデータをダウンロードできる。ダウンロードリンクには24時間の有効期限があり、期限切れの場合は再エクスポートが必要である。

**画面へのアクセス方法**：エクスポート完了メールに含まれるダウンロードリンクをクリックしてアクセスする。URLパス `/account/exports/:id` に直接アクセスすることも可能である。

**主要な操作・処理内容**：
1. エクスポートファイルの自動ダウンロードが開始される
2. 自動ダウンロードが開始されない場合は「Download your data」リンクをクリック
3. ダウンロードリンク期限切れの場合は「request a new export」リンクでアカウント設定画面へ遷移

**画面遷移**：メール内のリンクまたはアカウント設定画面から遷移してくる。戻るリンクでアカウント設定画面に遷移する。ダウンロードリンク期限切れ時は「request a new export」リンクでアカウント設定画面へ遷移する。

**権限による表示制御**：管理者またはオーナー権限を持つユーザーのみアクセス可能。かつ、エクスポートを要求した本人のみがダウンロードできる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 77 | アカウントデータエクスポート | 主機能 | アカウントデータのエクスポート状況を表示 |

## 画面種別

詳細

## URL/ルーティング

| メソッド | パス | アクション |
|---------|------|-----------|
| GET | /account/exports/:id | show（エクスポート詳細/ダウンロード画面） |

## 入出力項目

本画面には入力項目はない（表示のみ）。

## 表示項目

| 項目名 | 説明 |
|--------|------|
| ページタイトル（エクスポート有効時） | "Download Export" |
| ページタイトル（エクスポート期限切れ時） | "Download Expired" |
| 戻るリンク | "Account Settings" - アカウント設定画面へのリンク |
| 案内メッセージ（有効時） | "Your export is ready. The download should start automatically." |
| ダウンロードリンク（有効時） | "Download your data" |
| 期限切れメッセージ | "That download link has expired. You'll need to request a new export." |
| 再エクスポートリンク | "request a new export" |

## イベント仕様

### 1-ページ表示時（自動ダウンロード）

ページ表示時にauto-clickコントローラによりダウンロードリンクが自動的にクリックされる。

1. auto-clickコントローラがダウンロードリンクを自動クリック
2. ブラウザがZIPファイルのダウンロードを開始
3. ファイルはattachment形式でダウンロードされる

### 2-Download your data リンク押下

手動でエクスポートファイルをダウンロードする。

1. rails_blob_pathでActive Storageのダウンロードパスを生成
2. disposition: "attachment"によりファイルダウンロードが開始
3. turbo: falseでTurboを無効化し、通常のダウンロード動作

### 3-Account Settings 戻るリンク押下

アカウント設定画面に遷移する。ホットキー（左矢印・ESC）も対応。

### 4-request a new export リンク押下（期限切れ時）

アカウント設定画面に遷移し、新しいエクスポートを要求できる。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | account_exports | SELECT | エクスポート情報を取得 |
| ダウンロード | active_storage_blobs | SELECT | ファイル情報を取得 |

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

#### account_exports

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id | params[:id] | URLパラメータから取得 |
| SELECT | status | "completed" | 完了ステータスのみ表示 |
| SELECT | user_id | Current.user.id | 要求者のみアクセス可 |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|----------|----------|
| 情報 | Your export is ready. The download should start automatically. | エクスポートが有効な場合 |
| 警告 | That download link has expired. You'll need to request a new export. | エクスポートが期限切れの場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 未ログイン | ログイン画面にリダイレクト |
| 非管理者/非オーナー | 403 Forbidden |
| エクスポートが存在しない | @exportがnilとなり、期限切れ表示 |
| エクスポート要求者以外がアクセス | @exportがnilとなり、期限切れ表示 |
| ダウンロードリンク期限切れ（24時間超過） | 期限切れ表示 |

## 備考

- エクスポートファイルは24時間で期限切れとなる
- エクスポート処理はバックグラウンドジョブ（DataExportJob）で実行
- 完了時にExportMailerからメール通知が送信される
- ファイル形式はZIP（fizzy-account-{account_id}-export-{id}.zip）
- 同時エクスポート制限あり（CURRENT_EXPORT_LIMIT = 10件）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | export.rb | `app/models/export.rb` | Exportモデル基底クラス、ステータス管理、build_laterメソッド |
| 1-2 | account/export.rb | `app/models/account/export.rb` | アカウントエクスポートの具体実装 |

**読解のコツ**: Export基底クラスでステータス（pending/processing/completed/failed）を管理。has_one_attached :fileでActive Storageを使用。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | exports_controller.rb | `app/controllers/account/exports_controller.rb` | showアクションの実装、権限チェック |

**主要処理フロー**:
1. **2行目**: before_action :ensure_admin_or_owner - 管理者/オーナー権限チェック
2. **4行目**: before_action :set_export - エクスポート情報取得
3. **8-9行目**: showアクション - ビュー表示
4. **25-27行目**: set_exportメソッド - completedステータスかつ本人のエクスポートのみ取得

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.erb | `app/views/account/exports/show.html.erb` | 条件分岐による表示切替、自動ダウンロード |

**主要処理フロー**:
- **1-5行目**: @export.present?でページタイトルを切り替え
- **16-22行目**: エクスポート有効時 - 自動ダウンロード案内とリンク
- **19行目**: rails_blob_path + auto-clickコントローラで自動ダウンロード
- **23-24行目**: 期限切れ時 - 再エクスポートリンク

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

```
ブラウザ
    │
    └─ GET /account/exports/:id
           └─ Account::ExportsController#show
                  ├─ ensure_admin_or_owner (before_action)
                  │      └─ Current.user.admin? || Current.user.owner?
                  │
                  └─ set_export
                         └─ Current.account.exports.completed.find_by(
                                id: params[:id], user: Current.user
                            )
                         └─ @export = nil (期限切れ/存在しない場合)
                               または
                            @export = Account::Export (有効な場合)

ダウンロード時:
    │
    └─ GET /rails/active_storage/blobs/:signed_id/:filename
           └─ ActiveStorage::BlobsController#show
                  └─ ファイルダウンロード
```

### データフロー図

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

エクスポートID ─────────▶ ExportsController#show ────────▶ show.html.erb
(URLパラメータ)                  │                              │
                                 ▼                              ▼
                          account_exports              ┌─ 有効時: ダウンロードリンク
                          (SELECT completed)           │   + auto-click
                                 │                     │
                                 ▼                     └─ 期限切れ: 再エクスポートリンク
                          @export (または nil)

ダウンロードリンク ─────▶ ActiveStorage ─────────────▶ ZIPファイルダウンロード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| exports_controller.rb | `app/controllers/account/exports_controller.rb` | コントローラ | エクスポート画面制御 |
| export.rb | `app/models/export.rb` | モデル | エクスポート基底クラス |
| account/export.rb | `app/models/account/export.rb` | モデル | アカウントエクスポート |
| show.html.erb | `app/views/account/exports/show.html.erb` | ビュー | ダウンロード画面 |
| data_export_job.rb | `app/jobs/data_export_job.rb` | ジョブ | エクスポート処理 |
| export_mailer.rb | `app/mailers/export_mailer.rb` | メーラー | 完了通知メール |
| auto_click_controller.js | `app/javascript/controllers/auto_click_controller.js` | Stimulus | 自動クリック |
