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

## 概要

本ドキュメントは、GitLabにおけるFogBugzからのインポート状態・プロジェクト選択画面の設計を記載したものである。

### 本画面の処理概要

FogBugzから取得したプロジェクト（リポジトリ）一覧を表示し、ユーザーがインポートするプロジェクトを選択・実行できる画面である。ユーザーマッピング設定を反映してインポートを行い、各プロジェクトのインポート状態をリアルタイムで監視できる。

**業務上の目的・背景**：FogBugzインポート画面（No.296）で認証し、ユーザーマッピング画面（No.297）で設定を完了した後、実際にインポートするプロジェクトを選択するための画面である。FogBugzのプロジェクトに関連付けられたケース（Issue）がインポートされる。

**画面へのアクセス方法**：
1. FogBugzインポート画面（No.296）で認証
2. ユーザーマッピング画面（No.297）でマッピングを設定（オプション）
3. 本画面へリダイレクト

**主要な操作・処理内容**：
1. FogBugzプロジェクト一覧を表示
2. インポート先ネームスペースの選択
3. インポート先プロジェクト名のカスタマイズ
4. 「Import」ボタンでインポート実行
5. インポート状態のリアルタイム監視
6. ユーザーマッピングの再設定リンク

**画面遷移**：
- 遷移元：Fogbugzユーザーマッピング画面（No.297）
- 遷移先：インポートされたプロジェクト詳細画面

**権限による表示制御**：
- プロジェクト作成権限を持つユーザーのみがインポートを実行可能
- namespace_idが指定されている場合、そのネームスペースへのインポート権限が必要

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 105 | GitHubインポート | 主機能 | FogBugzからのインポート処理・状態管理 |

## 画面種別

一覧・操作

## URL/ルーティング

```
GET /import/fogbugz/status
GET /import/fogbugz/status.json
POST /import/fogbugz
GET /import/fogbugz/realtime_changes.json
```

ルーティング定義: `config/routes/import.rb`
```ruby
resource :fogbugz, only: [:create, :new], controller: :fogbugz do
  get :status
  post :callback
  get :realtime_changes

  get   :new_user_map,    path: :user_map
  post  :create_user_map, path: :user_map
end
```

## 入出力項目

### 入力項目（リポジトリ選択時）

| 項目名 | 項目ID | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| リポジトリID | repo_id | 整数 | 必須 | インポート対象のFogBugzプロジェクトID |
| 新しい名前 | new_name | 文字列 | 任意 | GitLabでのプロジェクト名（デフォルトは元の名前） |
| 新しいネームスペース | target_namespace | 文字列 | 任意 | インポート先ネームスペース |

### 出力項目（JSON API）

| 項目名 | 説明 |
|--------|------|
| imported_projects | インポート済み/進行中のプロジェクト一覧 |
| provider_repos | インポート可能なプロジェクト一覧 |
| incompatible_repos | 常に空配列（FogBugzでは非互換リポジトリなし） |

## 表示項目

| 項目名 | 説明 |
|--------|------|
| ページタイトル | 「FogBugz import」 |
| FogBugzアイコン | バグアイコン（48px） |
| フォームタイトル | 「Import projects from FogBugz」 |
| ユーザーマップリンク | ユーザーマッピング設定画面へのリンク |
| プロジェクト一覧 | FogBugzプロジェクトのテーブル |
| インポート状態 | 各プロジェクトのインポート進捗状況 |

## イベント仕様

### 1-インポート実行

「Import」ボタンを押下すると以下の処理が実行される：

```ruby
# app/controllers/import/fogbugz_controller.rb (行56-71)
def create
  credentials = { uri: session[:fogbugz_uri], token: session[:fogbugz_token] }

  service_params = params.merge({
    umap: session[:fogbugz_user_map] || client.user_map,
    organization_id: Current.organization.id
  })

  result = Import::FogbugzService.new(client, current_user, service_params).execute(credentials)

  if result[:status] == :success
    render json: ProjectSerializer.new.represent(result[:project], serializer: :import)
  else
    render json: { errors: result[:message] }, status: result[:http_status]
  end
end
```

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

基底クラス`Import::BaseController`の`realtime_changes`アクションにより、3秒間隔でインポート状態を更新。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Importボタン押下 | projects | INSERT | 新規プロジェクトを作成 |
| Importボタン押下 | project_import_data | INSERT | インポートデータを保存 |
| Importボタン押下 | import_states | INSERT | インポート状態を記録 |
| Importボタン押下 | namespaces | INSERT/SELECT | インポート先ネームスペースを取得/作成 |

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

#### projects

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | new_name または プロジェクト名 | プロジェクト名 |
| INSERT | path | プロジェクト名から生成 | URLパス |
| INSERT | namespace_id | target_namespace から取得 | インポート先ネームスペース |
| INSERT | import_type | 'fogbugz' | インポート種別 |
| INSERT | creator_id | current_user.id | 作成者 |

## メッセージ仕様

| メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|-------------|---------------|---------------|---------|
| MSG001 | エラー | You don't have permissions to import this project | 権限不足の場合 |
| MSG002 | エラー | Project {repo} could not be found | プロジェクトが見つからない場合 |
| MSG003 | エラー | Invalid URL: {url} | URLがブロックされている場合 |
| MSG004 | エラー | Fogbugz import failed due to an error: {error} | インポートエラー時 |

## 例外処理

| 例外パターン | 処理内容 |
|-------------|---------|
| FogBugzセッションがない | FogBugzインポート画面（No.296）へリダイレクト |
| プロジェクトが見つからない | 422エラーとエラーメッセージを返却 |
| 権限不足 | 401エラーとエラーメッセージを返却 |
| URLブロック | 400エラーとエラーメッセージを返却 |

## 備考

- フィルタリング機能は無効（`filterable: false`）
- FogBugzインポートでは非互換リポジトリは存在しない
- ユーザーマッピングはセッション保存またはclient.user_mapをフォールバックとして使用
- ユーザーマップ設定画面への「customize」リンクが提供される

---

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

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

### 推奨読解順序

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

FogBugzプロジェクト情報とインポートパラメータの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | fogbugz_controller.rb | `app/controllers/import/fogbugz_controller.rb` | importable_repos（行75-78）、create内のservice_params |
| 1-2 | fogbugz_service.rb | `app/services/import/fogbugz_service.rb` | サービスのパラメータとレスポンス構造 |

**読解のコツ**: umapパラメータにユーザーマッピング情報が渡される。セッションにない場合はclient.user_mapがフォールバック。

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

statusアクションとcreateアクションを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | fogbugz_controller.rb | `app/controllers/import/fogbugz_controller.rb` | status（行50-54）、create（行56-71） |
| 2-2 | base_controller.rb | `app/controllers/import/base_controller.rb` | 親クラスのstatusメソッド |

**主要処理フロー**:
1. **行50-54**: `status`アクション - client.valid?チェック後に親クラスのstatusを呼び出し
2. **行56-71**: `create`アクション - FogbugzServiceでインポート実行

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

画面表示の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | status.html.haml | `app/views/import/fogbugz/status.html.haml` | ユーザーマップリンク、_githubish_statusパーシャル |
| 3-2 | _githubish_status.html.haml | `app/views/import/_githubish_status.html.haml` | 共通インポート状態表示コンポーネント |

**主要処理フロー**:
- **行8-9**: 「customize」リンクでユーザーマッピング画面へ遷移可能
- **行11**: `_githubish_status`パーシャルに`filterable: false`を渡す

#### Step 4: サービスレイヤーを理解する

インポート処理の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | fogbugz_service.rb | `app/services/import/fogbugz_service.rb` | executeメソッド、create_project |

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

```
GET /import/fogbugz/status
    │
    └─ Import::FogbugzController#status
           │
           ├─ client.valid? チェック
           │      └─ 無効な場合: redirect_to new_import_fogbugz_path
           │
           └─ Import::BaseController#status
                  │
                  ├─ serialized_imported_projects
                  │
                  ├─ serialized_provider_repos
                  │      └─ importable_repos (client.repos)
                  │
                  └─ serialized_incompatible_repos (空配列)

POST /import/fogbugz
    │
    └─ Import::FogbugzController#create
           │
           ├─ credentials (uri, token from session)
           │
           ├─ service_params (umap, organization_id)
           │
           └─ Import::FogbugzService#execute
                  │
                  └─ Gitlab::FogbugzImport::ProjectCreator#execute
```

### データフロー図

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

セッション情報     ───▶  Gitlab::FogbugzImport::Client  ───▶  プロジェクト一覧
(token, uri)             #repos                              (JSON)
                                                              │
                                                              ▼
ユーザーマッピング ───▶  Import::FogbugzService        ───▶  Project (作成)
+ ユーザー選択           #execute
(repo_id, umap等)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| fogbugz_controller.rb | `app/controllers/import/fogbugz_controller.rb` | コントローラー | リクエスト処理 |
| status.html.haml | `app/views/import/fogbugz/status.html.haml` | テンプレート | ステータス画面表示 |
| _githubish_status.html.haml | `app/views/import/_githubish_status.html.haml` | パーシャル | インポート状態共通UI |
| fogbugz_service.rb | `app/services/import/fogbugz_service.rb` | サービス | インポート処理 |
| base_controller.rb | `app/controllers/import/base_controller.rb` | コントローラー | 基底クラス |
| project_creator.rb | `lib/gitlab/fogbugz_import/project_creator.rb` | ライブラリ | プロジェクト作成 |
| client.rb | `lib/gitlab/fogbugz_import/client.rb` | ライブラリ | FogBugz APIクライアント |
