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

## 概要

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

### 本画面の処理概要

**業務上の目的・背景**：Giteaインポート状態画面は、ユーザーがGiteaサーバーからインポート可能なリポジトリを一覧表示し、インポート対象を選択・実行するための画面である。Giteaサーバーからの移行作業において、どのリポジトリをインポートするか選択し、インポート進捗を確認するという業務ニーズに対応する。

**画面へのアクセス方法**：Giteaインポート画面（new）から認証成功後に自動的に遷移する。または直接 `/import/gitea/status` にアクセスする（認証済みの場合）。

**主要な操作・処理内容**：
1. Giteaリポジトリの一覧を表示する
2. インポート先のネームスペースを選択する
3. プロジェクト名を変更する（任意）
4. 個別リポジトリのインポートを開始する
5. インポート進捗をリアルタイムで確認する
6. インポート済みプロジェクトを表示する

**画面遷移**：
- 遷移元：Giteaインポート画面
- 遷移先：プロジェクト詳細画面（インポート完了時）

**権限による表示制御**：
- ログインユーザーのみアクセス可能
- namespace_id 指定時、そのネームスペースへのインポート権限が必要
- ユーザーのネームスペース選択権限（can_select_namespace）に応じた表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 105 | GitHubインポート | 主機能 | Giteaインポート状態の表示と実行（GitHubインポート機能を継承） |

## 画面種別

一覧 / 操作

## URL/ルーティング

| メソッド | パス | コントローラー#アクション | 説明 |
|----------|------|---------------------------|------|
| GET | `/import/gitea/status` | `import/gitea#status` | 状態画面表示（HTML） |
| GET | `/import/gitea/status.json` | `import/gitea#status` | リポジトリ一覧取得（JSON） |
| POST | `/import/gitea` | `import/gitea#create` | インポート開始 |
| GET | `/import/gitea/realtime_changes.json` | `import/gitea#realtime_changes` | 進捗更新取得 |

## 入出力項目

### リポジトリ一覧取得（status.json）

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| フィルタ | filter | String | No | リポジトリ名フィルタ |

### インポート開始（create）

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| リポジトリID | repo_id | Integer | Yes | GiteaリポジトリID |
| 新しい名前 | new_name | String | No | インポート後のプロジェクト名 |
| ターゲットネームスペース | target_namespace | String | Yes | インポート先ネームスペースパス |

## 表示項目

| 項目名 | 説明 |
|--------|------|
| ページタイトル | 「Gitea import」 |
| Giteaアイコン | Giteaロゴの表示 |
| 「Import projects from Gitea」見出し | 見出しテキスト |
| リポジトリ一覧 | インポート可能なリポジトリリスト |
| インポート済み一覧 | 既にインポートされたプロジェクト |
| ネームスペース選択 | インポート先の選択ドロップダウン |
| プロジェクト名入力 | インポート後の名前指定 |
| インポートボタン | 個別インポート開始ボタン |
| 進捗表示 | インポート中のステータス表示 |

## イベント仕様

### 1-インポートボタン押下

**トリガー**：リポジトリ行の「Import」ボタンをクリック

**処理フロー**：
1. フォームバリデーション
2. `POST /import/gitea` を呼び出し
3. Import::GithubService.execute を実行（Giteaはこのサービスを継承利用）
4. 成功時：インポート開始、進捗表示に切り替え
5. 失敗時：エラーメッセージを表示

### 2-リアルタイム進捗更新

**トリガー**：3秒間隔のポーリング

**処理フロー**：
1. `GET /import/gitea/realtime_changes.json` を呼び出し
2. インポート中プロジェクトの状態を取得
3. UI上の進捗表示を更新
4. 完了/失敗時は「Go to project」リンクを表示

### 3-フィルタリング

**トリガー**：検索ボックスに入力（デフォルト有効）

**処理フロー**：
1. フィルタ条件でリポジトリリストをフィルタリング
2. リポジトリ一覧を更新

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| インポート開始 | projects | INSERT | プロジェクトレコード作成 |
| インポート開始 | import_states | INSERT | インポート状態作成 |
| インポート開始 | namespaces | - | ネームスペース検証 |
| インポート進行中 | import_states | UPDATE | 状態更新 |

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

#### projects

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | new_name または Giteaリポジトリ名 | |
| INSERT | path | name から生成 | |
| INSERT | namespace_id | target_namespace から取得 | |
| INSERT | import_type | 'gitea' | |
| INSERT | import_url | GiteaリポジトリURL | |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 成功 | (ステータスアイコン表示) | インポート完了時 |
| MSG002 | 進行中 | Importing... | インポート中 |
| MSG003 | エラー | Import failed | インポート失敗時 |
| MSG004 | エラー | You need to specify both an access token and a Host URL. | 認証情報不足時 |

## 例外処理

| 例外条件 | 画面表示・動作 |
|----------|---------------|
| 認証トークン無効 | new画面にリダイレクト、エラーメッセージ表示 |
| ホストURL無効 | new画面にリダイレクト、エラーメッセージ表示 |
| ネームスペースアクセス不可 | 404エラー |
| インポート失敗 | 失敗ステータス表示 |
| レート制限超過 | 429エラー |

## 備考

- リアルタイム更新は3秒間隔（Gitlab::PollingInterval）
- GiteaController は GithubController を継承しているため、多くの機能を共有
- Gitea API v1 を使用
- フィルタリング機能はデフォルトで有効（filterable: true がデフォルト）
- ページネーション機能はデフォルトで無効（paginatable: false がデフォルト）
- `_githubish_status` パーシャルを再利用

---

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

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

### 推奨読解順序

#### Step 1: コントローラーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | gitea_controller.rb | `app/controllers/import/gitea_controller.rb` | status アクション |
| 1-2 | github_controller.rb | `app/controllers/import/github_controller.rb` | 親クラスの create, realtime_changes |

**主要処理フロー**:
1. **行19-35**: `status` アクションでHTML/JSON分岐
2. **行22-24**: JSON応答で imported_projects, provider_repos, incompatible_repos を返却
3. **行75-78**: `client_repos` でGitea APIからリポジトリ取得
4. **行80-82**: `client` でGitea APIクライアント生成

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | status.html.haml | `app/views/import/gitea/status.html.haml` | 状態画面の構造 |
| 2-2 | _githubish_status.html.haml | `app/views/import/_githubish_status.html.haml` | 共通ステータスパーシャル |

**status.html.hamlの構造**（行1-7）:
- `page_title`: 「Gitea import」
- Giteaアイコン表示（sprite_icon）
- 「Import projects from Gitea」見出し
- `_githubish_status` パーシャルを `provider: 'gitea'` で呼び出し

**_githubish_statusパーシャルの主要データ属性**:
- `provider`: プロバイダ名（gitea）
- `repos_path`: リポジトリ取得API
- `jobs_path`: 進捗取得API
- `import_path`: インポート実行API
- `default_target_namespace`: デフォルトのインポート先

#### Step 3: Vue.jsコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.js | `app/assets/javascripts/import_entities/import_projects/index.js` | エントリーポイント |
| 3-2 | import_projects_table.vue | `app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue` | テーブルコンポーネント |

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

```
Import::GiteaController#status (< Import::GithubController)
    │
    ├─ format.html → 画面表示
    │      └─ _githubish_status パーシャル
    │             └─ Vue.js #import-projects-mount-element
    │
    └─ format.json → API応答
           ├─ serialized_imported_projects（インポート済み）
           ├─ serialized_provider_repos（Gitea repos）
           └─ serialized_incompatible_repos（互換性なし）

Import::GiteaController#create (継承)
    │
    └─ Import::GithubService.new.execute
           ├─ Gitlab::LegacyGithubImport::ParallelImporter
           └─ Project.create
                  └─ ImportState.create

Import::GiteaController#realtime_changes (継承)
    │
    └─ Import::GithubRealtimeRepoSerializer
           └─ already_added_projects の状態を返却
```

### データフロー図

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

Gitea API ───▶ GiteaController#status (JSON)
                    │
                    ├─ client.repos (Gitea APIクライアント)
                    │      └─ Gitlab::LegacyGithubImport::Client
                    │             └─ api_version: 'v1'
                    │
                    └─ serialized_provider_repos ───▶ Vue.js表示

インポート要求 ───▶ GiteaController#create (継承)
                    │
                    └─ Import::GithubService.execute
                           │
                           ├─ Project.create (DB)
                           └─ Sidekiq Job登録 ───▶ バックグラウンドインポート

ポーリング ───▶ GiteaController#realtime_changes (継承)
                    │
                    └─ ImportState取得 ───▶ 進捗表示更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| status.html.haml | `app/views/import/gitea/status.html.haml` | テンプレート | 状態画面のビュー |
| _githubish_status.html.haml | `app/views/import/_githubish_status.html.haml` | テンプレート | 共通ステータスパーシャル |
| gitea_controller.rb | `app/controllers/import/gitea_controller.rb` | コントローラー | Giteaインポートコントローラー |
| github_controller.rb | `app/controllers/import/github_controller.rb` | コントローラー | 親クラス |
| index.js | `app/assets/javascripts/import_entities/import_projects/index.js` | JavaScript | Vue.jsエントリーポイント |
| import_projects_table.vue | `app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue` | Vue | テーブルコンポーネント |
| client.rb | `lib/gitlab/legacy_github_import/client.rb` | クライアント | Gitea APIクライアント（api_version: 'v1'） |
| import.rb | `config/routes/import.rb` | 設定 | ルーティング定義 |
