# 画面設計書 187-組織アクティビティ

## 概要

本ドキュメントは、GitLabの組織アクティビティ画面の設計を記述したものである。

### 本画面の処理概要

**業務上の目的・背景**：組織内で行われた活動（コミット、マージリクエスト、イシュー等）を時系列で表示する画面である。組織管理者やメンバーが組織全体の活動状況を把握し、進捗確認やコラボレーションの状況を監視するために使用される。イベントタイプによるフィルタリング機能により、特定の種類の活動に絞って確認できる。

**画面へのアクセス方法**：組織のサイドナビゲーションから「Activity」を選択、または直接URL `/-/organizations/:organization_path/activity` にアクセスする。

**主要な操作・処理内容**：
1. 組織内の最近のアクティビティ一覧表示
2. イベントタイプによるフィルタリング（Comment、Design、Issue、Merge、Repository、Membership、Wiki）
3. ページネーションによる過去のアクティビティ閲覧
4. 各イベントの詳細リンクへの遷移

**画面遷移**：
- 遷移元：組織詳細画面（184-組織詳細）、サイドナビゲーション
- 遷移先：各イベントの詳細画面（コミット詳細、MR詳細、イシュー詳細等）

**権限による表示制御**：
- `read_organization` 権限を持つユーザーが閲覧可能
- 公開組織の場合、未ログインユーザーも閲覧可能
- 表示されるイベントはユーザーの閲覧権限に基づいてフィルタリングされる

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 136 | アクティビティフィード | 主機能 | 組織アクティビティの表示 |

## 画面種別

一覧

## URL/ルーティング

- パス: `/-/organizations/:organization_path/activity`
- HTTPメソッド: GET（HTML）、GET（JSON）
- コントローラー: `Organizations::OrganizationsController#activity`

## 入出力項目

| 項目名 | 項目ID | データ型 | 必須 | 入力形式 | 説明 |
|--------|--------|----------|------|----------|------|
| イベントフィルター | event_filter | String | No | セレクト | all/comments/designs/issue/merged/push/team/wiki |
| オフセット | offset | Integer | No | 数値 | ページネーション用オフセット |
| リミット | limit | Integer | No | 数値 | 1ページあたりの件数（デフォルト20） |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| ページタイトル | 見出し | "Activity" |
| フィルター | フィルタードサーチ | イベントタイプの絞り込み |
| イベント一覧 | リスト | アクティビティカードの一覧 |
| イベントカード | カード | ユーザー、アクション、対象、日時 |
| 空状態 | メッセージ | "No activities found" |
| ページネーション | ナビゲーション | 前/次ページボタン |
| ローディング | インジケーター | データ取得中の表示 |

## イベント仕様

### 1-フィルター変更

1. イベントタイプを選択
2. 現在のオフセットをリセット（0に）
3. 選択されたフィルターでイベントを再取得
4. 一覧を更新表示

### 2-ページネーション（次ページ）

1. 現在のオフセット + DEFAULT_PER_PAGE を計算
2. 新しいオフセットでイベントを取得
3. 一覧を更新表示

### 3-ページネーション（前ページ）

1. 現在のオフセット - DEFAULT_PER_PAGE を計算（最小0）
2. 新しいオフセットでイベントを取得
3. 一覧を更新表示

### 4-イベントカードクリック

1. 該当イベントの詳細画面へ遷移（コミット詳細、MR詳細等）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | events | SELECT | イベント一覧の取得 |
| 画面表示 | projects | SELECT | プロジェクト情報の取得 |
| 画面表示 | groups | SELECT | グループ情報の取得 |

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

この画面では参照のみを行い、データベースの更新は発生しない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | エラー | An error occurred loading the activity. Please refresh the page to try again. | データ取得エラー時 |
| MSG-002 | 情報 | No activities found | イベントが存在しない場合 |

## 例外処理

| 例外パターン | 処理内容 |
|-------------|----------|
| 権限不足 | アクセス拒否（403） |
| データ取得エラー | アラートでエラーメッセージを表示 |
| イベント閲覧権限なし | 該当イベントを非表示（サーバーサイドフィルタ） |

## 備考

- イベントデータはJSON形式でAjax取得される（`activity_organization_path` + `format: :json`）
- 1ページあたりの件数は `DEFAULT_PER_PAGE`（20件）
- `limit + 1` を取得して次ページの有無を判定
- イベントの可視性は `event.visible_to_user?(current_user)` で判定される
- イベントレンダリングは `Events::RenderService` で処理される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | event.rb | `app/models/event.rb` | イベントモデルの構造 |
| 1-2 | event_filter.rb | `app/models/event_filter.rb` | フィルター定数の定義 |

**読解のコツ**: `EventFilter::ALL`, `EventFilter::COMMENTS` 等の定数を確認すること。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | organizations_controller.rb | `app/controllers/organizations/organizations_controller.rb` | activityアクション |

**主要処理フロー**:
1. **行13**: `before_action :event_filter, only: [:activity]` - フィルターの設定
2. **行14**: `before_action :authorize_read_organization!` - 権限チェック
3. **行31-48**: `def activity` - HTML/JSON両対応のレスポンス

#### Step 3: ヘルパーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | organization_helper.rb | `app/helpers/organizations/organization_helper.rb` | organization_activity_app_data |

**主要処理フロー**:
- **行78-84**: `organization_activity_app_data` - Vue用データ準備
- **行150-180**: `organization_activity_event_types` - フィルターオプション

#### Step 4: フロントエンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | activity.html.haml | `app/views/organizations/organizations/activity.html.haml` | マウントポイント |
| 4-2 | app.vue | `app/assets/javascripts/organizations/activity/components/app.vue` | メインコンポーネント |
| 4-3 | filters.js | `app/assets/javascripts/organizations/activity/filters.js` | フィルター変換処理 |

**主要処理フロー**:
- **行82-84**: `mounted` - 初期データ取得
- **行86-90**: `onSearchFilter` - フィルター変更処理
- **行92-114**: `fetchEvents` - Ajaxでイベント取得

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

```
activity.html.haml
    │
    └─ #js-organizations-activity (Vue mount point)
           │
           └─ OrganizationsActivityApp (app.vue)
                  │
                  ├─ FilteredSearch
                  │      └─ イベントタイプフィルター
                  │
                  ├─ ContributionEvents
                  │      └─ イベントカード表示
                  │
                  └─ GlKeysetPagination / GlEmptyState
```

### データフロー図

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

URLアクセス ───▶ OrganizationsController#activity (HTML)
                      │
                      └─▶ HAMLテンプレート
                              │
                              └─▶ Vue.js App
                                      │
                                      └─ mounted: fetchEvents

フィルター変更 ─▶ onSearchFilter
                      │
                      └─ fetchEvents(offset=0)

ページ遷移 ────▶ handleNext/handlePrevPage
                      │
                      └─ fetchEvents(newOffset)

fetchEvents ────▶ axios.get (activity.json)
                      │
                      └─ OrganizationsController#activity (JSON)
                              │
                              ├─ EventCollection
                              │      └─ load_events
                              │
                              ├─ Events::RenderService
                              │
                              └─▶ JSON Response
                                      │
                                      └─▶ イベント一覧表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| organizations_controller.rb | `app/controllers/organizations/organizations_controller.rb` | コントローラー | リクエスト処理 |
| activity.html.haml | `app/views/organizations/organizations/activity.html.haml` | ビュー | マウントポイント |
| app.vue | `app/assets/javascripts/organizations/activity/components/app.vue` | Vue | メインコンポーネント |
| filters.js | `app/assets/javascripts/organizations/activity/filters.js` | JavaScript | フィルター処理 |
| contribution_events.vue | `app/assets/javascripts/contribution_events/components/contribution_events.vue` | Vue | イベント表示 |
| organization_helper.rb | `app/helpers/organizations/organization_helper.rb` | ヘルパー | app_data生成 |
| event_collection.rb | `app/models/event_collection.rb` | モデル | イベント取得 |
| render_service.rb | `app/services/events/render_service.rb` | サービス | イベントレンダリング |
