# 画面設計書 11-プロジェクト一覧

## 概要

本ドキュメントは、GitLabダッシュボードのプロジェクト一覧画面（Dashboard Projects Index）の画面設計を定義したものである。

### 本画面の処理概要

ログインユーザーが参加しているプロジェクトの一覧を表示し、プロジェクトへの迅速なアクセスを可能にするダッシュボード画面である。

**業務上の目的・背景**：ユーザーは複数のプロジェクトに参加することが一般的であり、それらを一元管理・把握する必要がある。本画面は、ユーザーが関与するすべてのプロジェクトを一覧で確認し、目的のプロジェクトへ素早くアクセスするための起点となる。プロジェクトの最終活動日時やスター数などの情報も表示され、プロジェクトの状況把握を支援する。

**画面へのアクセス方法**：ログイン後、サイドバーまたはトップナビゲーションから「Projects」メニューを選択。直接URLアクセスの場合は `/dashboard/projects` へアクセスする。

**主要な操作・処理内容**：
1. プロジェクト一覧の表示（ページネーション対応）
2. プロジェクト名による検索・フィルタリング
3. ソート順の変更（名前順、最終活動日時順、作成日順など）
4. プロジェクトへのスター追加・削除
5. 各プロジェクトの詳細画面への遷移
6. 新規プロジェクト作成画面への遷移
7. プロジェクトのフィルタリング（Personal、Contributed、Starred、Memberなど）

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

**権限による表示制御**：ログインユーザーのみアクセス可能。表示されるプロジェクトはユーザーがメンバーとして参加しているプロジェクト、または公開・内部公開プロジェクトに限定される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 123 | プロジェクトダッシュボード | 主機能 | 参加プロジェクトの一覧表示 |
| 6 | プロジェクトスター | 補助機能 | プロジェクトのスター追加・削除 |

## 画面種別

一覧

## URL/ルーティング

| URL | HTTPメソッド | 説明 |
|-----|-------------|------|
| `/dashboard/projects` | GET | プロジェクト一覧（HTML） |
| `/dashboard/projects.atom` | GET | プロジェクト一覧（ATOMフィード） |
| `/dashboard/projects/contributed` | GET | コントリビュートしたプロジェクト一覧 |
| `/dashboard/projects/starred` | GET | スターしたプロジェクト一覧 |
| `/dashboard/projects/personal` | GET | 個人プロジェクト一覧 |
| `/dashboard/projects/member` | GET | メンバーのプロジェクト一覧 |
| `/dashboard/projects/inactive` | GET | 非アクティブプロジェクト一覧 |

## 入出力項目

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

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| sort | string | No | ソート順（name, latest_activity_asc, latest_activity_desc, created_asc, created_desc, stars_desc） |
| personal | boolean | No | 個人プロジェクトのみ表示フラグ |
| archived | string | No | アーカイブ状態フィルタ（only, true, false） |
| name | string | No | プロジェクト名検索 |
| page | integer | No | ページ番号 |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| projects | Array | プロジェクト一覧 |
| @sort | string | 現在のソート順 |

## 表示項目

### プロジェクト一覧

| 項目名 | 説明 | 備考 |
|--------|------|------|
| プロジェクトアバター | プロジェクトのアイコン画像 | |
| プロジェクト名 | プロジェクトのフルパス（namespace/project_name） | リンク |
| 説明 | プロジェクトの説明文 | 省略表示 |
| スター数 | プロジェクトへのスター数 | |
| フォーク数 | プロジェクトのフォーク数 | |
| 最終活動日時 | 最後にアクティビティがあった日時 | 相対時間表示 |
| 可視性アイコン | Public/Internal/Private | アイコン表示 |
| トピック | プロジェクトに設定されたトピック | バッジ表示 |

## イベント仕様

### 1-プロジェクトリストの読み込み

Vue.jsアプリケーション（`#js-your-work-projects-app`）がマウントされ、APIを通じてプロジェクト一覧を取得する。

**処理フロー**：
1. ページ読み込み時にVueアプリケーションが初期化
2. `dashboard_projects_app_data`からアプリケーション設定を取得
3. JSON APIを通じてプロジェクト一覧を非同期取得
4. フィルタ・ソート条件に基づいてリストを表示

### 2-ソート順変更

ソート条件を変更すると、URLパラメータが更新され、プロジェクト一覧が再取得される。

### 3-プロジェクトスター操作

スターボタンをクリックすると、該当プロジェクトにスターが追加または削除される。

**処理フロー**：
1. スターボタンクリック
2. Star APIへPOST/DELETEリクエスト
3. 成功時、スター数とボタン状態を更新

### 4-検索・フィルタリング

検索ボックスに入力またはフィルタを選択すると、条件に合致するプロジェクトのみ表示される。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ表示 | projects | SELECT | ユーザーが参加しているプロジェクトを取得 |
| スター追加 | users_star_projects | INSERT | ユーザーとプロジェクトの関連を作成 |
| スター削除 | users_star_projects | DELETE | ユーザーとプロジェクトの関連を削除 |
| スター操作 | projects | UPDATE | star_countの更新 |

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

#### projects

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, path, namespace_id, description, visibility_level, star_count, last_activity_at | ユーザーがアクセス可能なプロジェクト | ProjectsFinder経由 |

#### users_star_projects

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | user_id, project_id, created_at | current_user.id, project.id, Time.current | スター追加時 |
| DELETE | - | user_id = current_user.id AND project_id = target.id | スター削除時 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | 情報 | "You don't have any projects yet." | プロジェクトが存在しない場合 |
| MSG-002 | 情報 | "Create a project or explore public projects" | ウェルカムページ表示時 |

## 例外処理

| 例外条件 | 処理内容 | 表示メッセージ |
|----------|----------|---------------|
| 未ログイン | ログイン画面へリダイレクト | - |
| ページ範囲外 | 最終ページを表示 | - |
| API通信エラー | エラーメッセージ表示 | "Something went wrong. Please try again." |

## 備考

- Vue.jsベースのSPA実装（`#js-your-work-projects-app`）
- ATOMフィードによるRSS購読に対応
- 最後のプッシュ情報がある場合はバナー表示（`_last_push`パーシャル）
- Ultimate Trial広告の表示機能あり

---

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

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

### 推奨読解順序

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

まず、プロジェクトのデータ構造とFinderパターンを理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | project.rb | `app/models/project.rb` | Projectモデルの定義、アソシエーション、スコープ |
| 1-2 | projects_finder.rb | `app/finders/projects_finder.rb` | プロジェクト検索ロジック、フィルタリング条件 |

**読解のコツ**: Railsのモデルはincludeで多くのモジュールを取り込んでいる。主要なスコープとアソシエーションに注目すること。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | projects_controller.rb | `app/controllers/dashboard/projects_controller.rb` | indexアクション、before_actionフィルタ |

**主要処理フロー**:
1. **Line 11**: `prepend_before_action`でRSS認証を処理
2. **Line 12**: `before_action :set_non_archived_param`でアーカイブフィルタ設定
3. **Line 13**: `before_action :set_sorting`でソート条件設定
4. **Line 19-32**: `index`アクションでHTML/ATOMレスポンスを分岐

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/dashboard/projects/index.html.haml` | HAMLテンプレート、Vue.jsアプリのマウントポイント |

**主要処理フロー**:
- **Line 13-17**: プロジェクト有無による条件分岐、Vueアプリのマウント

#### Step 4: ルーティングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | dashboard.rb | `config/routes/dashboard.rb` | ダッシュボードプロジェクト関連のルート定義 |

**主要処理フロー**:
- **Line 27-35**: projectsリソースとコレクションルートの定義

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

```
Dashboard::ProjectsController#index
    |
    +-- set_non_archived_param (before_action)
    |
    +-- set_sorting (before_action)
    |
    +-- render 'dashboard/projects/index'
           |
           +-- render "projects/last_push"
           |
           +-- show_dashboard_projects_welcome_page? (条件分岐)
           |      |
           |      +-- render "zero_authorized_projects" (プロジェクトなし)
           |      |
           |      +-- render 'dashboard/projects_head' (プロジェクトあり)
           |             |
           |             +-- #js-your-work-projects-app (Vue.js)
           |
           +-- dashboard_projects_app_data (ヘルパー)
```

### データフロー図

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

URLパラメータ ───▶ Dashboard::ProjectsController ───▶ HTMLレスポンス
(sort, page等)          |                              (Vue.jsアプリ)
                        |
                        v
                   ProjectsFinder
                        |
                        v
                   Project (Model)
                        |
                        v
                   PostgreSQL
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| projects_controller.rb | `app/controllers/dashboard/projects_controller.rb` | コントローラ | リクエスト処理、レスポンス生成 |
| index.html.haml | `app/views/dashboard/projects/index.html.haml` | ビュー | 画面テンプレート |
| projects_finder.rb | `app/finders/projects_finder.rb` | ファインダー | プロジェクト検索ロジック |
| project.rb | `app/models/project.rb` | モデル | プロジェクトデータ定義 |
| dashboard.rb | `config/routes/dashboard.rb` | ルート | URL定義 |
| _projects_head.html.haml | `app/views/dashboard/_projects_head.html.haml` | パーシャル | ヘッダー部分 |
| _last_push.html.haml | `app/views/projects/_last_push.html.haml` | パーシャル | 最終プッシュバナー |
