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

## はじめに

このガイドラインは、GitLabのコードベースを効率的に理解するための手引きです。
RubyやRails、Vue.jsに精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

---

## 1. 言語基礎

> このセクションでは、GitLabで使用される主要言語の基本構文と概念を解説します。

### 1.1 使用言語・技術スタック

| カテゴリ | 技術 | バージョン |
|---------|------|-----------|
| バックエンド | Ruby on Rails | 7.2.x |
| データベース | PostgreSQL | - |
| キャッシュ | Redis | 5.x |
| フロントエンド | Vue.js 2/3 | 2.7.x / 3.5.x |
| API | REST (Grape) / GraphQL | - |
| バックグラウンドジョブ | Sidekiq | - |
| ビルド | Webpack / Vite | - |

### 1.2 Ruby プログラム構造

Rubyはオブジェクト指向言語で、すべてがオブジェクトです。

**基本構文例** (`app/models/user.rb:1-10`)
```ruby
# frozen_string_literal: true

require 'carrierwave/orm/activerecord'

class User < ApplicationRecord
  extend Gitlab::ConfigHelper
  include Gitlab::ConfigHelper
  include Gitlab::SQL::Pattern
  include AfterCommitQueue
  include Avatarable
```

**解説:**
- `# frozen_string_literal: true`: 文字列リテラルを不変（イミュータブル）にする宣言。パフォーマンス向上のため、すべてのファイルの先頭に記述されています
- `require`: 外部ライブラリの読み込み
- `class ... < ApplicationRecord`: ActiveRecordモデルの継承
- `extend`: クラスメソッドとしてモジュールを取り込む
- `include`: インスタンスメソッドとしてモジュールを取り込む

### 1.3 データ型と変数

```ruby
# 定数定義（大文字スネークケース）
DEFAULT_NOTIFICATION_LEVEL = :participating
MAX_USERNAME_LENGTH = 255

# シンボル（コロン始まり）
:participating  # イミュータブルな識別子

# 配列
SECONDARY_EMAIL_ATTRIBUTES = [
  :commit_email,
  :notification_email,
  :public_email
].freeze  # freezeで変更不可に

# ハッシュ
HASHED_STORAGE_FEATURES = {
  repository: 1,
  attachments: 2
}.freeze
```

### 1.4 制御構造

```ruby
# 条件分岐
if user.admin?
  grant_full_access
elsif user.moderator?
  grant_moderate_access
else
  grant_basic_access
end

# ガード節（早期リターン）
return unless objects_found?(issue_id, user_id)

# ブロック
users.each do |user|
  process(user)
end

# シンボルによるメソッド参照
users.map(&:name)  # users.map { |u| u.name } と同等
```

### 1.5 モジュール/インポート

**Railsのオートロード** (`config/application.rb:115-121`)
```ruby
config.eager_load_paths.push(*%W[#{config.root}/lib
  #{config.root}/app/models/badges
  #{config.root}/app/models/hooks
  #{config.root}/app/models/members
  #{config.root}/app/graphql/resolvers/concerns
  #{config.root}/app/graphql/mutations/concerns
  #{config.root}/app/graphql/types/concerns])
```

**解説:** Railsは命名規約に基づいて自動的にファイルを読み込みます。`app/`配下のファイルは明示的な`require`なしで利用可能です。

---

## 2. プロジェクト固有の概念

> このセクションでは、GitLab特有の概念を解説します。

### 2.1 Enterprise Edition (EE) / FOSS 構成

GitLabはオープンソース版（CE/FOSS）とEnterprise Edition（EE）の二重構造を持っています。

```ruby
# config/application.rb:144-150
Gitlab.ee do
  load_paths.call(dir: 'ee')
end

Gitlab.jh do
  load_paths.call(dir: 'jh')
end
```

**ディレクトリ構造:**
- `app/`, `lib/`: Community Edition（無料版）のコード
- `ee/app/`, `ee/lib/`: Enterprise Edition専用のコード
- `jh/`: JiHu Edition（中国向け）専用のコード

**EE機能の拡張パターン** (`app/workers/new_issue_worker.rb:43`)
```ruby
NewIssueWorker.prepend_mod
```
`prepend_mod`により、EE版で同名のモジュールが存在すれば自動的に機能が拡張されます。

### 2.2 Feature Categories

すべてのエンドポイントやワーカーは「機能カテゴリ」に分類されます。

```ruby
# app/workers/new_issue_worker.rb:11
feature_category :team_planning
```

これにより、エラー追跡やパフォーマンス監視で責任範囲が明確になります。

### 2.3 Concerns（共有機能モジュール）

共通機能は`concerns`として抽出されています。

**モデルのconcerns** (`app/models/concerns/`)
- `Avatarable`: アバター画像の管理
- `Sortable`: ソート機能
- `Mentionable`: @メンション機能
- `Subscribable`: 購読機能

**コントローラーのconcerns** (`app/controllers/concerns/`)
- `EnforcesTwoFactorAuthentication`: 2FA強制
- `SessionlessAuthentication`: セッションレス認証

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| `{model}_controller.rb` | コントローラー | `projects_controller.rb` |
| `{model}s/` (複数形) | 名前空間ディレクトリ | `app/services/issues/` |
| `{verb}_{noun}_service.rb` | サービスクラス | `create_issue_service.rb` |
| `{model}_{action}_worker.rb` | バックグラウンドジョブ | `new_issue_worker.rb` |
| `{model}s_finder.rb` | 検索クラス | `issues_finder.rb` |
| `{model}_presenter.rb` | プレゼンター | `issue_presenter.rb` |
| `{model}_policy.rb` | 認可ポリシー | `project_policy.rb` |
| `{model}_serializer.rb` | シリアライザー | `issue_serializer.rb` |
| `{model}_uploader.rb` | ファイルアップローダー | `avatar_uploader.rb` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| `can_*?` | 権限チェックメソッド | `can_create_group?` |
| `*?` | booleanを返すメソッド | `admin?`, `active?` |
| `*!` | 破壊的または例外を投げるメソッド | `save!`, `destroy!` |
| `*_at` | タイムスタンプカラム | `created_at`, `deleted_at` |
| `*_id` | 外部キー | `user_id`, `project_id` |
| `*_count` | カウントキャッシュ | `issues_count` |
| `Base*` | 抽象基底クラス | `BaseService`, `BaseController` |
| `Application*` | アプリケーション基底クラス | `ApplicationRecord`, `ApplicationController` |

### 3.3 プログラム分類一覧

| 分類 | ディレクトリ | 命名規則 | 責務 |
|-----|------------|---------|------|
| Model | `app/models/` | 単数形 | データ構造とビジネスルール |
| Controller | `app/controllers/` | 複数形 + `_controller` | HTTPリクエスト処理 |
| Service | `app/services/` | 動詞 + 名詞 + `_service` | ビジネスロジック |
| Worker | `app/workers/` | 動詞/名詞 + `_worker` | 非同期処理 |
| Finder | `app/finders/` | 複数形 + `_finder` | データ検索 |
| Presenter | `app/presenters/` | 単数形 + `_presenter` | 表示用データ加工 |
| Serializer | `app/serializers/` | 単数形 + `_serializer` | JSON/API変換 |
| Policy | `app/policies/` | 単数形 + `_policy` | 認可ロジック |
| Uploader | `app/uploaders/` | 単数形 + `_uploader` | ファイルアップロード |
| Validator | `app/validators/` | 単数形 + `_validator` | カスタムバリデーション |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
gitlabhq/
├── app/                          # アプリケーションコア
│   ├── assets/                   # フロントエンドアセット
│   │   ├── javascripts/          # Vue.js, JavaScript
│   │   └── stylesheets/          # CSS/SCSS
│   ├── channels/                 # ActionCable WebSocketチャネル
│   ├── components/               # ViewComponent
│   ├── controllers/              # HTTPコントローラー
│   ├── finders/                  # データ検索クラス
│   ├── graphql/                  # GraphQL定義
│   │   ├── mutations/            # GraphQL Mutation
│   │   ├── resolvers/            # GraphQL Resolver
│   │   └── types/                # GraphQL Type
│   ├── helpers/                  # ビューヘルパー
│   ├── mailers/                  # メール送信
│   ├── models/                   # ActiveRecordモデル
│   │   └── concerns/             # モデル共通機能
│   ├── policies/                 # Pundit認可ポリシー
│   ├── presenters/               # プレゼンター
│   ├── serializers/              # JSONシリアライザー
│   ├── services/                 # ビジネスロジック
│   ├── uploaders/                # CarrierWaveアップローダー
│   ├── validators/               # カスタムバリデーター
│   ├── views/                    # ERB/HAMLテンプレート
│   └── workers/                  # Sidekiqワーカー
├── config/                       # 設定ファイル
│   ├── initializers/             # 初期化スクリプト
│   ├── routes/                   # ルーティング定義
│   └── locales/                  # 国際化ファイル
├── db/                           # データベース
│   ├── migrate/                  # マイグレーション
│   └── fixtures/                 # フィクスチャ
├── ee/                           # Enterprise Edition
│   └── (appと同構造)
├── lib/                          # ライブラリ
│   ├── api/                      # Grape REST API
│   ├── gitlab/                   # Gitlabモジュール
│   └── tasks/                    # Rakeタスク
├── spec/                         # RSpecテスト
├── vendor/                       # ベンダーライブラリ
└── gems/                         # 内部gem
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `app/models/` | データモデルとビジネスルール | `user.rb`, `project.rb`, `issue.rb` |
| `app/controllers/` | Webリクエストハンドリング | `application_controller.rb`, `projects_controller.rb` |
| `app/services/` | 複雑なビジネスロジック | `base_service.rb`, `issues/create_service.rb` |
| `app/workers/` | バックグラウンドジョブ | `new_issue_worker.rb`, `mail_scheduler_worker.rb` |
| `app/finders/` | データ検索・フィルタリング | `issuable_finder.rb`, `projects_finder.rb` |
| `lib/api/` | REST API定義 (Grape) | `api.rb`, `projects.rb`, `users.rb` |
| `app/graphql/` | GraphQL API定義 | `types/`, `mutations/`, `resolvers/` |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

GitLabはRailsの標準的なMVCアーキテクチャをベースに、サービス層とバックグラウンドジョブ層を追加した構成です。

```
┌──────────────────────────────────────────────────────────────────┐
│                         クライアント層                            │
│    Web Browser / Git Client / API Client / GraphQL Client        │
└───────────────────────────┬──────────────────────────────────────┘
                            │
┌───────────────────────────┴──────────────────────────────────────┐
│                      Webサーバー層 (Puma)                         │
├──────────────────────────────────────────────────────────────────┤
│   ┌────────────────┐  ┌────────────────┐  ┌────────────────┐    │
│   │   Rails MVC    │  │   Grape API    │  │    GraphQL     │    │
│   │  Controllers   │  │   Endpoints    │  │   Resolvers    │    │
│   └───────┬────────┘  └───────┬────────┘  └───────┬────────┘    │
└───────────┼───────────────────┼───────────────────┼─────────────┘
            │                   │                   │
┌───────────┴───────────────────┴───────────────────┴─────────────┐
│                        サービス層                                │
│     ┌──────────────────────────────────────────────────────┐    │
│     │  Services / Finders / Policies / Presenters          │    │
│     └───────────────────────────┬──────────────────────────┘    │
└─────────────────────────────────┼───────────────────────────────┘
                                  │
┌─────────────────────────────────┴───────────────────────────────┐
│                       モデル層                                   │
│     ┌──────────────────────────────────────────────────────┐    │
│     │  ActiveRecord Models / Concerns / Validators          │    │
│     └───────────────────────────┬──────────────────────────┘    │
└─────────────────────────────────┼───────────────────────────────┘
                                  │
┌─────────────────────────────────┴───────────────────────────────┐
│                     データストア層                               │
│   ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────────┐   │
│   │PostgreSQL│  │  Redis   │  │  Gitaly  │  │ Object Store │   │
│   │ (主DB)   │  │(キャッシュ)│  │ (Git操作)│  │  (ファイル)   │   │
│   └──────────┘  └──────────┘  └──────────┘  └──────────────┘   │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                    非同期処理層 (Sidekiq)                        │
│     ┌──────────────────────────────────────────────────────┐    │
│     │  Workers (バックグラウンドジョブ)                       │    │
│     └──────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────┘
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| Controller | HTTPリクエスト受付、認証、レスポンス | `app/controllers/projects_controller.rb` |
| Service | ビジネスロジック、トランザクション管理 | `app/services/issues/create_service.rb` |
| Finder | データ検索、フィルタリング、権限適用 | `app/finders/issues_finder.rb` |
| Policy | 認可ロジック | `app/policies/project_policy.rb` |
| Model | データ永続化、バリデーション、関連 | `app/models/project.rb` |
| Worker | 非同期処理、重い処理の遅延実行 | `app/workers/new_issue_worker.rb` |
| Presenter | 表示用データ加工 | `app/presenters/project_presenter.rb` |
| Serializer | API応答のJSON変換 | `app/serializers/issue_serializer.rb` |

### 5.3 データフロー

**Issueの作成フロー例:**

```
1. POST /projects/:id/issues
       │
       ▼
2. IssuesController#create
       │ params検証、認証確認
       ▼
3. Issues::CreateService#execute
       │ ビジネスルール適用、バリデーション
       ▼
4. Issue.create!
       │ ActiveRecord保存
       ▼
5. NewIssueWorker.perform_async
       │ 非同期で通知等を実行
       ▼
6. EventCreateService / NotificationService
       │ イベント記録、通知送信
       ▼
7. ServiceResponse（成功/失敗）
```

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

**Webアプリケーション** (`config/routes.rb`)
```ruby
Rails.application.routes.draw do
  # Search
  get 'search' => 'search#show', as: :search

  # API
  draw :api  # config/routes/api.rb を読み込み

  # Projects
  resources :projects do
    resources :issues
  end
end
```

**REST API** (`lib/api/api.rb`)
```ruby
module API
  class API < ::API::Base
    mount ::API::Projects
    mount ::API::Issues
    mount ::API::MergeRequests
    # ...
  end
end
```

### 6.2 ビジネスロジック（Service層）

**基底クラス** (`app/services/base_service.rb`)
```ruby
class BaseService
  include BaseServiceUtility
  include Gitlab::Experiment::Dsl

  attr_accessor :project, :current_user, :params

  def initialize(project, user = nil, params = {})
    @project = project
    @current_user = user
    @params = params.dup
  end

  delegate :repository, to: :project
end
```

**サービスの実装例** (`app/services/issues/create_service.rb`)
```ruby
module Issues
  class CreateService < Issues::BaseService
    def execute(skip_system_notes: false)
      # バリデーション
      return error('not authorized') unless can?(current_user, :create_issue, container)

      # Issue作成
      issue = build_issue

      if issue.save
        # 成功時の後処理
        success(issue: issue)
      else
        error(issue.errors.full_messages)
      end
    end
  end
end
```

### 6.3 データアクセス（Finder層）

**検索クラス** (`app/finders/issuable_finder.rb:1-50`)
```ruby
class IssuableFinder
  prepend FinderWithCrossProjectAccess
  include FinderMethods
  include CreatedAtFilter

  attr_accessor :current_user, :params

  class << self
    def scalar_params
      @scalar_params ||= %i[
        assignee_id
        author_id
        milestone_title
        search
      ]
    end
  end

  def execute
    items = init_collection
    items = filter_items(items)
    items = sort_items(items)
    items
  end
end
```

### 6.4 バックグラウンドジョブ（Worker層）

**ワーカー実装** (`app/workers/new_issue_worker.rb`)
```ruby
class NewIssueWorker
  include ApplicationWorker

  data_consistency :always
  sidekiq_options retry: 3
  feature_category :team_planning
  urgency :high
  worker_resource_boundary :cpu

  def perform(issue_id, user_id, issuable_class = 'Issue', skip_notifications = false)
    return unless objects_found?(issue_id, user_id)

    ::EventCreateService.new.open_issue(issuable, user)
    ::NotificationService.new.new_issue(issuable, user) unless skip_notifications
    issuable.create_cross_references!(user)
  end
end
```

**ワーカーの重要な属性:**
- `data_consistency`: データ整合性レベル
- `sidekiq_options`: リトライ設定
- `feature_category`: 機能カテゴリ（エラー追跡用）
- `urgency`: 優先度（`:high`, `:low`, `:throttled`）
- `worker_resource_boundary`: リソース境界（`:cpu`, `:memory`）

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| Service Object | ビジネスロジックのカプセル化 | 高 | `app/services/` |
| Finder | 検索ロジックの分離 | 高 | `app/finders/` |
| Concern | 共通機能のモジュール化 | 高 | `app/models/concerns/` |
| Policy | 認可ロジックの分離 | 高 | `app/policies/` |
| Presenter | 表示ロジックの分離 | 中 | `app/presenters/` |
| ServiceResponse | 統一的な戻り値 | 高 | `app/services/service_response.rb` |
| prepend_mod | EE機能拡張 | 高 | 各クラス末尾 |

### 各パターンの詳細

#### パターン1: ServiceResponse

**目的:** サービスクラスから統一的なフォーマットで結果を返す

**実装例:**
```ruby
# ファイル: app/services/service_response.rb
class ServiceResponse
  def self.success(payload: {}, message: nil, http_status: :ok)
    new(status: :success, message: message, payload: payload, http_status: http_status)
  end

  def self.error(message:, payload: {}, http_status: :bad_request)
    new(status: :error, message: message, payload: payload, http_status: http_status)
  end
end

# 使用例
def execute
  if valid?
    ServiceResponse.success(payload: { issue: issue })
  else
    ServiceResponse.error(message: 'Validation failed')
  end
end
```

**解説:** すべてのサービスクラスはこのパターンで結果を返すことで、コントローラーでの処理が統一されます。

#### パターン2: Finder + スコープ

**目的:** 検索条件を柔軟に組み合わせる

**実装例:**
```ruby
# ファイル: app/finders/issues_finder.rb
class IssuesFinder < IssuableFinder
  def execute
    items = super
    items = by_assignee(items)
    items = by_milestone(items)
    items
  end

  private

  def by_assignee(items)
    return items unless params[:assignee_id]
    items.where(assignee_id: params[:assignee_id])
  end
end
```

#### パターン3: prepend_mod（EE拡張）

**目的:** CE版のクラスをEE版で拡張する

**実装例:**
```ruby
# ファイル: app/workers/new_issue_worker.rb (末尾)
NewIssueWorker.prepend_mod

# ファイル: ee/app/workers/ee/new_issue_worker.rb
module EE
  module NewIssueWorker
    def perform(issue_id, user_id, ...)
      super
      # EE固有の処理
      log_audit_event if user.project_bot?
    end
  end
end
```

**解説:** `prepend_mod`を使うことで、CE版のメソッドを上書きしつつ、`super`で元の処理も呼び出せます。

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定（routes.rb または lib/api/）
2. 処理の流れを追跡（呼び出し関係を追う）
3. データの変換を確認
4. 最終的な出力を確認

### 8.2 フロー追跡の実例

#### 例1: Issue作成フロー

**概要:** ユーザーがWebからIssueを作成した際の処理フロー

**処理フロー:**
```
routes.rb → ProjectsController#issues → Issues::CreateService → Issue.save → NewIssueWorker
```

**詳細な追跡:**

1. **ルーティング** (`config/routes.rb`)
   ```ruby
   resources :projects do
     resources :issues
   end
   # POST /projects/:project_id/issues => issues#create
   ```

2. **コントローラー** (`app/controllers/projects/issues_controller.rb`)
   ```ruby
   def create
     @issue = ::Issues::CreateService.new(
       container: project,
       current_user: current_user,
       params: issue_params
     ).execute

     respond_to do |format|
       if @issue.persisted?
         format.html { redirect_to project_issue_path(@project, @issue) }
       else
         format.html { render :new }
       end
     end
   end
   ```

3. **サービス** (`app/services/issues/create_service.rb`)
   ```ruby
   def execute
     issue = build_issue

     if issue.save
       after_create(issue)
       ServiceResponse.success(payload: { issue: issue })
     else
       ServiceResponse.error(message: issue.errors.full_messages)
     end
   end

   def after_create(issue)
     NewIssueWorker.perform_async(issue.id, current_user.id)
   end
   ```

4. **ワーカー（非同期）** (`app/workers/new_issue_worker.rb`)
   ```ruby
   def perform(issue_id, user_id, ...)
     ::EventCreateService.new.open_issue(issuable, user)
     ::NotificationService.new.new_issue(issuable, user)
   end
   ```

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイントを特定したか
- [ ] 呼び出し関係を把握したか
- [ ] データの変換ポイントを確認したか
- [ ] エラーハンドリングを確認したか
- [ ] 最終的な出力を確認したか
- [ ] 非同期処理（Worker）を確認したか
- [ ] EE拡張の有無を確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. `docs/code-to-docs/README.md` - プロジェクト概要
2. `docs/code-to-docs/アーキテクチャ設計書/` - 全体構成
3. `docs/code-to-docs/機能一覧/` - 機能俯瞰

#### 特定機能を理解したい場合
1. `docs/code-to-docs/機能設計書/` - 機能詳細
2. `docs/code-to-docs/画面設計書/` - UI仕様
3. `docs/code-to-docs/API設計書/` - API仕様

#### 改修作業を行う場合
1. 該当機能の設計書
2. `docs/code-to-docs/データベース設計書/` - DB構造
3. `docs/code-to-docs/単体テストケース一覧/` - テスト仕様

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| README.md | プロジェクト概要 | 最初に |
| アーキテクチャ設計書 | システム全体構成 | 全体把握時 |
| 機能設計書 | 各機能の詳細仕様 | 機能理解時 |
| 画面設計書 | UI/UX仕様 | フロントエンド開発時 |
| API設計書 | REST/GraphQL仕様 | API開発時 |
| データベース設計書 | テーブル定義 | DB操作時 |
| バッチ設計書 | 定期実行処理 | バッチ開発時 |
| テスト方針書 | テスト戦略 | テスト作成時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: メソッドがどこで定義されているかわからない
A: 以下の順序で探索してください:
1. 同じクラス内
2. `include`されたconcerns（`app/models/concerns/`）
3. 親クラス（`< ApplicationRecord`など）
4. EE拡張（`ee/app/`配下の同名ファイル）

#### Q: ルーティングが複雑でエンドポイントが見つからない
A: `config/routes/`配下に分割されています。`draw :api`などの呼び出しを追跡してください。

#### Q: EEとCEの境界がわからない
A:
- CEのコードは`app/`, `lib/`配下
- EEのコードは`ee/app/`, `ee/lib/`配下
- `prepend_mod`がある箇所はEE拡張ポイント

#### Q: テストの場所がわからない
A:
- モデル: `spec/models/`
- コントローラー: `spec/controllers/` または `spec/requests/`
- サービス: `spec/services/`
- ワーカー: `spec/workers/`

### デバッグのヒント

1. **ログ確認**: `log/development.log`でSQLやリクエストを追跡
2. **Railsコンソール**: `bundle exec rails console`で対話的にテスト
3. **pry-byebug**: コード中に`binding.pry`を挿入してデバッグ
4. **Feature Flag確認**: `Gitlab::Feature.enabled?(:flag_name)`の状態確認

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| CE | Community Edition（無料版） |
| EE | Enterprise Edition（有料版） |
| JH | JiHu Edition（中国向け版） |
| Sidekiq | Rubyのバックグラウンドジョブフレームワーク |
| Grape | Ruby製のREST API フレームワーク |
| Gitaly | Git操作を担当するサービス |
| Workhorse | 大容量ファイル処理を担当するGoサービス |
| Feature Category | 機能の責任範囲を示す分類 |
| prepend_mod | EE機能を動的に追加するパターン |

### B. 主要ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `Gemfile` | Ruby依存関係 | gem一覧 |
| `package.json` | Node依存関係 | npm/yarnパッケージ |
| `config/application.rb` | Railsアプリ設定 | ミドルウェア、パス設定 |
| `config/routes.rb` | ルーティング | URLマッピング |
| `app/models/user.rb` | ユーザーモデル | 認証、プロフィール |
| `app/models/project.rb` | プロジェクトモデル | リポジトリ、設定 |
| `app/services/base_service.rb` | サービス基底 | 共通インターフェース |
| `lib/api/api.rb` | API起点 | REST APIマウント |

### C. 参考資料

- [Ruby on Rails Guides](https://guides.rubyonrails.org/)
- [GitLab Development Documentation](https://docs.gitlab.com/ee/development/)
- [GitLab Architecture Overview](https://docs.gitlab.com/ee/development/architecture.html)
- [Vue.js Documentation](https://vuejs.org/guide/introduction.html)
- [Grape Documentation](https://github.com/ruby-grape/grape)
- [Sidekiq Wiki](https://github.com/mperham/sidekiq/wiki)
