# 機能設計書 108-プロジェクトエクスポート

## 概要

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

### 本機能の処理概要

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

**業務上の目的・背景**：プロジェクトのバックアップ、他のGitLabインスタンスへの移行、アーカイブ保存などのユースケースに対応する。完全なプロジェクトデータを単一ファイルとしてエクスポートし、可搬性を確保する。

**機能の利用シーン**：
- 別のGitLabインスタンスへの移行準備
- プロジェクトのバックアップ作成
- 規制対応のためのアーカイブ
- プロジェクトテンプレートの作成

**主要な処理内容**：
1. エクスポート権限の確認
2. 各コンポーネントのエクスポート（バージョン、アバター、ツリー、アップロード等）
3. リポジトリのバンドル作成
4. Wiki、デザイン、スニペットリポジトリのバンドル作成
5. LFSオブジェクトの収集
6. tar.gzアーカイブの作成
7. エクスポートファイルの保存・通知

**関連システム・外部連携**：
- Sidekiq（バックグラウンドエクスポート）
- Gitaly（リポジトリバンドル作成）
- オブジェクトストレージ（エクスポートファイル保存）
- 通知サービス（完了/失敗通知）

**権限による制御**：
- プロジェクトへの`admin_project`権限が必要
- テンプレートプロジェクトはテンプレート権限で可

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 299 | URLインポート | 主画面 | リポジトリURLからのインポート |

## 機能種別

データエクスポート / アーカイブ作成 / バックグラウンド処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| project_id | Integer | Yes | プロジェクトID | 有効なプロジェクトID |
| params | Hash | No | エクスポートオプション | - |

### 入力データソース

- プロジェクト設定画面
- API呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| export_file | File | tar.gzアーカイブ |

### 出力先

- オブジェクトストレージ
- ダウンロード（ユーザー）

## 処理フロー

### 処理シーケンス

```
1. 権限チェック
   └─ admin_project権限を確認
2. エクスポート開始
   └─ 内部イベント追跡
3. 各コンポーネントのエクスポート
   └─ version, avatar, tree, uploads, repo, wiki, lfs, snippets, design
4. アーカイブ作成
   └─ tar.gzファイルを生成
5. ファイル保存
   └─ ImportExportUploadに保存
6. 完了通知
   └─ 成功/失敗を通知
7. クリーンアップ
   └─ 一時ファイルを削除
```

### フローチャート

```mermaid
flowchart TD
    A[エクスポート開始] --> B{admin_project権限?}
    B -->|No| C[権限エラー]
    B -->|Yes| D[各Exporterを実行]
    D --> E{全Exporter成功?}
    E -->|No| F[エラー通知]
    E -->|Yes| G[アーカイブ作成]
    G --> H{アーカイブ成功?}
    H -->|No| F
    H -->|Yes| I[ファイル保存]
    I --> J[成功通知]
    J --> K[一時ファイル削除]
    F --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-108-01 | 権限要件 | admin_project権限が必要 | 全エクスポート |
| BR-108-02 | テンプレート例外 | テンプレートプロジェクトはtemplate_source?でチェック | テンプレートプロジェクト |
| BR-108-03 | バージョン情報 | GitLabバージョンをエクスポートに含める | 全エクスポート |
| BR-108-04 | 一時ファイルクリーンアップ | 処理終了時に一時ファイルを削除 | 全エクスポート |

### 計算ロジック

エクスポートファイルサイズ:
- リポジトリサイズ + アップロードファイル + LFSオブジェクト + メタデータ

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| メタデータ取得 | 各種テーブル | SELECT | プロジェクト関連データ取得 |
| エクスポート保存 | import_export_uploads | INSERT/UPDATE | エクスポートファイル情報保存 |

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

#### import_export_uploads テーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | export_file | エクスポートファイルパス | - |
| INSERT/UPDATE | project_id | プロジェクトID | - |
| INSERT/UPDATE | user_id | 実行ユーザーID | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | PermissionError | 権限不足 | 権限を確認 |
| - | ExportError | エクスポート失敗 | エラー内容を確認 |
| - | 通知 | 各種エラー | メール通知で確認 |

### リトライ仕様

- エクスポート失敗時は手動で再実行が必要

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

- 読み取り専用操作が主体
- エクスポート完了時にファイル情報をDB保存

## パフォーマンス要件

- 大規模プロジェクトはバックグラウンドで長時間実行
- リポジトリサイズに比例して処理時間増加

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

- エクスポートファイルには機密情報が含まれる可能性
- アクセス権限を持つユーザーのみダウンロード可能
- 監査ログへの記録

## 備考

- アフターエクスポート戦略でエクスポート後の処理をカスタマイズ可能
- パラレルエクスポートによる高速化オプションあり（EE）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | export_service.rb | `app/services/projects/import_export/export_service.rb` | エクスポートサービスの構造 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | export_service.rb | `app/services/projects/import_export/export_service.rb` | メインエクスポート処理 |

**主要処理フロー**:
1. **15-24行目**: `execute`メソッドで権限チェックとエクスポート実行
2. **26-30行目**: `exporters`で各Exporter一覧
3. **56-71行目**: `save_all!`で全Exporterを実行
4. **73-79行目**: `save_exporters`で各Exporterを順次実行
5. **81-83行目**: `save_export_archive`でアーカイブ保存

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

```
Projects::ImportExport::ExportService
    │
    ├─ execute
    │      │
    │      ├─ can?(:admin_project, project)
    │      ├─ save_all!
    │      │      │
    │      │      ├─ save_exporters
    │      │      │      ├─ VersionSaver
    │      │      │      ├─ AvatarSaver
    │      │      │      ├─ TreeSaver
    │      │      │      ├─ UploadsSaver
    │      │      │      ├─ RepoSaver
    │      │      │      ├─ WikiRepoSaver
    │      │      │      ├─ LfsSaver
    │      │      │      ├─ SnippetsRepoSaver
    │      │      │      └─ DesignRepoSaver
    │      │      │
    │      │      └─ save_export_archive
    │      │             └─ Saver.save
    │      │
    │      └─ execute_after_export_action
    │
    └─ cleanup
           └─ 一時ファイル削除
```

### データフロー図

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

プロジェクト ───────────▶ ExportService ───────────────▶ tar.gzアーカイブ
                              │
                              ├─ Exporters
                              │      │
                              │      ├─ メタデータ (JSON)
                              │      ├─ リポジトリ (bundle)
                              │      ├─ アップロード (files)
                              │      └─ LFS (objects)
                              │
                              └─ Saver
                                     │
                                     └─ tar.gz作成
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| export_service.rb | `app/services/projects/import_export/export_service.rb` | ソース | メインエクスポートサービス |
| version_saver.rb | `lib/gitlab/import_export/version_saver.rb` | ソース | バージョン情報保存 |
| avatar_saver.rb | `lib/gitlab/import_export/avatar_saver.rb` | ソース | アバター保存 |
| tree_saver.rb | `lib/gitlab/import_export/project/tree_saver.rb` | ソース | プロジェクトツリー保存 |
| uploads_saver.rb | `lib/gitlab/import_export/uploads_saver.rb` | ソース | アップロードファイル保存 |
| repo_saver.rb | `lib/gitlab/import_export/repo_saver.rb` | ソース | リポジトリバンドル作成 |
| saver.rb | `lib/gitlab/import_export/saver.rb` | ソース | アーカイブ作成 |
