# 画面設計書 267-コホート分析

## 概要

本ドキュメントは、GitLab管理者エリアにおける「コホート分析」画面の設計を記載したものです。ユーザーの登録月別のアクティビティを分析し、ユーザーリテンションを可視化するための画面です。

### 本画面の処理概要

**業務上の目的・背景**：SaaS製品やサービスの成功において、ユーザーリテンション（継続利用率）は重要な指標です。コホート分析により、管理者は特定の月に登録したユーザーグループが時間経過とともにどの程度アクティブに利用し続けているかを把握できます。これにより、ユーザー離脱の傾向を特定し、適切なエンゲージメント施策を検討できます。

**画面へのアクセス方法**：管理者エリア > ユーザー > コホート、または `/admin/cohorts` に直接アクセスします。管理者権限が必要です。

**主要な操作・処理内容**：
1. 月別ユーザー登録コホートの表示
2. 各コホートの返却ユーザー率の確認
3. 非アクティブユーザー数の確認
4. 過去12ヶ月分のコホートデータ表示

**画面遷移**：
- 遷移元：管理者ダッシュボード、ユーザー一覧画面
- 遷移先：新規ユーザー作成画面

**権限による表示制御**：管理者権限を持つユーザーのみがアクセス可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 126 | リポジトリアナリティクス | 主機能 | ユーザーコホート分析の表示 |
| 111 | ユーザー管理 | 補助機能 | ユーザー情報の参照 |

## 画面種別

一覧 / 分析

## URL/ルーティング

- URL: `/admin/cohorts`
- HTTPメソッド: GET
- コントローラー: `Admin::CohortsController#index`

## 入出力項目

本画面は表示専用のため、入力項目はありません。

## 表示項目

### コホートテーブル

| 項目名 | 説明 |
|--------|------|
| 登録月 | ユーザーが登録した月（YYYY-MM形式） |
| 非アクティブユーザー | その月に登録後、一度もログインしていないユーザー数 |
| アクティブユーザー | 登録月のアクティブユーザー総数 |
| Month 1〜11 | 登録月から1〜11ヶ月後のリテンション率（%）と実数 |

### ヘッダー

| セクション | 表示内容 |
|-----------|----------|
| New users | 新規ユーザー関連の列（登録月、非アクティブ、アクティブ） |
| Returning users | 返却ユーザー関連の列（Month 1〜11） |

### アクションボタン

| ボタン | 説明 |
|--------|------|
| New user | 新規ユーザー作成画面への遷移 |

## イベント仕様

### 1-コホートデータ取得

**トリガー**: 画面表示時

**処理フロー**:
1. `CohortsService.new.execute` を呼び出し
2. 結果をRailsキャッシュから取得（1日間キャッシュ）
3. キャッシュがない場合は新規計算
4. `CohortsSerializer` でシリアライズ
5. テーブル形式で表示

### 2-イベントトラッキング

**トリガー**: 画面表示時

**処理フロー**:
1. `ProductAnalyticsTracking`モジュールでイベント送信
2. `i_analytics_cohorts` イベントを記録
3. Redis HLLとSnowplowに送信

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| コホート表示 | users | SELECT | ユーザーの登録日とアクティビティを集計 |

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

#### users（SELECT）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | created_at | 過去12ヶ月以内 | DATE_TRUNCで月単位に集計 |
| SELECT | last_activity_on | NULL含む | DATE_TRUNCで月単位に集計 |

## メッセージ仕様

本画面にはユーザー向けメッセージは特にありません。

## 例外処理

| 状態 | 処理 |
|------|------|
| 権限不足 | アクセス拒否画面にリダイレクト |
| データ取得エラー | エラーログを記録、空のテーブルを表示 |

## 備考

- コホートデータは1日間キャッシュされる（`Rails.cache.fetch('cohorts', expires_in: 1.day)`）
- 過去12ヶ月分（`MONTHS_INCLUDED = 12`）のデータを表示
- リテンション率は「登録月の総アクティブユーザー数」に対する割合で計算
- `last_activity_on` が NULL のユーザーは非アクティブとしてカウント
- イベントトラッキングは Redis HLL と Snowplow の両方に送信

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | user.rb | `app/models/user.rb` | created_at、last_activity_on属性 |
| 1-2 | cohorts_serializer.rb | `app/serializers/cohorts_serializer.rb` | 出力データ構造 |

**読解のコツ**: `last_activity_on`がユーザーの最終アクティビティ日を管理していることを理解する。

#### Step 2: サービスクラスを理解する

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

**主要処理フロー**:
1. **行6-11**: `execute` - メインの実行メソッド
2. **行26-46**: `cohorts` - 月別コホートデータの生成
3. **行56-68**: `running_totals` - リテンション率の計算
4. **行82-94**: `counts_by_month` - 月別カウントのSQLクエリ

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cohorts_controller.rb | `app/controllers/admin/cohorts_controller.rb` | indexアクションとキャッシュ |

**主要処理フロー**:
1. **行16-17**: `index` - コホートデータの読み込み
2. **行22-28**: `load_cohorts` - キャッシュ付きでデータ取得

#### Step 4: ビューを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.html.haml | `app/views/admin/cohorts/index.html.haml` | メインレイアウト |
| 4-2 | _cohorts.html.haml | `app/views/admin/cohorts/_cohorts.html.haml` | コホートテーブルのレンダリング |
| 4-3 | _cohorts_table.html.haml | `app/views/admin/cohorts/_cohorts_table.html.haml` | テーブル構造 |

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

```
Admin::CohortsController#index
    │
    └─ load_cohorts
           │
           ├─ Rails.cache.fetch('cohorts', expires_in: 1.day)
           │
           ├─ CohortsService.new.execute
           │      │
           │      ├─ cohorts
           │      │      ├─ running_totals
           │      │      └─ counts_by_month (SQL)
           │      │
           │      └─ { months_included: 12, cohorts: [...] }
           │
           └─ CohortsSerializer.new.represent
```

### データフロー図

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

ページリクエスト ────▶ Rails.cache.fetch ─────────▶ キャッシュヒット時
                              │                     ├─ @cohorts
                              │                     └─ テーブル表示
                              │
                              └─ キャッシュミス時
                                    │
                                    └─ CohortsService
                                           │
                                           ├─ User.group(...).count
                                           │
                                           └─ 集計データ計算
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| 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` | シリアライザー | データ整形 |
| index.html.haml | `app/views/admin/cohorts/index.html.haml` | テンプレート | メイン画面 |
| _cohorts.html.haml | `app/views/admin/cohorts/_cohorts.html.haml` | パーシャル | テーブルラッパー |
| _cohorts_table.html.haml | `app/views/admin/cohorts/_cohorts_table.html.haml` | パーシャル | テーブル本体 |
| admin.rb | `config/routes/admin.rb` | ルーティング | URL定義 |
