# 画面設計書 20-グループ探索

## 概要

本ドキュメントは、GitLabのグループ探索画面（Explore Groups Index）の画面設計を定義したものである。

### 本画面の処理概要

公開されているグループを探索・検索するための画面である。未ログインユーザーでもアクセス可能。

**業務上の目的・背景**：GitLabでは、グループを使用してプロジェクトやユーザーを組織化する。本画面は、PublicまたはInternalなグループを検索・閲覧し、興味のあるグループを見つけて参加リクエストを送信したり、グループ内のプロジェクトを確認したりするための入口となる。

**画面へのアクセス方法**：サイドバーまたはナビゲーションから「Explore」>「Groups」メニューを選択。直接URLアクセスの場合は `/explore/groups` へアクセスする。

**主要な操作・処理内容**：
1. 公開グループ一覧の表示（ページネーション対応）
2. グループ名検索
3. 各グループの詳細画面への遷移
4. 新規グループ作成画面への遷移（権限がある場合）
5. グループへの参加リクエスト

**画面遷移**：
- 遷移元：トップページ、サイドバー、ナビゲーション
- 遷移先：グループ詳細画面、グループ新規作成画面

**権限による表示制御**：未ログインユーザーはPublicグループのみ閲覧可能。ログインユーザーはPublic + Internalグループを閲覧可能。「New group」ボタンはグループ作成権限がある場合のみ表示。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | グループ管理 | 主機能 | 公開グループの探索 |

## 画面種別

一覧

## URL/ルーティング

| URL | HTTPメソッド | 説明 |
|-----|-------------|------|
| `/explore/groups` | GET | グループ探索（HTML） |
| `/explore/groups.json` | GET | グループ探索（JSON API） |

## 入出力項目

### 入力項目（検索・フィルタ）

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| filter | string | No | グループ名検索 |
| active | boolean | No | アクティブフィルタ |
| page | integer | No | ページ番号 |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @groups | Array | グループ一覧 |

## 表示項目

### グループ一覧

| 項目名 | 説明 | 備考 |
|--------|------|------|
| グループ名 | グループのフルパス | リンク |
| アバター | グループのアバター画像 | |
| 説明 | グループの説明 | 部分表示 |
| 可視性 | Public/Internal | アイコン表示 |
| メンバー数 | グループのメンバー数 | |
| プロジェクト数 | グループ内のプロジェクト数 | |
| サブグループ数 | サブグループの数 | |

## イベント仕様

### 1-グループリストの読み込み

ページ読み込み時にGroupsFinderを使用してグループ一覧を取得する。

**処理フロー**：
1. GroupTree concernによるグループツリー構築
2. GroupsFinderによるグループ検索
3. MAX_QUERY_SIZE（10,000）による制限
4. テンプレートレンダリング

### 2-検索実行

検索フォームにグループ名を入力して検索すると、マッチするグループが表示される。

### 3-新規グループ作成

「New group」ボタンをクリックすると、グループ新規作成画面へ遷移する（権限がある場合のみ表示）。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ表示 | namespaces | SELECT | フィルタ条件に合致するグループを取得 |
| ページ表示 | routes | SELECT | グループのルート情報取得 |

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

#### namespaces

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, path, description, visibility_level, type | type: 'Group', visibility_level: public/internal | GroupsFinder経由 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | 情報 | "No groups found" | グループが存在しない場合 |
| MSG-002 | 説明 | "Below you will find all the groups that are public or internal. Contribute by requesting to join a group." | 常時表示 |

## 例外処理

| 例外条件 | 処理内容 | 表示メッセージ |
|----------|----------|---------------|
| 検索結果なし | 空状態UI表示 | No groups found |

## 備考

- サーバーサイドレンダリング + Vue.jsのハイブリッド実装（explore_groups_vueフラグで切り替え）
- HTML/JSON両形式のレスポンスをサポート
- GroupTree concernによるグループ階層構造の表示
- MAX_QUERY_SIZE: 10,000件の制限
- breadcrumb_titleとheader_titleの設定
- Pajamas::ButtonComponentによるUIコンポーネント使用

---

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

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

### 推奨読解順序

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

まず、グループのデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | group.rb | `app/models/group.rb` | Groupモデルの定義 |
| 1-2 | groups_finder.rb | `app/finders/groups_finder.rb` | グループ検索ロジック |

**読解のコツ**: GroupはNamespaceを継承し（STI）、サブグループ階層構造を持つ。visibility_levelでPublic/Internal/Privateを制御。

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

処理の起点となるコントローラを特定する。

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

**主要処理フロー**:
1. **Line 4**: GroupTree concernをinclude
2. **Line 6-7**: feature_category、urgency設定
3. **Line 9**: MAX_QUERY_SIZE定数（10,000）
4. **Line 11-25**: indexアクションでHTML/JSON形式を分岐
5. **Line 14-19**: explore_groups_vueフラグによる条件分岐
6. **Line 29-31**: render_groupsメソッドでGroupsFinder実行

#### Step 3: ビューテンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/explore/groups/index.html.haml` | HAMLテンプレート |

**主要処理フロー**:
- **Line 1-3**: breadcrumb_title、page_title、header_title設定
- **Line 5-6**: Ultimate Trial、Product Usage Data表示
- **Line 8-17**: ページタイトルとNew groupボタン
- **Line 19-22**: explore_groups_vueフラグによる条件分岐
- **Line 20**: Vue.jsアプリのマウント（`#js-explore-groups`）
- **Line 22**: SSR版のgroupsパーシャル

#### Step 4: GroupTree concernを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | group_tree.rb | `app/controllers/concerns/group_tree.rb` | render_group_tree |

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

```
Explore::GroupsController#index
    |
    +-- respond_to
            |
            +-- format.html
            |       |
            |       +-- [explore_groups_vue enabled]
            |       |       |
            |       |       +-- push_force_frontend_feature_flag(:explore_groups_vue, true)
            |       |       +-- render :index (Vue.js mount)
            |       |
            |       +-- [explore_groups_vue disabled]
            |               |
            |               +-- render_groups
            |
            +-- format.json
                    |
                    +-- render_groups
                            |
                            +-- render_group_tree (GroupTree concern)
                                    |
                                    +-- GroupsFinder.new(current_user, active: params[:active]).execute
                                    +-- .limit(MAX_QUERY_SIZE)
```

### データフロー図

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

URLパラメータ ───▶ Explore::GroupsController ───▶ HTML/JSONレスポンス
(filter, active)        |
                        v
                  GroupsFinder
                        |
                        v
                  Group (Model/Namespace)
                        |
                        v
                  PostgreSQL
                        |
                        v
                  render_group_tree
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| groups_controller.rb | `app/controllers/explore/groups_controller.rb` | コントローラ | リクエスト処理 |
| index.html.haml | `app/views/explore/groups/index.html.haml` | ビュー | 画面テンプレート |
| _groups.html.haml | `app/views/explore/groups/_groups.html.haml` | パーシャル | グループリスト |
| groups_finder.rb | `app/finders/groups_finder.rb` | ファインダー | グループ検索 |
| group.rb | `app/models/group.rb` | モデル | グループデータ定義 |
| group_tree.rb | `app/controllers/concerns/group_tree.rb` | Concern | グループツリー構築 |
| explore.rb | `config/routes/explore.rb` | ルート | URL定義 |
