# API Contract Master

## 目標

固定 `v1` 對外契約，避免前後端與 SDK 在開發中漂移。

> 參數必填/可選與路由實際狀態，請優先看：
> [PYTHON_API_PARAMETER_GUIDE.md](/Users/chirs/Documents/workspace/marketing/mkt.ose.tw/docs/backend/PYTHON_API_PARAMETER_GUIDE.md)

## 這輪契約調整（2026-03-22）

- `experiment_key` 改為系統生成（`EX+timestamp`），不接受使用者輸入。
- `variant_key` 改為系統生成（`VA+timestamp`），不接受使用者輸入。
- Variant 不再暴露 `status`、`is_control` 作為使用者可編輯欄位。
- `variant_changes` 移除 `enabled` 欄位（每筆 change 預設啟用）。
- 建立 Experiment API 成功時，需同步建立一個原始版本 Variant（系統管理）。
- Runtime 實驗匹配需基於 URL 規則與裝置限制。

## 分區

- Admin API
- Editor API
- Runtime API

## Admin API（v1）

### Sites

- `GET /api/admin/sites`
- `GET /api/admin/sites/{site_id}`

### Experiments

- `GET /api/admin/experiments`
- `GET /api/admin/experiments/{experiment_id}`
- `POST /api/admin/experiments`
- `PATCH /api/admin/experiments/{experiment_id}`
- `GET /api/admin/experiments/{experiment_id}/activity`

`POST/PATCH /api/admin/experiments` 使用者輸入重點：

- `name`
- `module_type`
- `status`
- `targeting_config.url_rules`
- `targeting_config.device_targets`

使用者不輸入：

- `experiment_key`（系統生成）

### Variants

- `GET /api/admin/variants/{variant_id}`
- `GET /api/admin/variants?experiment_id=...`
- `POST /api/admin/variants`
- `PATCH /api/admin/variants/{variant_id}`

`POST/PATCH /api/admin/variants` 使用者輸入重點：

- `name`
- `traffic_weight`

使用者不輸入：

- `variant_key`（系統生成）
- `status`
- `is_control`

### Releases

- `GET /api/admin/releases?experiment_id=...`
- `GET /api/admin/releases/{release_id}`
- `POST /api/admin/releases/build`
- `POST /api/admin/releases/{release_id}/publish`
- `POST /api/admin/releases/{release_id}/rollback`
- `POST /api/admin/releases/{release_id}/archive`

### Goals / SDK Config

- `GET /api/admin/goals`
- `GET /api/admin/goals/{goal_id}`
- `GET /api/admin/sdk-configs`
- `GET /api/admin/sdk-configs/{sdk_config_id}`

## Editor API（v1）

- `POST /api/editor/sessions`
- `GET /api/editor/sessions/{session_id}`
- `PATCH /api/editor/sessions/{session_id}`
- `DELETE /api/editor/sessions/{session_id}`
- `GET /api/editor/variants/{variant_id}/changes`
- `PUT /api/editor/variants/{variant_id}/changes`
- `POST /api/editor/previews/build`

`PUT /api/editor/variants/{variant_id}/changes`：

- change 欄位不含 `enabled`
- change 是否生效由是否存在於 change set 決定

## Runtime API（v1）

- `POST /api/runtime/bootstrap`
- `POST /api/runtime/assign`
- `POST /api/runtime/payload`
- `POST /api/runtime/events/impression`
- `POST /api/runtime/events/conversion`

## 契約原則

- 所有 API 回傳統一 DTO，不回傳 Directus raw item
- editor 專用 DTO 與 runtime 專用 DTO 分離
- breaking change 需升 API 版本
- 對外 `C/U/D` 一律經 FastAPI，禁止 frontend 直接對 Directus 做新業務寫入
