# 画面設計書 169-インポート状態

## 概要

本ドキュメントはGitLabのグループインポート状態画面の設計仕様を記載したものである。

### 本画面の処理概要

グループのインポート処理が進行中であることを表示する待機画面である。インポート完了後は自動的にグループ詳細画面へリダイレクトされる。

**業務上の目的・背景**：グループのエクスポートファイルからインポートを行う際、処理完了までユーザーに進捗状況を伝える必要がある。本画面により、インポート処理が進行中であることをローディングインジケータと案内メッセージで表示し、ユーザーの待機を促す。

**画面へのアクセス方法**：グループインポート開始後に自動的にリダイレクトされる。または直接URL `/{group_path}/-/import` にアクセスする。

**主要な操作・処理内容**：
1. インポート進行中の表示（ローディングインジケータ）
2. 案内メッセージの表示
3. インポート完了時のリダイレクト
4. インポート失敗時のエラー表示とリダイレクト

**画面遷移**：
- 遷移元：グループ作成画面（インポート開始時）
- 遷移先：グループ詳細画面（成功時）、グループ作成画面（失敗時）

**権限による表示制御**：
- グループへのアクセス権限が必要

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 110 | バルクインポート | 主機能 | グループインポート状態の表示 |

## 画面種別

状態表示

## URL/ルーティング

- パス: `/{group_path}/-/import`
- コントローラー: `Groups::ImportsController#show`
- HTTPメソッド: GET

## 入出力項目

| 項目名 | 項目ID | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|--------|----------|------|------|
| グループパス | group_path | 入力 | String | 必須 | 対象グループのパス |
| 継続パラメータ | continue | 入力 | Hash | 任意 | リダイレクト先情報 |

## 表示項目

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| ページタイトル | 固定値 | "Import in progress" |
| ローディングアイコン | gl_loading_icon | スピナーアイコン |
| 案内メッセージ | 固定値 | "Please wait while we import the group for you. Refresh at will." |

## イベント仕様

### 1-ページ読み込み時

インポート状態に応じて表示またはリダイレクトを行う。

- トリガー: ページアクセス
- 処理:
  - インポート完了済み: グループ詳細画面へリダイレクト
  - インポート失敗: グループ作成画面へリダイレクト（エラーメッセージ付き）
  - インポート中: 待機画面を表示

### 2-ページリフレッシュ

ユーザーが手動でページを更新して最新状態を確認。

- トリガー: ブラウザリフレッシュ
- 処理: インポート状態を再確認し、適切な画面へ遷移または継続表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 状態表示 | group_import_states | SELECT | インポート状態の取得 |

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

#### group_import_states

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | status | group_id = グループID | 0:created, 1:started, 2:finished, -1:failed |
| SELECT | last_error | group_id = グループID | エラーメッセージ（最大255文字） |
| SELECT | jid | group_id = グループID | Sidekiqジョブ ID |
| SELECT | user_id | group_id = グループID | インポート実行者 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| MSG001 | 情報 | Import in progress | ページタイトル（常時） |
| MSG002 | 情報 | Please wait while we import the group for you. Refresh at will. | 進行中画面 |
| MSG003 | 成功 | The group was successfully imported. | インポート完了時（リダイレクト先） |
| MSG004 | エラー | Failed to import group: %{error} | インポート失敗時（リダイレクト先） |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| グループ未存在 | 404ページを表示 |
| インポート状態なし | グループ詳細画面へリダイレクト |
| インポート失敗 | グループ作成画面へリダイレクト（エラーメッセージ表示） |

## 備考

- インポート状態はstate_machineで管理（created → started → finished/failed）
- ユーザーは手動でページをリフレッシュして状態を確認可能
- インポート処理はSidekiqのバックグラウンドジョブで実行
- last_errorは最大255文字に切り詰められる（MAX_ERROR_LENGTH = 255）
- ContinueParamsモジュールを使用してリダイレクト先をカスタマイズ可能

---

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

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

### 推奨読解順序

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

インポート状態のデータモデルとステートマシンを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | group_import_state.rb | `app/models/group_import_state.rb` | ステートマシン定義、状態遷移 |

**読解のコツ**:
- `state_machine :status, initial: :created`（行14）でステートマシン開始
- `state`定義（行15-18）で状態値を確認: created(0), started(1), finished(2), failed(-1)
- `event`定義（行20-30）で状態遷移イベントを確認
- `in_progress?`メソッド（行39-41）で進行中判定

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

コントローラーの処理フローを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imports_controller.rb | `app/controllers/groups/imports_controller.rb` | showアクションのリダイレクトロジック |

**主要処理フロー**:
1. **行10**: `@group.import_state.nil? || @group.import_state.finished?`で完了チェック
2. **行11-15**: 完了時は`continue_params[:to]`またはグループ詳細へリダイレクト
3. **行16-18**: 失敗時はグループ作成画面へリダイレクト（エラーメッセージ付き）
4. **行19-21**: 進行中の場合は待機画面を表示

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

HAMLテンプレートの構成を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/groups/imports/show.html.haml` | 待機画面のUI構成 |

**主要処理フロー**:
- `page_title`（行1）でタイトル設定
- `.save-group-loader`（行3）でローダーコンテナ
- `gl_loading_icon`（行6）でスピナー表示
- 案内メッセージ（行9）でリフレッシュ可能を案内

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

```
Groups::ImportsController#show
    │
    ├─ Group#import_state (関連取得)
    │      │
    │      └─ GroupImportState
    │             │
    │             ├─ finished? (状態確認)
    │             │
    │             ├─ failed? (失敗確認)
    │             │
    │             └─ in_progress? (進行中確認)
    │
    ├─ [完了時] redirect_to group_path(@group)
    │
    ├─ [失敗時] redirect_to new_group_path(@group)
    │
    └─ [進行中] View: show.html.haml
           │
           └─ ローディングインジケータ表示
```

### データフロー図

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

URLリクエスト ───▶ ImportsController#show ───▶ 状態判定
                         │
                         ▼
               GroupImportState取得
                         │
                ┌────────┴────────┐
                │                 │
                ▼                 ▼
         完了/失敗判定      進行中判定
                │                 │
                ▼                 ▼
         リダイレクト処理    HAMLテンプレート表示
                │                 │
                ▼                 ▼
    グループ詳細/作成画面   ローディング画面
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| show.html.haml | `app/views/groups/imports/show.html.haml` | テンプレート | 待機画面UI |
| imports_controller.rb | `app/controllers/groups/imports_controller.rb` | コントローラー | リクエスト処理・リダイレクト |
| group_import_state.rb | `app/models/group_import_state.rb` | モデル | インポート状態管理 |
| continue_params.rb | `app/controllers/concerns/continue_params.rb` | Concern | リダイレクト先パラメータ処理 |
| group.rb | `app/models/group.rb` | モデル | グループ関連（import_state関連付け） |
