# 機能設計書 121-ユーザーダッシュボード

## 概要

本ドキュメントは、GitLabにおけるユーザーダッシュボード機能の設計仕様を記述したものである。ユーザーダッシュボードは、ログインしたユーザーが自身の活動状況、割り当てられたイシュー/マージリクエスト、参加プロジェクトの情報を一元的に把握するための中央画面を提供する。

### 本機能の処理概要

**業務上の目的・背景**：開発者やプロジェクト管理者は、日々複数のプロジェクトにまたがって作業を行う。ユーザーダッシュボードは、自身に関連するすべての活動情報を単一の画面で確認できるようにすることで、作業の優先順位付けや進捗把握を効率化する。これにより、重要なタスクの見落としを防ぎ、開発チーム全体の生産性向上に寄与する。

**機能の利用シーン**：GitLabにログインした直後のホーム画面として、またはナビゲーションメニューから「ダッシュボード」を選択した際に表示される。日々の業務開始時に自分に割り当てられたタスクを確認する場面、フォローしているユーザーやプロジェクトの最新活動を追跡する場面、お気に入りプロジェクトの更新状況を確認する場面などで利用される。

**主要な処理内容**：
1. ユーザーの認証状態を確認し、ホームページデータを取得
2. アクティビティフィード（イベント）の取得・フィルタリング
3. 割り当てられたイシュー・マージリクエストの一覧取得
4. スターしたプロジェクトの一覧取得
5. フォローしているユーザーの活動取得
6. イベントのレンダリングとページネーション処理

**関連システム・外部連携**：内部的にRedisを利用したHLLカウンターでユーザー行動を追跡。Snowplowへの分析イベント送信も行われる。

**権限による制御**：ログイン済みユーザーのみがアクセス可能。表示される情報は、ユーザーがアクセス権を持つプロジェクト・グループに限定される。フィーチャーフラグ `personal_homepage` が有効な場合のみホーム機能が利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 219 | ダッシュボード | 主画面 | ユーザーダッシュボードの表示 |
| 11 | プロジェクト一覧 | 参照画面 | 参加プロジェクトの一覧表示 |
| 18 | アクティビティ画面 | 参照画面 | ユーザーアクティビティの表示 |

## 機能種別

データ取得・表示（READ操作）/ アクティビティ集約

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| filter | String | No | イベントフィルタ種別（your_projects/projects/starred/followed） | 許可値リストに含まれること |
| offset | Integer | No | イベント取得開始位置 | 0以上の整数 |
| limit | Integer | No | 取得イベント数 | 正の整数（MAX_LIMIT制限あり） |

### 入力データソース

- セッション情報（current_user）
- イベントフィルタ設定（Cookieまたはパラメータ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @homepage_app_data | Hash | ホームページ表示用データ（personal_homepage有効時） |
| @events | Array<Event> | アクティビティイベント配列 |
| @issues | Array<Issue> | 割り当てイシュー一覧 |
| @merge_requests | Array<MergeRequest> | 関連マージリクエスト一覧 |

### 出力先

- HTML画面（ダッシュボードビュー）
- JSON API（アクティビティ取得時）
- Atom/RSSフィード

## 処理フロー

### 処理シーケンス

```
1. 認証チェック
   └─ 未認証の場合はログイン画面へリダイレクト
2. フィーチャーフラグ確認
   └─ personal_homepageが有効か判定
3. ホームページデータ取得（home アクション）
   └─ homepage_app_dataの生成
   └─ 内部イベントの追跡（user_views_homepage）
4. アクティビティデータ取得（activity アクション）
   └─ フィルタに基づくイベント取得
   └─ イベントのレンダリング処理
5. イシュー/MR一覧取得
   └─ IssuableCollectionsAction経由でデータ取得
6. レスポンス生成
   └─ HTML/JSON形式で返却
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信] --> B{認証済み?}
    B -->|No| C[ログイン画面へリダイレクト]
    B -->|Yes| D{personal_homepage有効?}
    D -->|Yes| E[ホームページデータ取得]
    D -->|No| F[404エラー]
    E --> G[内部イベント追跡]
    G --> H[ビューレンダリング]

    I[activityアクション] --> J{JSONリクエスト?}
    J -->|Yes| K[イベントデータ取得]
    J -->|No| L[HTMLページ表示]
    K --> M[フィルタ適用]
    M --> N[イベントレンダリング]
    N --> O[JSON応答]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-121-01 | イベントフィルタリング | your_projects/projects/starredはプロジェクトイベント、followedはユーザーイベントを取得 | filterパラメータ指定時 |
| BR-121-02 | デフォルトイベント取得 | フィルタ未指定時は現在のユーザーのイベントを取得 | filterパラメータなし |
| BR-121-03 | イベント表示制限 | current_userが閲覧権限を持つイベントのみ表示 | 常時 |

### 計算ロジック

イベント取得数の制限：
- UserRecentEventsFinder: DEFAULT_LIMIT = 20, MAX_LIMIT = 100
- EventCollection: デフォルトoffset = 0

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ホーム表示 | users | SELECT | 現在ユーザー情報取得 |
| アクティビティ取得 | events | SELECT | ユーザー/プロジェクトイベント取得 |
| プロジェクト取得 | projects | SELECT | 参加・スタープロジェクト取得 |

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

#### events

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | author_id, action, target_type, target_id, created_at | author_id = current_user.id または projects IN authorized_projects | フィルタ条件による |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | 認証エラー | 未ログイン状態でアクセス | ログイン画面へリダイレクト |
| 404 | 機能無効 | personal_homepageフラグが無効 | not_foundを返却 |
| 400 | 不正リクエスト | Atomフォーマットでフィルタ未設定 | bad_request返却 |

### リトライ仕様

データベースタイムアウト時は標準的なRailsリトライ機構に従う。

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

読み取り専用のため、明示的なトランザクション管理は不要。

## パフォーマンス要件

- urgency: low（全アクション）
- イベント取得は最大100件に制限
- keyset paginationによる効率的なページネーション

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

- 認証必須（authenticate_sessionless_user!でRSS/ICS対応）
- クロスプロジェクトアクセスチェック
- ユーザープロファイル閲覧権限の確認

## 備考

- フロントエンド機能フラグ `global_time_tracking_report` がactivityアクションで有効化される
- EE版では追加のダッシュボード機能が提供される（DashboardController.prepend_mod_with）

---

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

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

### 推奨読解順序

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

ダッシュボードで表示されるイベントやユーザー情報の構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Event | `app/models/event.rb` | イベントの種類（action）とターゲット（target_type/target_id）の関連を理解 |
| 1-2 | User | `app/models/user.rb` | authorized_projects, followeesなどの関連を確認 |

**読解のコツ**: Eventモデルはpolymorphic associationを使用しており、target_typeによって異なるモデル（Issue, MergeRequest, Note等）を参照する。

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

コントローラーがリクエストをどのように処理するかを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DashboardController | `app/controllers/dashboard_controller.rb` | homeとactivityアクションの流れ |

**主要処理フロー**:
1. **37-45行目**: homeアクション - personal_homepageフラグチェックとホームページデータ取得
2. **47-56行目**: activityアクション - HTMLまたはJSONレスポンスの分岐
3. **64-76行目**: load_eventsメソッド - フィルタに基づくイベント取得ロジック

#### Step 3: イベント取得処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | UserRecentEventsFinder | `app/finders/user_recent_events_finder.rb` | ユーザーイベント取得のクエリ構築 |
| 3-2 | EventCollection | `app/services/event_collection.rb` | プロジェクトイベントの集約 |
| 3-3 | EventFilter | `app/models/event_filter.rb` | イベントフィルタリングロジック |

**主要処理フロー**:
- **UserRecentEventsFinder 40-47行目**: execute_singleでの単一ユーザーイベント取得
- **UserRecentEventsFinder 49-70行目**: execute_multiでの複数ユーザー（フォロー中）イベント取得

#### Step 4: ホームページデータを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | HomepageData concern | `app/controllers/concerns/homepage_data.rb` | homepage_app_dataの構築 |

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

```
DashboardController
    │
    ├─ home (action)
    │      ├─ Feature.enabled?(:personal_homepage)
    │      ├─ track_internal_event('user_views_homepage')
    │      └─ homepage_app_data(current_user)
    │
    ├─ activity (action)
    │      └─ load_events
    │             ├─ load_project_events
    │             │      ├─ ProjectsFinder
    │             │      └─ EventCollection
    │             └─ load_user_events
    │                    └─ UserRecentEventsFinder
    │
    └─ issues/merge_requests (actions)
           └─ IssuableCollectionsAction (concern)
                  ├─ IssuesFinder
                  └─ MergeRequestsFinder
```

### データフロー図

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

current_user ───────────▶ DashboardController ─────────────▶ HTML View
                               │
filter param ──────────────────┤
                               │
                         ┌─────┴─────┐
                         │           │
              UserRecentEventsFinder EventCollection
                         │           │
                         └─────┬─────┘
                               │
                         EventFilter
                               │
                         Events::RenderService
                               │
                               ▼
                         @events (Array<Event>)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DashboardController | `app/controllers/dashboard_controller.rb` | コントローラー | メインエントリーポイント |
| Dashboard::ApplicationController | `app/controllers/dashboard/application_controller.rb` | 基底コントローラー | 認証・共通処理 |
| UserRecentEventsFinder | `app/finders/user_recent_events_finder.rb` | ファインダー | ユーザーイベント取得 |
| EventCollection | `app/services/event_collection.rb` | サービス | プロジェクトイベント集約 |
| EventFilter | `app/models/event_filter.rb` | モデル | イベントフィルタリング |
| HomepageData | `app/controllers/concerns/homepage_data.rb` | Concern | ホームページデータ生成 |
| FiltersEvents | `app/controllers/concerns/filters_events.rb` | Concern | イベントフィルタ処理 |
| IssuableCollectionsAction | `app/controllers/concerns/issuable_collections_action.rb` | Concern | Issue/MR一覧取得 |
| Event | `app/models/event.rb` | モデル | イベントデータ構造 |
| events/_events | `app/views/events/_events.html.haml` | ビュー | イベント一覧表示 |
