Files
shaguabijia-app-server/docs/api/README.md
T
marco 6c7eaa9734 docs: 跟齐 5 月 PR (#4 user/feedback / #5 ad-cooldown / #6 PG / abd8eab meituan 降级)
整轮 doc 跟齐 2026-05 落地但 doc 没补全/没更新的内容. 按 P0~P3 优先级处理.

P0 - 新 API doc + index 更新:
* docs/api/user-profile.md  (新) PATCH /api/v1/user/profile 改昵称
* docs/api/user-avatar.md   (新) POST /api/v1/user/avatar 上传头像(魔数嗅探/旧文件清理)
* docs/api/user-delete.md   (新) DELETE /api/v1/user 注销账号(软删+匿名化)
* docs/api/feedback.md      (新) POST /api/v1/feedback 提交反馈(含截图)
* docs/api/README.md           加 User/Feedback 组 + /media 静态服务段 +
                                修 UserOut "无接口可改恒为 null" 过时描述

P0 - 美团降级 / 现有 doc 校准:
* docs/api/meituan-coupons.md      加 "未配 MT_CPS 凭证降级返空" 说明
* docs/api/meituan-referral-link.md 同上 + 客户端兜底建议
* docs/api/meituan-feed.md         区分两种空结果路径(未配 vs 调用失败) +
                                    /health.mt_cps_configured 排障入口
* docs/integrations/meituan.md     "未配凭证降级" + "feed 静默吞错" 写进集成层
* ad-reward-status.md              PR #5 commit 已自带 doc 更新, 复核无需再改

P1 - 主文档大改:
* docs/后端技术实现.md
  - §1 能力表加 用户资料/外卖比价/钱包/福利/广告/反馈 (从 3 条扩到 9 条)
  - §1 数据模型纠正 "仅 1 张 user 表" -> 现有 10 张 + alembic_version
  - §2 DB 行 PG 主 / SQLite 兜底 + 加 psycopg3 行
  - §3 目录树补 user.py / feedback.py / media.py / repositories/feedback.py /
        scripts 子项 / docs/postgres-migration.md
  - §7 数据模型重写: 10 张业务表速查表 + alembic 合并迁移 f01db5d77dac 始末
  - §8 部署: 加 init_postgres.py 一句话流程 + checklist 加 "DATABASE_URL 切 PG"
        + "psycopg3 已装" + "MEDIA_ROOT 可写"
  - §10 已知问题: 加 美团降级 / agent 不鉴权 / MEDIA_ROOT serve / init_postgres bug /
        alembic 多 head 风险; 删过时 SQLite 行
  - 接口计数 11 -> 38

* docs/待办与技术债.md
  - 已解决追加: PG 切换 / 外卖比价透传 / 用户资料反馈接口 / 美团降级 /
                看广告 4 态冷却
  - 新增 "P2 DB 与 Alembic 治理" 段: alembic 多 head 团队规约 (含本次撞坑实录) +
    init_postgres.py 已知 5 处小 bug + MEDIA_ROOT serve

P2 - PG 迁移文档互指 + 迁移链补完:
* docs/数据库迁移.md
  - 顶部加 postgres-migration.md / 后端技术实现.md 互指
  - §6 迁移链 9 条 -> 12 条 (含 feedback_table / convert_dishes_jsonb /
        merge_pg_jsonb_and_feedback_heads)
  - §7 踩坑里 "多 head" 一行扩成完整故事 + 修复命令 + 团队预防规约
* docs/postgres-migration.md
  - 顶部加 数据库迁移.md / 后端技术实现.md §10 互指

P3 - 上线清单:
* docs/看广告赚金币上线清单.md
  - 设计要点加 PR #5 4 态 CTA + 后端权威派生说明 +
    VIDEO_ROUND_REQUIRED_COUNT/VIDEO_ROUND_COOLDOWN_SECONDS 常量
  - §E 端到端验收加 本轮冷却 / 弹窗 limit note / 跨设备一致 三项

所有最后更新日期同步到 2026-05-31.
2026-05-31 11:05:10 +08:00

10 KiB
Raw Blame History

傻瓜比价 App 后端 — API 接口文档(索引)

Base URL:生产 https://app-api.shaguabijia.com;本地联调 http://<开发机>:8770 协议:HTTP / JSON,请求与响应体均 application/json,字段统一 snake_case 鉴权:需鉴权的接口在请求头带 Authorization: Bearer <access_token> 最后更新:2026-05-31 架构:app/api/v1/ 只放很轻的接口层;穿山甲/微信支付/极光/短信/美团等 SDK 集成的重逻辑在 app/integrations/,实现细节见 docs/integrations/


接口总览

# 方法 + 路径 鉴权 详情
1 GET /health 详情
2 POST /api/v1/auth/jverify-login 详情
3 POST /api/v1/auth/sms/send 详情
4 POST /api/v1/auth/sms/login 详情
5 POST /api/v1/auth/refresh 详情
6 GET /api/v1/auth/me Bearer 详情
7 POST /api/v1/auth/logout Bearer 详情
8 POST /api/v1/coupon/step 详情
9 POST /api/v1/meituan/coupons 详情
10 POST /api/v1/meituan/feed 详情
11 POST /api/v1/meituan/referral-link 详情
比价透传(前缀 /api/v1,外卖 MVP;与 coupon/step 同为透传 pricebot-backend
12 POST /api/v1/intent/recognize 详情
13 POST /api/v1/price/step 详情
钱包 / 我的资产(前缀 /api/v1/wallet
14 GET /api/v1/wallet/account Bearer 详情
15 GET /api/v1/wallet/coin-transactions Bearer 详情
16 GET /api/v1/wallet/cash-transactions Bearer 详情
17 GET /api/v1/wallet/exchange-info 详情
18 POST /api/v1/wallet/exchange Bearer 详情
19 POST /api/v1/wallet/bind-wechat Bearer 详情
20 POST /api/v1/wallet/unbind-wechat Bearer 详情
21 GET /api/v1/wallet/withdraw-info Bearer 详情
22 POST /api/v1/wallet/withdraw Bearer 详情
23 GET /api/v1/wallet/withdraw/status Bearer 详情
24 GET /api/v1/wallet/withdraw-orders Bearer 详情
签到(前缀 /api/v1/signin
25 GET /api/v1/signin/status Bearer 详情
26 POST /api/v1/signin Bearer 详情
任务(前缀 /api/v1/tasks
27 GET /api/v1/tasks Bearer 详情
28 POST /api/v1/tasks/{task_key}/claim Bearer 详情
省钱(前缀 /api/v1/savings
29 GET /api/v1/savings/summary Bearer 详情
30 GET /api/v1/savings/battle Bearer 详情
31 GET /api/v1/savings/records Bearer 详情
看广告发奖(前缀 /api/v1/ad
32 GET /api/v1/ad/pangle-callback 验签 详情
33 GET /api/v1/ad/reward-status Bearer 详情
34 POST /api/v1/ad/test-grant Bearer 详情
用户资料(前缀 /api/v1/user
35 PATCH /api/v1/user/profile Bearer 详情
36 POST /api/v1/user/avatar Bearer 详情
37 DELETE /api/v1/user Bearer 详情
帮助与反馈(前缀 /api/v1/feedback
38 POST /api/v1/feedback Bearer 详情
静态资源StaticFiles 挂载,见下方 /media 静态服务)
- GET /media/avatars/<file> 用户头像;返回二进制图片
- GET /media/feedback/<file> 反馈截图;返回二进制图片

⚠️ 美团三个接口当前无鉴权,且 referral-linksid 允许客户端传值覆盖默认渠道——见各接口"备注"。 coupon/step 及外卖比价的 intent/recognize / price/step 都透传到 pricebot-backend,MVP 阶段均不鉴权(device_id 透传,待补 JWT——见各接口详情)。 福利相关业务接口(wallet/signin/tasks/savings、ad/reward-status)均需 Bearer;wallet/exchange-info 是静态规则无鉴权;ad/pangle-callback 不走 JWT、靠穿山甲验签;ad/test-grant 仅本地联调(开关控制,生产 404)。 金额字段一律以为单位(*_cents)。


通用约定

  • 时间格式:ISO 8601 UTC(如 2026-05-27T12:34:56Z
  • 错误响应:FastAPI 标准结构 {"detail": "<错误信息>"},配合语义化 HTTP 状态码:
    • 400 业务参数错(如验证码不对)
    • 401 未认证 / token 无效或过期 / 用户被禁(响应头带 WWW-Authenticate: Bearer
    • 403 账号被禁用
    • 422 请求体字段校验失败(FastAPI 自动校验,如手机号格式)
    • 429 触发限流(短信发送过频)
    • 502 上游调用失败(极光验证/解密失败、美团接口失败)
  • 接口文档(交互式):APP_ENV 非 prod 时开放 GET /docsSwagger UI)、GET /redoc;生产环境关闭。

游标分页约定

钱包流水 / 提现单 / 省钱明细等列表接口统一用游标分页:

  • 请求 query:limit(每页条数,1100,默认 20)、cursor(上一页返回的 next_cursor,首页不传)。
  • 响应:{ "items": [...], "next_cursor": <int|null> }next_cursor末条记录的 id;为 null 表示已到底,无更多数据。
  • itemsid 倒序(最新在前)。

复用数据结构

TokenPair

字段 类型 说明
access_token string 访问令牌,之后每个鉴权请求带 Authorization: Bearer <它>
refresh_token string 刷新令牌
token_type string 固定 "Bearer"
expires_in int access 剩余秒数(默认 7200 = 2h
refresh_expires_in int refresh 剩余秒数(默认 2592000 = 30d

TokenWithUser

继承 TokenPair 全部字段,额外多一个 userUserOut)。登录类接口成功时返回此结构。

UserOut

字段 类型 说明
id int 用户主键
phone string 手机号(注销账号后变 deleted_<id> 占位释放唯一约束)
nickname string | null 昵称,经 PATCH /api/v1/user/profile 修改
avatar_url string | null 头像相对 URL(/media/avatars/...),经 POST /api/v1/user/avatar 上传
register_channel string 注册渠道:jverify / sms
status string active / disabled / deleted
created_at datetime 注册时间
last_login_at datetime 最近登录时间

CouponCard(券卡片,couponsfeeditems 元素)

字段 类型 说明
product_view_sign string 换链主键(传给 referral-link
platform int 1=外卖/到家, 2=到店
biz_line int | null 到店子类:1到餐 2到综 3酒店 4门票
name string 商品名
head_image_url string 头图
brand_name string | null 品牌名
brand_logo_url string | null 品牌 logo
sell_price string 现价
original_price string 原价
discount_amount string 优惠额 = 原价 现价
commission_rate string 佣金比例,如 "1.4%"
commission_amount string | null 预估佣金(元)
sale_volume string | null 销量
poi_name string | null 最近门店名
distance_text string | null 格式化距离,如 "600m" / "1.5km"
distance_meters float | null 原始距离(米)
available_poi_num int | null 可用门店数
coupon_num int | null 券张数
valid_days int | null 券有效天数
price_label string | null "15天低价"
rank_label string | null "2小时北京外卖销量榜第1名"
rating_label string | null "4.6分"

/media 静态服务

用户上传文件(头像/反馈截图)落盘到 settings.MEDIA_ROOT(默认 ./data/media/),由 FastAPI 的 StaticFiles 挂在 settings.MEDIA_URL_PREFIX(默认 /media)对外暴露:

  • GET /media/avatars/<file> — 用户头像(JPEG/PNG/WebP)
  • GET /media/feedback/<file> — 反馈截图(同上)

生产建议:由 nginx 直接 serve MEDIA_ROOT 目录,绕过应用进程减少压力。

URL 格式:服务端返回相对路径(如 /media/avatars/u1_a4f2b3c8e9d2e0a1.jpg),客户端按自己的 BASE_URL 拼绝对地址——dev 下可能是 10.0.2.2/LAN IP/127.0.0.1,服务端不知道客户端怎么访问到自己。

文件名服务端随机生成 u<user_id>_<16 位 hex>.<ext>,杜绝路径穿越与覆盖。


附:鉴权与刷新机制

  • 签发:登录成功后签发 access(HS256,2h) + refresh(30d),payload 含 sub(user_id)、typ(access/refresh)、iatexp
  • 携带:客户端对需鉴权接口自动加 Authorization: Bearer <access>(登录类接口跳过)。
  • 校验/me/logout:验签 → 验过期 → 验 typ=access → 查库确认用户存在且 status=active,任一不过 → 401。
  • 续期:access 过期触发 401 → 客户端用 refresh 调 /refresh 换新 token 对并重放原请求;refresh 也失效 → 清本地、跳登录。
  • 无状态:token 不落库,服务端无法主动吊销(logout 为占位),靠短 access 有效期限制泄露风险。JWT 密钥 JWT_SECRET_KEY 必须为高熵随机串(生产严禁用默认值)。