# バッチ設計書 59-PagesDomainVerificationCronWorker

## 概要

本ドキュメントは、GitLabにおけるPagesカスタムドメインの検証をスケジュールするバッチ処理「PagesDomainVerificationCronWorker」の設計を定義する。

### 本バッチの処理概要

**業務上の目的・背景**：GitLab Pagesでは、ユーザーがカスタムドメインを設定してプロジェクトのWebサイトを公開できる。カスタムドメインの所有権を確認するため、DNSレコードによる検証が必要となる。本バッチは、検証が必要なドメインを定期的に検出し、個別の検証ワーカーをスケジュールすることで、ドメイン所有権の継続的な確認を実現する。これにより、不正なドメイン使用や設定ミスを検出できる。

**バッチの実行タイミング**：Cronジョブとして定期実行。検証が必要なドメインをfind_eachで順次処理。

**主要な処理内容**：
1. データベースがリードオンリーモードでないことを確認
2. 検証が必要なPagesドメインを取得（needs_verificationスコープ）
3. 各ドメインに対してPagesDomainVerificationWorkerをキューイング

**前後の処理との関連**：PagesDomainVerificationWorkerが実際のDNS検証を実行。検証結果に基づいてドメインの有効化/無効化が行われる。

**影響範囲**：pages_domainsテーブルのverification関連カラムが更新される。検証失敗時はドメインが無効化される可能性がある。

## バッチ種別

監視処理 / ドメイン検証スケジューラ

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 定期実行（Cron設定に依存） |
| 実行時刻 | Cron設定に依存 |
| 実行曜日 | 毎日 |
| 実行日 | - |
| トリガー | cron |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| データベースモード | Gitlab::Database.read_only?がfalse |
| 検証対象ドメイン | needs_verificationスコープに該当するドメインが存在 |

### 実行可否判定

データベースがリードオンリーモードの場合は即時終了。検証対象ドメインがない場合は何もせずに終了。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | Cronジョブのため引数なし |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| pages_domains | DB | Pagesカスタムドメイン一覧 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| PagesDomainVerificationWorkerキュー | Sidekiq | 個別ドメイン検証ジョブ |

### 出力ファイル仕様

ファイル出力なし

## 処理フロー

### 処理シーケンス

```
1. リードオンリーモードチェック
   └─ Gitlab::Database.read_only?がtrueなら終了
2. 検証が必要なドメインを取得
   └─ PagesDomain.needs_verification.with_logging_info
3. 各ドメインに対して検証ワーカーをキュー
   └─ with_contextでプロジェクトコンテキストを設定
   └─ PagesDomainVerificationWorker.perform_async(domain.id)
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{read_only?}
    B -->|Yes| C[バッチ終了]
    B -->|No| D[検証が必要なドメイン取得]
    D --> E{ドメインあり?}
    E -->|No| C
    E -->|Yes| F[with_contextでプロジェクト設定]
    F --> G[PagesDomainVerificationWorker.perform_async]
    G --> H{次のドメインあり?}
    H -->|Yes| F
    H -->|No| C
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 検証対象取得 | pages_domains | SELECT | needs_verificationスコープで取得 |
| 検証結果更新 | pages_domains | UPDATE | PagesDomainVerificationWorker経由 |

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

#### pages_domains

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, domain, project_id | needs_verificationスコープ | with_logging_infoで関連情報も取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | リードオンリー | データベースがリードオンリーモード | スキップ（次回実行で再試行） |
| - | DB接続エラー | データベース接続失敗 | Sidekiqによるリトライ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Sidekiqデフォルト |
| リトライ間隔 | 指数バックオフ |
| リトライ対象エラー | すべての例外 |

### 障害時対応

バッチ失敗時は次回のCronスケジュールで再実行される。個別の検証失敗はPagesDomainVerificationWorkerのリトライ機構で対応。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし（スケジューリングのみ） |
| コミットタイミング | - |
| ロールバック条件 | - |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 検証対象ドメイン数に依存 |
| 目標処理時間 | find_eachによるバッチ処理で制限 |
| メモリ使用量上限 | 低（キューイングのみ） |

## 排他制御

特になし。個別の検証ワーカーが各ドメインを処理。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | 各ドメイン処理時 | with_contextによるproject情報 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| エラー件数 | Sidekiq失敗キュー | 運用チーム |

## 備考

- data_consistency: :always を使用
- feature_category: :pages
- worker_resource_boundary: :cpu（CPU集約型として設定）
- CronjobQueueをinclude
- PagesDomain.needs_verificationスコープで検証対象を抽出
- with_logging_infoでログ出力用の関連情報も取得
- with_contextでプロジェクトコンテキストを設定してワーカーをキュー
- PagesDomainVerificationWorkerがVerifyPagesDomainServiceを実行
