# 帳票設計書 14-Cohorts Report

## 概要

本ドキュメントは、GitLabにおけるCohorts Report機能の帳票設計書である。ユーザーコホート分析レポートを画面表示する機能について、表示内容、データ構造、処理フローを定義する。

### 本帳票の処理概要

Cohorts Reportは、ユーザーの登録月別にグループ化（コホート）し、各コホートのリテンション（継続利用）状況を時系列で分析するダッシュボード画面である。過去12ヶ月分のコホートデータを表示する。

**業務上の目的・背景**：ユーザーのリテンション状況を把握し、離脱傾向を分析することで、ユーザーエンゲージメント向上施策の立案に活用する。新規ユーザーの定着率を時系列で追跡することで、オンボーディングプロセスの改善点を特定したり、機能リリース後のユーザー行動変化を測定したりすることができる。

**帳票の利用シーン**：管理者がインスタンス全体のユーザーリテンション状況を確認する場合、新機能リリース後のユーザー行動変化を分析する場合、オンボーディング改善施策の効果測定を行う場合、経営層への月次報告資料として利用する場合などで利用される。

**主要な出力内容**：
1. 登録月別コホート一覧（過去12ヶ月）
2. 各コホートの総ユーザー数
3. 各コホートの非アクティブユーザー数
4. 月別アクティビティ率（パーセンテージ）
5. 月別アクティブユーザー数（累計）

**帳票の出力タイミング**：管理者画面のCohortsページにアクセスした際に表示される。データは1日間キャッシュされる。

**帳票の利用者**：システム管理者、プロダクトマネージャー、ユーザーエクスペリエンス担当者

## 帳票種別

画面表示（コホート分析テーブル）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | Cohorts | `/admin/cohorts` | 画面アクセス |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | HTML（画面表示） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A |
| 出力方法 | 画面表示 |
| 文字コード | UTF-8 |

## 帳票レイアウト

### レイアウト概要

画面構成（コホートテーブル）

```
┌───────────────────────────────────────────────────────────────┐
│                      Cohorts Report                           │
├───────────────────────────────────────────────────────────────┤
│ 登録月     | Total | Inactive | Month 1 | Month 2 | ... | M12 │
├───────────────────────────────────────────────────────────────┤
│ Jan 2026  |  150  |    20    | 130(87%)| 100(67%)| ... |     │
│ Dec 2025  |  200  |    30    | 170(85%)| 140(70%)| ... |     │
│ Nov 2025  |  180  |    25    | 155(86%)| 120(67%)| ... |     │
│ ...       |  ...  |   ...    |   ...   |   ...   | ... | ... │
└───────────────────────────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | レポートタイトル | "Cohorts" | 固定値 | 文字列 |
| 2 | 期間 | 過去12ヶ月 | MONTHS_INCLUDED定数 | 文字列 |

### 明細部（コホートテーブル）

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | registration_month | 登録月 | users.created_at（月単位） | "MMM YYYY"形式 |
| 2 | total | 総ユーザー数 | COUNT(*) | 数値（カンマ区切り） |
| 3 | inactive | 非アクティブ数 | last_activity_on IS NULL | 数値（カンマ区切り） |
| 4 | activity_months[0] | 1ヶ月目アクティビティ | 計算値 | 数値(パーセント) |
| 5 | activity_months[1] | 2ヶ月目アクティビティ | 計算値 | 数値(パーセント) |
| ... | activity_months[n] | n+1ヶ月目アクティビティ | 計算値 | 数値(パーセント) |

### フッター部

N/A

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 管理者権限 | 管理者画面へのアクセス権限 | Yes |
| 期間 | 過去12ヶ月 | Yes（固定） |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | registration_month | 降順（最新月が先頭） |

### 改ページ条件

N/A（単一画面）

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

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| users | ユーザー情報 | 主テーブル |

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

#### users

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| created_at | registration_month | created_at > 12.months.ago | 月単位でTRUNCATE |
| last_activity_on | activity_months | - | 月単位でTRUNCATE |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| total | コホート内の総ユーザー数 | - | activity_months[0].total |
| inactive | last_activity_onがNULLのユーザー数 | - | - |
| activity_months[n].total | n月以降にアクティブなユーザー累計 | - | 累積和で計算 |
| activity_months[n].percentage | (activity_months[n].total / total) * 100 | 整数 | 0%の場合は0を表示 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[画面アクセス] --> B[管理者権限チェック]
    B -->|権限あり| C{キャッシュ存在?}
    B -->|権限なし| Z[アクセス拒否]
    C -->|Yes| D[キャッシュから取得]
    C -->|No| E[CohortsService実行]
    E --> F[counts_by_month集計]
    F --> G[running_totals計算]
    G --> H[キャッシュに保存]
    H --> I[CohortsSerializer変換]
    D --> I
    I --> J[画面表示]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| データなし | ユーザーが存在しない | 空のテーブル表示 | - |
| 権限エラー | 管理者権限がない | Access denied | 管理者権限を取得する |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | ユーザー数に依存 |
| 目標出力時間 | 2秒以内（キャッシュなし）、即時（キャッシュあり） |
| キャッシュ有効期間 | 1日間 |

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

- 管理者画面のため、管理者権限を持つユーザーのみアクセス可能
- 集計データのみ表示し、個別ユーザー情報は含まれない
- 内部イベントトラッキング（i_analytics_cohorts）で利用状況を記録

## 備考

- データは1日間キャッシュされるため、リアルタイムではない
- 過去12ヶ月分（MONTHS_INCLUDED = 12）が固定で表示される
- コホート分析は累積型（後の月にアクティブ = 前の月もアクティブとカウント）

---

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

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

### 推奨読解順序

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

コホートデータの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cohorts_entity.rb | `app/serializers/cohorts_entity.rb` | 全体構造。months_includedとcohortsを公開 |
| 1-2 | cohort_entity.rb | `app/serializers/cohort_entity.rb` | 各コホートの構造。registration_month, total, inactive, activity_months |

**読解のコツ**: Grape::Entityを使用したシリアライザ。exposeで公開する属性を定義。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cohorts_controller.rb | `app/controllers/admin/cohorts_controller.rb` | コントローラ。indexアクションがエントリーポイント |

**主要処理フロー**:
1. **10-14行目**: track_event - 利用状況のトラッキング
2. **16-18行目**: indexアクション - load_cohortsを呼び出し
3. **22-28行目**: load_cohorts - キャッシュ付きでCohortsServiceを実行

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cohorts_service.rb | `app/services/cohorts_service.rb` | コホート計算のコアロジック |

**主要処理フロー**:
- **4行目**: MONTHS_INCLUDED = 12 - 12ヶ月分を対象
- **6-11行目**: executeメソッド - months_includedとcohortsを返す
- **26-46行目**: cohortsメソッド - 各月のコホートデータを生成
- **56-68行目**: running_totals - 累積アクティブユーザー数を計算
- **82-94行目**: counts_by_month - created_atとlast_activity_onでグループ化

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

```
Admin::CohortsController#index
    │
    ├─ load_cohorts
    │      │
    │      ├─ Rails.cache.fetch('cohorts', expires_in: 1.day)
    │      │      │
    │      │      └─ CohortsService#execute
    │      │             ├─ cohorts (12ヶ月分のコホート生成)
    │      │             │      ├─ counts_by_month (DBクエリ)
    │      │             │      └─ running_totals (累積計算)
    │      │             │
    │      │             └─ {months_included: 12, cohorts: [...]}
    │      │
    │      └─ CohortsSerializer#represent
    │             ├─ CohortsEntity
    │             │      └─ CohortEntity (×12)
    │             │             └─ CohortActivityMonthEntity
    │             │
    │             └─ JSONレスポンス
    │
    └─ @cohorts (ビューに渡す)
```

### データフロー図

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

users テーブル ─────────▶ CohortsService ────────────▶ CohortsSerializer
(created_at,               │                              │
 last_activity_on)         ├─ counts_by_month             └─▶ CohortsEntity
                           │   (GROUP BY月)                    │
                           │                                   └─▶ CohortEntity×12
                           ├─ running_totals                        │
                           │   (累積計算)                           ├─ registration_month
                           │                                        ├─ total
                           └─ cohorts                               ├─ inactive
                               (12ヶ月分)                           └─ activity_months[]
                                                                         │
                                                                         └─▶ CohortActivityMonthEntity
                                                                              ├─ total
                                                                              └─ percentage
                                                                                    ↓
                                                                               画面表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cohorts_controller.rb | `app/controllers/admin/cohorts_controller.rb` | ソース | コントローラ |
| cohorts_service.rb | `app/services/cohorts_service.rb` | ソース | コホート計算サービス |
| cohorts_serializer.rb | `app/serializers/cohorts_serializer.rb` | ソース | シリアライザ |
| cohorts_entity.rb | `app/serializers/cohorts_entity.rb` | ソース | 全体エンティティ |
| cohort_entity.rb | `app/serializers/cohort_entity.rb` | ソース | コホートエンティティ |
| cohort_activity_month_entity.rb | `app/serializers/cohort_activity_month_entity.rb` | ソース | 月別アクティビティエンティティ |
| index.html.haml | `app/views/admin/cohorts/index.html.haml` | テンプレート | 画面テンプレート |
