ENZH
和 AI 讨论这篇文章
ChatGPTClaude

盘盘猫开始算生意账了

Day 20 到 Day 23 这四天基本都在赶里程碑,正式交付了三个,积分经济、每日运势 Hub、PostHog 数据分析。四天一共合了 17 个 PR,166 次 commit。这几天想得比较多的是转化和留存,感觉开始有点算生意账的意思了。

盘盘猫冲过三个里程碑旗帜的马拉松赛道盘盘猫冲过三个里程碑旗帜的马拉松赛道

一个人也开始认真写 PR 了

这四天我开始按里程碑来做。每个里程碑都是一块完整、能交付的东西,做完以后能说清楚前后差在哪。PR 也是从这时候开始认真写的。

一个人给自己写 PR 图什么?对我来说主要图三件事,把当时想干什么记下来,留一份能往回查的改动历史,还有逼自己想清楚这次到底要交付什么、为什么要做。三件里最要紧的是最后那件,前两件算顺带的。

每个 PR 的描述都按固定格式写,有摘要,有改动表格,还有带复选框的测试计划。写的时候是有点麻烦,但三周以后你想搞明白「当时为什么改这个」,这些东西是实打实地有用。

M1 积分经济,100 个文件

M1 要做的是把「免费用」改成「免费试 + 付费用」。积分逻辑本身没什么技术含量,就是加加减减,这次费劲的全是边上的事。

匿名用户怎么合并

新用户一进来就是一个 Supabase 匿名账户,不用注册,能浏览,能用免费积分,也能保存测算结果。等他哪天想登录了,不管走 Google OAuth、邮箱还是兑换码,他的数据都得无缝合并过去,积分余额、测算记录、聊天历史、推荐关系,一样都不能丢。

匿名账户登录时,积分、记录、聊天历史、推荐关系整批无缝合并进登录账户,一样都不丢匿名账户登录时,积分、记录、聊天历史、推荐关系整批无缝合并进登录账户,一样都不丢

兑换码这条路本身就是个 state machine:idle → checking → redeeming/logging_in → success/error。RedeemCodeInput 组件会自动把输入格式化成 PPM-XXXX-XXXX,整个生命周期都由它处理。这里有个设计我觉得还挺巧,匿名用户输了兑换码,后端直接把这个码设成匿名账户的密码,下次登录就用这个码。

后来 PR #103 还修了一个数据库约束漏项的 bug,liunian 这个应用类型没写进 llm_costs_app_check 约束,生产环境的 INSERT 直接失败。这种 bug 挺难受的,只在某个功能的某条路径上才炸,平时完全看不出来。

跨标签页积分不同步

这个 bug 是这么出来的。用户在一个标签页买了积分,切到另一个标签页,余额还是旧的。他以为没买成,又买了一次,钱就花了两遍。

解决办法是用 Supabase 的实时订阅。每个标签页都盯着积分变动,任何一个标签页扣了或者加了积分,其他标签页一秒内就同步过来。听着简单,但订阅的生命周期得处理对,组件挂载时订阅,卸载时取消,标签页休眠以后还得重连。细节不少,坑基本都在生命周期上。

两个标签页各自订阅积分变动,一个标签页扣或加积分,另一个一秒内同步,避免误以为没买成而重复付款两个标签页各自订阅积分变动,一个标签页扣或加积分,另一个一秒内同步,避免误以为没买成而重复付款

5 种升级提示

UpgradePrompt 组件有 5 种触发类型,每种对应的用户状态都不一样:

  • 测算到一半积分用完(最着急,也最想买)
  • 看每日运势时余额不够(不太着急,先让用户有个印象)
  • 测算做完、正满意的时候(心情好,适合顺势多卖一点)
  • 推荐提示(社交场景,包装成「送礼」)
  • 第一次发现新功能(出于好奇,先试用再转付费)

提示有卡片和横幅两种样式,还有 24 小时的关闭冷却期,用户关掉了就一天之内别再弹,不然会觉得被骚扰。

M2 每日运势 Hub,又是 100 个文件

算命这类产品天生是有事才来,用户带着问题来,拿到答案就走了。每日运势 Hub 就是为留存做的,给用户一个每天回来的理由。Hub 里放了五张卡片,八字日柱运势、星座运势、每日塔罗牌、黄历、占卜引导,每张卡都有自己的 CSS 主题。

内容全部预生成

这里做了个挺重要的决定,内容不在用户打开时现算,北京时间午夜的 cron 任务会提前生成好,用户打开直接读现成的。/api/cron/daily-content 这个 endpoint 用 Gemini 生成八字和星座运势,存进 daily_content 表,7 天前的数据自动清掉。cron endpoint 比对密钥用的是常量时间的 XOR,这是安全审计提出来的。另外还按 IP 做了 rate limit(30 次/分钟),时区统一按 Asia/Shanghai 算。

这样用户早上 8 点打开 Hub,内容已经在那了,不转圈,直接出来。感觉用户判断「这产品靠不靠谱」,很多时候就看这种地方,是一下就开,还是要转 3 秒。

午夜 cron 提前把内容生成好存下,用户早上打开直接读现成的,秒开不转圈,而不是打开时现算等三秒午夜 cron 提前把内容生成好存下,用户早上打开直接读现成的,秒开不转圈,而不是打开时现算等三秒

占星模块顺手重构了

同一个 PR 里还把占星模块的国际化重构了。一份 347 行的三语字典(zh-CN/zh-TW/en),行星、星座、相位、宫位都在里面,外加 70 多个结果页面的字符串。星盘轮盘重新画了一版,暗色底配金色,有度数刻度线,行星和星座标签是中文的,还有能交互的提示框。星盘的计算和布局函数写了 78 个测试盖住。

合盘持久化

新加了一张 synastry_readings 表,出生信息加密存储,保存、加载、聊天整条流程都通了,历史记录的 API 也接上了。加密这块没得商量,因为合盘测算里装的是两个人的出生信息。

M3 接 PostHog,11 个文件

M3 是接 PostHog。兑换码的事件追踪放在 after() 里做,这样不会卡住兑换的响应。顺手还清掉了旧的管理路由,它们已经被管理后台取代了。三个里程碑里这个规模最小,但用处不小。之前用户在产品里干了什么,全靠猜,接上以后就能看到了,反馈这个环算是闭上了。

转化、留存这些事

这四天想得比较多的是转化漏斗、留存钩子、日活参与、推荐激励这些东西。这些都是生意上的问题,但反正最后都得靠代码来解。转化靠那 5 种升级提示,留存靠每日运势 Hub,还是那句话,给用户一个每天回来的理由,PostHog 负责把这些变成看得见的数字。留存这件事,这次算是第一次认真想了一遍。功能清单还在那儿,慢慢排。

和 AI 讨论这篇文章
ChatGPTClaude

订阅更新

新文章发布时发到你的邮箱,不发别的。


© Xingfan Xia 2024 - 2026 · CC BY-NC 4.0