# 機能設計書 61-受信レコメンデーション

## 概要

本ドキュメントは、Ghost CMSにおける受信レコメンデーション機能の設計を記述する。この機能は、他のGhostサイトや外部サイトからのレコメンデーション（推薦）を受信・管理し、サイト管理者に通知する機能である。

### 本機能の処理概要

この機能では、Webmentionプロトコルを利用して他サイトからの推薦情報を受信し、管理者に通知することができる。

**業務上の目的・背景**：Ghostエコシステム内でのサイト間相互推薦を実現するため、他サイトからの推薦を自動的に検出・記録する必要がある。これにより、サイト運営者は自身のサイトがどの程度他サイトから推薦されているかを把握でき、コミュニティとの関係性を強化できる。

**機能の利用シーン**：
- 他のGhostサイトが自サイトをレコメンデーションに追加した際
- 管理者が受信したレコメンデーションの一覧を確認する際
- レコメンデーション受信時にメール通知を受け取る際

**主要な処理内容**：
1. Webmentionイベントの監視とレコメンデーション検出
2. `.well-known/recommendations.json`形式のURLからのレコメンデーション情報抽出
3. 受信レコメンデーションのデータベースへの記録
4. 管理者へのメール通知送信
5. 受信レコメンデーション一覧のAPI提供

**関連システム・外部連携**：Webmentionサービス、メール配信サービス（Mailgun等）

**権限による制御**：Admin API経由でのアクセスには管理者権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 54 | レコメンデーション設定 | 参照画面 | 他サイトからの推薦の確認 |

## 機能種別

データ連携 / CRUD操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| limit | number | No | 取得件数制限 | 正の整数 |
| page | number | No | ページ番号 | 正の整数 |

### 入力データソース

- Webmentionイベント（DomainEvents経由）
- `.well-known/recommendations.json`エンドポイント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | string | レコメンデーションID |
| source | string | 推薦元サイトURL |
| verified | boolean | 検証済みフラグ |
| createdAt | Date | 受信日時 |

### 出力先

- データベース（mentions テーブル）
- Admin API レスポンス
- メール通知

## 処理フロー

### 処理シーケンス

```
1. Webmentionイベント受信
   └─ DomainEventsからMentionCreatedEventを購読

2. レコメンデーション判定
   └─ ソースURLが/.well-known/recommendations.jsonで終わるか確認

3. 検証済みチェック
   └─ mention.verifiedがtrueであることを確認

4. メール通知送信
   └─ IncomingRecommendationServiceでメール通知を生成・送信

5. 一覧取得（browse API）
   └─ ページネーション付きでレコメンデーション一覧を返却
```

### フローチャート

```mermaid
flowchart TD
    A[Webmention受信] --> B{/.well-known/recommendations.json?}
    B -->|Yes| C{verified?}
    B -->|No| D[通常のWebmention処理]
    C -->|Yes| E[レコメンデーション検出ログ出力]
    C -->|No| F[処理終了]
    E --> G[メール通知送信]
    G --> H[処理完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | URL形式検証 | ソースURLが`/.well-known/recommendations.json`で終わる必要がある | Webmention受信時 |
| BR-02 | 検証済み必須 | `verified`フラグがtrueの場合のみ処理対象 | レコメンデーション判定時 |
| BR-03 | 通知対象者 | recommendation-receivedアラート有効なユーザーにのみ通知 | メール送信時 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| browse | mentions | SELECT | 受信レコメンデーション一覧取得 |

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

#### mentions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | source | /.well-known/recommendations.jsonで終わるURL | フィルタ条件 |
| SELECT | verified | true | フィルタ条件 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | NotFoundError | 対象データが存在しない | 空の結果を返却 |
| - | ValidationError | 不正なパラメータ | バリデーションエラーを返却 |

### リトライ仕様

メール送信失敗時は例外をログ出力し、処理を継続

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

単一のSELECT操作のため、特別なトランザクション制御は不要

## パフォーマンス要件

- ページネーションによる大量データ対応
- 非同期イベント処理による応答性確保

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

- Admin API経由のアクセスには認証が必要
- ソースURLの検証によるスプーフィング対策

## 備考

- Webmentionプロトコルに基づくFediverse連携機能の一部
- レコメンデーション機能は設定で無効化可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | incoming-recommendations.js | `ghost/core/core/server/api/endpoints/incoming-recommendations.js` | APIエンドポイントの構造を理解 |

**読解のコツ**: Controller形式のAPI定義パターンを理解する。`docName`、`permissions`、`query`の関係性が重要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | incoming-recommendations.js | `ghost/core/core/server/api/endpoints/incoming-recommendations.js` | browseメソッドの呼び出し構造 |

**主要処理フロー**:
1. **7-20行目**: browse APIの定義、limitとpageオプションをサポート
2. **17-18行目**: recommendationsサービスのincomingRecommendationControllerへ委譲

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.js | `ghost/core/core/server/services/recommendations/index.js` | サービスラッパーのエクスポート |
| 3-2 | recommendation-service-wrapper.js | `ghost/core/core/server/services/recommendations/recommendation-service-wrapper.js` | サービス初期化と依存関係注入 |

**主要処理フロー**:
- **40-46行目**: 設定による機能有効/無効の判定
- **127-143行目**: IncomingRecommendationServiceの初期化
- **156-179行目**: WebmentionイベントからのURL判定とメール送信

#### Step 4: イベント処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | recommendation-service-wrapper.js | `ghost/core/core/server/services/recommendations/recommendation-service-wrapper.js` | MentionCreatedEventの購読処理 |

**主要処理フロー**:
- **172-179行目**: DomainEventsからMentionCreatedEventを購読し、レコメンデーションURLを判定

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

```
incoming-recommendations.js (API Endpoint)
    │
    └─ recommendations/index.js
           │
           └─ RecommendationServiceWrapper
                  │
                  ├─ IncomingRecommendationController.browse()
                  │
                  └─ IncomingRecommendationService
                         │
                         ├─ mentionsApi (Webmention API)
                         │
                         └─ emailService.send()
```

### データフロー図

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

Webmention ───────▶ MentionCreatedEvent ───────▶ ログ出力
イベント                    │                           │
                           ▼                           ▼
                  isRecommendationUrl判定 ───────▶ メール通知
                           │
                           ▼
Browse API ───────▶ IncomingRecommendationController ───▶ JSON Response
リクエスト                                                (一覧データ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| incoming-recommendations.js | `ghost/core/core/server/api/endpoints/incoming-recommendations.js` | ソース | APIエンドポイント定義 |
| index.js | `ghost/core/core/server/services/recommendations/index.js` | ソース | サービスエクスポート |
| recommendation-service-wrapper.js | `ghost/core/core/server/services/recommendations/recommendation-service-wrapper.js` | ソース | サービス初期化・イベント購読 |
| recommendation-enabler-service.js | `ghost/core/core/server/services/recommendations/recommendation-enabler-service.js` | ソース | 機能有効化サービス |
