# 帳票設計書 12-Group Export

## 概要

本ドキュメントは、GitLabにおけるGroup Export機能の帳票設計書である。グループ全体をアーカイブファイル（tar.gz形式）としてエクスポートする機能について、出力形式、データ構造、処理フローを定義する。

### 本帳票の処理概要

Group Export機能は、GitLabグループの設定情報やメンバー情報などをtar.gz形式のアーカイブファイルとしてエクスポートする機能である。サブグループを含むグループ階層全体の移行やバックアップに使用される。

**業務上の目的・背景**：組織のグループ構造を別のGitLabインスタンスに移行する場合や、グループ設定のバックアップを作成する必要がある。この機能により、グループの階層構造、メンバーシップ、ラベル、マイルストーン、バッジなどのグループレベルの設定を一括でエクスポートできる。特に大規模な組織再編時やGitLabインスタンス間の移行時に重要な役割を果たす。

**帳票の利用シーン**：グループ管理者がグループを別のGitLabインスタンスに移行する場合、組織再編に伴うグループ構造の複製、監査目的でのグループ設定のアーカイブ保存、災害復旧用のバックアップ作成などの場面で利用される。

**主要な出力内容**：
1. グループ設定情報（名前、パス、説明、可視性レベル）
2. グループメンバー情報（ユーザー、ロール、アクセスレベル）
3. グループラベル
4. グループマイルストーン
5. グループバッジ
6. サブグループ情報（階層構造）
7. グループ変数（CI/CD変数）

**帳票の出力タイミング**：グループ設定画面の「Export group」ボタンをクリックした際に非同期で生成される。GroupExportWorkerにより処理され、完了後にメールで通知される。

**帳票の利用者**：グループ管理者（admin_group権限を持つユーザー）、システム管理者

## 帳票種別

アーカイブ出力（tar.gz形式）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | グループ設定 - 一般設定 | `/:group/-/edit` | Export group ボタン |
| - | グループ詳細API | `POST /api/v4/groups/:id/export` | API呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | tar.gz（gzip圧縮されたtarアーカイブ） |
| 用紙サイズ | N/A（アーカイブファイル） |
| 向き | N/A |
| ファイル名 | `{group_name}_export.tar.gz` |
| 出力方法 | ダウンロード / メール通知後ダウンロード |
| 文字コード | UTF-8 |

### アーカイブ固有設定

| 項目 | 内容 |
|-----|------|
| 圧縮形式 | gzip |
| 暗号化 | なし |
| 分割出力 | なし |

## 帳票レイアウト

### レイアウト概要

tar.gzアーカイブ内のディレクトリ構造

```
group_export/
├── VERSION                    # エクスポートバージョン
└── tree/                     # グループツリーデータ
    └── groups/
        └── _subgroups/       # サブグループデータ（再帰構造）
            ├── group.ndjson  # グループ情報
            ├── labels.ndjson # ラベル
            ├── members.ndjson # メンバー
            └── ...
```

### ヘッダー部

N/A（アーカイブファイルのためヘッダー部なし）

### 明細部

#### VERSION ファイル

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | version | エクスポートバージョン番号 | Gitlab::ImportExport.version | 文字列 |

#### group.ndjson ファイル

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | id | グループID | namespaces.id | 数値 |
| 2 | name | グループ名 | namespaces.name | 文字列 |
| 3 | path | グループパス | namespaces.path | 文字列 |
| 4 | description | 説明 | namespaces.description | 文字列 |
| 5 | visibility_level | 公開レベル | namespaces.visibility_level | 数値 |
| 6 | created_at | 作成日時 | namespaces.created_at | ISO8601 |

### フッター部

N/A

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| グループID | エクスポート対象のグループ | Yes |
| ユーザー権限 | admin_group権限 | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| - | N/A（関連データは各リレーションの作成順） | - |

### 改ページ条件

N/A（アーカイブファイル）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| namespaces | グループ情報 | type = 'Group' |
| members | メンバー情報 | source_type = 'Namespace' |
| labels | ラベル | group_id = namespaces.id |
| milestones | マイルストーン | group_id = namespaces.id |
| badges | バッジ | group_id = namespaces.id |

### テーブル別参照項目詳細

#### namespaces (groups)

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| id | group.id | 指定されたグループID | - |
| name | group.name | - | - |
| path | group.path | - | - |
| description | group.description | - | - |
| visibility_level | group.visibility_level | - | - |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| N/A | - | - | 計算項目なし |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[Export要求] --> B[権限検証]
    B -->|権限あり| C[既存エクスポート削除]
    B -->|権限なし| Z[エラー: Permission denied]
    C --> D[Saversの実行]
    D --> E[VersionSaver]
    E --> F[TreeSaver]
    F --> G[tar.gz圧縮]
    G --> H[ImportExportUploadに保存]
    H --> I[監査ログ記録]
    I --> J[成功通知メール]
    J --> K[終了]
    D -->|エラー| L[エラー通知メール]
    L --> K
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 権限エラー | admin_group権限がない | You don't have permission to export this group | 管理者権限を取得する |
| ディスク容量不足 | 一時ディレクトリの容量不足 | Unable to save export file | ディスク容量を確保する |
| タイムアウト | 処理時間超過 | Export timed out | 小さなグループで再試行 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | グループサイズに依存（通常〜数百MB） |
| 目標出力時間 | 中規模グループで5分以内 |
| 同時出力数上限 | Sidekiqワーカー数に依存 |

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

- エクスポートファイルにはグループの全設定が含まれるため、admin_group権限の検証が必須
- 監査ログにエクスポート操作が記録される（silent_admin_exports_enabled設定で制御可能）
- エクスポートファイルはオブジェクトストレージに一時保存され、有効期限後に自動削除される

## 備考

- エクスポート処理はGroupExportWorkerにより非同期で実行される
- プロジェクトはグループエクスポートに含まれない（個別にProject Exportが必要）
- サブグループは再帰的にエクスポートされる

---

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

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

### 推奨読解順序

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

グループエクスポートで出力されるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | import_export_upload.rb | `app/models/import_export_upload.rb` | グループエクスポートファイルの保存先。belongs_to :group を確認 |

**読解のコツ**: Project Exportと同じモデルを使用するが、group関連のアソシエーションに注目。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | export_service.rb | `app/services/groups/import_export/export_service.rb` | メインのエクスポートサービス。execute()とasync_execute()を確認 |

**主要処理フロー**:
1. **6-13行目**: 初期化。Shared、Loggerのセットアップ
2. **15-21行目**: async_execute - GroupExportWorkerへの委譲
3. **23-30行目**: execute - 同期実行、権限検証、save!呼び出し
4. **38-43行目**: validate_user_permissions - admin_group権限チェック
5. **53-62行目**: save! - saversの実行とfile_saverの保存

#### Step 3: 各Saverの処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | version_saver.rb | `lib/gitlab/import_export/version_saver.rb` | バージョン情報の保存 |
| 3-2 | tree_saver.rb | `lib/gitlab/import_export/group/tree_saver.rb` | グループツリーのNDJSON出力 |

**主要処理フロー**:
- **75-76行目**: saversメソッド - version_saverとtree_exporterを定義
- **79-85行目**: tree_exporter - Group::TreeSaverのインスタンス化
- **92-93行目**: file_saver - Saverクラスでtar.gz圧縮

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

```
Groups::ImportExport::ExportService#execute
    │
    ├─ validate_user_permissions
    │      └─ current_user.can?(:admin_group, group)
    │
    ├─ remove_existing_export!
    │      └─ ImportExportUpload#remove_export_file!
    │
    └─ save!
           ├─ save_exporters
           │      ├─ Gitlab::ImportExport::VersionSaver#save
           │      └─ Gitlab::ImportExport::Group::TreeSaver#save
           │
           ├─ file_saver.save
           │      └─ Gitlab::ImportExport::Saver#save
           │             ├─ compress_and_save (tar.gz圧縮)
           │             └─ save_upload
           │
           ├─ audit_export
           │      └─ Gitlab::Audit::Auditor.audit
           │
           └─ notify_success
                  └─ NotificationService#group_was_exported
```

### データフロー図

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

Group モデル ───────────▶ TreeSaver ─────────────────▶ tree/groups/group.ndjson
                         (NDJSON変換)

Members ────────────────▶ TreeSaver ─────────────────▶ tree/groups/members.ndjson

Labels ─────────────────▶ TreeSaver ─────────────────▶ tree/groups/labels.ndjson

Milestones ─────────────▶ TreeSaver ─────────────────▶ tree/groups/milestones.ndjson

VERSION ────────────────▶ VersionSaver ──────────────▶ VERSION

全ファイル ─────────────▶ Saver ──────────────────────▶ {group}_export.tar.gz
                         (tar.gz圧縮)                    ↓
                                                     ImportExportUpload
                                                        ↓
                                                     オブジェクトストレージ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| export_service.rb | `app/services/groups/import_export/export_service.rb` | ソース | メインエクスポートサービス |
| version_saver.rb | `lib/gitlab/import_export/version_saver.rb` | ソース | バージョン情報の保存 |
| tree_saver.rb | `lib/gitlab/import_export/group/tree_saver.rb` | ソース | グループツリーのNDJSON出力 |
| saver.rb | `lib/gitlab/import_export/saver.rb` | ソース | tar.gz圧縮とアップロード |
| import_export_upload.rb | `app/models/import_export_upload.rb` | ソース | エクスポートファイル保存モデル |
| group_export_worker.rb | `app/workers/group_export_worker.rb` | ソース | 非同期エクスポートワーカー |
| notification_service.rb | `app/services/notification_service.rb` | ソース | 完了/エラー通知 |
