# TEST_PLAN — メール配信システム（IEEE 829）

v1.0 · 2026-06-18 · カバレッジ目標: 中核ロジック 80%+

## Entry Criteria
SRS/SDD 承認済 / Store・Mailer 抽象が実装済 / `npm test` が起動可能。

## Exit Criteria
全 Must 要件の TC が PASS / lint・typecheck・build 緑 / E2E 全 PASS（DRY_RUN）。

## Suspension Criteria
中核ロジックのテストが連続失敗 → 実装ではなく設計（core.ts）へ差し戻し。

## テストピラミッド
- 単体（多数）: core.ts の冪等/楽観ロック/上限/ステップ進行、auth、mailerゲート、本文生成。
- 結合（中）: Hono app + InMemoryStore + DryRunMailer を `app.request()` で検証。
- E2E（少）: シナリオ（正常3/異常2/境界1）を InMemoryStore 上で再現。

## トレーサビリティ（TC → 要件）
| TC | 対象要件 | 検証内容 | 種別 |
|---|---|---|---|
| TC-FR-AUTH-001 | FR-AUTH-001 | 未認証で管理APIが401 | 結合 |
| TC-FR-AUTH-002 | FR-AUTH-002 | 正パスワードでCookie発行/誤りで拒否/署名改竄拒否 | 単体 |
| TC-FR-SUB-001 | FR-SUB-001 | 作成・一覧・状態変更・email正規化 | 単体 |
| TC-FR-SUB-002 | FR-SUB-002 | 重複emailで行数不変・更新 | 単体 |
| TC-FR-SUB-003 | FR-SUB-003 | リスト作成・所属・解除 | 単体 |
| TC-FR-BC-001 | FR-BC-001 | 下書き作成 | 結合 |
| TC-FR-BC-002 | FR-BC-002 | 予約(scheduled)設定 | 単体 |
| TC-FR-BC-003 | FR-BC-003 | DRY_RUN/未承認は送信せず記録 | 単体 |
| TC-FR-BC-004 | FR-BC-004 | 2回実行でsending遷移・送信1回（楽観ロック） | 単体 |
| TC-FR-BC-005 | FR-BC-005 | 中断後の再開で未送信分のみ送信 | 単体 |
| TC-FR-BC-006 | FR-BC-006 | scheduled時のみキャンセル可 | 単体 |
| TC-FR-BC-007 | FR-BC-007 | unsub/bounced除外 | 単体 |
| TC-FR-STEP-001 | FR-STEP-001 | キャンペーン/ステップ定義 | 単体 |
| TC-FR-STEP-002 | FR-STEP-002 | 遅延に従い順次送信 | 単体 |
| TC-FR-STEP-003 | FR-STEP-003 | 各ステップ1回のみ | 単体 |
| TC-FR-STEP-004 | FR-STEP-004 | 重複enroll不可・停止者は進まない | 単体 |
| TC-FR-HOOK-001 | FR-HOOK-001 | Webhookで登録+list+enroll | 結合 |
| TC-FR-HOOK-002 | FR-HOOK-002 | フォームGET/POST同処理 | 結合 |
| TC-FR-HOOK-003 | FR-HOOK-003 | 無効token404/不正email400 | 結合 |
| TC-FR-DELIV-001 | FR-DELIV-001 | 本文に配信停止リンク+送信者表示 | 単体 |
| TC-FR-DELIV-002 | FR-DELIV-002 | /u/:token でunsubscribed | 結合 |
| TC-FR-DELIV-003 | FR-DELIV-003 | bounce/complaintで状態反映 | 結合 |
| TC-FR-SAFE-001 | FR-SAFE-001 | ティック/日次上限を超えない | 単体 |
| TC-FR-SAFE-002 | FR-SAFE-002 | Idempotency-Key付与 | 単体 |
| TC-FR-UI-001/002 | FR-UI-* | E2E/手動（DOM存在・空状態文言） | E2E |
| TC-NFR-REL-001 | NFR-REL-001 | 多重起動で二重送信なし | 単体 |
| TC-NFR-SEC-001 | NFR-SEC-001 | 認証必須・Cookie属性 | 結合 |
| TC-NFR-COMPAT-001 | NFR-COMPAT-001 | CF無しでnpm test緑 | CI |
