# Design 本文件描述 Send Engine 的核心模組、資料流、模組邊界與 Auth/Scope 設計。 本引擎只負責事件控制與執行,不提供 UI。 ESP 介接暫定為 Amazon SES。 ## 核心模組 - Event Ingest - List Store(多租戶) - Campaign / Send Job - Sender Adapter - Delivery & Bounce Handling ## Sending Proxy 規格整合 ### 目標與邊界 - 接收內容網站或會員平台送來的發送工作 - 呼叫 Amazon SES API(優先 SES v2) - 必帶 Configuration Set + Message Tags - 消費 SES 回流事件(Bounce / Complaint / Delivery) - 必要時回寫 Member Center 不負責: - List-Unsubscribe one-click endpoint 本身的服務實作 - 會員最終名單權威資料庫 ### 狀態機 Job 狀態(目前實作): - pending - running - completed - failed - cancelled Job 狀態(規劃擴充): - queued - sending - sent - partially_failed Recipient 狀態: - pending - sent - delivered - soft_bounced - hard_bounced - complained - suppressed ### SES 事件回流架構(建議) - `SES Configuration Set -> SNS Topic -> SQS Queue -> ECS Worker` - Worker 職責: - Poll SQS - 解析 SNS envelope 與 SES payload - 更新 DB 狀態 - 必要時呼叫 Member Center 停用/註記 API 目前實作: - 先以 `POST /webhooks/ses` 接收事件並更新資料 - `SNS -> SQS -> Worker` 尚未落地 ## 信任邊界與 Auth 模型 ### 外部角色 - Member Center:事件來源與名單權威來源(authority) - 各租戶網站:內容來源(campaign/content producer) - Send Engine:執行與狀態記錄(executor) ### 信任邊界 - Send Engine 不自行發放 tenant 身分;一律以 Member Center 代表的 tenant scope 為準 - 所有 API 必須攜帶 tenant_id,且在驗證後固定於 request context ### 驗證方式(建議) 1. **Member Center → Send Engine** - 使用簽名 Webhook(主推),或 OAuth2 Client Credentials - token 內含 `tenant_id` 與 scopes(例如 `newsletter:events.write`) 2. **租戶網站 → Send Engine** - 使用 OAuth2 Client Credentials 或 JWT(由 Member Center 簽發) - token 內含 `tenant_id` 與 scopes(例如 `newsletter:send.write`) 3. **Send Engine → Member Center** - 使用 OAuth2 Client Credentials(Send Engine 作為 client) - scopes 只允許 `newsletter:list.read` / `newsletter:events.read` / `newsletter:events.write` ### Tenant Scope 取得與約束 - **事件 ingest**:以 token 中的 `tenant_id` 為唯一來源,不接受 body 覆寫 - **Send Job 建立**:tenant_id 從 token 取得;list_id 必須屬於該 tenant - **名單同步**:由 Member Center 主動推送(全量/增量),Send Engine 不主動拉取名單 - **回寫事件**:回寫時攜帶同一 tenant_id,Member Center 做二次驗證 ### 防護與審計 - 所有跨服務呼叫需記錄 `tenant_id`、`client_id`、`scope`、`request_id` - API 層進行 scope 檢查與 tenant 一致性檢查 - Event Ingest 與 Webhook 需具備重放防護(timestamp + nonce) ### 名單外流風險控制 - Send Engine 不提供「名單查詢 API」 - 全量同步由 Member Center 發動並推送 - 如需測試/診斷,僅回傳計數與版本資訊,不回傳名單內容 ## 資料模型原則 - 事件為 append-only,快照表僅反映最新狀態 - 任何狀態變更必須可追溯(含來源與租戶)