docs(auth): 登录注册 - 补充短信渠道与组合验证策略设计
This commit is contained in:
285
docs/design/sms-channels-and-auth-policy.md
Normal file
285
docs/design/sms-channels-and-auth-policy.md
Normal file
@@ -0,0 +1,285 @@
|
||||
# 短信渠道插件与登录注册策略方案
|
||||
|
||||
状态:设计提案,未实施。本文不表示接口、数据库或页面已交付。
|
||||
|
||||
## 1. 目标与默认决策
|
||||
|
||||
- 支持多个短信渠道实例;同一供应商允许配置多个账号、应用或签名。
|
||||
- 首批提供阿里云、腾讯云两个系统级官方短信插件,复用现有插件生命周期和配置 schema,不另建插件中心。
|
||||
- 后台新增短信渠道、场景路由、发送记录;登录注册设置增加短信验证码登录、邮箱验证码登录、短信注册、邮箱注册、短信与邮箱双验证注册。
|
||||
- “短信+邮箱注册”指两者都必须验证,不是任意一个。短信注册与邮箱注册同时开启则表示任选其一。双验证开启后与单验证注册互斥,防止绕过。
|
||||
- 第一期只开放中国大陆手机号,内部统一为 E.164。国际短信、营销群发、随机负载均衡、公开第三方可执行短信插件不在本期。
|
||||
- 保留现有密码登录与会话机制;注册暂保留现有用户名、密码和服务协议要求,不顺便改成无密码注册。验证码登录本身不要求密码。
|
||||
- 短信发送是有费用的外部写操作。配置检查不发送短信;真实测试需要管理员明确触发并确认接收号码。
|
||||
|
||||
## 2. 当前实现与改造依据
|
||||
|
||||
仓库检查表明:
|
||||
|
||||
| 现状 | 代码依据(仓库相对位置) | 设计影响 |
|
||||
| --- | --- | --- |
|
||||
| 密码登录支持用户名或邮箱;普通注册要求邮箱验证码,首个管理员例外 | `backend/internal/auth/auth.go` | 分离登录方法、注册策略与发送能力,不能只加页面开关 |
|
||||
| 邮件验证码用于注册和找回密码,已有 HMAC 和事务消费 | `backend/internal/auth/email.go`、`password_reset.go`、`backend/internal/repository/repository.go` | 演进为统一挑战机制,保留安全能力,不复制 SMS 版邮件流程 |
|
||||
| 用户没有手机号和联系方式验证时间 | `backend/internal/model/models_identity.go` | 新增手机与验证状态,历史邮箱不能直接视为已验证 |
|
||||
| 非空邮箱已有大小写归一化唯一索引 | `backend/internal/database/schema.go` | 手机增加等价唯一约束,不重复建设现有邮箱唯一索引 |
|
||||
| 支付插件已有系统级启停、host 执行、配置 schema、Registry 及可信进程 RPC | `backend/internal/app/payment_plugins.go`、`plugin_management.go`、`backend/internal/payment/` | 复用插件宿主模式;不要把短信注册在模型 provider 或支付 registry 中 |
|
||||
| 登录注册后台目前主要管理注册总开关和 Linux.do | `web/src/pages/admin/components/access-settings-panel.tsx` | 改为统一认证策略页面,邮件配置继续负责 SMTP |
|
||||
| Linux.do 可自动创建新用户;运行平台已有 Redis 协调能力 | `backend/internal/auth/linuxdo.go`、`backend/internal/platform/coordination.go` | 新用户必须经过统一注册策略;多实例限流不能依赖进程 mutex |
|
||||
|
||||
工作区存在与本方案无关的用户修改。本次仅新增设计文档和索引,不触碰这些修改。
|
||||
|
||||
## 3. 架构和职责
|
||||
|
||||
```text
|
||||
HTTP handler
|
||||
-> service 别名 -> app 组合根
|
||||
-> auth:登录、注册、联系方式绑定、策略及会话
|
||||
-> verification:验证码挑战、失败次数、有效期及消费条件
|
||||
-> sms:路由、限额、发送尝试及状态对账
|
||||
-> SMS Registry -> 官方插件适配器 -> 官方 Go SDK
|
||||
-> 现有 SMTP 发信器
|
||||
-> repository/model:查询、事务与持久化
|
||||
-> platform:Redis/单机协调、定时对账
|
||||
```
|
||||
|
||||
建议新增 `backend/internal/sms/`、`backend/internal/verification/`;供应商适配器放 `backend/internal/sms/providers/aliyun/` 与 `tencent/`。注册事务由 repository 统一完成,验证码域不直接创建用户,短信域不决定谁能登录。
|
||||
|
||||
`app` 注入邮件与短信发送依赖,域包不反向 import `app` 或 `service`。新增前端业务模块 `services/api/sms.ts`,只使用项目 `http` 入口。
|
||||
|
||||
### 3.1 插件、渠道、模板、路由必须分开
|
||||
|
||||
| 对象 | 含义 | 示例 |
|
||||
| --- | --- | --- |
|
||||
| 插件 | 一种供应商协议能力 | `official-sms-aliyun`、`official-sms-tencent` |
|
||||
| 渠道实例 | 独立账号/应用、密钥、默认签名、启停、配额 | 阿里云主渠道、阿里云备用账号、腾讯云备用渠道 |
|
||||
| 场景模板绑定 | 某渠道某场景的云端模板及变量映射 | 登录、注册、管理员测试 |
|
||||
| 场景路由 | 首选渠道及明确有序的备用渠道 | 登录走阿里,明确拒绝时可尝试腾讯 |
|
||||
|
||||
新增 manifest 的 `smsProviders` contribution 和管理分类 `sms`;第一期使用系统官方 host-backed 执行模式。配置 schema 描述密钥、地区、应用和模板字段,宿主渲染渠道表单。密钥按渠道保存,而不是一个插件只能保存一份账号。
|
||||
|
||||
插件提供 `Descriptor`、`ValidateConfig`、`Send`,并以能力声明提供送达状态查询。宿主定义模板变量 `code`、`ttlMinutes` 等,再由适配器转换成供应商格式。插件不能创建验证码、登录用户、读取用户表或创建会话。
|
||||
|
||||
未来可信进程插件可使用独立的 `yingce.sms/v1` ABI;本期不复制一套大型进程运行时。进程隔离不等于安全沙箱,不能据此允许上传任意不可信二进制。
|
||||
|
||||
## 4. SDK 参考基线
|
||||
|
||||
本次通过供应商官方 GitHub API 核对 tag、对应提交和模块文件(2026-09-22):
|
||||
|
||||
| 供应商 | 官方 SDK / API | 本次发现的最新正式 tag | tag 所指提交时间(UTC) |
|
||||
| --- | --- | --- | --- |
|
||||
| 阿里云 | `github.com/alibabacloud-go/dysmsapi-20170525/v5`,API `2017-05-25` | `v5.6.0` | 2026-07-01 13:57:25 |
|
||||
| 腾讯云 | `github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms`,包 `v20210111` | SDK 仓库 `v1.3.184` | 2026-09-21 18:47:20 |
|
||||
|
||||
阿里 tag 的 `go.mod` 声明 Go 1.14,依赖 `darabonba-openapi/v2 v2.2.2` 和 `tea v1.5.1`;腾讯 SMS 子模块声明 Go 1.14,并依赖 `common v1.3.184`。这只是模块声明,与项目 Go 1.25 的实际集成兼容性仍须编译验证。
|
||||
|
||||
正式 tag 不等于已经在本项目证明稳定。腾讯此版本刚发布,将其列为候选,不宣称经过长期生产验证。实施时重新核对正式 tag、变更记录和安全修复,通过模块解析、编译、契约测试及真实小流量验收后固定 `go.mod/go.sum`;不要使用浮动 latest 或 master。腾讯还须确认 SMS/common 子模块可解析版本匹配。
|
||||
|
||||
已查看官方模型源码:阿里发送使用签名、模板编码和 JSON 模板参数,返回包含 `Code`、`BizId`、`RequestId`;腾讯使用 `SmsSdkAppId`、`TemplateId`、`TemplateParamSet`,手机号支持 E.164,返回逐号码状态与流水号。适配器必须解析业务结果,而不只检查 Go error 或 HTTP 状态。
|
||||
|
||||
官方核对入口与固定版本源码:
|
||||
|
||||
```text
|
||||
https://api.github.com/repos/alibabacloud-go/dysmsapi-20170525/tags?per_page=10
|
||||
https://github.com/alibabacloud-go/dysmsapi-20170525/tree/v5.6.0
|
||||
https://api.github.com/repos/alibabacloud-go/dysmsapi-20170525/commits/v5.6.0
|
||||
https://github.com/alibabacloud-go/dysmsapi-20170525/blob/v5.6.0/client/send_sms_request_model.go
|
||||
https://github.com/alibabacloud-go/dysmsapi-20170525/blob/v5.6.0/client/send_sms_response_body_model.go
|
||||
https://api.github.com/repos/TencentCloud/tencentcloud-sdk-go/tags?per_page=10
|
||||
https://api.github.com/repos/TencentCloud/tencentcloud-sdk-go/commits/v1.3.184
|
||||
https://github.com/TencentCloud/tencentcloud-sdk-go/blob/v1.3.184/tencentcloud/sms/go.mod
|
||||
https://github.com/TencentCloud/tencentcloud-sdk-go/blob/v1.3.184/tencentcloud/sms/v20210111/models.go
|
||||
```
|
||||
|
||||
SDK 负责签名与协议,不自行实现阿里或腾讯签名算法。发送调用配置明确超时、取消和受控网络出口;关闭或明确约束 SDK 自动重试,防止宿主与 SDK 双层重试。默认使用官方域名和地区枚举,不提供任意 endpoint 输入框;同样遵守项目出站安全策略。
|
||||
|
||||
## 5. 登录注册开关合同
|
||||
|
||||
### 5.1 管理界面
|
||||
|
||||
```text
|
||||
登录方式
|
||||
密码登录 保留现有能力
|
||||
开启短信验证码登录 独立开关
|
||||
开启邮件验证码登录 独立开关
|
||||
Linux.do 登录 保留现有配置
|
||||
|
||||
注册策略
|
||||
开放新用户注册 总开关
|
||||
开启短信验证码注册 单验证入口
|
||||
开启邮件验证码注册 单验证入口
|
||||
开启短信+邮箱注册 强制双验证,与上面两个入口互斥
|
||||
```
|
||||
|
||||
持久化不是五个不受约束的布尔值:登录使用独立方法开关;注册使用总开关和 `methods` 集合,允许 `[]`、`[sms]`、`[email]`、`[sms,email]` 或 `[sms_email]`。`sms_email` 不得与单验证方法同时出现。
|
||||
|
||||
开启双验证时,UI 明示将关闭单验证入口,服务端同样拒绝冲突配置。关闭双验证后要求明确选择单验证入口,不自动恢复隐含历史配置。
|
||||
|
||||
注册总开关关闭时,禁止发注册验证码、创建注册流程及最终提交;不影响已有用户登录。登录验证码不会为未知号码自动注册用户。注册方法与登录方法相互独立:开启短信注册不会隐式开启短信登录。
|
||||
|
||||
策略保存与最终提交均强校验依赖;渠道有启用实例、对应模板与路由,邮件有可用配置。检查只能证明本地配置完整,不承诺云端模板审核、余额或网络一定正常。公网配置只返回有效方法与可展示的不可用原因,不泄露供应商或密钥。
|
||||
|
||||
策略保存使用版本号防覆盖;认证流程绑定版本,最终提交重新校验当前策略,避免发送验证码后利用旧策略绕过管理员调整。
|
||||
|
||||
### 5.2 双验证注册流程
|
||||
|
||||
1. 创建短期 `auth_flow`,方法为 `sms_email`,绑定浏览器持有的不可猜测流程凭据。
|
||||
2. 输入手机号、邮箱;分别发送 `register/sms` 与 `register/email` 验证码,挑战绑定该流程与归一化目标。
|
||||
3. 两个输入都有明确的倒计时、失效和错误反馈;不能在发送时就创建用户。
|
||||
4. 最终提交在一个数据库事务里校验并消费两个挑战、创建唯一用户及验证标记;任意失败均不能只消费其中一个。
|
||||
5. 注册结果/幂等键绑定流程,响应丢失后的重试不能创建第二个用户或重复发放赠送额度。会话创建与注册成功状态协调,通知发送不进入数据库长事务。
|
||||
|
||||
成功验证一项后修改手机号或邮箱,必须使对应验证结果失效。不得只拿两个不受流程绑定的 `challengeId` 任意拼接。
|
||||
|
||||
### 5.3 账号归属和已有流程
|
||||
|
||||
- 同手机号/邮箱的唯一性由数据库兜底;手机号与邮箱已分别属于两个账户时拒绝注册,不自动合并。
|
||||
- 新注册的联系方式写入验证时间。历史邮箱、首个管理员可选邮箱、OAuth 返回邮箱不能一律补成已验证。
|
||||
- 对无可信验证证据的已有账户,先通过原有登录方式进入安全设置,再完成邮箱/手机绑定验证;验证码登录只使用已验证联系方式,避免把历史填错的邮箱变成接管入口。
|
||||
- 本期必须包含最小联系方式绑定入口,否则已有用户无法安全启用手机登录。绑定/换绑需要近期重新认证、新联系方式验证和唯一性检查;不凭新号码验证码直接替换既有账户归属。
|
||||
- 首个管理员仍使用独立初始化路径,但创建权限必须由数据库事务/全局初始化状态保护,不依赖单进程用户计数和 mutex。
|
||||
- Linux.do 已有用户登录不变;首次创建用户必须进入统一注册策略。双验证开启时先完成双验证,再绑定 OAuth 身份,不能通过第三方自动注册绕过。
|
||||
- 邮箱域名白名单仍作用于含邮箱的新注册,不应用于既有用户登录;找回密码目的隔离,不受“关闭邮箱验证码登录”误伤。
|
||||
|
||||
## 6. 验证码与反滥用
|
||||
|
||||
统一 `verification_challenges`:用途、媒介、流程、目标摘要、验证码 HMAC、状态、过期时间、尝试次数、已用时间。验证码不明文持久化,HMAC 包含挑战 ID、用途、媒介和目标,采用用途分离的密钥派生。
|
||||
|
||||
建议初始值(产品配置,不是供应商限制):6 位密码学安全随机数字,5 分钟有效,60 秒重发间隔,每个挑战最多 5 次错误,每个目标每小时 5 次/每天 10 次。IP、流程、目标、渠道、全站分别限流,并给共享出口场景保留可调阈值。
|
||||
|
||||
- Redis 模式使用原子限流和共享冷却;单机模式也必须保证原子性。验证码唯一消费、目标唯一归属和硬性发送预算依靠数据库条件更新/事务,不能只依赖 Redis 或进程锁。
|
||||
- 错误次数更新必须真实提交,不能因为返回业务错误而随验证事务回滚。耗尽后锁定挑战。
|
||||
- 验证码目的包括登录、注册、绑定、密码找回,不能跨用途复用。新一代验证码发布时失效旧一代,重发受目标总额度约束。
|
||||
- 全局失败预算防止攻击者通过反复申请新挑战刷新错误次数。高风险请求增加人机校验;不能只依赖浏览器倒计时。
|
||||
- 登录验证码申请对账户存在性给出统一受理语义,未知账号不真实发送;系统不可用、频率超限等真实错误仍返回机器可读 reason,不伪称“短信已送达”。
|
||||
- 写操作校验 Origin/CSRF 边界;验证码和手机号不得进入 URL。日志过滤 SDK 原始错误中的请求参数、密钥、正文和地址。
|
||||
|
||||
## 7. 发送、路由和状态记录
|
||||
|
||||
### 7.1 发送路径
|
||||
|
||||
先原子预占预算、创建挑战和发送记录,再在事务外调用供应商,最后持久化结果。第一期使用有上限的同步单次发送,验证码仅在内存中交给 SDK,不引入持久化明文验证码的通用任务队列。
|
||||
|
||||
记录创建失败则不发送;调用超时或调用后数据库更新失败,原记录保留为待核对/结果未知。进程崩溃遗留的发送中记录由恢复任务转为未知并对账,禁止自动再次发送。明确失败的挑战失效;结果未知但实际收到的正确验证码可在限时、限次内验证,不要求“送达回执”才能登录。
|
||||
|
||||
幂等请求绑定流程、场景、目标和请求摘要,同一 key 不得用来更换目标。每个逻辑消息与每次供应商尝试分开记录。
|
||||
|
||||
### 7.2 故障切换原则
|
||||
|
||||
| 情况 | 行为 |
|
||||
| --- | --- |
|
||||
| 首选渠道本地不可用,尚未调用供应商 | 可按配置选择下一个可用渠道 |
|
||||
| 供应商明确拒绝且适配器能确认未受理 | 只有列入可切换错误白名单时才试备用渠道,并写独立尝试记录 |
|
||||
| 超时、断连、响应解析失败、状态不明 | 不自动重试、不跨渠道补发,先对账或让用户冷却后明确申请新验证码 |
|
||||
| 已受理但没有送达回执 | 不作为失败自动补发 |
|
||||
| 参数非法、目标非法、平台风险阻断 | 直接拒绝,不通过换渠道绕过校验 |
|
||||
|
||||
`OutId`、`SessionContext` 等追踪字段不未经证实就当成供应商幂等保证。不宣称跨网络提供严格 exactly-once;目标是可追踪、保守重试和最小化重复计费。
|
||||
|
||||
### 7.3 两个状态维度
|
||||
|
||||
发送受理状态:准备中、发送中、已受理、明确失败、结果未知、平台阻断。
|
||||
|
||||
送达状态:等待回执、已送达、送达失败、不可确认。API 受理成功不能直接写“发送成功/已送达”。验证码消费状态独立,不与送达状态混用。
|
||||
|
||||
第一期优先通过经凭据认证的供应商查询接口补齐回执,带查询时间窗口、退避和停止期限;无查询能力明确显示不可确认。若某供应商使用消费式回执拉取,必须先确定独占消费者及落库策略,避免多个渠道实例争抢回执。公开 webhook 后续按供应商真实认证机制建设,不做通用无鉴权回调。
|
||||
|
||||
### 7.4 记录字段与统计
|
||||
|
||||
列表:时间、脱敏手机号、业务场景、渠道、模板、受理状态、送达状态、耗时、归一化错误、供应商流水号。详情展示每次渠道尝试、配置版本快照和状态时间线;支持时间、渠道、场景、状态与号码精确查询。
|
||||
|
||||
不存验证码、不存完整短信正文、不原样保存 SDK 请求响应。目标按需要加密保存,查询索引使用带密钥摘要,列表仅显示掩码;访问和查询均受管理员权限与审计约束。密钥只回传 `hasSecret`,保留/替换/清空语义明确,不能把掩码当密钥保存。
|
||||
|
||||
统计区分受理率和送达率,展示已查询到的计费条数;缺少实际价格时不显示伪造的准确费用。首期不提供历史验证码“一键重发”,避免重放旧码。建议日志默认保留 90 天,具体由平台配置;挑战短期保留后清理。
|
||||
|
||||
## 8. 数据模型和迁移
|
||||
|
||||
| 数据对象 | 关键内容 |
|
||||
| --- | --- |
|
||||
| `users` 扩展 | `phone`、`phone_verified_at`、`email_verified_at`;非空归一化手机号唯一索引 |
|
||||
| `sms_channels` | 实例 ID、插件/provider ID、启停、加密凭据、非敏感配置、配置版本、操作人 |
|
||||
| `sms_template_bindings` | 渠道、场景、模板 ID、命名变量/有序变量映射;渠道+场景唯一 |
|
||||
| `sms_routes` | 场景、首选及有序备用列表、切换策略、配置版本 |
|
||||
| `sms_messages` | 逻辑发送 ID、流程/挑战关联、幂等摘要、脱敏目标、总体状态 |
|
||||
| `sms_send_attempts` | 每次供应商调用、渠道/模板快照、请求 ID、流水号、错误及回执 |
|
||||
| `auth_flows` | 方法、用途、目标绑定、流程凭据摘要、策略版本、完成结果与过期时间 |
|
||||
| `verification_challenges` | 统一验证码挑战及尝试计数、消费状态 |
|
||||
| 预算计数对象 | 按渠道/全局时间桶原子预占,未知结果保留额度,不把未确认费用退款 |
|
||||
|
||||
现有 SystemSetting 保存认证策略,不另造通用配置中心。数据库持久化是身份与审计真相源;Redis 仅用于协调与加速。
|
||||
|
||||
SQLite 与 PostgreSQL 都要覆盖迁移及并发行为。升级时关闭短信能力,按原注册总开关映射原邮箱注册策略,不自动开放注册。旧的短期验证码可明确失效并提示重取,不增加永久双写兼容层。注册及找回密码一起切换到统一挑战消费路径,避免两套不一致的限流实现。
|
||||
|
||||
历史邮箱验证状态迁移只采纳可证明的证据;不存在证据时保留未验证,不批量推断。上线先备份、迁移、配置并验收渠道,最后开放入口;回退先关闭新方法并使在途流程失效,不直接删除记录或回滚数据库字段。
|
||||
|
||||
## 9. 后台和前台交互
|
||||
|
||||
后台增加三个页面/页签:
|
||||
|
||||
1. 短信渠道:新增、编辑、启停、场景模板、首选/备用路由、额度和最近错误;静态配置检查与实际试发分开。
|
||||
2. 短信记录:筛选列表、详情时间线和手动刷新回执(不是重新发送)。
|
||||
3. 登录与注册:方法开关、双验证互斥提示、依赖状态、注册总开关及 Linux.do 设置。
|
||||
|
||||
渠道编辑用现有 AppDrawer;测试发送用带明确费用提示的确认弹窗。插件管理只管理插件可用性,渠道管理负责账号实例,避免两个地方维护两套密钥。
|
||||
|
||||
正常停用/卸载操作检查路由与认证依赖,要求先调整依赖;安全紧急停用可以明确确认后立即阻断发送,但要同步标记受影响认证方法不可用并告警,不能悄悄把双验证降为单验证。历史记录保留渠道/provider/模板快照。
|
||||
|
||||
前台登录按有效能力展示密码、手机验证码、邮箱验证码入口;注册根据策略展示手机、邮箱任选或双验证表单,双验证不是两个可互相跳过的 tab。首个管理员初始化独立展示。账号安全页提供联系方式验证和绑定。
|
||||
|
||||
## 10. API 草案
|
||||
|
||||
以下为目标接口,不是已存在接口;与现有 auth/service/handler 统一迁移,不长期保留第二套验证码入口。
|
||||
|
||||
```text
|
||||
GET /api/auth/settings
|
||||
POST /api/auth/flows
|
||||
POST /api/auth/flows/:id/codes
|
||||
POST /api/auth/login/code
|
||||
POST /api/auth/register
|
||||
POST /api/auth/contacts/verification
|
||||
POST /api/auth/contacts/bind
|
||||
|
||||
GET /api/admin/sms/providers
|
||||
GET /api/admin/sms/channels
|
||||
POST /api/admin/sms/channels
|
||||
PATCH /api/admin/sms/channels/:id
|
||||
POST /api/admin/sms/channels/:id/test
|
||||
GET /api/admin/sms/routes
|
||||
PUT /api/admin/sms/routes/:scene
|
||||
GET /api/admin/sms/messages
|
||||
GET /api/admin/sms/messages/:id
|
||||
POST /api/admin/sms/messages/:id/refresh-status
|
||||
GET /api/admin/settings/auth-policy
|
||||
PATCH /api/admin/settings/auth-policy
|
||||
```
|
||||
|
||||
验证码申请只能选用途与目标,不能由未登录客户端指定供应商、渠道、模板或任意短信正文。对外仅返回流程/挑战标识、过期/重发时间和统一受理状态。测试接口限定管理员、单号码、测试模板及硬性频率上限,不创建可用于登录的挑战。
|
||||
|
||||
继续使用 `{code,data,msg,reason}` 信封。新增明确 reason,例如 `AUTH_METHOD_DISABLED`、`REGISTRATION_DISABLED`、`VERIFICATION_INVALID`、`VERIFICATION_EXPIRED`、`VERIFICATION_ATTEMPTS_EXCEEDED`、`SMS_CHANNEL_UNAVAILABLE`、`SMS_QUOTA_EXCEEDED`。最终名称与已有 error-code 表对齐,不以解析 msg 判断错误。
|
||||
|
||||
## 11. 实施阶段与验收
|
||||
|
||||
### A:短信能力闭环
|
||||
|
||||
SDK 固定版本与适配器、系统插件贡献、渠道/模板/路由、后台试发、发送尝试和查询回执。先证明“多个渠道能安全发送并如实记录”,不提前开启公开登录入口。
|
||||
|
||||
### B:统一验证码与认证策略
|
||||
|
||||
统一挑战模型、原子次数/消费、短信和邮件登录、三种注册组合、联系方式绑定、历史邮箱处理、OAuth 首次注册和初始化边界。
|
||||
|
||||
### C:联调与发布
|
||||
|
||||
真实页面、供应商小流量、双数据库与多实例验收;更新数据库、HTTP API、插件开发、功能清单和 pending-test 专题。限流、配额、安全及核心失败路径属于发布前必需项,不留作上线后补丁。
|
||||
|
||||
必须验证:
|
||||
|
||||
- 同一供应商多个实例隔离;插件停用/渠道停用依赖与密钥不回显。
|
||||
- 两家 SDK 请求转换、业务失败、网络超时、逐号码失败、模板参数顺序、禁用自动重试。
|
||||
- 超时不自动补发;重放请求不重复发短信;发送后落库失败/进程崩溃不重复调用上游。
|
||||
- 五个 UI 开关的所有合法组合、冲突拒绝、注册总开关和在途策略变化。
|
||||
- 双验证任一错误/过期/已消费时不建号、不部分消费;并发提交仅一个成功。
|
||||
- 验证码不可跨用途/目标/流程使用;失败计数与冷却在多实例生效。
|
||||
- 既有邮箱、管理员初始化、第三方账号、手机号/邮箱冲突,不发生隐式绑定与账号合并。
|
||||
- SQLite/PostgreSQL 唯一索引、事务竞争、预算硬上限和迁移默认行为。
|
||||
- 后台与登录注册真实路由的明暗主题、倒计时、刷新恢复、错误/空态和键盘交互。
|
||||
|
||||
按风险选择专项 Go 测试、前端相关测试和构建;供应商真实验收必须有已审核签名/模板、受限测试凭据与用户认可的接收号码。本次方案阶段不运行业务测试、不启动服务、不产生短信费用。
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
## 设计沉淀
|
||||
|
||||
- [短信渠道插件与登录注册策略](design/sms-channels-and-auth-policy.md):阿里云/腾讯云官方 SDK 候选基线、多渠道与模板路由、发送记录、验证码安全、短信和邮箱登录注册组合及分阶段验收(设计提案,未实施)。
|
||||
|
||||
- [画布批量生成一致性治理](design/canvas-consistency-repair.mdx):节点丢失、批次状态与引用解析的根因、已实施边界重构、回归证据和仍待验收的性能/同步场景。
|
||||
|
||||
- [画布 Agent 外观与 Live2D](content/docs/backend/canvas-agent-appearance.mdx):独立助手名称、文案模板、模型包边界、Core 部署和验收要求。
|
||||
|
||||
Reference in New Issue
Block a user