# 機能設計書 126-リポジトリアナリティクス

## 概要

本ドキュメントは、GitLabにおけるリポジトリアナリティクス機能の設計仕様を記述したものである。本機能は、リポジトリのコード言語構成、コミット頻度分析、およびコントリビューター活動の統計情報を提供し、プロジェクトの技術的特性を可視化する。

### 本機能の処理概要

**業務上の目的・背景**：ソフトウェアプロジェクトの技術的な健全性を評価するためには、コードベースの言語構成や開発活動のパターンを定量的に把握することが重要である。リポジトリアナリティクスは、言語別のコード比率、時系列でのコミット傾向、コントリビューター数の推移などを分析し、技術選定の妥当性評価やリファクタリング計画の策定を支援する。

**機能の利用シーン**：プロジェクトのAnalyticsメニューやREADME表示画面で言語バッジとして確認される場面、技術スタック評価を行う場面、新規参画者がコードベースの構成を把握する場面などで利用される。

**主要な処理内容**：
1. リポジトリファイルの言語検出（Linguist使用）
2. 言語別コード行数・バイト数の集計
3. 言語構成比率（share）の計算
4. 言語情報のキャッシュと更新
5. コホート分析（管理者向け）
6. 使用トレンド分析（管理者向け）

**関連システム・外部連携**：GitHub Linguistライブラリを使用した言語検出。Gitalyサービスを介したリポジトリアクセス。

**権限による制御**：プロジェクトへの読み取りアクセス権が必要。管理者向け分析機能（コホート、使用トレンド）は管理者権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 267 | コホート分析 | 主画面 | ユーザーコホート分析 |
| 268 | 使用トレンド | 主画面 | 使用状況トレンド |

## 機能種別

データ取得・分析（READ操作）/ 統計計算

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| project_id | String | Yes | プロジェクトID | 有効なプロジェクト |
| ref | String | No | 分析対象ブランチ/タグ | リポジトリに存在するref |

### 入力データソース

- Gitリポジトリ（ファイル内容）
- repository_languages テーブル（キャッシュデータ）
- programming_languages テーブル（言語マスタ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| languages | Array<Hash> | 言語構成（name, share, color） |
| language_id | Integer | 言語ID |
| share | Float | 構成比率（0-100） |
| color | String | 言語表示色（#RRGGBB形式） |

### 出力先

- HTML画面（言語バー表示）
- JSON API
- プロジェクト言語バッジ

## 処理フロー

### 処理シーケンス

```
1. 権限チェック
   └─ プロジェクト読み取り権限確認
2. 言語データ取得
   └─ キャッシュ確認（repository_languages）
3. キャッシュミス時
   └─ Gitリポジトリから言語検出
   └─ Linguistによる言語判定
   └─ 言語構成の集計
   └─ キャッシュ更新
4. 言語情報の整形
   └─ 構成比率計算
   └─ 色情報付与
5. レスポンス生成
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信] --> B{権限チェック}
    B -->|No| C[403 Forbidden]
    B -->|Yes| D{キャッシュ存在?}
    D -->|Yes| E[キャッシュデータ取得]
    D -->|No| F[リポジトリ言語検出]
    F --> G[Linguist解析]
    G --> H[言語構成集計]
    H --> I[キャッシュ保存]
    I --> E
    E --> J[構成比率計算]
    J --> K[レスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-126-01 | 言語検出対象 | vendorディレクトリ等は除外（Linguist設定） | 言語検出時 |
| BR-126-02 | 構成比率計算 | バイト数ベースでシェア計算 | 常時 |
| BR-126-03 | 最小シェア閾値 | 0.1%未満の言語は表示から除外する場合あり | UI表示時 |
| BR-126-04 | キャッシュ更新 | プッシュ時またはバックグラウンドジョブで更新 | リポジトリ更新時 |

### 計算ロジック

**言語構成比率計算**:
```ruby
total_bytes = languages.sum(&:bytes)
languages.each do |lang|
  lang.share = (lang.bytes.to_f / total_bytes * 100).round(2)
end
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 言語取得 | repository_languages | SELECT | プロジェクトの言語構成取得 |
| 言語マスタ | programming_languages | SELECT | 言語名・色情報取得 |
| キャッシュ更新 | repository_languages | INSERT/UPDATE/DELETE | 言語構成キャッシュ更新 |

### テーブル別操作詳細

#### repository_languages

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | project_id, programming_language_id, share | project_id = @project.id | 言語構成取得 |
| INSERT/UPDATE | share | 計算された構成比率 | キャッシュ更新時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | Forbidden | 権限不足 | アクセス拒否 |
| 404 | Not Found | 空リポジトリ | 空データ返却 |

### リトライ仕様

Gitaly/Linguist解析タイムアウト時は非同期ジョブでリトライ。

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

- 読み取り: トランザクション不要
- キャッシュ更新: 暗黙的トランザクション

## パフォーマンス要件

- 言語検出は非同期ワーカーで実行推奨
- キャッシュ利用により応答時間短縮
- 大規模リポジトリでは検出に時間がかかる場合あり

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

- プロジェクト読み取り権限の確認
- 非公開リポジトリの言語情報は非公開

## 備考

- 言語検出はGitHub Linguistをベースとしている
- .gitattributesでカスタム言語設定可能
- 管理者向けコホート分析・使用トレンドはapp/services/analyticsで実装

---

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

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

### 推奨読解順序

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

言語構成データの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RepositoryLanguage | `app/models/repository_language.rb` | 言語構成モデル |
| 1-2 | ProgrammingLanguage | `app/models/programming_language.rb` | 言語マスタモデル |

**読解のコツ**: RepositoryLanguageはproject_idとprogramming_language_idの組み合わせで一意。shareは0-100のパーセント値。

#### Step 2: 言語取得サービスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Projects::RepositoryLanguagesService | `app/services/projects/repository_languages_service.rb` | 言語取得メインロジック |

#### Step 3: GraphsControllerとの連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Projects::GraphsController#get_languages | `app/controllers/projects/graphs_controller.rb` (79-84行目) | コントローラー連携 |

**主要処理フロー**:
- **79-84行目**: get_languagesメソッド - RepositoryLanguagesService呼び出しと整形

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

```
Projects::GraphsController#get_languages
    │
    └─ Projects::RepositoryLanguagesService.new(@project, current_user).execute
           │
           ├─ Project#repository_languages (キャッシュ)
           │
           └─ (キャッシュミス時)
                  └─ Gitlab::LanguageDetection
                         └─ Linguist (言語検出)

管理者向け分析:
Admin::ApplicationController
    │
    ├─ Cohort分析
    │      └─ Analytics::UsersActivity
    │
    └─ 使用トレンド
           └─ Analytics::InstanceStatistics
```

### データフロー図

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

Git Repository ─────────▶ RepositoryLanguagesService ───────▶ API Response
                               │
                               │
                         ┌─────┴─────┐
                         │           │
                    (cache hit) (cache miss)
                         │           │
              repository_languages  Linguist
                         │           │
                         │     language detection
                         │           │
                         │      cache update
                         │           │
                         └─────┬─────┘
                               │
                         format response
                               │
                               ▼
                         @languages (Array<Hash>)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RepositoryLanguage | `app/models/repository_language.rb` | モデル | 言語構成データ |
| ProgrammingLanguage | `app/models/programming_language.rb` | モデル | 言語マスタ |
| Projects::RepositoryLanguagesService | `app/services/projects/repository_languages_service.rb` | サービス | 言語取得ロジック |
| Projects::GraphsController | `app/controllers/projects/graphs_controller.rb` | コントローラー | グラフ表示連携 |
| Gitlab::LanguageDetection | `lib/gitlab/language_detection.rb` | ライブラリ | 言語検出 |
| DetectRepositoryLanguagesWorker | `app/workers/detect_repository_languages_worker.rb` | ワーカー | 非同期言語検出 |
