# 機能設計書 106-GitLabインポート

## 概要

本ドキュメントは、GitLabの他のGitLabインスタンスからのプロジェクトインポート機能についての機能設計書である。

### 本機能の処理概要

GitLabインポートは、GitLabエクスポートファイル（tar.gzアーカイブ）からプロジェクトをインポートする機能である。エクスポートファイルにはプロジェクトのメタデータ、リポジトリ、イシュー、マージリクエスト、Wiki、アップロードファイルなどが含まれる。

**業務上の目的・背景**：異なるGitLabインスタンス間でのプロジェクト移行を支援する。オンプレミスからSaaSへの移行、SaaS間の移行、バックアップからの復元などのユースケースに対応する。

**機能の利用シーン**：
- GitLab.comから自己ホストGitLabへの移行
- 自己ホストGitLab間の移行
- プロジェクトのバックアップと復元
- 複製プロジェクトの作成

**主要な処理内容**：
1. エクスポートファイルのアップロード受付
2. ファイルの検証（形式、サイズ、内容）
3. アーカイブの展開
4. バージョン互換性チェック
5. プロジェクトメタデータのインポート
6. リポジトリのリストア
7. 関連データ（イシュー、MR、Wiki等）のインポート
8. アップロードファイルのリストア

**関連システム・外部連携**：
- Workhorse（大容量ファイルアップロード）
- Sidekiq（バックグラウンドインポート）
- Gitaly（リポジトリ操作）
- オブジェクトストレージ（エクスポートファイル保存）

**権限による制御**：
- ターゲット名前空間への`import_projects`権限が必要
- ファイルサイズ制限（管理者設定で変更可能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 288 | GitLabインポート状態 | 主画面 | GitLabからのインポート状態 |
| 300 | GitLabプロジェクトインポート | 主画面 | GitLabエクスポートからのインポート |

## 機能種別

データインポート / ファイルアップロード / バックグラウンド処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | プロジェクト名 | 英数字、ハイフン、アンダースコア |
| path | String | No | プロジェクトパス | URLセーフな文字列 |
| namespace_id | Integer | Yes | 名前空間ID | 有効な名前空間ID |
| file | File | Yes | エクスポートファイル | .tar.gz形式、サイズ制限内 |

### 入力データソース

- GitLabインポート画面
- ファイルアップロード（Workhorse経由）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| project | Object | 作成されたプロジェクト |
| import_status | String | インポート状態 |

### 出力先

- プロジェクト（GitLab内）
- インポート状態画面

## 処理フロー

### 処理シーケンス

```
1. ファイルアップロード
   └─ Workhorse経由でファイルを受け付け
2. ファイル検証
   └─ 形式（.tar.gz）とサイズの検証
3. プロジェクト作成
   └─ GitLabProjectsImportServiceで作成
4. インポート実行
   └─ Importerでデータをインポート
5. リストア処理
   └─ 各コンポーネントを順次リストア
6. 完了通知
   └─ インポート完了を画面に反映
```

### フローチャート

```mermaid
flowchart TD
    A[ファイルアップロード] --> B{ファイル形式OK?}
    B -->|No| C[エラー：.gz形式が必要]
    B -->|Yes| D{サイズ制限内?}
    D -->|No| E[エラー：サイズ超過]
    D -->|Yes| F{import_projects権限?}
    F -->|No| G[権限エラー]
    F -->|Yes| H[プロジェクト作成]
    H --> I{作成成功?}
    I -->|No| J[エラー表示]
    I -->|Yes| K[インポート開始]
    K --> L[バックグラウンド処理]
    L --> M{インポート成功?}
    M -->|Yes| N[完了通知]
    M -->|No| O[失敗通知]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-106-01 | ファイル形式 | .tar.gz形式のみ受付 | 全インポート |
| BR-106-02 | サイズ制限 | max_import_size設定に従う | 全インポート |
| BR-106-03 | バージョン互換性 | エクスポートバージョンとの互換性チェック | 全インポート |
| BR-106-04 | プロジェクト上書き | original_pathが同一の場合は上書き可能 | 管理者権限時 |

### 計算ロジック

最大インポートサイズ:
- `Gitlab::CurrentSettings.max_import_size.megabytes`で取得
- 管理者が設定可能

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| プロジェクト作成 | projects | INSERT | 新規プロジェクトレコード作成 |
| イシュー作成 | issues | INSERT | エクスポートからインポート |
| マージリクエスト作成 | merge_requests | INSERT | エクスポートからインポート |
| その他関連データ | 各種テーブル | INSERT | エクスポートからインポート |

### テーブル別操作詳細

#### projects テーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | 指定されたプロジェクト名 | - |
| INSERT | path | 指定されたパスまたは名前から生成 | - |
| INSERT | namespace_id | 指定された名前空間ID | - |
| INSERT | import_type | 'gitlab_project' | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Flash Alert | ファイル形式エラー | .tar.gz形式でアップロード |
| - | Flash Alert | プロジェクト作成エラー | エラー内容を確認して修正 |
| - | 通知 | インポート失敗 | 失敗理由を確認 |

### リトライ仕様

- インポート失敗時は手動で再実行が必要

## トランザクション仕様

- プロジェクト作成はトランザクション内で実行
- インポートデータはバッチ単位でコミット

## パフォーマンス要件

- 大容量ファイルはWorkhorse経由でストリーミングアップロード
- インポート処理はバックグラウンドで実行
- 大規模プロジェクトは長時間処理になる可能性あり

## セキュリティ考慮事項

- ファイルサイズ制限によるDoS防止
- アップロードファイルの形式検証
- 権限チェック（import_projects, admin_namespace）

## 備考

- Query Limitingは無効化される（大量のDBアクセスが発生するため）
- インポートファイルはインポート完了後に削除される

---

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

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

### 推奨読解順序

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

インポートに関わるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | gitlab_projects_controller.rb | `app/controllers/import/gitlab_projects_controller.rb` | コントローラの全体構造 |

**読解のコツ**: `Import::BaseController`を継承し、WorkhorseAuthorizationをインクルードしている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | gitlab_projects_controller.rb | `app/controllers/import/gitlab_projects_controller.rb` | 各アクションの処理 |

**主要処理フロー**:
1. **10-15行目**: `new`アクションで名前空間と権限チェック
2. **17-44行目**: `create`アクションでインポート実行
3. **62-64行目**: `uploader_class`でImportExportUploaderを使用
4. **66-68行目**: `maximum_size`で最大サイズ取得

#### Step 3: インポート処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | importer.rb | `lib/gitlab/import_export/importer.rb` | メインインポート処理 |

**主要処理フロー**:
- **20-38行目**: `execute`メソッドでインポート実行
- **44-47行目**: `restorers`で各リストアラーを定義
- **77-87行目**: リポジトリ、Wiki、デザインリポジトリのリストア
- **95-111行目**: アップロード、LFS、スニペットのリストア

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

```
Import::GitlabProjectsController
    │
    ├─ #new
    │      └─ 名前空間選択画面
    │
    └─ #create
           │
           ├─ file_is_valid? (ファイル形式チェック)
           │
           └─ Projects::GitlabProjectsImportService
                  │
                  └─ Gitlab::ImportExport::Importer
                         │
                         ├─ FileImporter (アーカイブ展開)
                         ├─ VersionChecker (バージョンチェック)
                         │
                         └─ Restorers
                                ├─ RepoRestorer
                                ├─ WikiRestorer
                                ├─ TreeRestorer
                                ├─ AvatarRestorer
                                ├─ UploadsRestorer
                                ├─ LfsRestorer
                                └─ SnippetsRepoRestorer
```

### データフロー図

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

エクスポートファイル ───────▶ GitlabProjectsController ───────▶ プロジェクト
(.tar.gz)                      │
名前空間選択                    ├─ ImportService
プロジェクト名                  │      │
                               │      └─ Importer
                               │             │
                               │             ├─ アーカイブ展開
                               │             ├─ バージョンチェック
                               │             └─ 各種リストア
                               │
                               └─ インポート完了通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| gitlab_projects_controller.rb | `app/controllers/import/gitlab_projects_controller.rb` | ソース | HTTPエンドポイント |
| importer.rb | `lib/gitlab/import_export/importer.rb` | ソース | メインインポート処理 |
| file_importer.rb | `lib/gitlab/import_export/file_importer.rb` | ソース | ファイル展開 |
| version_checker.rb | `lib/gitlab/import_export/version_checker.rb` | ソース | バージョンチェック |
| repo_restorer.rb | `lib/gitlab/import_export/repo_restorer.rb` | ソース | リポジトリリストア |
| tree_restorer.rb | `lib/gitlab/import_export/project/tree_restorer.rb` | ソース | プロジェクトツリーリストア |
| uploads_restorer.rb | `lib/gitlab/import_export/uploads_restorer.rb` | ソース | アップロードリストア |
