# 機能設計書 129-GitLab Pages

## 概要

本ドキュメントは、GitLabにおけるGitLab Pages機能の設計仕様を記述したものである。GitLab Pagesは、Gitリポジトリからの静的サイトホスティングを提供し、プロジェクトドキュメント、ブログ、ポートフォリオなどの静的Webサイトを公開する機能である。

### 本機能の処理概要

**業務上の目的・背景**：ソフトウェアプロジェクトでは、APIドキュメント、ユーザーガイド、プロジェクト紹介ページなどの静的コンテンツを公開する必要がある。GitLab Pagesは、CI/CDパイプラインで生成された静的ファイルを自動的にホスティングし、別途Webサーバーを用意することなくドキュメントサイトを公開できる。これにより、ドキュメントとソースコードを同一リポジトリで管理でき、バージョン整合性を保った公開が可能になる。

**機能の利用シーン**：プロジェクトのDeploy > Pagesメニューから設定・管理を行う場面、CI/CDパイプラインでページをデプロイする場面、カスタムドメインを設定する場面、オンボーディングウィザードで初期設定を行う場面などで利用される。

**主要な処理内容**：
1. Pages有効化状態の確認とオンボーディング
2. 設定されたドメイン一覧の表示
3. HTTPS設定の管理
4. ユニークドメインの生成・再生成
5. Pages削除処理
6. CI/CD連携によるデプロイ

**関連システム・外部連携**：GitLab Pages Daemonによる静的サイト配信。Let's Encrypt連携による自動SSL証明書発行。カスタムドメインのDNS検証。

**権限による制御**：Pages閲覧には読み取り権限、設定変更には更新権限、削除には削除権限が必要。プロジェクトのPagesサポートが有効であることが前提。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 127 | Pages設定 | 主画面 | GitLab Pages設定の管理 |

## 機能種別

設定管理（CRUD操作）/ デプロイ制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pages_https_only | Boolean | No | HTTPSのみ許可 | true/false |
| pages_unique_domain_enabled | Boolean | No | ユニークドメイン有効化 | true/false |
| pages_primary_domain | String | No | プライマリドメイン設定 | 有効なドメイン形式 |

### 入力データソース

- プロジェクト設定（project_settings）
- ユーザー入力（フォーム）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @domains | Array<PagesDomain> | 設定済みドメイン一覧 |
| @pipeline_wizard_data | Hash | オンボーディングウィザードデータ |

### 出力先

- HTML画面（Pages設定・管理画面）

## 処理フロー

### 処理シーケンス

```
1. 前提条件チェック
   └─ require_pages_enabled!
2. 権限チェック
   └─ authorize_read_pages! / authorize_update_pages! / authorize_remove_pages!
3. アクション実行
   └─ show: ドメイン一覧表示（オンボーディング対応）
   └─ new: パイプラインウィザード表示
   └─ update: HTTPS設定・ユニークドメイン設定更新
   └─ destroy: Pagesデプロイ削除
   └─ regenerate_unique_domain: ユニークドメイン再生成
4. レスポンス生成
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信] --> B{Pages有効?}
    B -->|No| C[エラー表示]
    B -->|Yes| D{アクション判定}
    D -->|show| E{オンボーディング?}
    E -->|Yes| F[newへリダイレクト]
    E -->|No| G[ドメイン一覧表示]
    D -->|new| H[パイプラインウィザード表示]
    D -->|update| I{権限チェック}
    I -->|OK| J[設定更新]
    I -->|NG| K[403 Forbidden]
    D -->|destroy| L{削除権限?}
    L -->|OK| M[Pages削除]
    L -->|NG| K
    D -->|regenerate| N{更新権限?}
    N -->|OK| O[ユニークドメイン再生成]
    N -->|NG| K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-129-01 | オンボーディングリダイレクト | pages_show_onboarding?がtrueの場合、newアクションへリダイレクト | showアクション時 |
| BR-129-02 | ユニークドメイン再生成 | pages_unique_domain_enabledがtrueの場合のみ許可 | regenerate_unique_domain時 |
| BR-129-03 | HTTPS設定 | pages_https_onlyの変更はupdate権限が必要 | 設定更新時 |

### 計算ロジック

**ユニークドメイン生成**:
```ruby
Gitlab::Pages.generate_unique_domain(project)
# プロジェクトIDベースのユニークなサブドメインを生成
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ドメイン取得 | pages_domains | SELECT | プロジェクトのPagesドメイン取得 |
| 設定更新 | project_settings | UPDATE | Pages関連設定更新 |
| Pages削除 | pages_deployments | UPDATE/DELETE | デプロイ無効化・削除 |

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

#### pages_domains

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | project_id, domain, verified_at, enabled_until | project_id = @project.id ORDER BY domain | ドメイン一覧 |

#### project_settings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | pages_unique_domain, pages_unique_domain_enabled, pages_primary_domain | project_id = @project.id | 設定更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | Forbidden | 権限不足 | アクセス拒否 |
| 404 | Not Found | Pages未有効 | エラー画面表示 |
| 422 | Unprocessable | 設定更新失敗 | flashでエラーメッセージ表示 |

### リトライ仕様

設定更新失敗時はリダイレクトしてフラッシュメッセージで通知。

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

- 設定更新: Projects::UpdateService経由で暗黙的トランザクション
- Pages削除: Pages::DeleteService内で関連データの一括処理

## パフォーマンス要件

- feature_category: pages
- ドメイン一覧はorder(:domain)でソート

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

- Pages閲覧/更新/削除の権限分離
- HTTPSのみ設定によるセキュリティ強化
- カスタムドメインの所有権検証

## 備考

- EE版で追加のPages機能が提供される（prepend_mod_with）
- Let's Encryptによる自動SSL対応（auto_ssl_enabled）
- オンボーディングウィザードでCI/CD設定をサポート

---

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

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

### 推奨読解順序

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

PagesドメインとPagesデプロイの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | PagesDomain | `app/models/pages_domain.rb` | ドメインモデル、SSL証明書管理 |
| 1-2 | PagesDeployment | `app/models/pages_deployment.rb` | デプロイ管理 |

**読解のコツ**:
- PagesDomainはverification_codeでDNS検証を行う
- certificate_sourceでuser_provided/gitlab_provided（Let's Encrypt）を区別

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

コントローラーの処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Projects::PagesController | `app/controllers/projects/pages_controller.rb` | 各アクションの処理フロー |

**主要処理フロー**:
1. **4-7行目**: before_actionでの権限・有効化チェック
2. **11-17行目**: newアクション - パイプラインウィザードデータ
3. **19-28行目**: showアクション - オンボーディングチェックとドメイン一覧
4. **30-38行目**: destroyアクション - Pages::DeleteService呼び出し
5. **40-54行目**: updateアクション - Projects::UpdateService呼び出し
6. **56-71行目**: regenerate_unique_domainアクション

#### Step 3: 削除サービスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Pages::DeleteService | `app/services/pages/delete_service.rb` | 削除ロジック |

**主要処理フロー**:
- **6-9行目**: 権限チェック
- **11行目**: PagesDeployment.deactivate_all
- **17行目**: PagesDomain.for_project.delete_all
- **19行目**: DestroyPagesDeploymentsWorker.perform_async

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

```
Projects::PagesController
    │
    ├─ show (action)
    │      ├─ pages_show_onboarding? チェック
    │      └─ @project.pages_domains.order(:domain)
    │
    ├─ new (action)
    │      └─ @pipeline_wizard_data 設定
    │
    ├─ update (action)
    │      └─ Projects::UpdateService.new(@project, current_user, params).execute
    │
    ├─ destroy (action)
    │      └─ Pages::DeleteService.new(@project, current_user).execute
    │             ├─ PagesDeployment.deactivate_all(project)
    │             ├─ PagesDomain.for_project(project).delete_all
    │             └─ DestroyPagesDeploymentsWorker.perform_async
    │
    └─ regenerate_unique_domain (action)
           └─ Gitlab::Pages.generate_unique_domain(@project)
                  └─ @project.project_setting.update(pages_unique_domain: result)
```

### データフロー図

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

CI/CD Pipeline ─────────▶ Pages Deployment ────────────────▶ Static Site
                               │
params ─────────────────▶ PagesController ─────────────────▶ HTML View
                               │
                         ┌─────┴─────┐
                         │           │
                      settings   domains
                         │           │
              project_settings  pages_domains
                         │           │
                   UpdateService  DeleteService
                         │           │
                         └─────┬─────┘
                               │
                               ▼
                         Response/Redirect
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Projects::PagesController | `app/controllers/projects/pages_controller.rb` | コントローラー | エントリーポイント |
| Pages::DeleteService | `app/services/pages/delete_service.rb` | サービス | Pages削除 |
| PagesDomain | `app/models/pages_domain.rb` | モデル | ドメイン管理 |
| PagesDeployment | `app/models/pages_deployment.rb` | モデル | デプロイ管理 |
| Projects::UpdateService | `app/services/projects/update_service.rb` | サービス | 設定更新 |
| Gitlab::Pages | `lib/gitlab/pages.rb` | ライブラリ | Pages関連ユーティリティ |
| DestroyPagesDeploymentsWorker | `app/workers/destroy_pages_deployments_worker.rb` | ワーカー | 非同期削除 |
