docs/api目录文档分类和补全

---------

Co-authored-by: guke <guke@autohome.com.cn>
Reviewed-on: #111
This commit was merged in pull request #111.
This commit is contained in:
2026-07-03 15:00:37 +08:00
parent ee132aa93b
commit a563c1ca4b
102 changed files with 2418 additions and 217 deletions
+67
View File
@@ -0,0 +1,67 @@
# 今日领券完成状态(completed-today 族)
> 所属:Coupon 组(前缀 `/api/v1/coupon` | 鉴权:无(按 device_id 判断) | [← 返回 API 索引](../README.md)
---
## GET /completed-today — 今天是否已完成整轮领券
判断这台设备今天是否跑到 done 帧。已完成 → 首页「去领取」卡置灰。
### 入参(query
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `device_id` | string | ✅ | 设备 ID(需与领券循环上报的一致) |
Mock 请求:
```
GET /api/v1/coupon/completed-today?device_id=android_abc123def456
```
### 出参
响应 `200`:`CouponCompletedTodayOut`
| 字段 | 类型 | 说明 |
|---|---|---|
| `completed` | bool | 今天是否已跑完整轮 |
Mock 出参:
```json
{"completed": true}
```
---
## POST /completed-today/reset — 重置今日已完成
删这台设备今天的 completion → `has_completed_today` 变 false,首页「去领取」卡恢复可点。开发设置用。
### 入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `device_id` | string | ✅ | 设备 ID |
| `package` | string | ❌ | App 包名(默认 "" |
| `user_id` | int \| null | ❌ | 登录用户 ID |
Mock 入参:
```json
{
"device_id": "android_abc123def456"
}
```
### 出参
```json
{"ok": true}
```
---
## 说明
- 判断维度 `device_id`(客户端两端都用 ANDROID_ID
- 用户决策 A 方案:到 done 即算完成,不管单券成败
- MVP 不鉴权
+128
View File
@@ -0,0 +1,128 @@
# 领券引导窗频控(prompt 族)
> 所属:Coupon 组(前缀 `/api/v1/coupon` | 鉴权:无(按 device_id 判断,MVP 阶段) | [← 返回 API 索引](../README.md)
领券引导窗频控:今天这台设备**这个 App** 已弹过/领过/拒过 → 不再弹。各 App 独立(美团弹过不压淘宝/京东)。
---
## GET /prompt/should-show — 是否还应弹引导窗
客户端切到外卖 App 时查。
### 入参(query
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `device_id` | string | ✅ | 设备 ID |
| `package` | string | ❌ | App 包名(默认 "",老客户端兼容全局态) |
Mock 请求:
```
GET /api/v1/coupon/prompt/should-show?device_id=android_abc&package=com.sankuai.meituan
```
### 出参
响应 `200`:`CouponPromptShouldShowOut`
| 字段 | 类型 | 说明 |
|---|---|---|
| `should_show` | bool | 今天是否还应弹引导窗 |
Mock 出参:
```json
{"should_show": true}
```
---
## POST /prompt/shown — 引导窗弹出即上报
客户端弹出引导窗那刻调 → 记一条今日 engagementshown),今天这个 App 不再自动弹。频控主判据管跨重装。
### 入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `device_id` | string | ✅ | 设备 ID |
| `package` | string | ✅ | App 包名 |
| `user_id` | int \| null | ❌ | 登录用户 ID |
Mock 入参:
```json
{
"device_id": "android_abc123def456",
"package": "com.sankuai.meituan",
"user_id": 42
}
```
### 出参
```json
{"ok": true}
```
---
## POST /prompt/dismiss — 用户拒绝/关闭引导窗
客户端点关闭时调 → 记 dismissed,今天这个 App 不再弹。
### 入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `device_id` | string | ✅ | 设备 ID |
| `package` | string | ❌ | App 包名(默认 "" |
| `user_id` | int \| null | ❌ | 登录用户 ID |
Mock 入参:
```json
{
"device_id": "android_abc123def456",
"package": "com.sankuai.meituan"
}
```
### 出参
```json
{"ok": true}
```
---
## POST /prompt/reset — 重置今日引导窗状态
删这台设备今天的 engagement → 今天又能弹。开发测频控用。
### 入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `device_id` | string | ✅ | 设备 ID |
| `package` | string | ❌ | App 包名(默认 "" |
| `user_id` | int \| null | ❌ | 登录用户 ID |
Mock 入参:
```json
{
"device_id": "android_abc123def456"
}
```
### 出参
```json
{"ok": true}
```
---
## 说明
- 频控按 `(device, package, 日)`,各 App 独立
- 弹出即占用今天一次(管跨重装),后续领取/拒绝再升级 type
- user_id 可选,登录态带上就一并记(资产留痕)
- MVP 不鉴权
+75
View File
@@ -0,0 +1,75 @@
# POST /api/v1/coupon/session — 领券任务流水上报
> 所属:Coupon 组(前缀 `/api/v1/coupon` | 鉴权:无(按 device_id/trace_id 区分) | [← 返回 API 索引](../README.md)
客户端两段上报一次领券流水(发起 / 收尾),按 `trace_id` upsert 到 `coupon_session`。供 admin「领券数据」看板算发起/完成数、耗时分位、机型维度。
## 入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `trace_id` | string | ✅ | 领券 trace 标识(同领券循环 step 的 trace_id |
| `device_id` | string | ✅ | 设备 ID(与领券循环一致) |
| `status` | string | ✅ | `started` / `completed` / `failed` / `abandoned` |
| `started_at_ms` | int | ✅ | 发起墙钟毫秒(客户端 `System.currentTimeMillis` |
| `user_id` | int \| null | ❌ | 登录用户 ID(未登录可空) |
| `platforms` | list[string] \| null | ❌ | 勾选的平台列表 |
| `origin_package` | string \| null | ❌ | 发起领券的 App 包名 |
| `device_model` | string \| null | ❌ | 机型(如 `24115RA8EC` |
| `rom` | string \| null | ❌ | ROM 信息(如 `MIUI 14.0.8` |
| `app_env` | string \| null | ❌ | 应用环境(`prod` / `test` |
| `elapsed_ms` | int \| null | ❌ | 全程耗时(ms),收尾帧必带 |
| `platform_elapsed` | dict \| null | ❌ | 各平台耗时(如 `{"meituan": 3200, "jd": 2800}`),收尾帧带 |
| `claimed_count` | int \| null | ❌ | 本场实际领到的券张数 |
| `trace_url` | string \| null | ❌ | trace 云端 URLdone 帧带) |
Mock 入参(started:
```json
{
"trace_id": "tr_20260703_a1b2c3d4",
"device_id": "android_abc123def456",
"status": "started",
"started_at_ms": 1719993600000,
"user_id": 42,
"platforms": ["meituan", "jd"],
"origin_package": "com.sankuai.meituan",
"device_model": "24115RA8EC",
"rom": "MIUI 14.0.8",
"app_env": "prod"
}
```
Mock 入参(completed:
```json
{
"trace_id": "tr_20260703_a1b2c3d4",
"device_id": "android_abc123def456",
"status": "completed",
"started_at_ms": 1719993600000,
"user_id": 42,
"platforms": ["meituan", "jd"],
"origin_package": "com.sankuai.meituan",
"device_model": "24115RA8EC",
"rom": "MIUI 14.0.8",
"app_env": "prod",
"elapsed_ms": 12500,
"platform_elapsed": {"meituan": 5200, "jd": 4800},
"claimed_count": 3,
"trace_url": "https://trace.shaguabijia.com/tr_20260703_a1b2c3d4"
}
```
## 出参
响应 `200`:
```json
{"ok": true}
```
## 错误码
- `422` 必填字段缺失或类型不符
## 说明
- 不鉴权(同领券循环 MVP,按 `device_id`/`trace_id`
- 写库失败不连累客户端(fire-and-forget,吞掉返回 ok
- 一次领券两段上报:发起(started)→ 收尾(completed/failed/abandoned
+33
View File
@@ -0,0 +1,33 @@
# GET /api/v1/coupon/stats — 累计领券数
> 所属:Coupon 组(前缀 `/api/v1/coupon` | 鉴权:Bearer | [← 返回 API 索引](../README.md)
「我的」页战绩卡「领取优惠券 X 张」数据源。该登录用户累计领到的券数(`SUM(claimed_count)`,与领券完成时给用户看的「本次领了 N 张」同源)。
**鉴权(CurrentUser** — 区别于同文件不鉴权的 `/step` 透传与 `/prompt` 频控:个人战绩按 `user_id` 聚合,必须有登录态。
## 入参
无(`user_id` 从 JWT 取)。
## 出参
响应 `200`:`CouponStatsOut`
| 字段 | 类型 | 说明 |
|---|---|---|
| `coupon_count` | int | 累计领到的券张数 |
Mock 出参:
```json
{
"coupon_count": 42
}
```
## 错误码
- `401` 未鉴权 / token 失效
## 说明
- 口径:`SUM(claimed_count)` — 各成功领券记录 pricebot 展示张数之和
- 只算登录用户,按 `user_id` 聚合(非 device_id
+24
View File
@@ -0,0 +1,24 @@
# POST /api/v1/coupon/step — 一键领券任务步进(透传到 pricebot)
> 所属:Coupon 组(前缀 `/api/v1/coupon` | 鉴权:Bearer access_token(客户端契约;Server MVP 阶段不强校验) | [← 返回 API 索引](../README.md)
## 入参
任意 JSON body,**不做 schema 校验**,原样透传给上游。后端仅从中读 `device_id``trace_id``step` 用于日志。
## 出参
pricebot-backend 的响应**原样返回**(JSON object)。
## 错误码
- `400` body 不是合法 JSON
- `502` pricebot 上游不可达(网络错误)或返回 5xx
## 说明
把请求体原样转发到 `PRICEBOT_BASE_URL``/api/coupon/step`async httpx)。真正的领券逻辑在 **pricebot-backend(另一个 repo,GoalEngine + 事件驱动)**,本接口只是"透传壳"。
是产品"一键领券"的接入点,**前端已接通**:首页「去领取」→ `CouponPromptDialog` 确认 → 权限检查 → 无障碍引擎 `PriceBotService.startCouponClaim()` → 循环调本接口,后端逐张券下发 launch/wait/done。
⚠️ **客户端契约 vs Server 实现**:Android 客户端通过 `AuthInterceptor` 已自动带 `Authorization: Bearer <access_token>` 头(契约层 OK);Server MVP 阶段**暂未启用强校验**——[coupon.py](../../app/api/v1/coupon.py) 没接 `Depends(get_current_user)`,只读 `device_id` 透传给 pricebot 区分设备,后端拿不到 `user_id` → 领券行为暂时绑不到登录用户(采集不到用户级画像)。待补强校验 + `device_id↔user_id` 绑定,详见 [待办与技术债.md](../guides/待办与技术债.md) P1。
**相关配置**:
- `PRICEBOT_BASE_URL`(默认 `http://localhost:8000`
- `PRICEBOT_REQUEST_TIMEOUT_SEC`(默认 30s,因领券单帧最多 wait 6s