# バッチ設計書 45-Users::CreateStatisticsWorker

## 概要

本ドキュメントは、GitLabにおけるユーザー統計作成バッチ（Users::CreateStatisticsWorker）の設計仕様を定義したものである。

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

GitLabインスタンスのユーザー統計情報を定期的に集計・保存するバッチ処理である。

**業務上の目的・背景**：GitLab管理者は、インスタンス内のユーザー構成を把握するために統計情報を必要とする。本バッチは、アクセスレベル別のユーザー数、ボットユーザー数、ブロックされたユーザー数などの統計情報を定期的に集計し、管理者ダッシュボードや利用状況レポートで使用可能な形式で保存することを目的としている。これにより、ライセンス管理、容量計画、セキュリティ監査などの管理業務を支援する。

**バッチの実行タイミング**：日次実行（毎日15時2分 UTC）

**主要な処理内容**：
1. UsersStatistics.create_current_stats!を呼び出し
2. 各アクセスレベル（Guest、Planner、Reporter、Developer、Maintainer、Owner）のユーザー数をカウント
3. ボットユーザー数、ブロックユーザー数をカウント
4. グループ・プロジェクトに所属していないユーザー数をカウント
5. 統計レコードを作成して保存

**前後の処理との関連**：本バッチは独立して動作し、他のバッチとの直接的な依存関係はない。生成された統計は管理者UIやAPI経由で参照される。

**影響範囲**：users_statisticsテーブル（新規レコード作成）

## バッチ種別

集計処理

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 日次 |
| 実行時刻 | 15:02 (UTC) |
| 実行曜日 | 毎日 |
| 実行日 | - |
| トリガー | cron |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| データベース接続 | usersテーブル、user_highest_rolesテーブルへの読み取りアクセスが可能であること |

### 実行可否判定

特別な実行可否判定ロジックはなく、cronスケジュールに基づいて常に実行される。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | 本バッチはパラメータを受け取らない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| users | DB | ユーザーレコード |
| user_highest_roles | DB | ユーザーの最高アクセスレベル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| users_statistics | DB | ユーザー統計レコード |

### 出力ファイル仕様

ファイル出力はなし

## 処理フロー

### 処理シーケンス

```
1. バッチ開始
   └─ CronjobQueueからperformメソッドが呼び出される
2. 統計データ収集
   └─ UsersStatistics.create_current_stats!を呼び出し
3. アクセスレベル別カウント
   └─ UserHighestRole.with_highest_access_levelで各レベルをカウント
4. ボット・ブロックユーザーカウント
   └─ User.bots、User.blockedでカウント
5. レコード作成
   └─ users_statisticsテーブルに新規レコードを作成
6. バッチ終了
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[UsersStatistics.create_current_stats!]
    B --> C[アクセスレベルなしユーザーをカウント]
    C --> D[Guestユーザーをカウント]
    D --> E[Plannerユーザーをカウント]
    E --> F[Reporterユーザーをカウント]
    F --> G[Developerユーザーをカウント]
    G --> H[Maintainerユーザーをカウント]
    H --> I[Ownerユーザーをカウント]
    I --> J[Botsユーザーをカウント]
    J --> K[Blockedユーザーをカウント]
    K --> L[統計レコード作成]
    L --> M{作成成功?}
    M -->|はい| N[バッチ終了]
    M -->|いいえ| O[エラートラッキング]
    O --> N
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ユーザー数カウント | user_highest_roles | SELECT COUNT | アクセスレベル別ユーザー数 |
| ボットカウント | users | SELECT COUNT | ボットユーザー数 |
| ブロックカウント | users | SELECT COUNT | ブロックされたユーザー数 |
| 統計作成 | users_statistics | INSERT | 統計レコードの作成 |

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

#### users_statistics

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | without_groups_and_projects | カウント値 | アクセスレベルnullのユーザー数 |
| INSERT | with_highest_role_guest | カウント値 | Guestレベルのユーザー数 |
| INSERT | with_highest_role_planner | カウント値 | Plannerレベルのユーザー数 |
| INSERT | with_highest_role_reporter | カウント値 | Reporterレベルのユーザー数 |
| INSERT | with_highest_role_developer | カウント値 | Developerレベルのユーザー数 |
| INSERT | with_highest_role_maintainer | カウント値 | Maintainerレベルのユーザー数 |
| INSERT | with_highest_role_owner | カウント値 | Ownerレベルのユーザー数 |
| INSERT | bots | カウント値 | ボットユーザー数 |
| INSERT | blocked | カウント値 | ブロックされたユーザー数 |
| INSERT | created_at | 現在時刻 | 作成日時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ActiveRecord::RecordInvalid | バリデーションエラー | エラートラッキングして継続 |
| - | ActiveRecord::StatementInvalid | DB接続エラー | Sidekiqリトライ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Sidekiqデフォルト |
| リトライ間隔 | 指数バックオフ |
| リトライ対象エラー | DB接続エラー等の一時的エラー |

### 障害時対応

RecordInvalidエラーはGitlab::ErrorTracking.track_exceptionで記録されるが、バッチ自体は正常終了する。次回実行時に再度統計が作成される。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 統計レコード作成全体 |
| コミットタイミング | create!成功時 |
| ロールバック条件 | create!失敗時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1レコード作成 |
| 目標処理時間 | 60秒以内 |
| メモリ使用量上限 | Gitlab::Database::BatchCount使用 |

## 排他制御

本バッチはidempotentではなく（rubocop:disable Scalability/IdempotentWorker）、同時実行の排他制御は行っていない。ただし、統計レコードは新規作成のみで更新は行わないため、同時実行による不整合リスクは低い。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | バッチ開始時 | ワーカー名、実行開始時刻 |
| 終了ログ | バッチ終了時 | 実行完了 |
| エラーログ | エラー発生時 | エラーメッセージ、例外情報 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理時間 | 120秒 | システム管理者 |
| エラー件数 | 1件 | システム管理者 |

## 備考

- feature_categoryは「user_profile」に分類される
- data_consistencyは「sticky」で、レプリカDBを使用可能
- Gitlab::Database::BatchCountを使用して効率的にカウントを実行
- 統計データはUsersStatistics.latestで最新の統計を取得可能
- activeメソッドで合計アクティブユーザー数を算出（without_groups_and_projects + 各ロール + bots）
- totalメソッドでactive + blockedの合計を算出
