# 租戶站台介接指引（Member Center + Send Engine）

此文件給**租戶站台**使用，描述如何：
- 訂閱 / 確認 / 退訂 / 偏好管理（Member Center）
- 建立發信任務（Send Engine）

不包含 Member Center ↔ Send Engine 的內部事件同步細節。

---

## 1. 系統流程圖（租戶站台角度）

```
Tenant Site
  |
  | (1) Subscribe
  v
Member Center
  |
  | (2) Send confirmation email
  v
End User
  |
  | (3) Confirm link
  v
Member Center

Tenant Site
  |
  | (4) Request unsubscribe token
  v
Member Center
  |
  | (5) Unsubscribe with token
  v
Member Center

Tenant Site
  |
  | (6) Create send job
  v
Send Engine
  |
  | (7) Deliver via ESP
  v
End User
```

---

## 2. Auth / Scope（租戶站台）

租戶站台沒有真人帳號，使用 **Client Credentials** 取得 access token。

- 向 Member Center 申請 OAuth Client
- OAuth Client 建議使用 `usage=send_api`（專供發送）；`tenant_api` 留給其他租戶 API
- scope 依用途最小化

建議 scopes：
- `newsletter:send.write`（Send Engine 建立發信任務）
- `newsletter:send.read`（查詢發信狀態，若需要）

> Send Engine 會驗證 token 內的 `tenant_id` 與 scope。

### 取得 Token（範例）
```bash
curl -s -X POST https://{member-center}/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=<CLIENT_ID>&client_secret=<CLIENT_SECRET>&scope=newsletter:send.write"
```

### 使用 Token（範例）
```bash
curl -s -X POST https://{send-engine}/api/send-jobs \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{ \"tenant_id\": \"<TENANT_ID>\", \"list_id\": \"<LIST_ID>\", \"subject\": \"Weekly\", \"body_text\": \"Hello\" }'
```

### Send Engine 驗證 Token（JWT / JWKS）
- Send Engine 以 Member Center 的 JWKS 驗簽 access token（JWS）。
- 驗證重點：`iss`、`aud`、`scope`、`tenant_id`、`exp`。
- `iss`：由 Member Center `Auth__Issuer` 設定（例：`http://localhost:7850/`）
- `aud`：Send Engine 流程預設 `send_engine_api`，由 Auth resource registry 決定；舊版 `Auth__SendEngineAudience` 仍作為相容 seed 來源

---

## 3. API 表格（租戶站台 → Member Center）

| 功能 | Method | Path | 必填 | 說明 |
|---|---|---|---|---|
| 訂閱 | POST | `/newsletter/subscribe` | `list_id`, `email` | 回傳 `confirm_token` |
| 確認訂閱 | GET | `/newsletter/confirm` | `token` | double opt-in 確認 |
| 申請退訂 token | POST | `/newsletter/unsubscribe-token` | `list_id`, `email` | 回傳 `unsubscribe_token` |
| 退訂 | POST | `/newsletter/unsubscribe` | `token` | 單一清單退訂 |
| 讀取偏好 | GET | `/newsletter/preferences` | `list_id`, `email` | 需 list_id + email |
| 更新偏好 | POST | `/newsletter/preferences` | `list_id`, `email`, `preferences` | 需 list_id + email |

---

### 訂閱（範例）
```bash
curl -s -X POST https://{member-center}/newsletter/subscribe \
  -H "Content-Type: application/json" \
  -d '{
    "list_id": "<LIST_ID>",
    "email": "user@example.com",
    "preferences": {"lang": "zh-TW"}
  }'
```

### 申請退訂 token（範例）
```bash
curl -s -X POST https://{member-center}/newsletter/unsubscribe-token \
  -H "Content-Type: application/json" \
  -d '{
    "list_id": "<LIST_ID>",
    "email": "user@example.com"
  }'
```

### 退訂（範例）
```bash
curl -s -X POST https://{member-center}/newsletter/unsubscribe \
  -H "Content-Type: application/json" \
  -d '{
    "token": "<UNSUBSCRIBE_TOKEN>"
  }'
```

---

## 4. API 表格（租戶站台 → Send Engine）

| 功能 | Method | Path | 必填 | 說明 |
|---|---|---|---|---|
| 建立發信任務 | POST | `/api/send-jobs` | `list_id`, `subject`, `body_html/body_text` | 發送排程 |
| 查詢發信任務 | GET | `/api/send-jobs/{id}` | `id` | 讀取狀態 |
| 取消發信任務 | POST | `/api/send-jobs/{id}/cancel` | `id` | 取消發送 |

### 建立發信任務（範例）
```bash
curl -s -X POST https://{send-engine}/api/send-jobs \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "<TENANT_ID>",
    "list_id": "<LIST_ID>",
    "name": "Weekly Update",
    "subject": "Weekly Update",
    "body_html": "<p>Hello</p>",
    "body_text": "Hello",
    "scheduled_at": "2026-02-11T02:00:00Z"
  }'
```

---

## 5. 安全注意事項（租戶站台）

- `list_id + email` 為租戶隔離最小邊界，必須一併提供
- 不要保存退訂 token；使用時再向 Member Center 申請
- Token 必須妥善保管，避免跨租戶濫用
