# 機能設計書 62-管理者通知

## 概要

本ドキュメントは、Ghost CMSにおける管理者通知機能の設計を記述する。この機能は、システムイベントに関する通知を管理者に対して表示・管理するための機能である。

### 本機能の処理概要

この機能では、Ghost本体のバージョンアップ情報、セキュリティアラート、カスタム通知などをシステム管理者に対して通知し、確認・消去できるようにする。

**業務上の目的・背景**：サイト管理者が重要なシステム情報を見逃さないよう、管理画面上に通知を表示する必要がある。特にセキュリティアップデートやバージョンアップ情報は、サイトの安全性と機能性を維持するために重要である。

**機能の利用シーン**：
- 新しいGhostバージョンがリリースされた際の通知表示
- セキュリティ脆弱性に関するアラート通知
- カスタムインテグレーションからの通知
- 管理者が通知を確認・消去する際

**主要な処理内容**：
1. 通知の一覧取得（browse）
2. 新規通知の追加（add）
3. 通知の消去/既読マーク（destroy）
4. 全通知の一括消去（destroyAll）
5. 通知のバージョンフィルタリング
6. ユーザー別既読管理

**関連システム・外部連携**：更新チェックサービス（Ghost.orgのupdate check API）

**権限による制御**：通知の閲覧・追加・削除には管理者権限が必要

## 関連画面

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

## 機能種別

CRUD操作 / データ管理

## 入力仕様

### 入力パラメータ

#### browse
| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| user.id | string | Yes | 現在のユーザーID | - |

#### add
| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| notifications | array | Yes | 追加する通知の配列 | - |
| notifications[].id | string | No | 通知ID（自動生成可） | - |
| notifications[].message | string | Yes | 通知メッセージ | - |
| notifications[].status | string | No | ステータス（default: alert） | - |
| notifications[].type | string | No | タイプ（info/alert） | - |
| notifications[].dismissible | boolean | No | 消去可能フラグ | - |
| notifications[].custom | boolean | No | カスタム通知フラグ | - |

#### destroy
| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| notification_id | string | Yes | 消去する通知ID | 必須 |
| user.id | string | Yes | 現在のユーザーID | - |

### 入力データソース

- Settings テーブル（notifications キー）
- Admin API リクエスト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | string | 通知ID（ObjectId形式） |
| message | string | 通知メッセージ |
| status | string | ステータス（alert等） |
| type | string | タイプ（info/alert） |
| dismissible | boolean | 消去可能フラグ |
| location | string | 表示位置（bottom等） |
| custom | boolean | カスタム通知フラグ |
| seen | boolean | 既読フラグ |
| seenBy | array | 既読ユーザーIDリスト |
| addedAt | Date | 追加日時 |
| createdAtVersion | string | 作成時のGhostバージョン |

### 出力先

- Settings テーブル（notifications キー）
- Admin API レスポンス

## 処理フロー

### 処理シーケンス

```
1. browse処理
   ├─ settingsCacheから全通知を取得
   ├─ 通知の有効性チェック（配列形式確認）
   ├─ 追加日時でソート（降順）
   ├─ バージョンフィルタリング
   └─ 未読通知のみ返却

2. add処理
   ├─ デフォルト値の設定
   ├─ 重複チェック
   ├─ リリース通知がある場合は既存のリリース通知を削除
   └─ 通知を追加してSettings保存

3. destroy処理
   ├─ 通知の存在確認
   ├─ dismissible属性チェック
   ├─ seen=true、seenByにユーザーID追加
   └─ Settings保存
```

### フローチャート

```mermaid
flowchart TD
    A[browse開始] --> B[settingsCacheから通知取得]
    B --> C{通知配列が有効?}
    C -->|No| D[dangerousDestroyAllで初期化]
    C -->|Yes| E[addedAtでソート]
    D --> F[空配列を返却]
    E --> G{各通知をフィルタ}
    G --> H{createdAtVersionあり?}
    H -->|Yes| I{現在バージョン以上?}
    H -->|No| J{リリース通知?}
    I -->|Yes| K[通知を含める]
    I -->|No| L[除外]
    J -->|Yes| M{バージョン比較}
    J -->|No| N{既読?}
    M -->|新しい| K
    M -->|古い| L
    N -->|No| K
    N -->|Yes| L
    K --> O[結果配列に追加]
    L --> G
    O --> P[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 重複防止 | 同一IDの通知は追加しない | add時 |
| BR-02 | リリース通知置換 | 新しいリリース通知がある場合、古いものを削除 | add時にcustom=false |
| BR-03 | バージョンフィルタ | 現在のバージョン以降の通知のみ表示 | browse時 |
| BR-04 | 既読管理 | seenByでユーザー別に既読管理 | browse/destroy時 |
| BR-05 | 消去不可通知 | dismissible=falseの通知は削除不可 | destroy時 |

### 計算ロジック

バージョン比較: semverライブラリを使用してバージョン文字列を比較

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| browse | settings | SELECT | notifications設定値の取得 |
| add | settings | UPDATE | notifications設定値の更新 |
| destroy | settings | UPDATE | notifications設定値の更新 |
| destroyAll | settings | UPDATE | notifications設定値のリセット |

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

#### settings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT/UPDATE | key='notifications' | JSON配列形式 | settingsCacheを経由 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | NoPermissionError | dismissible=falseの通知を削除しようとした | エラーメッセージ「You do not have permission to dismiss this notification.」 |
| - | NotFoundError | 存在しない通知IDを指定 | エラーメッセージ「Notification does not exist.」 |

### リトライ仕様

特になし（同期処理）

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

Settings テーブルへの保存は単一操作のため、特別なトランザクション制御は不要

## パフォーマンス要件

- settingsCacheを使用してデータベースアクセスを最小化
- 通知配列は通常小規模のため、特別なパフォーマンス対策は不要

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

- Admin API経由のアクセスには認証が必要
- セキュリティアラート（type: alert）は管理者メールにも送信される
- 通知データの破損時は自動的に初期化（dangerousDestroyAll）

## 備考

- 通知データはsettingsテーブルにJSON形式で保存される
- Ghost.orgの更新チェックサービスからの通知も同じ機構を利用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | notifications.js | `ghost/core/core/server/services/notifications/notifications.js` | Notificationsクラスの構造とメソッド |

**読解のコツ**: クラスベースのサービス設計。settingsCacheとSettingsModelの依存関係注入パターンを理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | notifications.js | `ghost/core/core/server/api/endpoints/notifications.js` | APIエンドポイントの定義 |

**主要処理フロー**:
1. **10-21行目**: browse API - ユーザーコンテキストを渡してサービス呼び出し
2. **23-49行目**: add API - 通知追加と設定保存
3. **51-78行目**: destroy API - 通知の既読化と設定保存
4. **86-101行目**: destroyAll - 全通知既読化（テスト用）

#### Step 3: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.js | `ghost/core/core/server/services/notifications/index.js` | サービスインスタンス生成 |
| 3-2 | notifications.js | `ghost/core/core/server/services/notifications/notifications.js` | 本体ロジック |

**主要処理フロー**:
- **29-48行目**: fetchAllNotifications - 全通知取得と有効性チェック
- **72-121行目**: browse - バージョンフィルタリングと既読フィルタ
- **123-181行目**: add - 重複チェックとリリース通知置換
- **192-229行目**: destroy - 既読マーク処理

#### Step 4: バージョン比較ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | notifications.js | `ghost/core/core/server/services/notifications/notifications.js` | browse内のsemver比較ロジック |

**主要処理フロー**:
- **77-118行目**: バージョンフィルタリング、createdAtVersionとの比較、リリース通知の特別処理

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

```
notifications.js (API Endpoint)
    │
    ├─ browse()
    │      └─ notifications.browse({user})
    │              └─ fetchAllNotifications()
    │              └─ wasSeen()
    │
    ├─ add()
    │      └─ notifications.add({notifications})
    │      └─ settingsBREADService.edit()
    │
    └─ destroy()
           └─ notifications.destroy({notificationId, user})
           └─ settingsBREADService.edit()
```

### データフロー図

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

settingsCache ─────▶ fetchAllNotifications() ─────▶ 通知配列
(notifications)            │
                          ▼
                    バージョンフィルタ
                          │
                          ▼
                    既読フィルタ(wasSeen) ─────▶ API Response
                                                 (未読通知)

Admin API ─────────▶ add/destroy ─────────▶ settingsBREADService
(通知操作)                                    .edit()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| notifications.js | `ghost/core/core/server/api/endpoints/notifications.js` | ソース | APIエンドポイント |
| index.js | `ghost/core/core/server/services/notifications/index.js` | ソース | サービスインスタンス生成 |
| notifications.js | `ghost/core/core/server/services/notifications/notifications.js` | ソース | 通知ロジック本体 |
| settings-service.js | `ghost/core/core/server/services/settings/settings-service.js` | ソース | 設定保存サービス |
