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

## はじめに

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

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

---

## 1. 言語基礎

> このセクションでは、JavaScript/Node.jsの基本構文と概念を解説します。

### 1.1 プログラム構造

Ghostは主にJavaScript(Node.js)で構築されています。フロントエンド部分にはTypeScriptとReactも使用されています。

**バックエンド (Node.js)**
```javascript
// ファイル: ghost/core/core/server/models/index.js:17-29
function init() {
    const baseNow = Date.now();
    exports.Base = require('./base');
    debug(`${Date.now() - baseNow}ms - Base.js require`);

    let modelsFiles = glob.sync('!(index).js', {cwd: __dirname});
    modelsFiles.forEach((model) => {
        const name = model.replace(/.js$/, '');
        const modelNow = Date.now();
        _.extend(exports, require('./' + name));
        debug(`${Date.now() - modelNow}ms - ${model} require`);
    });
}
```

**フロントエンド (React/TypeScript)**
```typescript
// apps/* 配下のReactアプリケーション
// 例: apps/admin-x-settings, apps/portal
import React from 'react';
```

### 1.2 データ型と変数

JavaScriptでは`const`, `let`を使用して変数を宣言します。

```javascript
// ファイル: ghost/core/core/server/ghost-server.js:51-61
constructor({url, env, serverConfig}) {
    this.url = url;
    this.env = env;
    this.serverConfig = serverConfig;

    this.rootApp = null;
    this.httpServer = null;

    // Tasks that should be run before the server exits
    this.cleanupTasks = [];
}
```

- `const`: 再代入不可の変数
- `let`: 再代入可能な変数
- `this.xxx`: クラスインスタンスのプロパティ

### 1.3 制御構造

**条件分岐:**
```javascript
// ファイル: ghost/core/ghost.js:16-25
switch (mode) {
case 'repl':
case 'timetravel':
case 'generate-data':
    require('./core/cli/command').run(mode);
    break;
default:
    // New boot sequence
    require('./core/boot')();
}
```

**ループ:**
```javascript
// ファイル: ghost/core/core/server/models/index.js:22-28
modelsFiles.forEach((model) => {
    const name = model.replace(/.js$/, '');
    const modelNow = Date.now();
    _.extend(exports, require('./' + name));
    debug(`${Date.now() - modelNow}ms - ${model} require`);
});
```

### 1.4 関数/メソッド定義

**通常の関数:**
```javascript
// ファイル: ghost/core/core/boot.js:66-73
async function initDatabase({config}) {
    const DatabaseStateManager = require('./server/data/db/database-state-manager');
    const dbStateManager = new DatabaseStateManager({knexMigratorFilePath: config.get('paths:appRoot')});
    await dbStateManager.makeReady();

    const databaseInfo = require('./server/data/db/info');
    await databaseInfo.init();
}
```

**クラスメソッド:**
```javascript
// ファイル: ghost/core/core/server/ghost-server.js:73-133
start(rootApp) {
    debug('Starting...');
    this.rootApp = rootApp;

    const {host, port, testmode, shutdownTimeout} = this.serverConfig;
    const self = this;

    return new Promise(function (resolve, reject) {
        self.httpServer = rootApp.listen(port, host);
        // ...
    });
}
```

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

**CommonJS形式 (Node.js標準):**
```javascript
// ファイル: ghost/core/core/app.js:1-8
const sentry = require('./shared/sentry');
const express = require('./shared/express');
const config = require('./shared/config');
const logging = require('@tryghost/logging');
const urlService = require('./server/services/url');

const fs = require('fs');
const path = require('path');
```

**ESM形式 (フロントエンドアプリ):**
```javascript
// apps/* のReactアプリケーション
import React from 'react';
import { useQuery } from '@tanstack/react-query';
```

---

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

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

### 2.1 フレームワーク固有の概念

#### Express.js (Webフレームワーク)
GhostはExpress.jsをベースにしたNode.jsアプリケーションです。

```javascript
// ファイル: ghost/core/core/server/web/parent/app.js:10-39
module.exports = function setupParentApp() {
    debug('ParentApp setup start');
    const parentApp = express('parent');

    parentApp.use(mw.requestId);
    parentApp.use(mw.logRequest);

    // Register event emitter on req/res to trigger cache invalidation webhook event
    parentApp.use(mw.emitEvents);

    // enabled gzip compression by default
    if (config.get('compress') !== false) {
        parentApp.use(compress());
    }
    // ...
    return parentApp;
};
```

#### Bookshelf.js (ORM)
データベース操作にはBookshelf.js(Knex.jsベース)を使用しています。

```javascript
// ファイル: ghost/core/core/server/models/base/index.js:1-20
// # Base Model
// This is the model from which all other Ghost models extend. The model is based on Bookshelf.Model
// ...
ghostBookshelf.Model = ghostBookshelf.Model.extend({
    // Bookshelf `hasTimestamps` - handles created_at and updated_at properties
    hasTimestamps: true,
    requireFetch: false,
    // ...
});
```

#### Ember.js (レガシー管理画面)
レガシー管理画面はEmber.jsで構築されています。

```javascript
// ghost/admin/package.json より
"ember": {
    "edition": "octane"
}
```

#### React + Vite (新管理画面)
新しいAdmin UIはReact + Viteで構築されています。

```javascript
// apps/admin-x-settings, apps/portal 等
// Vite + React + @tanstack/react-query
```

### 2.2 プロジェクト独自のパターン

#### ブートシーケンス
Ghostは明確なブートシーケンスを持っています。

```javascript
// ファイル: ghost/core/core/boot.js:438-499 (抜粋)
async function bootGhost({backend = true, frontend = true, server = true} = {}) {
    // Step 0 - Load config and logging
    config = require('./shared/config');
    logging = require('@tryghost/logging');

    // Step 1 - Initialize sentry
    const sentry = require('./shared/sentry');

    // Step 2 - Start server with minimal app
    const rootApp = require('./app')();

    // Step 3 - Initialize database
    await initDatabase({config});

    // Step 4 - Initialize core
    await initCore({ghostServer, config, frontend});

    // Step 5 - Initialize services
    await initServices();

    // Step 6 - Initialize Express apps
    const parentApp = await initExpressApps({frontend, backend, config});
}
```

#### サービスパターン
各機能はサービスとして分離されています。

```javascript
// ファイル: ghost/core/core/boot.js:309-386 (抜粋)
async function initServices() {
    const stripe = require('./server/services/stripe');
    const members = require('./server/services/members');
    const permissions = require('./server/services/permissions');
    // ...

    await stripe.init();
    await Promise.all([
        members.init(),
        permissions.init(),
        // ...
    ]);
}
```

---

## 3. 命名規則

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

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

| パターン | 意味 | 例 |
|---------|------|-----|
| `kebab-case.js` | 通常のモジュールファイル | `ghost-server.js`, `url-utils.js` |
| `index.js` | ディレクトリのエントリーポイント | `services/members/index.js` |
| `*.test.js` | テストファイル | `post.test.js` |
| `app.js` | Expressアプリケーション定義 | `web/api/app.js` |
| `admin-x-*` | 新しいReact管理画面アプリ | `admin-x-settings`, `admin-x-framework` |

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

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| `init*` | 初期化関数 | `initDatabase()`, `initCore()` |
| `setup*` | セットアップ関数 | `setupApiApp()`, `setupParentApp()` |
| `*Service` | サービスクラス | `MembersService`, `StripeService` |
| `*Model` | データモデル | `Post`, `Member`, `User` |
| `*Controller` | APIコントローラー | `posts`, `members` (endpoints) |
| `mw.*` | ミドルウェア | `mw.requestId`, `mw.logRequest` |
| `ghost*` | Ghost固有のコンポーネント | `ghostBookshelf`, `ghostServer` |
| `@tryghost/*` | Ghost内部パッケージ | `@tryghost/logging`, `@tryghost/errors` |

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

| 種類 | 配置場所 | 説明 |
|------|---------|------|
| コアサーバー | `ghost/core/core/server/` | メインのバックエンドロジック |
| フロントエンド | `ghost/core/core/frontend/` | サイトレンダリング |
| APIエンドポイント | `ghost/core/core/server/api/endpoints/` | REST API定義 |
| モデル | `ghost/core/core/server/models/` | データモデル |
| サービス | `ghost/core/core/server/services/` | ビジネスロジック |
| Adminアプリ | `apps/admin-x-*` | React管理画面アプリ |
| Publicアプリ | `apps/portal`, `apps/comments-ui` | 公開サイト用UIコンポーネント |
| デザインシステム | `apps/shade` | 新UIコンポーネントライブラリ |

---

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

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

```
Ghost-main/
├── ghost/                          # コアGhostパッケージ
│   ├── core/                       # メインGhostアプリケーション
│   │   ├── core/
│   │   │   ├── app.js             # ルートExpressアプリ
│   │   │   ├── boot.js            # ブートシーケンス
│   │   │   ├── bridge.js          # フロント/バック連携
│   │   │   ├── frontend/          # フロントエンドレンダリング
│   │   │   │   ├── helpers/       # Handlebarsヘルパー
│   │   │   │   ├── services/      # フロントエンドサービス
│   │   │   │   └── web/           # Webルーティング
│   │   │   ├── server/            # バックエンドサーバー
│   │   │   │   ├── api/           # API層
│   │   │   │   │   └── endpoints/ # APIエンドポイント
│   │   │   │   ├── data/          # データ層
│   │   │   │   │   ├── db/        # データベース接続
│   │   │   │   │   ├── migrations/# マイグレーション
│   │   │   │   │   └── schema/    # スキーマ定義
│   │   │   │   ├── models/        # Bookshelfモデル
│   │   │   │   ├── services/      # ビジネスロジック
│   │   │   │   └── web/           # Expressルーティング
│   │   │   └── shared/            # 共有ユーティリティ
│   │   ├── ghost.js               # CLIエントリーポイント
│   │   └── index.js               # モジュールエントリー
│   ├── admin/                      # Ember.js管理画面(レガシー)
│   └── i18n/                       # 国際化リソース
├── apps/                           # React UIアプリケーション
│   ├── admin-x-framework/          # 管理画面共通フレームワーク
│   ├── admin-x-settings/           # 設定画面
│   ├── admin-x-design-system/      # レガシーデザインシステム
│   ├── shade/                      # 新デザインシステム
│   ├── portal/                     # メンバーポータル
│   ├── comments-ui/                # コメントUI
│   ├── posts/                      # 投稿分析
│   ├── stats/                      # サイト統計
│   └── ...
├── e2e/                            # E2Eテスト
├── docker/                         # Docker設定
├── compose.yml                     # Docker Compose設定
└── package.json                    # ルートパッケージ設定
```

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

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `ghost/core/core/server/` | バックエンドロジック | `ghost-server.js`, `models/`, `services/` |
| `ghost/core/core/frontend/` | サイトレンダリング | `helpers/`, `services/routing/` |
| `ghost/core/core/server/api/endpoints/` | REST API | `posts.js`, `members.js` |
| `ghost/core/core/server/models/` | データモデル | `post.js`, `user.js`, `member.js` |
| `ghost/core/core/server/services/` | ビジネスロジック | `members/`, `stripe/`, `email-service/` |
| `apps/admin-x-framework/` | Admin共通機能 | APIフック、ルーティング |
| `apps/shade/` | UIコンポーネント | Radix UI + Tailwind CSS |
| `apps/portal/` | メンバーUI | 会員登録、サブスクリプション |

---

## 5. アーキテクチャ

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

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

Ghostはモジュラーモノリスアーキテクチャを採用しており、Yarn v1 + Nx monorepoで構成されています。

```
┌─────────────────────────────────────────────────────────────────┐
│                        Ghost Monorepo                            │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                    ghost/core                            │   │
│  │  ┌─────────────────┐    ┌─────────────────────────┐     │   │
│  │  │    Frontend     │    │       Server            │     │   │
│  │  │  (Site Render)  │    │   (Node.js/Express)     │     │   │
│  │  │                 │    │                         │     │   │
│  │  │  - Helpers      │    │  - API Endpoints        │     │   │
│  │  │  - Routing      │    │  - Models (Bookshelf)   │     │   │
│  │  │  - Themes       │    │  - Services             │     │   │
│  │  │  - Rendering    │    │  - Data/Schema          │     │   │
│  │  └─────────────────┘    └─────────────────────────┘     │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │                        apps/*                             │  │
│  │  ┌────────────┐ ┌────────────┐ ┌────────────────────┐    │  │
│  │  │   Admin    │ │   Portal   │ │  Comments/Search   │    │  │
│  │  │  (Ember)   │ │  (React)   │ │     (React)        │    │  │
│  │  └────────────┘ └────────────┘ └────────────────────┘    │  │
│  │                                                           │  │
│  │  ┌────────────────────────────────────────────────────┐  │  │
│  │  │              admin-x-* (React)                     │  │  │
│  │  │  ┌─────────────┐ ┌─────────┐ ┌─────────────────┐   │  │  │
│  │  │  │  settings   │ │  posts  │ │  activitypub    │   │  │  │
│  │  │  └─────────────┘ └─────────┘ └─────────────────┘   │  │  │
│  │  └────────────────────────────────────────────────────┘  │  │
│  │                                                           │  │
│  │  ┌──────────────────────────────────────────────────┐    │  │
│  │  │           Design Systems                         │    │  │
│  │  │  ┌────────────────┐ ┌────────────────────────┐   │    │  │
│  │  │  │     shade      │ │  admin-x-design-system │   │    │  │
│  │  │  │    (新)         │ │       (レガシー)         │   │    │  │
│  │  │  └────────────────┘ └────────────────────────┘   │    │  │
│  │  └──────────────────────────────────────────────────┘    │  │
│  └──────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| Presentation (Web) | HTTPリクエスト処理 | `server/web/api/app.js` |
| API | APIエンドポイント定義 | `server/api/endpoints/posts.js` |
| Service | ビジネスロジック | `server/services/members/service.js` |
| Model | データアクセス | `server/models/post.js` |
| Data | DB操作・スキーマ | `server/data/schema/schema.js` |

### 5.3 データフロー

```
HTTP Request
    ↓
Express Router (web/api/app.js)
    ↓
API Endpoint (api/endpoints/posts.js)
    ↓
Service Layer (services/posts/posts-service.js)
    ↓
Model Layer (models/post.js)
    ↓
Bookshelf ORM
    ↓
Knex Query Builder
    ↓
MySQL/SQLite Database
```

---

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

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

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

**CLIエントリーポイント:**
```javascript
// ファイル: ghost/core/ghost.js:1-25
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

const argv = process.argv;
const mode = argv[2];

// Switch between boot modes
switch (mode) {
case 'repl':
case 'timetravel':
case 'generate-data':
    require('./core/cli/command').run(mode);
    break;
default:
    // New boot sequence
    require('./core/boot')();
}
```

**ブートシーケンス:**
```javascript
// ファイル: ghost/core/core/boot.js:438-447
async function bootGhost({backend = true, frontend = true, server = true} = {}) {
    const startTime = Date.now();
    debug('Begin Boot');

    let bootLogger;
    let config;
    let ghostServer;
    let logging;
    let metrics;
    // ...
}
```

### 6.2 ビジネスロジック

サービス層が各機能のビジネスロジックを担当します。

```javascript
// ファイル: ghost/core/core/server/api/endpoints/posts.js:48-82
const controller = {
    docName: 'posts',
    browse: {
        headers: {
            cacheInvalidate: false
        },
        options: [
            'include',
            'filter',
            'fields',
            'collection',
            'formats',
            'limit',
            'order',
            'page',
            'debug',
            'absolute_urls'
        ],
        validation: {
            options: {
                include: {
                    values: allowedIncludes
                },
                formats: {
                    values: models.Post.allowedFormats
                }
            }
        },
        query(frame) {
            return postsService.browsePosts(frame.options);
        }
    },
    // ...
};
```

### 6.3 データアクセス

**Bookshelfモデル:**
```javascript
// ファイル: ghost/core/core/server/models/post.js:45-100
Post = ghostBookshelf.Model.extend({
    tableName: 'posts',
    actionsCollectCRUD: true,
    actionsResourceType: 'post',

    defaults: function defaults() {
        return {
            uuid: crypto.randomUUID(),
            status: 'draft',
            featured: false,
            type: 'post',
            visibility: 'public',
            email_recipient_filter: 'all',
            show_title_and_feature_image: true
        };
    },
    // ...
});
```

**スキーマ定義:**
```javascript
// ファイル: ghost/core/core/server/data/schema/schema.js:61-100
posts: {
    id: {type: 'string', maxlength: 24, nullable: false, primary: true},
    uuid: {type: 'string', maxlength: 36, nullable: false, index: true, validations: {isUUID: true}},
    title: {type: 'string', maxlength: 2000, nullable: false, validations: {isLength: {max: 255}}},
    slug: {type: 'string', maxlength: 191, nullable: false},
    // ...
}
```

### 6.4 ユーティリティ/共通機能

**設定管理:**
```javascript
// ghost/core/core/shared/config/
const config = require('./shared/config');
const setting = config.get('paths:appRoot');
```

**ロギング:**
```javascript
// @tryghost/logging パッケージ
const logging = require('@tryghost/logging');
logging.info('Ghost is running...');
logging.error('Error occurred:', error);
```

**デバッグ:**
```javascript
// @tryghost/debug パッケージ
const debug = require('@tryghost/debug')('boot');
debug('Begin: Load config');
```

---

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

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

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| Service Pattern | ビジネスロジックの分離 | 高 | `services/members/service.js` |
| API Controller | RESTエンドポイント定義 | 高 | `api/endpoints/posts.js` |
| Model Extension | Bookshelfモデル拡張 | 高 | `models/post.js` |
| Async/Await | 非同期処理 | 高 | `boot.js`, 全般 |
| Middleware Chain | Expressミドルウェア | 高 | `web/parent/app.js` |

### 各パターンの詳細

#### パターン1: Service Pattern

**目的:** ビジネスロジックをAPIから分離し、再利用可能にする

**実装例:**
```javascript
// ファイル: ghost/core/core/server/services/members/service.js (概念)
class MembersService {
    constructor(deps) {
        this.memberRepository = deps.memberRepository;
        this.stripeService = deps.stripeService;
    }

    async createMember(data) {
        // ビジネスロジック
    }
}

module.exports = MembersService;
```

**解説:** 各サービスは依存性注入を受け、初期化時に`init()`メソッドで設定されます。

#### パターン2: API Controller

**目的:** REST APIエンドポイントを定義し、バリデーションと処理を行う

**実装例:**
```javascript
// ファイル: ghost/core/core/server/api/endpoints/posts.js:48-82
const controller = {
    docName: 'posts',
    browse: {
        headers: { cacheInvalidate: false },
        options: ['include', 'filter', 'fields', 'limit', 'order', 'page'],
        validation: {
            options: {
                include: { values: allowedIncludes }
            }
        },
        permissions: { unsafeAttrs: unsafeAttrs },
        query(frame) {
            return postsService.browsePosts(frame.options);
        }
    }
};
```

**解説:** コントローラーは`docName`でリソース名を定義し、各HTTP操作(browse/read/add/edit/destroy)を実装します。

#### パターン3: Model Extension

**目的:** Bookshelfモデルを拡張してドメインロジックを追加

**実装例:**
```javascript
// ファイル: ghost/core/core/server/models/post.js:45-68
Post = ghostBookshelf.Model.extend({
    tableName: 'posts',
    hasTimestamps: true,

    defaults: function defaults() {
        return {
            uuid: crypto.randomUUID(),
            status: 'draft',
            featured: false
        };
    },

    // リレーション定義
    tags: function tags() {
        return this.belongsToMany('Tag');
    }
}, {
    // 静的メソッド
    transaction(fn) {
        return ghostBookshelf.transaction(fn);
    }
});
```

**解説:** `ghostBookshelf.Model.extend()`でベースモデルを拡張し、テーブル名、デフォルト値、リレーションを定義します。

---

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

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

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

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

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

#### 例1: 記事の公開フロー

**概要:** 記事を公開するAPIリクエストの処理フロー

**処理フロー:**
```
HTTP PUT /ghost/api/admin/posts/:id
    → web/api/app.js
    → api/endpoints/posts.js (edit)
    → services/posts/posts-service.js
    → models/post.js
    → Database
```

**詳細な追跡:**

1. **APIルーティング** (`ghost/core/core/server/web/api/app.js:26-27`)
   ```javascript
   apiApp.lazyUse('/content/', require('./endpoints/content/app'));
   apiApp.lazyUse('/admin/', require('./endpoints/admin/app'));
   ```

2. **APIエンドポイント** (`ghost/core/core/server/api/endpoints/posts.js`)
   ```javascript
   edit: {
       headers: {
           cacheInvalidate(result, options) {
               return getCacheHeaderFromEventString(
                   options.context.event,
                   result.posts[0]
               );
           }
       },
       options: ['include', 'id', 'formats', 'source', 'newsletter'],
       validation: { options: { include: { values: allowedIncludes } } },
       permissions: { unsafeAttrs },
       query(frame) {
           return postsService.editPost(frame);
       }
   }
   ```

3. **サービス層でのビジネスロジック** (`ghost/core/core/server/services/posts/`)
   - 記事のステータス変更
   - 公開日時の設定
   - イベントの発行

4. **モデル層でのデータ保存** (`ghost/core/core/server/models/post.js`)
   - Bookshelf ORMによるDB更新
   - タイムスタンプの自動更新

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

- [ ] エントリーポイントを特定したか
- [ ] 呼び出し関係を把握したか
- [ ] データの変換ポイントを確認したか
- [ ] エラーハンドリングを確認したか
- [ ] 最終的な出力を確認したか

---

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

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

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

#### 全体像を把握したい場合
1. `README.md` - プロジェクト概要
2. `AGENTS.md` (CLAUDE.md) - モノレポ構造とコマンド一覧
3. `ghost/core/core/boot.js` - ブートシーケンス

#### 特定機能を理解したい場合
1. `ghost/core/core/server/api/endpoints/` - API定義を確認
2. `ghost/core/core/server/services/` - ビジネスロジックを確認
3. `ghost/core/core/server/models/` - データモデルを確認

#### 改修作業を行う場合
1. 対象機能のAPIエンドポイント
2. 関連するサービス
3. テストファイル(`test/unit/`, `test/integration/`)

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

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| README.md | プロジェクト概要 | 最初に確認 |
| AGENTS.md | 開発ガイドライン | 開発開始時 |
| ghost/core/core/boot.js | ブートシーケンス | 起動フローの理解 |
| ghost/core/core/server/data/schema/schema.js | DBスキーマ | データ構造の確認 |
| apps/*/package.json | 各アプリの依存関係 | アプリ開発時 |

---

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

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

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

#### Q: `require`と`import`が混在しているのはなぜ?
A: バックエンド(Node.js)はCommonJS形式(`require`)、フロントエンド(React)はESM形式(`import`)を使用しています。TypeScriptファイルもESM形式です。

#### Q: サービスの初期化順序はどう決まる?
A: `boot.js`の`initServices()`関数で明示的に定義されています。依存関係のあるサービスは`await`で順次初期化、独立したサービスは`Promise.all()`で並列初期化されます。

#### Q: APIエンドポイントの追加方法は?
A: `ghost/core/core/server/api/endpoints/`にコントローラーを追加し、`ghost/core/core/server/web/api/endpoints/admin/`または`content/`でルートを登録します。

#### Q: モデルのリレーション定義はどこを見れば良い?
A: 各モデルファイル(例: `models/post.js`)内で`belongsTo`, `hasMany`, `belongsToMany`などのメソッドで定義されています。

### デバッグのヒント

**環境変数によるデバッグ出力:**
```bash
DEBUG=ghost:* yarn dev:legacy
```

**特定モジュールのデバッグ:**
```bash
DEBUG=ghost:boot,ghost:models yarn dev:legacy
```

**テストモードでの詳細ログ:**
```bash
DEBUG=ghost:test* yarn test:unit
```

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| Ghost Core | メインのGhostアプリケーション |
| Admin | 管理画面 |
| Portal | メンバー向けUI(サブスク、ログイン等) |
| Theme | サイトのテンプレート |
| Member | 有料/無料会員 |
| Newsletter | メールニュースレター |
| Tier | サブスクリプションの価格帯 |
| Lexical | 新しいリッチテキストエディター形式 |
| Mobiledoc | 旧リッチテキストエディター形式 |
| Shade | 新しいUIコンポーネントライブラリ |
| Admin-X | 新しいReactベースの管理画面アプリ |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `ghost/core/ghost.js` | CLIエントリーポイント | モード切り替え |
| `ghost/core/core/boot.js` | ブートシーケンス | 初期化処理 |
| `ghost/core/core/app.js` | ルートアプリ | Expressアプリ生成 |
| `ghost/core/core/server/ghost-server.js` | HTTPサーバー | サーバー起動/停止 |
| `ghost/core/core/server/models/` | データモデル | Bookshelfモデル |
| `ghost/core/core/server/services/` | サービス | ビジネスロジック |
| `ghost/core/core/server/api/endpoints/` | API | RESTエンドポイント |
| `ghost/core/core/server/data/schema/schema.js` | スキーマ | テーブル定義 |
| `apps/admin-x-framework/` | フレームワーク | APIフック、ルーティング |
| `apps/shade/` | デザインシステム | UIコンポーネント |

### C. 参考資料

- [Ghost公式ドキュメント](https://ghost.org/docs/)
- [Express.js公式ドキュメント](https://expressjs.com/)
- [Bookshelf.js公式ドキュメント](https://bookshelfjs.org/)
- [React公式ドキュメント](https://react.dev/)
- [Ember.js公式ドキュメント](https://emberjs.com/)
- [Vite公式ドキュメント](https://vitejs.dev/)
