ed76820e97
读完了两份 spec + 分派器,这分支的全貌清晰了。下面是可直接粘进 Gitea PR 的 MR 说明(标题 + 正文): 建议标题 feat(sms): 短信验证码可切换多 provider(极光/阿里云/创蓝),默认极光零改动 MR 正文(复制以下 markdown): ## 概述 把原单文件 `app/integrations/sms.py` 重构为**可切换 provider 包** `app/integrations/sms/`,在保留极光(默认、行为零改动)的基础上,新增两家验证码短信 provider: - **阿里云号码认证 dypns**(Mode A:阿里云生成/存储/校验验证码,核验免费) - **创蓝云智 253**(Mode B:本服务自管码,httpx 直连 + HMAC 签名) Provider 由 `SMS_PROVIDER` 按调用实时选择,默认 `jiguang`。短信=花钱 + 登录关键路径,故新 provider **opt-in、可灰度、秒级回退**,默认路径零变更。 ## 为什么 现有极光路径本地内存存码(多 worker 不共享,已是技术债),且单一供应商无法灰度/切换。引入 provider 抽象后:阿里云托管码可消除存码债,创蓝作为备选降低单点依赖,三家随配置切换与回退。 ## 改动内容 **架构(`app/integrations/sms/`)** | 文件 | 说明 | |---|---| | `__init__.py` | 对外仍暴露 `send_code/verify_code/SmsError`(auth 导入不变);按 `SMS_PROVIDER` **每次调用**分派;未知值回退 `jiguang` | | `base.py` | `SmsError`(status_code→HTTP) + provider 无关的 `mock_verify` | | `jiguang.py` | 原 `sms.py` 逻辑**原样迁入**,行为零改动(git 识别为 rename) | | `aliyun.py` | 新增,Mode A:`SendSmsVerifyCode` + `CheckSmsVerifyCode`,惰性加载 SDK | | `chuanglan.py` | 新增,Mode B:自管码 + `tpl/send` + HMAC 签名 | **两种验证码模式** - Mode A(阿里云):不本地存码,阿里云 `##code##` 托管生成+校验;本地仅留 per-phone 失败计数防爆破。 - Mode B(极光/创蓝):`secrets` 生成 N 位 → 进程内存 → 供应商只下发;本地一次性校验 + 失败 N 次作废。创蓝**复制**极光存码机器(不重构极光,零回归风险)。 **配置(`config.py` + `.env.example`)** - `SMS_PROVIDER = jiguang | aliyun | chuanglan`(默认 jiguang) - `ALIYUN_SMS_*`(AK/签名/模板/方案名/时长…) + `aliyun_sms_configured` 门控 - `CHUANGLAN_SMS_*`(账号/密码/模板/签名/endpoint…) + `chuanglan_sms_configured` 门控 - 复用现有 `SMS_MOCK / SMS_CODE_LENGTH / SMS_CODE_TTL_SEC / SMS_SEND_INTERVAL_SEC / SMS_MAX_VERIFY_ATTEMPTS` - 切到某 provider 却未配齐 → `send_code` 抛 `SmsError(503)`,不静默 **auth.py(最小改动)** - `verify_code` 现在可能抛 `SmsError`(阿里云降级 503)→ `sms_login`、`wechat_bind_phone_sms` 两处各包 `try/except SmsError → HTTPException`,与 `send_code` 现有写法一致。 **依赖** - `pyproject.toml` 增 `alibabacloud_dypnsapi20170525`(仅阿里云 provider 惰性 import;jiguang/chuanglan 不加载)。创蓝零新依赖(httpx + 标准库)。 **测试** - 新增 `test_sms_aliyun.py` / `test_sms_chuanglan.py`(均 monkeypatch 网络接缝,不发真短信) + `test_sms_dispatch.py`(分派/回退)。 - `test_auth.py` 相应更新。 - 现有测试走 `SMS_MOCK=true` 在分派层短路,不受影响。 **文档** - 设计 spec:`docs/superpowers/specs/2026-07-25-aliyun-sms-verify-design.md`、`2026-07-26-chuanglan-sms-verify-design.md` - 接口调研:`docs/integrations/aliyun/*`、`docs/integrations/chuanglan/tpl-send.md`、`docs/integrations/sms.md` ## 兼容性 & 回退 - **默认 `SMS_PROVIDER=jiguang`,线上行为与现状完全一致**;不改极光逻辑、不动 API 层频控与测试账号短路。 - 切阿里云/创蓝仅改环境变量,出问题秒切回极光;未知 `SMS_PROVIDER` 一律回退极光,防误配打挂登录。 --------- Co-authored-by: guke <guke@autohome.com.cn> Reviewed-on: #188
文档索引
项目文档结构说明。后续大模型增补/更新文档时,按此分类找到对应目录。
API 接口文档 (api/)
按业务领域分类,每个子目录对应一类接口。
分类目录
| 目录 | 分类 | URL 前缀 | 说明 |
|---|---|---|---|
| api/auth/ | 认证 | /api/v1/auth |
用户登录(极光一键登录/短信验证码)、Token 刷新(access + refresh)、登出、当前用户信息查询 |
| api/ad/ | 广告 | /api/v1/ad |
穿山甲 S2S 回调验签发奖、激励视频/信息流广告奖励结算、eCPM 上报、发奖状态查询、测试发奖(仅本地) |
| api/wallet/ | 钱包 | /api/v1/wallet |
账户资产查询(金币/现金余额)、金币与现金流水、兑换规则与执行、绑定/解绑微信、提现申请/状态/记录、免确认收款授权 |
| api/coupon/ | 领券 | /api/v1/coupon |
CPS 领券透传(step/session)、引导窗频控(should-show/shown/dismiss/reset)、每日完成状态、累计领券统计 |
| api/compare/ | 比价记录 | /api/v1/compare |
比价记录上报/列表/详情/统计、比价战绩里程碑查询及奖励领取(按成功比价数解锁金币) |
| api/savings/ | 省钱 | /api/v1/savings + /api/v1/platform/savings-feed |
省钱大作战(battle)、省钱明细/汇总、平台省钱动态 Feed |
| api/signin/ | 签到 | /api/v1/signin |
每日签到执行、签到加速(看广告多领)、签到状态查询 |
| api/tasks/ | 任务 | /api/v1/tasks |
任务列表查询、任务奖励领取(按 task_key) |
| api/invite/ | 邀请 | /api/v1/invite |
邀请码/分享链接生成、已邀请列表、邀请绑定(支持 clipboard/manual/fingerprint 三种归因) |
| api/user/ | 用户 | /api/v1/user |
个人资料编辑(昵称)、头像上传、新手引导状态/完成标记、注销账号 |
| api/device/ | 设备 | /api/v1/device |
设备注册/推送 token 更新、无障碍存活心跳、掉线检测(后置 pull)、告警确认 |
| api/platform/ | 平台配置 | /api/v1/platform |
平台统计数据、Feature Flag 开关、广告配置(穿山甲 ID)、App 版本更新检查(OTA);全部不鉴权 |
| api/intent/ | 意图/电商 | /api/v1/intent + /api/v1/price + /api/v1/ecom |
比价意图识别(Phase 1 单次/多帧/预券)、电商意图识别、比价步进(Phase 2) |
| api/meituan/ | 美团 CPS | /api/v1/meituan |
美团券列表/信息流/推广链接/销量榜;全部无鉴权 |
| api/other/ | 其它 | 分散 | 健康检查、CPS 短链重定向(含微信 OAuth)、反馈提交/配置/记录、埋点上报、订单上报、更低价上报、Trace 收尾 |
| api/admin/ | 管理后台 | /admin/api |
Admin 独立子应用,二级目录按子资源拆分:auth/(登录)、users/(用户管理/财务操作)、wallet/(流水查询)、withdraws/(提现审核/对账)、feedbacks/(反馈处理)、admins/(管理员管理)、ad/(广告对账/收益);单文件留根:审计日志、数据大盘、跑马灯种子、统计概览 |
| api/internal/ | 内部接口 | /internal |
服务间调用(pricebot→app-server):价格事实回写、店铺映射、启动确认样本、App 版本写入;X-Internal-Secret 鉴权 |
接口索引入口
完整接口列表(含路径、方法、鉴权方式)见 api/README.md。
文档命名规则
单端点文档按 URL 路径命名:{prefix}-{resource}.md(如 wallet-withdraw.md、auth-sms-send.md)。
含子资源的合并文档按族命名(如 device-liveness.md 覆盖 register/heartbeat/liveness/liveness-ack 四个端点)。
文件名唯一确定文档位置:大类目录 + 文件名前缀 → 直接匹配。
数据库文档 (database/)
数据库表结构说明,每表一个文件,database/OVERVIEW.md 为索引入口。
第三方集成 (integrations/)
外部 SDK/API 集成架构与实现说明:integrations/README.md。
| 文件 | 说明 |
|---|---|
| jiguang.md | 极光一键登录(REST 验证 + RSA 解密) |
| pangle.md | 穿山甲广告 S2S 回调 |
| wxpay.md | 微信支付 V3(提现/授权) |
| meituan.md | 美团 CPS 网关 |
开发指南 (guides/)
| 文件 | 说明 |
|---|---|
| 邀请功能-实现原理与本地测试.md | 邀请系统实现细节 |
| CPS发券分发与微信授权.md | CPS 发券 + 微信网页授权流程 |
| 看广告赚金币上线清单.md | 广告功能上线检查清单 |
| 待办与技术债.md | 待办事项与技术债务 |
架构与设计 (superpowers/)
需求规格与设计文档,按 YYYY-MM-DD-<topic>-design.md 命名。
后端技术实现 (后端技术实现.md)
后端整体技术架构说明。