# 画面設計書 29-スター一覧

## 概要

本ドキュメントは、GitLabのスター一覧画面に関する設計書である。この画面はプロジェクトをスター（お気に入り登録）したユーザーの一覧を表示する機能を提供する。

### 本画面の処理概要

スター一覧画面は、特定のプロジェクトをスターしたユーザーを一覧表示する。公開プロファイルのユーザー数と非公開プロファイルのユーザー数を表示し、検索やソート機能を提供する。

**業務上の目的・背景**：プロジェクトのスター数はプロジェクトの人気度や影響力を示す指標となる。この画面により、プロジェクトを支持しているユーザーを確認でき、コミュニティの形成状況やプロジェクトの評価を把握することができる。

**画面へのアクセス方法**：
- プロジェクト詳細画面のスター数をクリック
- 直接URL `/:namespace/:project/-/starrers` にアクセス

**主要な操作・処理内容**：
1. スター一覧の表示 - スターしたユーザーの一覧表示
2. ユーザー検索 - キーワードによるユーザーの絞り込み
3. ソート - 名前、スター日時でのソート
4. ユーザープロファイルへの遷移 - ユーザー名クリックで詳細画面へ

**画面遷移**：
- 遷移元：プロジェクト詳細画面
- 遷移先：各ユーザーのプロファイル画面

**権限による表示制御**：
- 全ユーザー：公開プロファイルのスターユーザーの閲覧
- 非公開プロファイルのユーザーは該当ユーザーまたは管理者のみ表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | プロジェクトスター | 主機能 | スターしたユーザー一覧表示 |

## 画面種別

一覧

## URL/ルーティング

- URL: `/:namespace/:project/-/starrers`
- ルーティング: `config/routes/project.rb` - `resources :starrers, only: [:index]`
- コントローラ: `Projects::StarrersController#index`

## 入出力項目

| 項目名 | 入力/出力 | 必須 | データ型 | 説明 |
|--------|----------|------|----------|------|
| search | 入力 | - | String | ユーザー名検索キーワード |
| sort | 入力 | - | String | ソート順（name_asc/name_desc/created_at等） |
| page | 入力 | - | Integer | ページ番号 |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 総スターユーザー数 | Integer | スターしたユーザーの総数 |
| 公開スターユーザー数 | Integer | 公開プロファイルのユーザー数 |
| 非公開スターユーザー数 | Integer | 非公開プロファイルのユーザー数 |
| スターユーザー一覧 | List | 各スターユーザーの情報 |
| ユーザー名 | String | スターしたユーザーの表示名 |
| ユーザー名リファレンス | String | @username形式のリファレンス |
| アバター | Image | ユーザーアバター画像 |
| スター日時 | DateTime | スターした日時 |
| 自分バッジ | Badge | 自分自身の場合に表示 |

## イベント仕様

### 1-ページ読み込み

1. `Projects::StarrersController#index` が呼び出される
2. `UsersStarProjectsFinder` でスターユーザーを検索
3. `preload_users` でユーザー情報をプリロード
4. `sort_by_attribute` でソート適用
5. ページネーション適用
6. スター数のカウント（総数、公開、非公開）
7. HTMLでレスポンス

### 2-検索

1. 検索フォームからsearchパラメータを送信
2. `UsersStarProjectsFinder#by_search` が検索パラメータでフィルタリング
3. `User.search` でユーザー名検索を実行
4. 検索結果を表示

### 3-ソート

1. ソートドロップダウンで順序を選択
2. `gl_redirect_listbox_tag` がsortパラメータ付きでリダイレクト
3. `sort_by_attribute` でソートされた結果を表示

### 4-ユーザープロファイルへの遷移

- ユーザー名をクリック
- 遷移先: `/:username`

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ読み込み | users_star_projects | SELECT | スターユーザー一覧の取得 |
| ページ読み込み | users | SELECT | ユーザー情報の取得 |

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

#### users_star_projects

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | project_id = @project.id | スター関係取得 |

#### users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | users_star_projects.user_id経由 | ユーザー情報取得 |

## メッセージ仕様

| 種別 | メッセージID | メッセージ内容 | 表示条件 |
|------|------------|--------------|---------|
| 情報 | starrers_count | X starrers: X public and X private | ヘッダー表示 |
| バッジ | its_you | It's you | 自分自身の場合 |
| 情報 | no_starrers_search | No starrers matched your search | 検索結果なし |
| 情報 | no_starrers | Nobody has starred this repository yet | スターなし |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| プロジェクトが存在しない | 404エラー |
| プロジェクト閲覧権限がない | アクセス拒否 |

## 備考

- スター一覧はユーザーのプロファイル公開設定に基づいてフィルタリングされる
- 非公開プロファイルのユーザーは該当ユーザー自身または管理者のみ表示
- ページネーションを使用して大量のスターユーザーを効率的に表示
- `Pajamas::CardComponent` を使用したカードレイアウトで表示
- `Pajamas::AvatarComponent` を使用してアバターを表示

---

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

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

### 推奨読解順序

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

スター関係に関連するモデルとファインダーを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | users_star_project.rb | `app/models/users_star_project.rb` | スター関係モデル |
| 1-2 | users_star_projects_finder.rb | `app/finders/users_star_projects_finder.rb` | スターユーザー検索ロジック |

**読解のコツ**: `UsersStarProject` モデルのスコープ（`with_active_user`, `with_visible_profile`, `sort_by_attribute`）でフィルタリングとソートの仕組みを理解する。

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

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

**主要処理フロー**:
1. **10-17行目**: `index` アクション
2. **11行目**: `UsersStarProjectsFinder` でスターユーザー検索
3. **12行目**: `@sort` パラメータ取得（デフォルトは `sort_value_name`）
4. **13行目**: `preload_users`, `sort_by_attribute`, `page` でデータ準備
5. **14-16行目**: スター数のカウント（総数、公開、非公開）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/projects/starrers/index.html.haml` | メインビュー |
| 3-2 | _starrer.html.haml | `app/views/projects/starrers/_starrer.html.haml` | スターユーザーパーシャル |

**主要処理フロー**:
- **1行目（index.html.haml）**: ページタイトル設定
- **4-7行目（index.html.haml）**: ヘッダーとスター数表示
- **8-17行目（index.html.haml）**: 検索フォームとソートドロップダウン
- **18-21行目（index.html.haml）**: スターユーザー一覧とページネーション
- **4-19行目（_starrer.html.haml）**: カードコンポーネントでユーザー表示

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

```
Projects::StarrersController#index
    │
    ├─ UsersStarProjectsFinder.new(@project, params, current_user).execute
    │      │
    │      ├─ UsersStarProject.with_active_user
    │      │
    │      ├─ by_project(@project)
    │      │
    │      ├─ by_search(params[:search])
    │      │      └─ User.search(query)
    │      │
    │      └─ filter_visible_profiles
    │             └─ with_visible_profile(@current_user)
    │
    ├─ @starrers.preload_users
    │
    ├─ @starrers.sort_by_attribute(@sort)
    │      ├─ order_user_name_asc (name_asc)
    │      ├─ order_user_name_desc (name_desc)
    │      └─ order_by(method) (その他)
    │
    ├─ @starrers.page(params[:page])
    │
    └─ スター数カウント
           ├─ @project.starrers.active.with_public_profile.size
           └─ @project.starrers.active.size
```

### データフロー図

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

リクエスト ───▶ StarrersController#index ───▶ @starrers
    │                     │
    ├─ search            ├─ UsersStarProjectsFinder
    │                     │      │
    ├─ sort              │      ├─ アクティブユーザーフィルタ
    │                     │      │
    └─ page              │      ├─ プロジェクトフィルタ
                         │      │
                         │      ├─ 検索フィルタ
                         │      │
                         │      └─ プロファイル可視性フィルタ
                         │
                         ├─ ソート適用
                         │
                         ├─ ページネーション
                         │
                         └─────────────────▶ HTML レスポンス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| starrers_controller.rb | `app/controllers/projects/starrers_controller.rb` | コントローラ | リクエストハンドリング |
| index.html.haml | `app/views/projects/starrers/index.html.haml` | テンプレート | メインビュー |
| _starrer.html.haml | `app/views/projects/starrers/_starrer.html.haml` | パーシャル | スターユーザーカード |
| users_star_projects_finder.rb | `app/finders/users_star_projects_finder.rb` | ファインダー | スターユーザー検索ロジック |
| users_star_project.rb | `app/models/users_star_project.rb` | モデル | スター関係 |
| project.rb | `config/routes/project.rb` | ルーティング | URL定義 |
