54 lines
2.3 KiB
Markdown
54 lines
2.3 KiB
Markdown
# Design
|
||
|
||
本文件描述 Send Engine 的核心模組、資料流、模組邊界與 Auth/Scope 設計。
|
||
本引擎只負責事件控制與執行,不提供 UI。
|
||
ESP 介接暫定為 Amazon SES。
|
||
|
||
## 核心模組
|
||
- Event Ingest
|
||
- List Store(多租戶)
|
||
- Campaign / Send Job
|
||
- Sender Adapter
|
||
- Delivery & Bounce Handling
|
||
|
||
## 信任邊界與 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,快照表僅反映最新狀態
|
||
- 任何狀態變更必須可追溯(含來源與租戶)
|