# 機能設計書 108-ニュースレター購読解除

## 概要

本ドキュメントは、QuickerSite CMSにおけるニュースレターの購読解除処理機能について記載する。ニュースレター配信メールに含まれる購読解除リンクをクリックすることで、メーリングリストから自動的に登録解除される機能である。

### 本機能の処理概要

**業務上の目的・背景**：ニュースレター購読者が不要になったメール配信を自ら停止できるようにするために本機能が必要である。法規制（CAN-SPAM法、GDPRなど）への対応として、購読解除機能の提供は必須要件となっている。

**機能の利用シーン**：ニュースレター配信メールに含まれる購読解除リンク（一意のキーを含むURL）をクリックした際に利用される。ワンクリックで購読解除が完了し、確認メッセージが表示される。

**主要な処理内容**：
1. 購読解除キーの検証
2. ニュースレターカテゴリの取得
3. 購読者のステータスを非アクティブに更新
4. 購読解除完了メッセージの表示
5. 管理者への通知メール送信（設定時）

**関連システム・外部連携**：ニュースレター購読者データベース（tblNewsletterCategorySubscriber）との連携。メール送信機能との連携（管理者通知）。

**権限による制御**：有効な購読解除キーを持つリクエストのみ処理。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 169 | 配信停止処理 | 主画面 | ニュースレターの購読解除処理 |

## 機能種別

データ更新処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| e | String | Yes | 購読解除キー（24文字） | 長さ24文字、存在確認 |

### 入力データソース

- QueryStringリクエスト: 購読解除キー

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| pageBody | String | 購読解除完了メッセージHTML |
| pageTitle | String | 購読解除完了タイトル |

### 出力先

画面表示、データベース更新、メール送信（管理者通知）

## 処理フロー

### 処理シーケンス

```
1. キー長チェック
   └─ eパラメータが24文字であることを確認

2. 購読者レコード検索
   └─ tblNewsletterCategorySubscriberからキーで検索

3. ニュースレターカテゴリ取得
   └─ cls_newsletterCategoryでカテゴリ情報を取得

4. ステータスチェック
   └─ 既に非アクティブの場合はホームページへリダイレクト

5. 購読解除実行
   └─ bActive=falseに更新

6. 完了メッセージ生成
   └─ カテゴリのsUnsubscribeFBテンプレートを使用
   └─ [NL_NAME]、[NL_EMAIL]を置換

7. 管理者通知
   └─ sNotifEmail設定時、管理者にメール送信
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{キー長=24?}
    B -->|No| C[ホームへリダイレクト]
    B -->|Yes| D[購読者検索]
    D --> E{レコード存在?}
    E -->|No| C
    E -->|Yes| F[カテゴリ取得]
    F --> G{カテゴリ存在?}
    G -->|No| C
    G -->|Yes| H{既に非アクティブ?}
    H -->|Yes| C
    H -->|No| I[bActive=false更新]
    I --> J[完了メッセージ生成]
    J --> K{通知設定あり?}
    K -->|Yes| L[管理者通知メール]
    K -->|No| M[ページ表示]
    L --> M
    M --> N[終了]
    C --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-801 | キー長検証 | 購読解除キーは24文字必須 | 常時 |
| BR-802 | 一意キー | 各購読者に一意の購読解除キーを発行 | 購読登録時 |
| BR-803 | 論理削除 | 物理削除ではなくbActive=falseで無効化 | 購読解除時 |
| BR-804 | 二重解除防止 | 既に非アクティブの場合は処理スキップ | 購読解除時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 購読者検索 | tblNewsletterCategorySubscriber | SELECT | キーで購読者を検索 |
| ステータス更新 | tblNewsletterCategorySubscriber | UPDATE | bActive=falseに更新 |

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

#### tblNewsletterCategorySubscriber

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | sKey, sName, sEmail, bActive, iCategoryID | sKeyで検索 | 購読者情報取得 |
| UPDATE | bActive | false | 購読解除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | リダイレクト | キー長不正 | ホームページへリダイレクト |
| - | リダイレクト | キー存在しない | ホームページへリダイレクト |
| - | リダイレクト | カテゴリ不存在 | ホームページへリダイレクト |
| - | リダイレクト | 既に非アクティブ | ホームページへリダイレクト |

### リトライ仕様

リトライ不要（ワンクリック処理）。

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

単一UPDATE文で実行。

## パフォーマンス要件

単純な更新処理のため、特別な要件なし。

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

- 24文字の一意キーによる認証
- cleanup関数によるSQLインジェクション対策
- quotrep関数による出力エスケープ
- convertStr関数による型変換

## 備考

- ニュースレター配信時に購読解除リンクがメールに自動挿入される
- 購読解除後も再購読は可能（同じメールアドレスでの再登録時はbActive=trueに更新）

---

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

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

### 推奨読解順序

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

まず、ニュースレターカテゴリを管理するクラス構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | newsletterCategory.asp | `asp/includes/newsletterCategory.asp` | cls_newsletterCategoryクラス、購読解除テンプレート |

**読解のコツ**: sUnsubscribeFB, sUnsubscribeFBTitleプロパティが購読解除完了メッセージのテンプレート。

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

処理の起点となるファイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | process.asp | `asp/process.asp` | pageAction="unsubscribe"時のinclude処理（50行目） |

**主要処理フロー**:
1. **50行目**: `case "unsubscribe"` - 購読解除アクションの分岐
2. **50行目**: `<!-- #include file="process_unsubscribe.asp"-->` - 処理インクルード

#### Step 3: 購読解除処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | process_unsubscribe.asp | `asp/process_unsubscribe.asp` | 購読解除のメインロジック |

**主要処理フロー**:
- **2行目**: キー長チェック（24文字）
- **5行目**: tblNewsletterCategorySubscriber検索
- **6-7行目**: レコード存在確認
- **8-10行目**: カテゴリ取得
- **21-22行目**: 既にアクティブかチェック
- **25行目**: bActive=falseに更新
- **27-34行目**: 管理者通知メール送信

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

```
process.asp (エントリーポイント)
    │
    ├─ process_unsubscribe.asp (購読解除処理)
    │      │
    │      ├─ db.execute() (購読者検索)
    │      │
    │      ├─ cls_newsletterCategory.pick() (カテゴリ取得)
    │      │
    │      ├─ db.execute() (ステータス更新)
    │      │
    │      └─ cls_mail_message.send() (管理者通知)
    │
    └─ template (テンプレート処理)
```

### データフロー図

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

e(キー) ────────▶ SELECT ────────────▶ 購読者レコード
       │                │                    │
       ▼                ▼                    ▼
tblNewsletterCategorySubscriber    cls_newsletterCategory
       │                │                    │
       ▼                ▼                    ▼
UPDATE bActive=false   テンプレート ────▶ pageBody
                          │
                          ▼
                   管理者通知メール
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| process_unsubscribe.asp | `asp/process_unsubscribe.asp` | ソース | 購読解除処理メイン |
| process.asp | `asp/process.asp` | ソース | ページアクションルーター |
| newsletterCategory.asp | `asp/includes/newsletterCategory.asp` | ソース | ニュースレターカテゴリクラス |
| mail_message.asp | `asp/includes/mail_message.asp` | ソース | メール送信クラス |
| database.asp | `asp/includes/database.asp` | ソース | データベース接続クラス |
