# 画面設計書 129-Pagesドメイン新規作成

## 概要

本ドキュメントは、GitLabプロジェクトにおけるPagesドメイン新規作成画面の設計仕様を定義するものです。

### 本画面の処理概要

Pagesドメイン新規作成画面は、GitLab Pagesに新しいカスタムドメインを追加するための画面です。カスタムドメイン名の入力と、オプションでSSL証明書の初期設定（Let's Encrypt自動取得/ユーザー提供）を行うことができます。

**業務上の目的・背景**：GitLab Pagesのデフォルトドメイン（`*.gitlab.io`など）ではなく、独自のドメイン名でWebサイトを公開したい場合にカスタムドメインを設定します。企業のブランドドメインでのサイト公開、プロジェクト専用URLの提供、SEO対策など、様々なビジネス要件に対応するためにカスタムドメイン機能が必要です。本画面は、その最初のステップとしてドメインの登録を行います。

**画面へのアクセス方法**：Pages設定画面（127-Pages設定）のドメイン一覧セクションから「Add domain」または「New domain」ボタンをクリックして遷移します。URLパターンは `/:namespace/:project/pages/domains/new` です。

**主要な操作・処理内容**：
1. カスタムドメイン名の入力
2. Let's Encrypt自動SSL有効化の設定（オプション）
3. ユーザー提供SSL証明書・秘密鍵の入力（オプション）
4. ドメインの作成

**画面遷移**：Pages設定画面から遷移。作成成功後はドメイン詳細画面（128-Pagesドメイン詳細）へ遷移し、DNS設定情報が表示されます。キャンセルボタンでPages設定画面へ戻ります。

**権限による表示制御**：`update_pages`権限を持つユーザーのみアクセス可能。ドメインの作成には同権限が必要です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 130 | Pagesドメイン管理 | 主機能 | カスタムドメインの追加 |

## 画面種別

登録

## URL/ルーティング

- パス: `/:namespace/:project/pages/domains/new`
- コントローラー: `Projects::PagesDomainsController#new`
- HTTPメソッド: GET（表示）、POST（作成）

## 入出力項目

### ドメイン作成フォーム

| 項目名 | 項目ID | 入出力 | 型 | 必須 | 説明 |
|--------|--------|--------|-----|------|------|
| ドメイン名 | domain | 入力 | string | ○ | 追加するカスタムドメイン名（例: example.com） |
| 自動SSL有効化 | auto_ssl_enabled | 入力 | boolean | - | Let's Encryptによる自動SSL（デフォルト: Let's Encrypt有効時はtrue） |
| 証明書 | user_provided_certificate | 入力 | text | - | ユーザー提供のSSL証明書（PEM形式） |
| 秘密鍵 | user_provided_key | 入力 | text | - | 証明書の秘密鍵（PEM形式） |

## 表示項目

### フォーム入力エリア

| 項目名 | 説明 |
|--------|------|
| ドメイン入力フィールド | カスタムドメイン名を入力するテキストフィールド |
| プレースホルダー | 「example.com」のサンプル表示 |
| SSL設定セクション | SSL証明書の設定オプション（カスタム証明書が有効な場合のみ表示） |

### ヘルプテキスト

| 項目名 | 説明 |
|--------|------|
| ドメイン設定ガイド | ドメイン設定方法の説明リンク |

## イベント仕様

### 1-ドメイン作成

「Create new domain」ボタン押下時の処理:

1. フォームバリデーション実行
   - ドメイン名の形式チェック
   - 既存ドメインとの重複チェック
   - GitLab Pagesルートドメインのサブドメイン禁止チェック
   - プロジェクトあたりのカスタムドメイン数制限チェック
2. 証明書が提供されている場合は整合性チェック
3. `Pages::Domains::CreateService`でドメイン作成
4. 検証コードの自動生成
5. 成功時: ドメイン詳細画面（128-Pagesドメイン詳細）へリダイレクト
6. 失敗時: エラーメッセージを表示し、フォームを再表示

### 2-キャンセル

「Cancel」ボタン押下時の処理:

1. 入力内容を破棄
2. Pages設定画面へリダイレクト

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ドメイン作成 | pages_domains | INSERT | 新規ドメインレコードの作成 |

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

#### pages_domains

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | domain | フォーム入力値 | カスタムドメイン名 |
| INSERT | project_id | 現在のプロジェクトID | |
| INSERT | verification_code | SecureRandom.hex(16) | 自動生成される検証コード |
| INSERT | auto_ssl_enabled | チェックボックス状態 | デフォルトはLet's Encrypt有効時true |
| INSERT | certificate | PEM形式証明書 | ユーザー提供時のみ |
| INSERT | key | PEM形式秘密鍵（暗号化） | ユーザー提供時のみ |
| INSERT | certificate_source | 'user_provided' / 'gitlab_provided' | |
| INSERT | scope | 'project' | デフォルト値 |
| INSERT | usage | 'pages' | デフォルト値 |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|----------|
| エラー | Domain is invalid | ドメイン形式エラー時 |
| エラー | Domain has already been taken | ドメイン重複時 |
| エラー | Subdomains of the Pages root domain %{root_domain} are reserved | Pagesルートドメインのサブドメイン使用時 |
| エラー | This project reached the limit of custom domains. (Max %d) | ドメイン数制限超過時 |
| エラー | Key doesn't match the certificate | 証明書と秘密鍵の不一致時 |
| エラー | Certificate misses intermediates | 中間証明書不足時 |
| 情報 | Support for custom certificates is disabled. Ask your system's administrator to enable it. | カスタム証明書が無効な場合 |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| 権限不足 | 403エラーを表示 |
| Pages機能が無効 | Pages機能無効エラーを表示 |
| バリデーションエラー | エラーメッセージを表示し、フォームを再表示 |

## 備考

- ドメイン名は大文字小文字を区別しない（小文字に正規化される）
- 検証コードは16バイトの16進数文字列で自動生成される
- ドメイン作成後は、DNSレコード設定画面（ドメイン詳細）でCNAMEとTXTレコードの設定情報を確認できる
- プロジェクトあたりのカスタムドメイン数には制限がある（`Gitlab::CurrentSettings.max_pages_custom_domains_per_project`）
- Let's Encryptが有効な環境では、auto_ssl_enabledのデフォルト値がtrueになる

---

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

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

### 推奨読解順序

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

Pagesドメインモデルのバリデーションを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | pages_domain.rb | `app/models/pages_domain.rb` | バリデーションルール、デフォルト値 |

**読解のコツ**: 27-44行目のバリデーション定義が重要です。特に`validate_pages_domain`, `validate_custom_domain_count_per_project`を確認してください。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | pages_domains_controller.rb | `app/controllers/projects/pages_domains_controller.rb` | new/createアクション |

**主要処理フロー**:
1. **7行目**: `authorize_update_pages!` - 権限チェック
2. **20-22行目**: `new`アクション - 空のドメインオブジェクト作成
3. **46-54行目**: `create`アクション - ドメイン作成処理

#### Step 3: ビューの構成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | new.html.haml | `app/views/projects/pages_domains/new.html.haml` | 新規作成画面のメインビュー |
| 3-2 | _form.html.haml | `app/views/projects/pages_domains/_form.html.haml` | フォーム部分（共通） |

**主要処理フロー**:
- **9行目**: gitlab_ui_form_forでフォーム生成
- **12行目**: 作成ボタン（Create new domain）
- **13行目**: キャンセルボタン

#### Step 4: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | create_service.rb | `app/services/pages/domains/create_service.rb` | ドメイン作成ロジック |

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

```
Projects::PagesDomainsController#new
    │
    ├─ require_pages_enabled!
    │
    ├─ authorize_update_pages!
    │
    ├─ @domain = @project.pages_domains.new
    │
    └─ View: new.html.haml
           ├─ _helper_text.html.haml
           ├─ _form.html.haml
           │      └─ _certificate.html.haml (証明書有効時)
           ├─ Create new domain button
           └─ Cancel button

Projects::PagesDomainsController#create
    │
    ├─ require_pages_enabled!
    │
    ├─ authorize_update_pages!
    │
    ├─ Pages::Domains::CreateService#execute
    │      │
    │      ├─ PagesDomain.new(create_params)
    │      │      └─ set_verification_code (after_initialize)
    │      │
    │      ├─ バリデーション実行
    │      │      ├─ validate_pages_domain
    │      │      ├─ validate_custom_domain_count_per_project
    │      │      └─ validate_matching_key (証明書あり時)
    │      │
    │      └─ @domain.save
    │
    └─ 成功: redirect_to show
       失敗: render 'new'
```

### データフロー図

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

domain名         ───▶ PagesDomainsController#create ───▶ pages_domains (INSERT)
auto_ssl_enabled ───▶        │
certificate      ───▶        │
key              ───▶        │
                            │
                            └─ Pages::Domains::CreateService
                                   │
                                   ├─ PagesDomain.new
                                   │      └─ verification_code生成
                                   │
                                   ├─ バリデーション
                                   │
                                   └─ save → ドメイン詳細へリダイレクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| pages_domains_controller.rb | `app/controllers/projects/pages_domains_controller.rb` | コントローラー | メインコントローラー |
| new.html.haml | `app/views/projects/pages_domains/new.html.haml` | ビュー | 新規作成画面 |
| _form.html.haml | `app/views/projects/pages_domains/_form.html.haml` | パーシャル | フォーム（共通） |
| _helper_text.html.haml | `app/views/projects/pages_domains/_helper_text.html.haml` | パーシャル | ヘルプテキスト |
| _certificate.html.haml | `app/views/projects/pages_domains/_certificate.html.haml` | パーシャル | 証明書設定 |
| pages_domain.rb | `app/models/pages_domain.rb` | モデル | ドメインモデル |
| create_service.rb | `app/services/pages/domains/create_service.rb` | サービス | 作成処理 |
