# 画面設計書 302-一括インポート履歴

## 概要

本ドキュメントは、GitLabの一括インポート（Direct Transfer）履歴表示画面の設計仕様を定義する。

### 本画面の処理概要

本画面は、過去に実行した一括インポート（Direct Transfer）の履歴と、各インポートの詳細な状態・結果を表示するための画面である。特定のインポートジョブに対する詳細情報の確認や、失敗したエンティティの確認が可能である。

**業務上の目的・背景**：一括インポートは大量のデータを移行する処理であり、完了までに時間がかかることがある。また、部分的な失敗が発生する可能性もある。本画面は、インポート処理の進捗状況を追跡し、問題が発生した場合に原因を特定できるようにすることで、移行作業の管理と問題解決を支援する。さらに、プレースホルダーユーザーの再割り当て状況も通知し、インポート後の作業完了を促す。

**画面へのアクセス方法**：
- 一括インポート状態画面の「View history」リンクから遷移
- URLに直接アクセス（`/import/bulk_imports/history`または`/import/bulk_imports/:id/history`）

**主要な操作・処理内容**：
1. 過去のインポートジョブ一覧の表示
2. インポートジョブごとのエンティティ（グループ/プロジェクト）一覧表示
3. 各エンティティのインポート状態（成功/失敗/処理中）の確認
4. 失敗したエンティティの詳細エラー情報の表示
5. プレースホルダーユーザー再割り当てアラートの表示
6. リアルタイム状態更新（ポーリング）

**画面遷移**：
- 遷移元：一括インポート状態画面、ナビゲーションメニュー
- 遷移先：失敗詳細画面、ヘルプドキュメント

**権限による表示制御**：
- ログインユーザー自身が実行したインポートのみ表示される
- 他のユーザーのインポート履歴は参照不可

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 110 | バルクインポート | 主機能 | 一括インポート履歴表示 |

## 画面種別

一覧・詳細画面

## URL/ルーティング

| メソッド | パス | アクション | 説明 |
|---------|------|----------|------|
| GET | `/import/bulk_imports/history` | history | 全履歴一覧表示 |
| GET | `/import/bulk_imports/:id/history` | history | 特定インポートの履歴詳細 |
| GET | `/import/bulk_imports/:id/history/:entity_id/failures` | failures | エンティティの失敗詳細 |
| GET | `/import/bulk_imports/realtime_changes.json` | realtime_changes | リアルタイム状態更新 |

## 入出力項目

### 入力項目（パスパラメータ）

| 項目名 | データ型 | 必須 | 説明 |
|--------|---------|------|------|
| id | Integer | No | BulkImport ID（特定インポートの詳細表示時） |
| entity_id | Integer | No | エンティティID（失敗詳細表示時） |

## 表示項目

### インポートジョブ一覧

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| id | Integer | インポートID |
| created_at | DateTime | 作成日時 |
| status_name | String | 状態（created/started/finished/timeout/failed/canceled） |
| source_url | String | ソースGitLabのURL |
| has_failures | Boolean | 失敗があるか |

### エンティティ一覧

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| id | Integer | エンティティID |
| source_full_path | String | ソースのフルパス |
| destination_slug | String | インポート先スラグ |
| destination_namespace | String | インポート先名前空間 |
| source_type | String | 種別（group_entity/project_entity） |
| status | String | 状態 |
| has_failures | Boolean | 失敗があるか |

### プレースホルダー再割り当てアラート

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| title | String | アラートタイトル |
| body | String | アラート本文（再割り当て待ちの数） |

## イベント仕様

### 1-インポート詳細表示

インポートジョブをクリックすると、`/import/bulk_imports/:id/history`に遷移し、そのインポートに属するエンティティ一覧が表示される。

### 2-失敗詳細表示

失敗したエンティティの「詳細」リンクをクリックすると、`/import/bulk_imports/:id/history/:entity_id/failures`に遷移し、失敗の詳細情報が表示される。

### 3-リアルタイム状態更新

画面表示中は3秒間隔で`/import/bulk_imports/realtime_changes.json`をポーリングし、処理中のインポートの状態を自動更新する。

### 4-Learn more リンク

プレースホルダー再割り当てアラートの「Learn more」ボタンクリック時、ヘルプドキュメント（`/help/user/import/mapping.md#placeholder-users`）に遷移する。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | bulk_imports | SELECT | インポート一覧取得 |
| 画面表示 | bulk_import_entities | SELECT | エンティティ一覧取得 |
| 画面表示 | import_source_users | SELECT | プレースホルダーユーザー状態取得 |
| 画面表示 | bulk_import_failures | SELECT | 失敗情報取得 |

本画面は参照専用であり、データベースへの更新は行わない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| MSG-302-001 | 通知 | Migration history | ページタイトル |
| MSG-302-002 | 情報 | プレースホルダーユーザー再割り当てアラート | 再割り当て待ちのソースユーザーがいる場合 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| インポートIDが存在しない | 404エラー画面を表示 |
| 他ユーザーのインポート | 404エラー画面を表示 |
| エンティティIDが存在しない | 404エラー画面を表示 |

## 備考

- プレースホルダーユーザー再割り当てアラートは`Import::PendingReassignmentAlertPresenter`で制御される
- ポーリング間隔は3秒（`POLLING_INTERVAL = 3_000`）
- 履歴データは実行ユーザーに紐づくため、管理者でも他ユーザーの履歴は参照不可

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | bulk_import.rb | `app/models/bulk_import.rb` | 状態遷移、has_failures判定 |
| 1-2 | entity.rb | `app/models/bulk_imports/entity.rb` | エンティティの状態管理 |
| 1-3 | source_user.rb | `app/models/import/source_user.rb` | プレースホルダーユーザーの状態 |

**読解のコツ**: `namespaces_with_unassigned_placeholders`メソッドでプレースホルダー再割り当て対象の判定ロジックを理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bulk_imports_controller.rb | `app/controllers/import/bulk_imports_controller.rb` | historyアクション、failuresアクション |

**主要処理フロー**:
1. **行54**: `history`アクションは空実装（ビュー描画のみ）
2. **行56-58**: `failures`アクションでエンティティ取得
3. **行88-92**: `bulk_import`メソッドでbefore_actionによる事前取得

#### Step 3: ビューを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | history.html.haml | `app/views/import/bulk_imports/history.html.haml` | Vue.jsマウントポイント、アラート表示ロジック |

**主要処理フロー**:
- **行3-5**: `@bulk_import`の有無でパンくずを切り替え
- **行10-17**: `PendingReassignmentAlertPresenter`でアラート表示制御
- **行19**: Vue.jsアプリのマウント

#### Step 4: プレゼンター層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | pending_reassignment_alert_presenter.rb | `app/presenters/import/pending_reassignment_alert_presenter.rb` | アラート表示条件、本文生成 |

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

```
Import::BulkImportsController
    │
    ├─ #history (GET)
    │      ├─ before_action :bulk_import
    │      │      └─ BulkImport.find(params[:id])
    │      │
    │      └─ View: history.html.haml
    │              ├─ PendingReassignmentAlertPresenter
    │              │      └─ bulk_import.namespaces_with_unassigned_placeholders
    │              │              └─ Import::SourceUser.for_namespace
    │              │
    │              └─ Vue.js #import-history-mount-element
    │
    └─ #failures (GET)
           ├─ bulk_import_entity
           │      └─ @bulk_import.entities.find(params[:entity_id])
           │
           └─ View: failures.html.haml
```

### データフロー図

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

パスパラメータ ───▶ BulkImportsController#history ───▶ 履歴一覧画面
(id: optional)              │
                           ▼
                    BulkImport.find(id)
                           │
                           ▼
                    PendingReassignmentAlertPresenter
                           │
                           ├─ namespaces_with_unassigned_placeholders
                           │      └─ Import::SourceUser取得
                           │
                           ▼
                    Vue.js アプリ描画
                           │
                           ▼
ポーリング ───▶ BulkImportsController#realtime_changes ───▶ 状態更新JSON
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| bulk_imports_controller.rb | `app/controllers/import/bulk_imports_controller.rb` | コントローラー | 画面制御・API提供 |
| history.html.haml | `app/views/import/bulk_imports/history.html.haml` | テンプレート | 履歴画面HTML |
| bulk_import.rb | `app/models/bulk_import.rb` | モデル | インポートジョブ管理 |
| entity.rb | `app/models/bulk_imports/entity.rb` | モデル | インポート対象管理 |
| source_user.rb | `app/models/import/source_user.rb` | モデル | プレースホルダーユーザー管理 |
| pending_reassignment_alert_presenter.rb | `app/presenters/import/pending_reassignment_alert_presenter.rb` | プレゼンター | アラート表示制御 |
| import.rb | `config/routes/import.rb` | ルーティング | URL定義 |
