借助 AI 完成两个微信小程序:从构想到发布的实战复盘

作者:袖梨 2026-09-21

从熟悉的后端系统转向微信小程序,困难并不只是学习页面和接口。数据应该留在本机还是同步到云端,历史记录如何迁移,线上能力为何与开发环境不同,都可能直接影响真实用户。借助 AI 完成两个小程序后,我更想复盘这些具体决策、故障与测试经验,以及平台规则对产品架构的实际约束。

本文同步自我的个人博客:haifeiWu.github.io

我是写 Go 的后端,日常打交道的是微服务、消息队列和存储引擎。微信小程序对我来说是完全陌生的领域:没有构建体系、没有单元测试的默认姿势、没有可观测性,甚至连「把数据存在哪」都需要重新想一遍。

最近这段时间,我做了一件事:和 AI 结对,把两个小程序从想法推到了线上。

一个是我自己的需求——开电车两年,充电账一直算不明白;另一个是给我家孩子做的——疫苗接种时间表太容易漏针。

这篇文章不写「AI 提效 10 倍」这种结论,而是把技术取舍、真实的坑、以及那些代码之外的障碍记录下来。

一、两个小程序

电车车主小助手

新能源充电记录 + 价格统计。核心设计是本地存储、无后端、零隐私接口,个人主体以「工具-记账」类目上架。

功能上它解决的是「把电车的账算清楚」:

  • 充电记录:金额、电量、充电时长、充电类型(快充/慢充/超充)、充电站、备注,单价自动计算
  • 峰谷电价统计:给记录标记峰/平/谷时段,统计谷电占比与错峰充电节省
  • 电池健康与真实电耗:按 SOC 增量估算满充容量得出 SOH 曲线,按相邻两次充电的里程差算真实百公里电耗
  • 油价监测与油电对比:在线获取各省实时油价,每次充电后展示「相比油车省了多少钱」
  • 里程推算、合并记录、日历视图、多车对比、CSV/Excel 导入导出

我的宝贝-宝贝生活记录

按《国家免疫规划疫苗儿童免疫程序》给每个宝宝生成个性化接种日历。

  • 接种时间表:按出生日期推算每一针的月龄,免费/自费方案可切换
  • 漏种自检与补种计划:算出针次,给出补种顺序
  • 入学入托查验:按一类疫苗口径核对查验清单
  • 接种后反应记录:只记录家长观察到的现象,不做任何判断
  • 订阅消息提醒:微信订阅消息主动推送,而不是等用户想起来打开

技术栈上两个项目刻意走了两条路:电车用纯本地存储,宝宝用微信云开发。这个差异后面会讲到,它直接决定了两边的数据安全策略完全不同。

二、电车车主小助手:把账算清楚

数据放哪:一个刻意的取舍

第一个决定就是不做后端

理由有三个:个人主体拿不到微信支付,做后端也没有变现路径;不想为了一个记账工具维护服务器;充电记录天然带位置属性,能不落别人的库就不落。

代价也很明确:清缓存、换手机,数据就没了。所以「导出」不是附属功能,而是数据安全的一部分——导出的 CSV 可以转发到微信聊天里长期保存,需要时再导入恢复。

这类取舍在小程序里非常常见:平台给你的能力边界,直接决定了你的架构。后端工程师习惯的「服务端是唯一真相源」,在这里从一开始就不成立。

记录按年分片

微信 Storage 单个 key 有 1MB 上限。最初所有记录存在一个 key 里,记录一多就会顶到天花板。

改法是按年分片:charge_records@2026charge_records@2025……新增和编辑只重写当年那一片,而不是把全部记录序列化一遍。从旧版本升级时,首次读数据会自动把 charge_records 里的历史记录搬到对应年份分片并清理旧键,用户不需要做任何事。

同时加了一个容量快照:某个分片接近 1MB 时,在「我的」页面提醒用户备份。

这个设计看起来像是过早优化,但在「所有数据都在用户手机上」的前提下,它是必须的——服务端可以扩容,用户的手机存储不行。

而恰恰是这段迁移逻辑,后来出过一次最危险的问题:迁移函数收到的「已存在记录」判定集合,是在把旧记录 push 进去之后才计算的,于是整批旧记录都被判为「已迁移」而跳过写入分片,紧接着旧键被删除——用户一升级,历史记录就没了。

抓到它的是一条专门为数据迁移写的断言:「迁移过程不丢记录」。这也是为什么值得为迁移单独写用例:这类 bug 不会出现在开发机上,只会出现在真实用户的升级路径里。

省了多少钱:把算法公开写在页面上

油电对比是这个工具最有传播力的功能,算法本身很简单:

等效里程 = 充电电量 ÷ 百公里电耗 × 100
油车成本 = 等效里程 × 百公里油耗 ÷ 100 × 油价
节省金额 = 油车成本 − 充电金额(负数代表比油车贵)

油耗、电耗、对比油号、油价省份都由用户自己设置。把公式直接印在设置页上,是因为这类「省钱计算」最容易被怀疑动了手脚——公开算法比任何文案都有说服力。

不信车机上那块「快乐表」

车机显示的电耗普遍偏乐观,这是电车圈的共识。所以我从充电记录里又榨了两层信息:

SOH(电池健康度):用「充电电量 ÷ SOC 增量」估算满充容量,再和标称容量比。样本随充电次数增长,画成曲线就能看出衰减趋势。

真实电耗:用相邻两次充电之间的里程差除以充电电量。这个数字来自充电桩的电表,而不是车机的估算,所以更接近真实。

这两个指标都不是新采集的数据,而是从「已经记下来的东西」里再算一层。产品设计中这类「数据复用」的性价比往往最高。

手工录入 67 条订单:一次被实测否决的方案

工具做好之后,第一个要解决的问题是:我过去两年的充电订单还在理想汽车 App 里,怎么搬进来?

最初的计划很朴素——用 Mac 上的微信小程序客户端逐条录入。实测之后放弃了:

  • 每次操作序列的第一次点击必被吞(用于激活窗口)
  • 选择器的点击只能跨 2 行,±1 行毫无反应
  • 拖动吸附完全不可控(拖 60 点滚 2 行,拖 30 点滚 0 行)
  • 键盘方向键的首次按键也常被吞

用大约 85 次交互,连一个日期都没选对。按这个比例,67 条需要 1000–1700 次交互、3–8 小时

于是方案换成:把一次性的体力活,换成一个可复用的功能

从 HAR 到导入闭环

  1. 从理想汽车 App 导出充电订单的 HAR 抓包
  2. 解析出订单列表,按小程序自己的 buildCsv() 生成 CSV——复用产品代码而不是另写一份导出,保证格式永远一致
  3. 在小程序里导入

解析时还发现抓包并不完整:接口返回 totalCount=68、pageCount=7,而 HAR 里只抓到了 3 页 30 条。于是用 HAR 里带的 X-LX-Token / X-LX-Deviceid 补齐第 4–7 页(响应是 gzip,还得去掉 Accept-Encoding),最终拿到 68 条,排除 1 条 0 电量的异常订单后导出 67 条、总金额 2403.25 元、总电量 3032.85 kWh

导入功能支持三种入口:选文件(从微信聊天记录里选 CSV/Excel)、粘贴 CSV 文本读剪贴板。按表头名自动识别列,跳过重复记录,车辆不存在时按名称自动创建。

判重是幂等的:第二次导入同一份数据,结果是「待导入 0 条 / 跳过重复 67 条」,记录数不会翻倍。坏行只跳过自己并给出带行号的提示,不会因为一行脏数据让整批导入失败。

为了支持 Excel,还引入了 SheetJS 的 mini 构建(250KB),主包体积从 106.5KB 涨到 336KB——小程序主包上限是 2MB,这个代价可以接受。这里也踩过一个精度坑:.xlsx 里未设日期格式的单元格会读成数字序列号,00:03 被截断成 00:02,原因是 SheetJS 用 General 格式把序列号截成了 8 位有效数字;解法是先折算成分钟再取整。

线上事故:接口全挂了,但不是接口的问题

上线之后,有用户反馈油价页面报错,截图上是两行字:

获取失败:主源:域名未配置(开发调试请勾选"不校验合法域名");备源:域名未配置

第一反应是第三方接口挂了。查下来不是:

  • 主源 v2.xxapi.cn 直连返回 200,数据日期 2026-09-12,覆盖 31 个省
  • 备源 api.nxvav.cn 返回 200
  • 第一次 curl 超时是本机代理干扰,--noproxy 之后正常

真正的根因是:小程序后台没有配置服务器域名。微信小程序的网络请求必须走白名单,开发工具里勾了「不校验合法域名」所以本地一切正常,线上没有白名单,两个源全被拦截。

那句「域名未配置」其实是项目自己代码里的翻译——wx.requesterrMsg 里含 domain,被 failMessage() 翻成了人话。这个翻译在开发期很贴心,但在线上掩盖了「这是配置问题、不是网络问题」的本质。

修复本身很简单:后台「开发设置 → 服务器域名」添加两条 request 合法域名(域名改动每月限 5 次)。难点在于怎么进后台

  • 需要管理员登录态,而账号的会话 cookie 是 session cookie
  • 用 Chrome profile 复制的方案失败——Chrome 把复制过来的加密 cookie 静默丢弃了,内存里只剩几个明文项
  • 最后的解法是从 macOS Keychain 取「Chrome Safe Storage」密钥,本地解密 cookie,再通过 CDP 的 Network.setCookie 直接注入,绕开 profile 加载

最后保存时还需要管理员微信扫码确认。这类「代码没问题、卡在平台操作」的事,在小程序开发里出现的频率比 bug 高得多。

测试:222 → 317 条 UI 断言跑在真实模拟器上

小程序没有现成的测试体系,但官方提供了 miniprogram-automator,可以驱动微信开发者工具的真实模拟器做点击、输入和断言。

用它跑了一轮从 UI 到功能的全面测试,覆盖启动与空状态、车辆管理、新增/编辑记录、明细列表、统计、导入导出等 8 个模块:

指标结果
断言总数222(后续迭代涨到 317)
通过全部通过
阻断级缺陷0

其中导入功能的三条入口全部可用,67 条真实订单解析 0 错误;导出 CSV 的 13 列表头、BOM、行数、时间升序都逐项核对过。

写 UI 自动化最大的价值不是「回归」,而是它逼你把每个边界场景想清楚——比如「0 元记录」「超长文本」「67 条数据渲染」这些平时不会手动测的场景,写成断言之后就成了资产。

但断言写错了比没有断言更危险。这里踩过一个典型的坑:早期为了「跑通」,有两条断言直接把当时的实现固化成了预期——一条要求页面上存在两个主按钮(实际设计是一个主按钮 + 一个次按钮),另一条断言超长文本「可完整保存、未经代码层截断」,注释里还写着「自动化会绕过 maxlength」。等到后来要修这些问题时,测试反而成了阻碍。同类问题还有表单输入框的索引断言:中间插入一个时长输入框之后,ins[5] 从「充电站」变成了「时长」,断言默默指向了错误的字段。

三、我的宝贝:当数据不能丢

如果说电车项目的关键词是「取舍」,宝宝项目的关键词就是「不敢丢」。

一次真实的数据丢失事故

用户反馈的第一句话就是:小程序更新后记录丢失了

排查之后,链路是这样的:

// pages/schedule/schedule.js
if (!babies.length) {
  CloudSync.syncUp();   // 本地读不到宝宝时,仍然上传 items: []
  return;
}

云函数 syncReminder 的逻辑是「以本次上传的 babyId 集合为准,清理孤儿文档」:

const rawItems = Array.isArray(event && event.items) ? event.items : [];  // 空数组放行
for (const doc of orphanDocs) {
  if (doc.babyId && !writtenBabyIds.has(doc.babyId)) {
    await db.collection('reminder_schedule').doc(doc._id).remove();  // 全删
  }
}

于是形成一个致命的放大链路:本地 storage 只要读空一次,云端的唯一备份就会被自己的云函数删干净,数据从「可恢复」变成「永久丢失」。

引信是 AppID 变更——微信本地 Storage 按 AppID 隔离,换了 AppID,老数据必然读不到。

修复方案是给这条链路加两道闸门,核心是区分「用户主动删除」和「storage 读空」

  • syncUp() 在本地无宝宝时默认拒绝上传,只有显式传 { allowPrune: true } 才放行
  • 云函数侧 const shouldPrune = items.length > 0 || event.allowPrune === true
  • 用户在「宝宝管理」里主动删光所有宝宝时,才显式传 { allowPrune: true },保住原本的设计意图

同一个空数组,两种语义,两种处置。这是整个修复里最关键的一笔。

修复过程用 TDD 验证:旧代码跑新测试 10 个红,新代码 17 个绿,全量测试从 201 涨到 227 条全绿。

隐私:云端只存「最小调度集」

订阅消息推送需要云端数据,但宝宝信息是敏感的。所以云端 reminder_schedule 集合只保存最小调度集:

openid / babyId / birthday / 提醒开关 / 提前量 / 订阅状态 / 已接种 doneDoseIds

不含宝宝昵称。订阅消息文案里的宝宝称呼固定为「您的宝宝」。

昵称、头像、接种记录详情这些全部只存在本机。云端知道「有个孩子在 2025-06-15 出生,还差第 3 针」,但不知道这个孩子叫什么——这个颗粒度是刻意设计的。

云函数的工程细节

三个云函数:syncReminder(上传调度集)、dailyReminder(每日 08:00 定时推送)、sendSubscribe(下发订阅消息)。

定时推送这个函数看起来简单,但要考虑的东西一点不少:

  • 分页 + 受控并发:每批 20 条,避免一次拉全表
  • 单次上限MAX_RECORDS_PER_RUN = 5000,防止超时
  • 幂等保护lastPushDate >= today 直接跳过,重复触发不会重复推送
  • 同日多针次只推一条:不然一天三针会轰炸用户
  • 可观测:返回 { processed, pushed, skipped, failed }

云函数没有专门的单元测试,所以这些边界都靠返回值暴露出来,方便在控制台排查。

数据准确性上的自我克制

这是整个项目里我最想写的一段。

从小红书抓了 122 篇同类笔记做需求调研后,整理出一批优化点。其中两条 AI 明确拒绝实现:

  • 接种间隔校验:需要权威的剂次间隔表,没有可靠来源 → 不做
  • 自费疫苗优先级推荐:需要价格数据和医学依据 → 不做

接种后反应记录功能里,不写「是否发烧」的阈值判断,不写「是否需就医」的结论,页面上常显一句话:

这里只记录你观察到的现象,不做任何判断。

入学入托查验指引的编写原则也是:没有官方来源的流程不许写进来,宁可让用户去问接种门诊。每条指引都带 sourceUrl / sourceName / verifiedAt

与此对应的是数据本身的准确性——调研时发现百白破免疫程序自 2025-01-01 起已由「3/4/5/18 月龄」改为「2/4/6/18 月龄 + 6 周岁」,而项目里的数据已经过期 20 个月,且完全没有 6 周岁剂次。这类错误在育儿工具里是硬伤,所以除了补数据,还加了一张「数据来源」卡片,把依据的程序版本、生效日期、官方来源链接都标出来。

顺带一个实现细节:来源链接做的是「复制」而不是「跳转」——小程序的 web-view 需要业务域名报备,个人主体通常没有。

验证体系:608 条单测、137 项 E2E、像素审计

宝宝项目的验证体系比电车重得多,因为它处理的是不能丢的数据。

静态一致性校验:对 7 个页面 + 7 个组件做 WXML ↔ JS ↔ JSON ↔ WXSS 交叉校验,检查绑定是否指向存在的变量、事件是否指向存在的方法、组件是否注册、样式引用是否存在。

这里有一个关键的实现选择:不用正则去猜 JS 里的方法名,而是用 mock 的 Page() / Component() 把页面 JS 真的 require 进来,捕获它注册的配置对象。这样方法简写、箭头函数、属性赋值全都成立。为了验证检测能力本身有效,还用 10 个合成 fixture 主动注入缺陷,确认都能被精确捕获。

E2E 拦截器:写探针时发现,只要打开首页就会触发一次真实的 syncReminder 调用,而这个调用会删掉该用户其他所有备份。所以在 App Service 层把 wx.cloud.callFunction 换成「只记录、永不外发」的包装器,全程拦下 4 次此类调用,没发出一条真实云请求。

这个拦截器自己还出过两个 bug(闭包捕获了被替换的数组、evaluate 序列化后引用不到 Node 侧常量),都是靠「有数据状态确实触发了 syncReminder」这条断言抓出来的——否则整个 E2E 会「全绿但什么都没验证」

像素级验证:加了色板验证之后报「品牌色命中 0%」,但变量下发的断言是通过的。根因是开发者工具截图带 Display P3 色彩配置,sRGB 的 #D23F5B 在 P3 里存成 (194,75,93)。加上 ICC 色彩转换后,命中率才正常。

假 canvas 测不出纵向溢出:接种小结卡的绘制断言全绿,真机截图却发现页脚压在记录上、第三条被卡片圆角切掉。原因是假 ctx 只记录绘制指令、不做裁剪,而原有的越界检查只查横向不查纵向。修法是把页脚从「钉死卡片底部」改成「紧贴内容」,绘制函数返回实际高度,必要时按新高度重画一遍,并补两条回归测试。

视觉:从「AI 味」到「温柔治愈系」

UI 经过三轮迭代:第一轮去装饰(删掉 ::before/::after 装饰圆、收敛渐变、阴影从 8 档收到 2 档),第二轮数字驱动 + icon-first,第三轮落地「温柔治愈系」设计语言。

其中最有价值的是对比度审计#FFFFFF#F58CA0 上只有 2.30:1,远低于 WCAG AA 要求的 4.5:1,覆盖了主按钮、标签等多个位置;知识页的返回按钮是 1.98:1,最差。

修法不是逐个改颜色,而是新增 utils/palette.js,从一个基准色派生整套 token,并把两个承载文字的 token 强制压暗到达标,然后用解析器逐规则判定,精确替换了 14 处实心白字 + 11 处浅底品牌字。

后来又发现粉色主题的按钮数字饱和度太强——根因是派生算法用的是「相对」衰减,基色越亮压暗步数越少、降饱和反而越少,于是漏出了荧光绯红。改成在派生循环内部加绝对彩度上限(只降不升)后,主色从 #D23F5B 变成 #BD5368,而其他四套配色逐字节不变。

四、上线才是真正的开始:平台规则

写代码只占这个项目一半的工作量,另一半全部消耗在平台规则上。

命名是第一道门

小程序名称看起来是最简单的事,实际是最难的。

第一轮:名称含「用药」触发医疗行业校验。要求上传《医疗机构执业许可证》,个人主体不可能提供。对照实验证实触发源是「用药」二字而非「宠物」——换成「服药 / 喂药 / 吃药 / 药盒 / 药单」都能通过。

第二轮:被驳回「命名过于广泛」。平台建议「采用具有独特性的名称,比如品牌或自身名字/小名」。正确结构是「独特标识词(品牌/小名)+ 功能关键词」。

还有几条硬规则:名称全平台唯一;必须是两个词以上的组合;不能含营销通用词;必须与实际功能一致。而名称一旦注册完成,个人主体的改名次数极少——等于获客关键词在注册那一刻就被锁死了

未认证的小程序,不能被搜索、也不能被分享

这是注册页的原文,也直接推翻了我们原本的论证前提。

之前的判断是「用一个描述性的名称去承接微信搜一搜的流量」。但如果不做微信认证,小程序既搜不到也分享不了——认证从「可选项」变成了「上线前必做项」。个人主体可以做认证,30 元/年。

服务类目与备案

两个项目分别选了「工具-记账」和「工具_健康管理」,都是个人主体无需额外资质的类目。ICP 备案也是必需的,个人可备案。

云开发:环境共享是个陷阱

一开始想复用已有的云开发环境,评估之后放弃:

  • 环境共享的配置入口不在浏览器侧——腾讯云 CloudBase 控制台的全部 21 个路由里都没有,只有微信开发者工具内嵌的云开发控制台才有
  • 跨账号复用还额外要求资源方部署 cloudbase_auth 云函数,调用方要改用 new wx.cloud.Cloud({ resourceAppid, resourceEnv })
  • 一个环境最多共享给 10 个小程序,且仅支持同主体

最终走独立开通路线。这个决定是对的:看起来省事的路,往往在别处收利息。

审核与发布

提审前要核对一堆前置条件:版本号、服务类目、隐私指引配置、接口权限自检。提交后状态「审核中」,预计 1–7 天。

审核通过后还需要手动点「发布」,不是自动上线的。

审核环节里有两次「差一点就出事」:

第一次:点了提交,页面毫无反应。 勾选须知、点「继续提交」,页面完全没变化,网络面板里也没有任何请求。扒了后台的 version_manager.js 才发现,提交函数是用 <a target="_blank"> 打开一个新标签页去填真正的表单,当前页永远不会变。另外还有一个残留的弹窗遮罩层在拦截点击,以及一个「隐私检查返回 -1 时静默中止、不给任何提示」的分支。

第二次:差一点带着坏掉的导出功能过审。 提交版本时按核查结论勾了「未采集用户隐私」,微信当场拦下:代码调用了 ClipboardMessageFile 接口,选「未采集」发布后这些接口权限会被回收。而 wx.setClipboardData / wx.getClipboardData / wx.shareFileMessage 正是这次刚做的导入导出功能的唯一通道——如果没被拦下,用户升级后会直接失去备份能力

根因是核查时搜了定位、登录、网络请求,唯独漏搜了剪贴板类接口。修正时还发现隐私指引里的用途描述已经过时(写的是「用于识别并粘贴充电桩编号」,而这个功能在代码里根本不存在)。

五、推广:从「做出来」到「有人用」

做完之后才是最难的部分。

小红书:被判「推广其他平台内容」

首发笔记的数据其实不算差(45 浏览、2 评论),但很快收到判定:

笔记存在推广其他平台的内容 / 存在展示其他平台界面信息的行为 / 存在尝试引导他人前往其他平台进行搜索、浏览或查看的行为

复盘时才发现,四条因素叠在一起必然触发:

  1. 「微信搜一下就有」——引导站外搜索
  2. 「小程序叫 XXX」——为其他平台产品做介绍
  3. 「我自己做了个小程序」——以分享形式宣传
  4. 4 张产品界面截图——展示其他平台界面信息

第 4 条是第一次完全没意识到的:不只是文字,截图同样是证据

处置方式是改而不是删(保住已有的互动数据):7 张配图全换成纯设计干货卡,零产品 UI;正文改成 640 字纯干货,自检不含「微信/小程序/App/关注/搜一下」。

电车那边的小红书笔记迭代了三次:首发 → 竞品文案调研后重发 → 确认正式名后删除重发(小红书图文笔记发布后不能换图,只能改文字)。删掉的那条有 72 曝光、5 赞、2 收藏、1 分享。

做竞品文案调研时(7 个关键词、171 条笔记、13 篇正文)发现一个规律:头部笔记全是车主晒真实(1747 / 1500 / 1026 / 707 赞),同类小程序的推广笔记只有 45–126 赞;高赞标题的共同点是「有具体对象和数字,一句自夸都没有」。

调研数据里最诱人的做法是把标题直接写成「一年充电花了 1068 元」——这个没做,因为那个数字是灌进去的演示数据,用第一人称写具体金额就是事实性误导。正文和配图都标注了「示例数据,不是真实」。

结论很现实:对个人号来说,合规路径只剩「内容涨粉 → 用户主动私信 → 私信里答复」,笔记本身不能再带任何钩子。

三个平台的打法完全不同

小红书知乎V2EX
读者车主/潜在用户搜索问题的用户程序员
驱动封面 + 数字答准问题技术实现的真实性
讨厌广告腔AI 味营销腔、夸大
流量推荐流,3-7 天搜索长尾,能吃几年社区讨论

在 V2EX 要做的不是「推广」,而是「分享我怎么做的」——功能列表在那里没人看,技术取舍和踩坑才是内容。这篇博客的思路其实也是从这里来的。

实际发帖时又撞了一串平台规则:帖子因为标题里带「微信小程序」被自动归到「微信」节点,得在 10 分钟编辑窗口内手动移到「分享创造」;回复区放图片时,只有 imgur 域名的链接会被渲染成图片,其他图床的链接会被服务端主动破坏成纯文本(在 [ ]( ) 之间插一个空格);而 V2EX 自带的图床上传需要先充值。最后的落地方案是:正文配图走 GitHub + jsDelivr,小程序码以回复形式附在 imgur 直链上。

微信搜一搜

名称、简介、服务类目、页面标题都是可被搜索的字段,「搜一搜」是零成本入口。但前提还是那一条:先完成微信认证

六、复盘

1. AI 结对最擅长的不是写代码,而是把一件事推到闭环。

单看写代码,AI 的产出需要逐行审。但它在「查文档、试错、跑验证、改配置、写文档、盯部署」这些环节上的价值远超预期。上面那些踩坑记录,大部分是它自己发现并记下来的。

2. 真正的对手是平台规则,不是技术难度。

域名白名单、命名审核、类目资质、认证要求、环境共享限制、小红书引流判定——这些没有一条能靠写代码解决,但它们决定了产品能不能上线、能不能被搜到、能不能被分享。

3. 断言要有「打脸」的能力。

这一周被自己的断言打脸了至少三次:假 canvas 测不出纵向溢出、像素断言栽在 Display P3 色彩空间、E2E 拦截器自己有 bug 导致「全绿但什么都没验证」。先加断言,再被断言打脸,是唯一能让验证体系真正可信的路径。

4. 数据安全要靠「默认拒绝」。

那次数据丢失事故的根本教训不是「云函数写错了」,而是破坏性操作默认放行。改成「默认拒绝 + 显式授权」之后,同一类事故就不可能再发生。这个原则在服务端同样适用。

5. 不知道的事,不要编。

AI 在医学规则上的自我克制,是这个项目里我最认可的部分。一个育儿工具如果为了「功能看起来更全」而编造接种间隔或用药建议,风险是不可接受的。宁可让用户去问专业的人,也不要给一个看起来专业但来源不明的答案。

6. 未验证的面积,不能再扩大。

功能堆到一定程度,用户自己按下了刹车——先补齐真机验证,再谈新功能。这是整个项目里最正确的决定之一。

七、还没修完的地方

如果只写「做完的部分」,这篇复盘就失真了。下面是记录里明确留着、但截至写下这些字时还没收口的尾巴:

  • 电车小程序的导航栏标题和导出文件名里,还写着旧名「用车小助手」,只在外部文案里统一成了「电车车主小助手」
  • 项目 README 里那句「本应用不采集用户个人信息,无需填《用户隐私保护指引》」与 2.0.0 实际提交的「采集用户隐私」声明矛盾,需要一起改掉
  • 「我的」页面写「不联网」,但油价是实时联网获取的,这个表述不准确
  • 宝宝小程序 2.0.1 的审核结果始终没查成——后台版本管理页太重,自动化连续超时,加上笔记本电池只剩 1%
  • 宝宝小程序配图里的功能(夜间模式、字号调节、补种计划)可能超前于线上已发布的版本,存在「货不对板」的风险

这些都是小事,但它们在记录里被反复提起过三次,说明**「知道该改」和「真的去改」之间还有一段距离**——这段距离不会因为用了 AI 而自动消失。

八、体验一下

电车车主小助手 小程序码

电车车主小助手:电车充电记账、峰谷电价、电池健康与油电对比。

我的宝贝-宝贝生活记录 小程序码

我的宝贝-宝贝生活记录:宝宝疫苗接种时间表、漏种补种与成长记录。

两个都是纯工具,不登录、不要手机号、没有广告。电车的数据只存在你自己手机上,宝宝的数据只有推送调度集会上云。

有问题或者建议,欢迎在评论区聊。

相关文章

精彩推荐