# 機能設計書 68-更新チェック

## 概要

本ドキュメントは、Ghost CMSにおける更新チェック機能の設計を記述する。この機能は、Ghost本体のバージョン更新を確認し、新しいバージョンや重要な通知を管理者に伝達する機能である。

### 本機能の処理概要

この機能では、Ghost.orgの更新チェックサービスに定期的にリクエストを送信し、新しいバージョンのリリース情報やセキュリティ通知を取得して、管理画面に通知として表示する。

**業務上の目的・背景**：Ghost CMSを安全かつ最新の状態で運用するために、新しいバージョンのリリースやセキュリティアップデートを管理者に通知する必要がある。この機能により、管理者はタイムリーにアップデートを適用できる。

**機能の利用シーン**：
- Ghost起動時の更新チェック
- 毎日のスケジュール更新チェック
- セキュリティアラート受信時

**主要な処理内容**：
1. 更新チェックスケジュールの設定
2. サイト統計データの収集（プライバシー設定に応じて）
3. Ghost.orgサービスへのHTTPリクエスト
4. レスポンスの解析と通知作成
5. アラート通知のメール送信

**関連システム・外部連携**：Ghost.org Update Check API、メール配信サービス

**権限による制御**：内部処理のため、直接的な権限制御は適用されない

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | What's New画面 | 結果表示画面 | Ghost新機能・更新情報の表示 |

## 機能種別

バッチ処理 / 外部連携

## 入力仕様

### 入力パラメータ（check）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| rethrowErrors | boolean | No | エラー再スロー（ワーカー向け） | - |
| forceUpdate | boolean | No | 強制実行フラグ | - |
| updateCheckUrl | string | No | カスタムチェックURL | - |

### 入力データソース

- Settings テーブル（db_hash, active_theme, next_update_check）
- Posts テーブル（投稿数）
- Users テーブル（ユーザー数）
- 設定ファイル（mail設定、env、プライバシー設定）

## 出力仕様

### 出力データ（通知）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | string | 通知ID |
| custom | boolean | カスタム通知フラグ |
| createdAt | Date | 作成日時 |
| status | string | ステータス |
| type | string | タイプ（info/alert） |
| dismissible | boolean | 消去可能フラグ |
| top | boolean | 上部表示フラグ |
| message | string | 通知メッセージ |

### 出力先

- Settings テーブル（notifications、next_update_check）
- メール通知（type: alert時）

## 処理フロー

### 処理シーケンス

```
1. チェック条件判定
   ├─ NODE_ENV確認（development/productionのみ）
   ├─ next_update_check時刻確認
   └─ forceUpdate確認

2. データ収集
   ├─ ghost_version, node_version, env, database_type
   ├─ email_transport, blog_id, theme
   └─ post_count, user_count, blog_created_at

3. HTTPリクエスト
   ├─ POST（プライバシー有効時）: 全データ送信
   └─ GET（プライバシー無効時）: ghost_versionのみ

4. レスポンス処理
   ├─ next_update_check更新
   ├─ 通知グループフィルタリング
   └─ 各通知に対してcreateCustomNotification

5. 通知作成
   ├─ 通知オブジェクト構築
   ├─ type=alertの場合はメール送信
   └─ notifications.add呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[check開始] --> B{環境チェック}
    B -->|非対象環境| C[終了]
    B -->|OK| D[next_update_check確認]
    D -->|まだ| C
    D -->|チェック時刻| E[updateCheckData収集]
    E --> F{プライバシー設定}
    F -->|無効| G[POST: 全データ送信]
    F -->|有効| H[GET: バージョンのみ]
    G --> I[レスポンス処理]
    H --> I
    I --> J[next_update_check更新]
    J --> K[通知グループフィルタ]
    K --> L[各通知処理]
    L --> M{type=alert?}
    M -->|Yes| N[管理者メール送信]
    M -->|No| O[通知追加]
    N --> O
    O --> P[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 環境制限 | development/production環境のみ実行 | check時 |
| BR-02 | スケジュール制限 | next_update_check以降のみ実行 | check時 |
| BR-03 | プライバシー制御 | isPrivacyDisabledでデータ送信制御 | updateCheckRequest時 |
| BR-04 | 通知グループ | notificationGroupsでフィルタリング | updateCheckResponse時 |
| BR-05 | アラートメール | type=alertはOwner/Administratorにメール送信 | createCustomNotification時 |
| BR-06 | 次回チェック | 24時間後のタイムスタンプを設定 | nextCheckTimestamp時 |

### 計算ロジック

blog_id: `md5(hostname + pathname + db_hash)`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| データ収集 | settings | SELECT | db_hash, active_theme取得 |
| データ収集 | posts | SELECT | 投稿数カウント |
| データ収集 | users | SELECT | ユーザー情報取得 |
| スケジュール更新 | settings | UPDATE | next_update_check更新 |
| 通知追加 | settings | UPDATE | notifications更新 |

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

#### settings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | key='db_hash' | ブログ識別用ハッシュ | - |
| SELECT | key='active_theme' | アクティブテーマ名 | - |
| SELECT | key='next_update_check' | 次回チェック時刻 | Unix timestamp |
| UPDATE | key='next_update_check' | 24時間後のタイムスタンプ | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | NotFound | 通知なし | 空の通知配列を返却 |
| - | Error | サービスエラー | next_update_check更新後ログ出力 |

### リトライ仕様

エラー時は次回スケジュールで再試行（next_update_checkを更新）

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

Settings の更新は個別のedit操作のため、特別なトランザクション制御は不要

## パフォーマンス要件

- HTTPリクエストタイムアウト: 1000ms
- スケジュール: 毎日ランダム時刻（s m h * * *形式）

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

- プライバシー設定でデータ送信を制御可能
- blog_idはmd5ハッシュ化
- アラート通知は管理者のみにメール送信

## 備考

- スケジュール実行はrun-update-check.jsをワーカーとして実行
- 開発環境でも動作確認可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.js | `ghost/core/core/server/services/update-check/index.js` | 初期化とスケジュール登録 |

**読解のコツ**: モジュールエクスポートが関数になっている点に注意。スケジュール登録はscheduleRecurringJobs。

**主要処理フロー**:
- **23-73行目**: メインエクスポート関数 - UpdateCheckServiceの初期化と実行
- **28-35行目**: 環境チェック（development/production）
- **40-70行目**: UpdateCheckServiceインスタンス生成
- **75-86行目**: scheduleRecurringJobs - 毎日のスケジュール登録

#### Step 2: サービスクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | update-check-service.js | `ghost/core/core/server/services/update-check/update-check-service.js` | メインロジック |

**主要処理フロー**:
- **27-61行目**: コンストラクタ - 依存関係の注入
- **63-66行目**: nextCheckTimestamp - 24時間後のタイムスタンプ
- **80-96行目**: updateCheckError - エラーハンドリング
- **102-154行目**: updateCheckData - サイト統計データ収集
- **165-209行目**: updateCheckRequest - HTTPリクエスト
- **249-303行目**: updateCheckResponse - レスポンス処理
- **311-364行目**: createCustomNotification - 通知作成・メール送信
- **373-391行目**: check - メインエントリポイント

#### Step 3: スケジュール実行を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | run-update-check.js | `ghost/core/core/server/services/update-check/run-update-check.js` | ワーカー実行用 |

**主要処理フロー**:
- ワーカースレッドから実行される際のエントリポイント

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

```
index.js (エントリポイント)
    │
    ├─ module.exports() - 即時実行
    │      │
    │      └─ new UpdateCheckService({...})
    │              │
    │              └─ check()
    │                     │
    │                     ├─ settings.read('next_update_check')
    │                     ├─ updateCheckRequest()
    │                     │      └─ updateCheckData()
    │                     │             ├─ settings.read()
    │                     │             ├─ posts.browse()
    │                     │             └─ users.browse()
    │                     │
    │                     └─ updateCheckResponse()
    │                            └─ createCustomNotification()
    │                                   ├─ sendEmail() (type=alert)
    │                                   └─ notifications.add()
    │
    └─ scheduleRecurringJobs()
           └─ jobsService.addJob({at: cron, job: run-update-check.js})
```

### データフロー図

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

設定/DB ───────────▶ updateCheckData() ──────▶ リクエストデータ
 │                        │
 ├─ db_hash              │
 ├─ active_theme         │
 ├─ posts                ▼
 └─ users         updateCheckRequest()
                         │
                         ▼
                  Ghost.org API ──────────▶ レスポンス
                         │
                         ▼
                  updateCheckResponse()
                         │
                         ├─ next_update_check更新 ──▶ settings
                         │
                         └─ createCustomNotification()
                                │
                                ├─ type=alert ──▶ メール送信
                                │
                                └─ notifications.add() ──▶ settings
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.js | `ghost/core/core/server/services/update-check/index.js` | ソース | エントリポイント・スケジュール |
| update-check-service.js | `ghost/core/core/server/services/update-check/update-check-service.js` | ソース | メインロジック |
| run-update-check.js | `ghost/core/core/server/services/update-check/run-update-check.js` | ソース | ワーカー実行用 |
| notifications.js | `ghost/core/core/server/api/endpoints/notifications.js` | ソース | 通知API |
