AI Vibe Coding 实战(续):SMS 套件产品决策与开发方案

上一篇中,我整理了为 CabloyJS 全栈框架开发 SMS 套件(通用底座 + 验证码 + 认证)时,输入的提示词和 Claude Code 返回的开发方案。在方案结尾,Claude Code 要求我确认三组产品决策:注册语义、号码范围和投放范围。

其中,"短信登录即自动注册"让我有些疑问:如果用户不需要填写用户名,那么 userName 应该怎么确定?我把这个问题和另外两组决策一起补充给 Claude Code,让它进一步调整方案。现在继续整理出来,供大家参考。

提示词如下:

  1. 注册语义:是否采用"短信登录即自动注册"?存疑。如果是自动注册,那么 userName 怎么确定?
  2. 号码范围:首期仅中国大陆,还是支持国际号码?支持国际号码。
  3. 投放范围:
    • 短信登录同时开放 Web/Admin。
    • 首期交付 Mock 闭环,同时接真实供应商:
      • 中国大陆:阿里云 / 腾讯云。
      • 国际号码:请推荐 1 到 2 家最流行的服务。

Claude Code 返回的"开发方案"如下:

这几项确认后,方案可以进一步收敛。先回答用户名问题:自动注册并非不能实现,但当前账号模型下,显式注册更自然。我建议首期调整为"短信注册与短信登录分离",不默认自动注册。

另外,国际短信服务推荐 Twilio、Vonage;首期建议接入 Twilio,将 Vonage 作为第二选择,而不是两家都必须实现。

一、注册语义:建议显式注册,由用户确定 userName

1. 为什么不直接自动生成用户名?

进一步核实源码后,当前 user.name 不只是一个内部技术标识:

  • 注册时从 profile.username 写入。
  • 用于用户展示。
  • 也是现有密码登录的用户名查找字段。
  • 当前资料编辑还允许修改它。

因此,不能简单把它解释为"自动生成、永不变化的内部 ID"。当前也没有一个独立持久化的 nickname 字段来承担展示名称。

对应源码:

  • 用户资料映射:vona/src/suite/a-home/modules/home-user/src/service/userAdapter.ts:13
  • 用户注册:vona/src/suite-vendor/a-vona/modules/a-user/src/bean/bean.user.ts:27
  • 密码登录查找:vona/src/suite-vendor/a-auth/modules/auth-simple/src/bean/authProvider.simple.ts:58

自动注册当然可以生成类似 sms_<随机标识> 的用户名,但会带来后续产品问题:是否允许修改、展示什么、以后设置密码时使用哪个名字等。为实现短信登录,首期不必同时改造整个账号命名模型。

2. 推荐的注册与登录契约

操作 输入 行为
短信注册 国际手机号、用户名、短信验证码 验证手机号,创建用户及短信身份映射,成功后登录
短信登录 国际手机号、短信验证码 只登录已存在的短信身份,不创建新用户

注册首期不强制要求密码或邮箱,也不创建虚假的密码凭据。

用户名规则建议:

  • 沿用并补齐现有用户名校验。
  • 去除首尾空白,按统一的大小写等价规则检查。
  • 在当前 instance 内唯一。
  • 禁止 admin 等系统保留名称。
  • 名称被占用时返回字段错误,不静默追加随机后缀。
  • 并发注册同一手机号、同一用户名时,仍必须保证最终唯一。

这里还需注意:当前资料编辑中的"Display name"实际上会修改同一个 user.name,但没有与注册一致的查重规则。实施时应让注册与改名共享必要的用户名约束,否则注册时保证唯一、改名时却可以制造冲突。

3. 手机号身份与用户名分开

建议保持三个概念独立:

字段/概念 用途
user.id 内部用户标识
user.name 用户选择的账号名称
SMS 身份映射 已验证的规范化手机号与 userId 的关联

因此:

  • 用户改名,不影响手机号登录。
  • 手机号不能直接作为默认用户名,避免在用户展示位置暴露完整号码。
  • 注册时用户名与旧账号相同,不自动关联。
  • 旧账号 mobile 与本次手机号相同,也不自动认领。

还需要显式关闭现有认证链的自动注册行为。 当前框架对 login 和 register 都可能创建用户,不能仅传入 intention: 'login' 就认为变成了"仅登录"。

对于不存在的短信身份,应在验证手机号归属后提示注册;发送验证码接口本身不公开账号是否存在。


二、号码范围:支持国际号码,统一为 E.164

建议前后端采用明确的国际号码契约:

  • 前端提供国家/地区选择器。
  • 服务端使用成熟号码解析库,例如基于 libphonenumber 的实现。
  • 最终统一保存、比较和发送为 E.164,例如 +86138...、+447...。
  • 发送与验证使用同一套规范化逻辑。
  • 不依赖简单正则判断所有国家号码。
  • 不通过界面语言、浏览器地区或 IP 猜测接收号码国家。

路由规则

接收目的地 默认发送渠道
中国大陆 阿里云或腾讯云
港澳台及其他国际目的地 Twilio,或配置选择 Vonage
显式开发/测试配置 sms-mock

不能把港澳台归入中国大陆短信渠道,也不能根据页面语言选择供应商。

"支持国际号码"不等于"默认开放全球发送"。 建议按国家/地区配置允许发送范围、配额和预算限制。不同目的地可能有 Sender ID、号码注册、模板或用途限制,需要逐个开通与验收。


三、国际服务商:推荐 Twilio 和 Vonage

这两家都是成熟、广泛使用的国际通信 API 服务商。这里是工程选型推荐,不声称它们存在可核实的全球市场份额第一、第二排名。

服务商 推荐定位 接入方式
Twilio 首期国际短信首选 Programmable Messaging
Vonage,原 Nexmo 第二选择或后续替代渠道 SMS API

1. Twilio:建议首期接入

适合当前架构的原因:

  • 提供通用短信发送 API。
  • 使用 E.164 接收号码。
  • 支持通过发送号码或 Messaging Service 配置发送方。
  • 有较完整的目的地权限及国家合规文档。

2. Vonage:适合作为第二选择

Vonage SMS API 提供通用的接收方、发送方、正文发送能力,适合实现另一个遵守相同契约的 SMS Provider。

最终在具体目标国家如何选择,仍应看:

  • 实际可开通的发送身份。
  • 到达率和时延测试。
  • 单价与短信分段计费。
  • 账号主体和当地合规要求。

3. 不选择托管 Verify 产品作为本次默认方案

Twilio 和 Vonage 都有托管验证码产品,但本次建议接入:

  • Twilio Programmable Messaging
  • Vonage SMS API

而不是直接使用它们的 Verify 产品。

因为本次已经计划由 sms-captcha 统一管理:

  • 验证码生成。
  • 有效期。
  • 手机号及用途绑定。
  • 尝试次数。
  • 单次消费。

供应商只负责传输,才能保证 Mock、阿里云、腾讯云和国际 Provider 使用同一套验证语义。


四、底座需要兼容两类供应商发送模式

新增国际供应商后,不能把统一 SMS 接口设计成"必须传供应商模板 ID",因为各家的接口并不相同:

Provider 典型发送方式
阿里云 签名 + 模板编号 + 命名参数 JSON
腾讯云 签名 + 模板编号 + 有序参数数组
Twilio 发送方/Messaging Service + 短信正文
Vonage 发送方 + 短信正文

因此建议保持业务调用统一:

ts 复制代码
// 拟议接口
await this.bean.sms.send({
  scene: 'sms-auth:signup',
  recipient: normalizedPhone,
  params: {
    code,
    minutes: 5,
  },
});

由服务端 Scene 配置和 Provider 适配完成差异转换:

  • 阿里云:{ code, minutes } 转为模板参数 JSON。
  • 腾讯云:按明确配置的参数顺序转换为数组。
  • Twilio/Vonage:使用服务端维护的本地化文本模板生成正文。

参数顺序不能依赖对象枚举;短信正文、供应商模板和发送方也不能由公开请求自由传入。

同时区分:

  • 接收号码地区:决定合规及可用渠道。
  • 短信内容语言:由业务语言策略决定。
  • 供应商账号区域:由 Client 配置决定。

三者不能混成一个 region 字段。


五、模块结构:保留四个核心模块,真实 Provider 独立扩展

既然首期明确包含多家真实供应商,建议保留原有四模块,并为供应商分别建模块:

模块 首期建议
cabloy-sms 必需:传输底座
sms-captcha 必需:验证码
sms-auth 必需:注册登录
sms-mock 必需:开发测试
sms-aliyun 必需:中国大陆 Provider
sms-tencent 必需:中国大陆 Provider
sms-twilio 推荐纳入首期:国际 Provider
sms-vonage 备选;需要两家国际渠道时再纳入

这些模块都归属 cabloy-sms 套件。独立模块可以隔离 SDK、凭据类型和供应商变化,不让所有使用者都加载所有 SDK。

如果希望严格保持只有四个模块,也可以把真实 Provider 放进 cabloy-sms,但既然现在已经确定存在多个真实供应商消费者,独立 Provider 模块更合适。

默认路由只选择一家发送。例如:

  • 中国大陆默认阿里云,可配置切换为腾讯云。
  • 国际默认 Twilio。
  • 不同时向多个 Provider 发送。
  • 超时结果不确定时,不自动换另一家重发。

六、Web/Admin 同时开放的含义

可以同时提供短信注册、登录入口,并共享同一套:

  • 用户。
  • SMS 身份映射。
  • Provider 配置机制。
  • Passport 与会话处理。

不能因从 Web 或 Admin 注册而生成两套同手机号用户。

但"登录入口开放"与"业务权限开放"必须分开:

  • 短信注册只获得普通注册用户权限。
  • 不因从 Admin 页面注册就赋予管理权限。

七、更新后的首期交付建议

首期范围建议定为:

  1. 底座 + Mock:先跑通统一发送契约。
  2. 阿里云、腾讯云、Twilio Provider:接入统一契约。
  3. 短信验证码:国际号码、用途绑定、限流冷却、单次消费和 Mock 回填。
  4. 显式短信注册 + 仅已有身份短信登录。
  5. Web/Admin 入口和权限回归验证。

真实 Provider 的验收需要区分:

  • 代码接入完成:请求映射、响应解析、错误处理已验证。
  • 真实短信验收完成:已批准账号、签名/模板/发送身份,向授权测试号码实际发送并确认收到。

前者不能代替后者,也不能以 Mock 闭环代替真实供应商验收。

我的最终建议是:显式注册确定 userName;国际号码统一 E.164;首期接阿里云、腾讯云、Twilio,Vonage 作为第二国际渠道备选。这能覆盖你明确的首期业务范围,同时避免把用户名体系改造、全球渠道开通和自动故障切换一起扩展进来。

Sources

本轮未修改代码。供应商资料依据官方文档搜索结果核对;页面全文抓取受网络限制,未据此承诺具体国家的可开通性、价格或实际到达率。


这一轮交流后,Claude Code 对注册语义、国际号码处理和真实供应商接入给出了更具体的建议,也明确了 Web/Admin 共用身份与权限控制的边界。限于篇幅,本文先整理到这里。如果想看后续实现过程,欢迎留言,我会继续整理。

相关推荐
重生之我在番茄自学网安拯救世界1 小时前
AI开发者日报 第2期 | Anthropic零 Rust 团队靠Claude重写核心 API,CPU 降 40–50%
人工智能·网络安全·大模型·ai编程·claude
vipxieliang2 小时前
微服务架构设计:从拆分到治理的完整指南
openai·ai编程
日日大王学编程2 小时前
开源Agent项目记忆设计决策对比
python·ai·langchain·开源·ai编程
五萝卜3 小时前
AI 供应链 RAG 安全
人工智能·网络安全·ai编程
灵感__idea3 小时前
Claude Code:能干活只是初级目标,再提10倍
ai编程·claude·cursor
柳杉3 小时前
让 AI 学会审美、建模和剪片:我收藏夹里的 14 个仓库
前端·ai编程·three.js
Carson带你学Android3 小时前
Android Studio Rabbit 2 发布:除了Gemini,40+ AI Agent 正式入驻!
android·ai编程
许雪里12 小时前
XXL-AI v1.4.0 发布|AI应用开发平台
agent·ai编程