# 機能設計書 15-ファイル閲覧

## 概要

本ドキュメントは、GitLabにおけるファイル閲覧機能の設計仕様を定義する。リポジトリ内のファイル内容表示とシンタックスハイライト対応について、処理フロー、入出力仕様、ビジネスルールを記載する。

### 本機能の処理概要

ファイル閲覧機能は、Gitリポジトリ内の個別ファイルの内容を表示する機能である。シンタックスハイライト、行番号表示、Blame表示へのリンクなど、開発者がコードを効率的に閲覧するための機能を提供する。

**業務上の目的・背景**：開発者がソースコードの詳細を確認・理解するための基本機能。コードレビュー、バグ調査、仕様理解など、開発業務のあらゆる場面で使用される。

**機能の利用シーン**：
- ソースコードの詳細を確認する場合
- 設定ファイルの内容を確認する場合
- コードレビュー時に差分の文脈を理解する場合
- コミットの詳細確認時に変更されたファイルを閲覧する場合
- コードナビゲーション（定義へのジャンプ等）を利用する場合

**主要な処理内容**：
1. リポジトリへのアクセス権限確認
2. 指定されたref（ブランチ/タグ/コミットSHA）の解決
3. 指定パスのBlobオブジェクト取得
4. ファイル内容のレンダリング（シンタックスハイライト）
5. 関連情報の表示（最終コミット、環境情報等）

**関連システム・外部連携**：
- Gitalyサーバーとの連携（Gitオブジェクト取得）
- LFS（Large File Storage）との連携
- コードナビゲーション（LSIF）との連携

**権限による制御**：
- プロジェクトのread_code権限が必要
- プライベートプロジェクトはメンバーのみ閲覧可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 31 | ファイル表示 | 主画面 | ファイル内容の表示 |
| 34 | Blame表示 | 遷移先画面 | Blame表示への遷移 |

## 機能種別

参照操作（Read）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| namespace_id | String | Yes | 名前空間パス | 存在する名前空間 |
| project_id | String | Yes | プロジェクトパス | 存在するプロジェクト |
| id | String | Yes | ref/ファイルパス | 有効なref、存在するファイル |
| ref_type | String | No | refの種類（heads/tags） | heads/tags/nil |

### 入力データソース

- URLパラメータ：プロジェクト識別子、ref、ファイルパス
- セッション：認証ユーザー情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| blob | Gitlab::Git::Blob | ファイルオブジェクト |
| content | String | ファイル内容（レンダリング済み） |
| commit | Gitlab::Git::Commit | 現在のコミット情報 |
| last_commit | Gitlab::Git::Commit | ファイルの最終変更コミット |
| environment | Environment | 関連する環境情報（オプション） |

### 出力先

- 画面表示：ファイル内容表示UI
- JSON API：ファイル情報のJSON

## 処理フロー

### 処理シーケンス

```
1. リクエスト受付
   └─ Projects::BlobController#showが呼び出される

2. 認証・認可チェック
   └─ authorize_read_code!で閲覧権限を確認

3. refとパスの抽出
   └─ ExtractsPath#assign_ref_varsでid（パス）からrefとパスを分離

4. コミットとBlobの取得
   └─ require_commit, require_blobでオブジェクト取得

5. Blobの展開（必要に応じて）
   └─ conditionally_expand_blobでファイル内容を読み込み

6. レスポンス生成
   ├─ HTML: シンタックスハイライト付きファイル表示
   └─ JSON: ファイル情報のJSON返却
```

### フローチャート

```mermaid
flowchart TD
    A[ファイル閲覧リクエスト] --> B{プロジェクト存在?}
    B -->|No| C[404エラー]
    B -->|Yes| D{閲覧権限?}
    D -->|No| E[403エラー]
    D -->|Yes| F[ref解決]
    F --> G{コミット存在?}
    G -->|No| C
    G -->|Yes| H{Blob存在?}
    H -->|No| I{ディレクトリ?}
    I -->|Yes| J[ツリー表示へリダイレクト]
    I -->|No| C
    H -->|Yes| K[Blob展開]
    K --> L{HTML/JSON?}
    L -->|HTML| M[ファイル表示]
    L -->|JSON| N[JSON返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 閲覧権限 | read_code権限が必要 | 常時 |
| BR-02 | ファイルサイズ制限 | 大きなファイルは一部のみ表示 | サイズ超過時 |
| BR-03 | バイナリファイル | バイナリファイルは内容表示不可 | バイナリ検出時 |
| BR-04 | LFS対応 | LFSファイルはLFSサーバーから取得 | LFSファイル時 |
| BR-05 | 最終コミット表示 | ファイルの最終変更コミット情報を表示 | 常時 |

### 計算ロジック

該当なし

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| プロジェクト取得 | projects | SELECT | プロジェクト情報の取得 |
| 環境取得 | environments | SELECT | 関連環境情報の取得 |

### Gitalyへのリクエスト

| 操作 | 内容 | 備考 |
|-----|------|------|
| FindCommit | 指定refのコミット取得 | - |
| GetBlob | Blobオブジェクト取得 | - |
| LastCommitForPath | 最終変更コミット取得 | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | Not Found | ファイルが存在しない | 正しいパスを確認 |
| 403 | Forbidden | 閲覧権限がない | 権限を確認 |
| 503 | Service Unavailable | Gitalyサーバーエラー | 再試行 |

### リトライ仕様

- Gitalyサーバーエラー時、ユーザーに再試行を促す

## トランザクション仕様

- 読み取り専用操作のため、トランザクション管理は不要

## パフォーマンス要件

- allow_gitaly_ref_name_cachingによるキャッシュ有効化
- 大きなファイルの部分読み込み
- コードナビゲーション情報の非同期読み込み

## セキュリティ考慮事項

- read_code権限の厳格なチェック
- パス トラバーサル攻撃の防止
- 機密情報を含むファイルの保護

## 備考

- MAX_EDIT_SIZE = 10MB を超えるファイルはブラウザで編集不可
- MAX_PREVIEW_CONTENT = 512KB を超えるプレビューはエラー

---

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

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

### 推奨読解順序

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

Git BlobオブジェクトとViewerを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | blob.rb | `lib/gitlab/git/blob.rb` | Gitブロブオブジェクトの構造 |
| 1-2 | blob.rb | `app/models/blob.rb` | アプリケーションレベルのBlob |

**読解のコツ**: Blobはファイル内容を表すGitオブジェクト。サイズ、MIMEタイプ、バイナリ判定などの属性を持つ。

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

コントローラーのファイル表示処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | blob_controller.rb | `app/controllers/projects/blob_controller.rb` | showアクションの処理フロー |

**主要処理フロー**:
1. **71-85行目**: showアクション、HTML/JSONの分岐
2. **185-190行目**: blobメソッド、リポジトリからBlob取得
3. **299-311行目**: show_html、HTML表示処理
4. **313-335行目**: show_json、JSON返却処理

#### Step 3: Blobレンダリングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | renders_blob.rb | `app/controllers/concerns/renders_blob.rb` | Blobレンダリングロジック |

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

```
Projects::BlobController#show
    │
    ├─ authorize_read_code! (権限チェック)
    │
    ├─ assign_ref_vars (ExtractsPath)
    │
    ├─ require_commit (コミット確認)
    │
    ├─ require_blob (Blob確認)
    │
    ├─ conditionally_expand_blob (内容展開)
    │
    └─ show_html / show_json
           ├─ @last_commit (最終コミット取得)
           ├─ @environment (環境情報取得)
           └─ @code_navigation_path (コードナビゲーション)
```

### データフロー図

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

URL (ref/path) ───▶ BlobController ───▶ HTML/JSON
                          │
                          ▼
                    ExtractsPath
                    (ref解決)
                          │
                          ▼
                    Repository#blob_at
                          │
                          ▼
                    Gitaly RPC ───▶ Blobデータ
                          │
                          ▼
                    シンタックスハイライト
                          │
                          ▼
                    ファイル表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| blob_controller.rb | `app/controllers/projects/blob_controller.rb` | コントローラー | ファイル表示のエントリーポイント |
| extracts_path.rb | `app/controllers/concerns/extracts_path.rb` | Concern | refとパスの抽出 |
| renders_blob.rb | `app/controllers/concerns/renders_blob.rb` | Concern | Blobレンダリング |
| repository.rb | `app/models/repository.rb` | モデル | リポジトリ操作のラッパー |
| blob.rb | `app/models/blob.rb` | モデル | アプリケーションBlob |
| blob.rb | `lib/gitlab/git/blob.rb` | Lib | GitBlob |
| highlight.rb | `lib/gitlab/highlight.rb` | Lib | シンタックスハイライト |
