# 画面設計書 24-プロジェクト詳細

## 概要

本ドキュメントは、GitLabのプロジェクト詳細画面（プロジェクトトップページ）に関する設計書である。この画面はプロジェクトの概要情報を表示し、リポジトリ、課題、マージリクエストなど各種機能へのハブとして機能する重要な画面である。

### 本画面の処理概要

プロジェクト詳細画面は、プロジェクトのトップページとして機能し、プロジェクトの基本情報、リポジトリの内容（README、ファイルツリー）、最近のアクティビティなどを表示する。ユーザーがプロジェクトにアクセスした際に最初に表示される画面である。

**業務上の目的・背景**：プロジェクト詳細画面は、開発者がプロジェクトの概要を把握し、各種機能（コード、課題、CI/CD等）に迅速にアクセスするための中央ハブとして設計されている。READMEの表示により、プロジェクトの目的や使用方法を理解しやすくし、新規参加者のオンボーディングを支援する。また、最新のアクティビティを表示することで、プロジェクトの活動状況を一目で確認できる。

**画面へのアクセス方法**：
- ダッシュボードのプロジェクト一覧からプロジェクト名をクリック
- サイドバーのプロジェクトメニューから選択
- 直接URL `/:namespace/:project` にアクセス
- 検索結果からプロジェクトを選択

**主要な操作・処理内容**：
1. プロジェクト概要の表示 - 名前、説明、アバター、可視性レベル
2. READMEの表示 - リポジトリ内のREADMEファイル内容を表示
3. ファイルツリーの表示 - リポジトリのルートディレクトリ構造を表示
4. アクティビティの表示 - 最近のプロジェクト活動
5. スター/フォーク操作 - プロジェクトへのスター追加、フォーク作成
6. 各種機能へのナビゲーション - サイドバーから各機能画面への遷移

**画面遷移**：
- 遷移元：ダッシュボード、探索画面、検索結果、他プロジェクトからのリンク
- 遷移先：ファイルツリー、ファイル詳細、課題一覧、MR一覧、パイプライン一覧、設定画面、フォーク画面

**権限による表示制御**：
- 未ログインユーザー：公開プロジェクトの概要閲覧、コード閲覧（公開時）
- ログインユーザー：アクセス権限に応じた機能表示、スター機能
- メンバー/オーナー：設定へのアクセス、管理機能の表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | プロジェクト作成 | 主機能 | プロジェクトトップページ・概要表示 |
| 136 | アクティビティフィード | 補助機能 | プロジェクトアクティビティの表示 |
| 6 | プロジェクトスター | 補助機能 | スター追加・削除 |

## 画面種別

詳細

## URL/ルーティング

- URL: `/:namespace/:project`
- ルーティング: `config/routes/project.rb`
- コントローラ: `ProjectsController#show`

## 入出力項目

| 項目名 | 入力/出力 | 必須 | データ型 | 説明 |
|--------|----------|------|----------|------|
| namespace_id | 入力 | 必須 | String | 名前空間（グループまたはユーザー） |
| project_id | 入力 | 必須 | String | プロジェクトパス |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| プロジェクト名 | String | プロジェクトの名前 |
| プロジェクトアバター | Image | プロジェクトのアイコン画像 |
| 可視性レベル | Enum | public/internal/private |
| 説明 | Text | プロジェクトの説明文 |
| トピック | Array | プロジェクトに付与されたトピック |
| スター数 | Integer | スター数 |
| フォーク数 | Integer | フォーク数 |
| README | Markdown | READMEファイルの内容（レンダリング済み） |
| ファイルツリー | Tree | リポジトリのディレクトリ構造 |
| 最終コミット情報 | Object | 最新コミットの情報 |
| アクティビティ | Array | 最近のプロジェクト活動 |

## イベント仕様

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

1. `ProjectsController#show` が呼び出される
2. `repository_root` でデフォルトブランチ（root_ref）を取得
3. インポート中の場合はインポート画面にリダイレクト
4. 削除予定の場合は警告メッセージを表示
5. `render_landing_page` で適切なビューを選択
6. リポジトリが存在しない場合は `projects/no_repo` を表示
7. デフォルトブランチが空の場合は `projects/missing_default_branch` を表示
8. 空リポジトリの場合は `projects/empty` を表示
9. 通常は `projects/show` を表示

### 2-スター切り替え

1. `ProjectsController#toggle_star` が呼び出される
2. `current_user.toggle_star(@project)` でスター状態を切り替え
3. 新しいスター数をJSONで返却

### 3-フォーク作成

- 遷移先: `/:namespace/:project/-/forks/new`

### 4-ファイル選択

- 遷移先: `/:namespace/:project/-/blob/:ref/:path`

### 5-設定画面へ

- 遷移先: `/:namespace/:project/edit`
- 権限: `admin_project` 権限が必要

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ読み込み | projects | SELECT | プロジェクト情報の取得 |
| ページ読み込み | users | SELECT | オーナー/メンバー情報の取得 |
| ページ読み込み | events | SELECT | アクティビティの取得 |
| スター切り替え | users_star_projects | INSERT/DELETE | スター状態の更新 |
| スター切り替え | projects | UPDATE | star_countの更新 |

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

#### projects

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | id = @project.id | プロジェクト全情報 |
| UPDATE | star_count | インクリメント/デクリメント | スター切り替え時 |

#### users_star_projects

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

## メッセージ仕様

| 種別 | メッセージID | メッセージ内容 | 表示条件 |
|------|------------|--------------|---------|
| 警告 | pending_delete | Project '%{project_name}' queued for deletion. | 削除予定の場合 |
| 情報 | empty_repo | This project is empty | 空リポジトリの場合 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| プロジェクトが存在しない | 404エラーページを表示 |
| アクセス権限がない | 404エラーページを表示（存在を隠す） |
| リポジトリが存在しない | no_repoビューを表示 |
| デフォルトブランチが欠損 | missing_default_branchビュー（503） |
| インポート中 | インポート状態画面にリダイレクト |

## 備考

- ATOMフィードに対応（`project_path(@project, rss_url_options)`）
- GraphQL APIを使用した非同期データ取得（最終コミット情報等）
- Gitaly連携によるリポジトリデータ取得
- `project_overview` イベントがトラッキングされる

---

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

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

### 推奨読解順序

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

プロジェクトのデータモデルと関連エンティティを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | project.rb | `app/models/project.rb` | Projectモデルの構造、アソシエーション |
| 1-2 | repository.rb | `app/models/repository.rb` | リポジトリ操作のラッパー |
| 1-3 | project_presenter.rb | `app/presenters/project_presenter.rb` | ビュー用のプレゼンター |

**読解のコツ**: `default_view` メソッドでプロジェクトの表示モードが決定される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | projects_controller.rb | `app/controllers/projects_controller.rb` | showアクションとrender_landing_page |

**主要処理フロー**:
1. **172-199行目**: `show` アクション
2. **173行目**: `repository_root` でルートref取得
3. **176-179行目**: インポート中チェックとリダイレクト
4. **181-183行目**: 削除予定フラグの警告表示
5. **185行目**: `ref_type` 設定
6. **187-198行目**: レスポンスフォーマット分岐
7. **431-450行目**: `render_landing_page` - 表示ロジック分岐

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/projects/show.html.haml` | メインビュー |
| 3-2 | _home_panel.html.haml | `app/views/projects/_home_panel.html.haml` | プロジェクトヘッダー |
| 3-3 | _sidebar.html.haml | `app/views/projects/_sidebar.html.haml` | サイドバー情報 |

**主要処理フロー**:
- **15行目（show.html.haml）**: `_home_panel` パーシャルでヘッダー表示
- **21行目（show.html.haml）**: `_sidebar` パーシャルでサイドバー表示
- **29-30行目（show.html.haml）**: `default_view` に基づく動的コンテンツ表示

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

```
ProjectsController#show
    │
    ├─ repository_root
    │      └─ @project.repository.root_ref
    │
    ├─ import_in_progress? チェック
    │      └─ redirect_to project_import_path
    │
    ├─ pending_delete? チェック
    │      └─ flash[:alert] 設定
    │
    ├─ @project.present(current_user)
    │
    └─ render_landing_page
           │
           ├─ can?(current_user, :read_code, @project)
           │      ├─ repository_exists? チェック
           │      ├─ missing_default_branch チェック
           │      └─ empty_repo? チェック
           │
           ├─ can?(current_user, :read_wiki, @project)
           │      └─ @wiki.find_page('home')
           │
           └─ feature_available?(:issues)
                  └─ issuables_collection
```

### データフロー図

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

リクエスト ───▶ ProjectsController#show ───▶ @project
    │                     │
    │                     ├─ Project.find ───▶ プロジェクトデータ
    │                     │
    │                     ├─ Repository ───▶ ファイルツリー/README
    │                     │
    │                     ├─ EventCollection ───▶ アクティビティ
    │                     │
    │                     └─ ProjectPresenter ───▶ ビュー用データ
    │
    └─────────────────────────────────────▶ HTML レスポンス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| projects_controller.rb | `app/controllers/projects_controller.rb` | コントローラ | リクエストハンドリング |
| show.html.haml | `app/views/projects/show.html.haml` | テンプレート | メインビュー |
| _home_panel.html.haml | `app/views/projects/_home_panel.html.haml` | パーシャル | プロジェクトヘッダー |
| _sidebar.html.haml | `app/views/projects/_sidebar.html.haml` | パーシャル | サイドバー |
| _files.html.haml | `app/views/projects/_files.html.haml` | パーシャル | ファイルツリー表示 |
| project.rb | `app/models/project.rb` | モデル | Projectモデル |
| repository.rb | `app/models/repository.rb` | モデル | リポジトリ操作 |
| project_presenter.rb | `app/presenters/project_presenter.rb` | プレゼンター | ビュー用データ整形 |
| project.rb | `config/routes/project.rb` | ルーティング | URLルーティング |
