# 通知設計書 12-フォーラムモデレーター通知

## 概要

本ドキュメントは、QuickerSite CMSにおける「フォーラムモデレーター通知」機能の通知設計について記述する。フォーラムの新規投稿（トピック作成および返信）をモデレーター（テーマ管理者）に自動転送し、コンテンツの監視・管理を支援する機能である。

### 本通知の処理概要

**業務上の目的・背景**：フォーラム運営において、モデレーターがすべての投稿を迅速に把握し、不適切なコンテンツの早期発見・対応を可能にすることが目的である。特にユーザー生成コンテンツの品質管理やスパム対策において重要な役割を果たす。モデレーターは通知を受け取ることで、フォーラムに常駐していなくても投稿を監視できる。

**通知の送信タイミング**：フォーラムに新規トピックまたは返信が投稿され、`post.Save`関数が正常に完了した直後に送信される。ただし、モデレーター自身が投稿した場合は通知されない。

**通知の受信者**：テーマ（フォーラム）に設定されたモデレーター（`theme.iContactID`で指定されたコンタクト）のメールアドレス（`theme.contact.sEmail`）に送信される。

**通知内容の概要**：投稿者名、トピック件名、投稿内容本文、添付ファイルリンク（存在する場合）、トピックへの直接リンク、および訪問者詳細情報（IPアドレス、ブラウザ情報等）が含まれる。

**期待されるアクション**：モデレーターは通知メールを確認し、投稿内容が適切かどうかを判断する。必要に応じてフォーラムにアクセスし、投稿の承認、編集、削除等のモデレーション作業を行う。

## 通知種別

メール

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高 |
| リトライ | 無（`On Error Resume Next`によりエラーは無視される） |

### 送信先決定ロジック

1. `theme.bForwardPostsToModerator`設定がTrueであることを確認
2. 投稿者が`theme.iContactID`（モデレーター）と異なることを確認
3. `theme.contact.sEmail`からモデレーターのメールアドレスを取得
4. 条件を満たす場合、モデレーターにメールを送信

## 通知テンプレート

### メール通知の場合

| 項目 | 内容 |
|-----|------|
| 送信元アドレス | `customer.webmasterEmail`（顧客設定のウェブマスターメール） |
| 送信元名称 | `customer.siteName`（サイト名） |
| 件名 | `l("moderatornotification") & " - " & theme.sSubjectNotification`（または`theme.sTopicSubjectNotification`） |
| 形式 | HTML |

### 本文テンプレート

返信の場合（`iPostID <> 0`）:
```html
{theme.sBodyNotification のテンプレート展開結果}
<hr />
{訪問者詳細情報}
```

新規トピックの場合（`iPostID = 0`）:
```html
{theme.sTopicBodyNotification のテンプレート展開結果}
<hr />
{訪問者詳細情報}
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | 添付ファイルはメール本文内のリンクとして表示される |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| `[QS_theme:postsubject]` | 元トピックの件名（返信時） | `parentTopic.sSubject` | 条件付き |
| `[QS_theme:Replyer]` | 返信者名（返信時） | `sAnName`または`logon.contact.sNickname` | 条件付き |
| `[QS_theme:reply]` | 返信内容（返信時） | `sBody` + `sFileLink()` | 条件付き |
| `[QS_theme:name]` | テーマ名（新規トピック時） | `theme.sName` | 条件付き |
| `[QS_theme:poster]` | 投稿者名（新規トピック時） | `sAnName`または`logon.contact.sNickname` | 条件付き |
| `[QS_theme:post]` | 投稿内容（新規トピック時） | `sBody` + `sFileLink()` | 条件付き |
| `[QS_theme:postlink]` | トピックへのリンクURL | `prepareLink()`関数 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | 投稿（`cls_post.Save`関数） | `theme.bForwardPostsToModerator = True` AND 投稿者 <> モデレーター | 新規トピックまたは返信が保存された時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `theme.bForwardPostsToModerator = False` | テーマ設定でモデレーター転送が無効 |
| `logon.contact.iId = theme.iContactID` | 投稿者がモデレーター本人の場合 |
| 更新（非新規）投稿 | `isNew = false`の場合は通知しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[投稿保存] --> B{新規投稿か?}
    B -->|No| Z[終了]
    B -->|Yes| C{bForwardPostsToModerator?}
    C -->|No| Z
    C -->|Yes| D{投稿者=モデレーター?}
    D -->|Yes| Z
    D -->|No| E[メール作成]
    E --> F{iPostID<>0?}
    F -->|Yes| G[返信テンプレート使用]
    F -->|No| H[新規トピックテンプレート使用]
    G --> I[テンプレート展開]
    H --> I
    I --> J[訪問者詳細追加]
    J --> K[メール送信]
    K --> Z
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| tblTheme | テーマ設定の取得 | モデレーター設定、通知テンプレート |
| tblContact | モデレーターのメールアドレス取得 | theme.iContactIDから参照 |
| tblPost | 投稿情報の取得 | 投稿内容と親トピック |

### テーブル別参照項目詳細

#### tblTheme

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| bForwardPostsToModerator | モデレーター転送フラグ | テーマID指定 |
| iContactID | モデレーターのコンタクトID | テーマID指定 |
| sBodyNotification | 返信通知テンプレート | テーマID指定 |
| sSubjectNotification | 返信通知件名 | テーマID指定 |
| sTopicBodyNotification | 新規トピック通知テンプレート | テーマID指定 |
| sTopicSubjectNotification | 新規トピック通知件名 | テーマID指定 |

#### tblContact

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| sEmail | モデレーターのメールアドレス | `iId = theme.iContactID` |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | 通知送信処理ではDBを更新しない |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 送信失敗 | SMTPサーバー接続エラー | `On Error Resume Next`により無視して継続 |
| テンプレートエラー | 変数置換失敗 | 処理継続（部分的な表示） |
| モデレーター未設定 | `theme.iContactID`がNULL | 通知処理がスキップされる |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

配信時間帯の制限なし。投稿が行われた時点で即座に送信される。

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

- メール本文には訪問者のIPアドレス、ブラウザ情報などの詳細情報が含まれる
- モデレーターのメールアドレスは`tblContact`テーブルで管理され、公開されない
- 投稿内容は`quotrep()`関数によりHTMLエスケープされる
- モデレーター本人の投稿は通知対象外として処理される

## 備考

- `bForwardPostsToModerator`のデフォルト値はTrue（`cls_theme`クラス初期化時）
- 訪問者詳細情報（`getVisitorDetails`関数）には、IPアドレス、ホスト名、ブラウザ情報、リファラー等が含まれる
- モデレーターが設定されていない場合（`theme.iContactID`がNULL）、通知は送信されない

---

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

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

### 推奨読解順序

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

テーマのモデレーター設定と通知関連プロパティを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | theme.asp | `asp/includes/theme.asp` | cls_themeクラスのプロパティ定義（bForwardPostsToModerator, iContactID等） |
| 1-2 | post.asp | `asp/includes/post.asp` | cls_postクラスのプロパティ定義 |

**読解のコツ**: `bForwardPostsToModerator`はテーマクラスの行33でデフォルトTrueに設定されている。

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

投稿の保存処理がモデレーター通知のトリガーとなる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | post.asp | `asp/includes/post.asp` | cls_post.Save関数が通知処理のエントリーポイント |

**主要処理フロー**:
1. **行107-156**: Save関数の冒頭でチェック処理、レコード保存
2. **行170**: `if isNew then` - 新規投稿の場合のみ通知処理へ
3. **行219-233**: モデレーター向け通知の送信処理

#### Step 3: モデレーター通知処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | post.asp | `asp/includes/post.asp` | 行219-233のモデレーター通知ロジック |

**主要処理フロー**:
- **行220**: `if theme.bForwardPostsToModerator and logon.contact.iId<>theme.iContactID then` - 送信条件チェック
- **行221-222**: メールオブジェクト作成、宛先設定
- **行223-230**: 返信/新規トピックの分岐とテンプレート展開
- **行231**: メール送信

#### Step 4: 訪問者詳細情報を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | functions.asp | `asp/includes/functions.asp` | getVisitorDetails関数の実装 |

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

```
default.asp
    │
    └─ cls_theme.build()
           │
           └─ cls_theme.postTopic() / cls_post.buildPost()
                  │
                  └─ cls_post.Save() [行107]
                         │
                         ├─ Check() [入力検証]
                         │
                         ├─ [DBへの保存処理]
                         │
                         └─ [通知処理 - 行170以降]
                                │
                                ├─ [テーマ購読者向け通知 - 行175-197]
                                │
                                ├─ [トピック購読者向け通知 - 行198-217]
                                │
                                └─ [モデレーター通知 - 行219-233]
                                       │
                                       ├─ 条件チェック
                                       │
                                       ├─ テンプレート展開
                                       │  └─ preparenotifyReply() / preparenotifyTopic()
                                       │
                                       ├─ getVisitorDetails() 追加
                                       │
                                       └─ cls_mail_message.send()
```

### データフロー図

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

投稿フォーム ───────▶ cls_post.Save() ───────▶ tblPostへINSERT
    │                      │
    │                      ▼
    │              bForwardPostsToModerator
    │              チェック
    │                      │
    │                      ▼
    │              theme.contact.sEmail
    │              から宛先取得
    │                      │
    │                      ▼
    │              preparenotify*()
    │              [テンプレート展開]
    │                      │
    │                      ▼
    │              getVisitorDetails()
    │              [訪問者情報追加]
    │                      │
    │                      ▼
    └─────────────▶ cls_mail_message.send() ───▶ モデレーターへメール送信
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| post.asp | `asp/includes/post.asp` | ソース | 投稿クラス定義、モデレーター通知の主要ロジック |
| theme.asp | `asp/includes/theme.asp` | ソース | テーマクラス定義、モデレーター設定管理 |
| mail_message.asp | `asp/includes/mail_message.asp` | ソース | メール送信クラス定義 |
| contact.asp | `asp/includes/contact.asp` | ソース | コンタクトクラス定義、モデレーター情報 |
| functions.asp | `asp/includes/functions.asp` | ソース | getVisitorDetails関数等のユーティリティ |
