Files
2026-05-21 16:26:58 +08:00

255 lines
9.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 恢复邀请体系并新增兑换卡密系统
## 1. 目标
在现有积分与支付体系上,恢复“我的邀请”业务闭环,并新增面向运营发放的卡密兑换体系。该任务覆盖协议、后端、web 前端、数据库迁移、运营脚本与审计留痕。
## 2. 当前现状(已确认)
### 2.1 邀请体系
- 后端当前只有 `GET /api/v1/invite/me`,返回 `{ code, used_count }`
- `web/` 当前没有邀请页或卡密兑换入口,但已有 `SettingsPage``StorePage``api.ts``resources.ts` 等可复用页面与资源层。
- 注册时数据库 trigger `initialize_profile_and_invite_code_on_signup()` 会:
- 为新用户生成自己的邀请码;
-`auth.users.raw_user_meta_data.invite_code` 合法,则给对应 `invite_codes.used_count + 1`
-`profiles.referred_by` 写成邀请人的 `profiles.id`
- 当前邀请只记录“被使用次数”,不记录逐个受邀人的充值达成状态,也没有邀请奖励发放逻辑。
### 2.2 积分与支付体系
- 当前积分账本 `points_ledger` / `points_audit_ledger` 支持 `register / consume / adjust / purchase / refund`
- 支付套餐当前定义在 `backend/src/core/config/static/packages/mapping.yaml`
- `new_user_pack`starter
- `starter_pack`
- `popular_pack`
- `premium_pack`
- Apple IAP 与 Creem 支付成功后,现有代码会写入积分账本与积分审计账本。
### 2.3 审计与卡密
- 当前仓库没有通用 `audit_logs` 或同类系统审计表落地实现。
- 当前没有卡密表、卡密生成脚本、卡密兑换接口或兑换 UI。
## 3. 用户要求(原始需求整理)
### 3.1 邀请恢复
- 恢复此前“藏起来”的邀请能力。
- 允许用户绑定别人的邀请码。
- 绑定后不可解绑。
- 每个账号只能绑定一次。
- 受邀人绑定邀请码后第一次 Creem 充值成功后:
- 邀请人获得奖励积分;
- 被邀请人获得奖励积分。
- 奖励积分值必须通过环境变量配置,当前目标值为 `40`
### 3.2 我的邀请页展示
- 能看到邀请人数。
- 能看到每个受邀关系对应奖励是否到账。
- 用户给出的目标示例是:页面应区分“已邀请人数”“已达成绑定后充值人数”“未达成绑定后充值人数”,以及奖励到账情况。
### 3.3 卡密系统
- 覆盖除“新手专享包”以外的三个套餐。
- 按价格从低到高生成卡密数量:
- 最低价套餐:100 张
- 中间套餐:40 张
- 最高价套餐:20 张
- 生成脚本放在 `infra/scripts` 下,由触发脚本执行。
- 生成一份 Excel,包含每个卡密及其对应套餐信息。
- 数据库允许新增表,用于分析卡密、套餐与激活状态。
- 在“我的邀请”页面下新增“兑换卡密”入口,点击弹窗输入卡密。
- 兑换成功后,显示“已激活某某套餐,获得 xx 积分”。
- 积分流水表与系统审计表都要记录卡密兑换链路。
## 4. 需求拆解
### 4.1 邀请业务数据补全
现有 `profiles.referred_by` 只能表示“我被谁邀请”,`invite_codes.used_count` 只能表示“邀请码被使用几次”,都不足以支撑:
- 单次绑定约束;
- 绑定后 Creem 充值达成判断;
- 奖励幂等发放;
- 页面按受邀人维度展示达成状态。
本任务需要新增显式邀请关系表,至少能表达:
- 邀请人用户 ID
- 受邀人用户 ID
- 绑定时使用的邀请码;
- 绑定时间;
- 是否已完成绑定后 Creem 充值;
- 绑定后 Creem 充值对应支付流水 ID;
- 邀请人奖励是否已发放;
- 受邀人奖励是否已发放;
- 对应账本 event_id / 审计事件 ID
- 幂等字段与唯一约束。
### 4.2 邀请奖励触发
触发点应绑定在“绑定邀请码后第一次 Creem 充值成功”这个业务事件,而不是注册时:
- Apple IAP 成功入账;
- Creem 支付成功入账;
- 绑定后 Creem 充值成功判定必须以 `creem` 交易表中的成功记录为准。
已确认规则:
- “绑定邀请码后第一次 Creem 充值成功”仅指真实付费购买成功;
- 必须在 `creem` 交易表存在成功记录,才算邀请绑定奖励达成;
- 卡密兑换不算作邀请绑定奖励达成;
- 邀请奖励只发一次,且邀请双方各一次。
### 4.3 邀请绑定入口
当前注册 trigger 支持“注册时带邀请码”,但需求要求恢复“绑定别人的代码”,且绑定后不可解绑、只能绑定一次。因此需要新增应用层接口,而不是只依赖注册 trigger:
- 绑定邀请码接口;
- 查询我的邀请详情接口;
- 接口错误码与前端文案;
- 明确禁止重复绑定、禁止绑定自己的码、禁止绑定不存在或失效的邀请码。
### 4.4 卡密体系
需要新增面向运营的可追踪卡密:
- 卡密主表;
- 套餐快照字段;
- 激活状态、激活人、激活时间;
- 生成批次;
- 导出字段;
- 幂等兑换保护。
建议卡密兑换本质上走“积分入账 + 审计 + 系统操作日志”一条完整链路,不直接绕过现有积分服务。
## 5. 协议与实现范围
### 5.1 协议文档(代码前必须更新)
以下协议需要先更新,再改实现:
- `docs/protocols/invite/invite-protocol.md`
- `docs/protocols/common/user-points-chat-data-protocol.md`
- `docs/protocols/common/http-error-codes.md`
- 如新增兑换接口,补充 `docs/protocols/points/points-balance-protocol.md` 或新增兑换协议文档
### 5.2 后端
- Alembic 迁移:
- 邀请关系表
- 卡密表
- 如采用通用系统审计表,则新增审计表
- `core.config.settings`
- 新增邀请奖励积分环境变量配置
- 邀请服务:
- 绑定邀请码
- 查询我的邀请详情(不仅仅是 `used_count`
- 绑定后 Creem 充值奖励发放
- 支付服务:
- Creem 绑定后 Creem 充值成功时触发邀请奖励检查
- 卡密服务:
- 兑换接口
- 幂等、校验、入账、审计
- 审计:
- 积分审计账本落地卡密兑换
- 系统审计表落地邀请绑定、邀请奖励发放、卡密生成、卡密兑换
### 5.3 前端(Web
- 在现有 `web` 设置体系中新增“我的邀请”入口或子页面:
- 绑定邀请码
- 展示我的邀请码
- 展示邀请人数 / 达成绑定后充值人数 / 待达成人数
- 展示逐个受邀人的奖励状态
- 在“我的邀请”下新增“兑换卡密”
- 点击弹窗输入
- 成功后提示并刷新余额 / 邀请数据
- 更新 web 端本地化文案、API 调用与资源失效逻辑
### 5.4 Infra / 运营
- 新建 `infra/scripts` 下卡密生成脚本
- 支持一键生成三档卡密
- 导出 Excel
- Excel 至少包含:
- 卡密
- 套餐编码
- 套餐名称/档位
- 对应积分
- 生成批次
- 是否已兑换
- 兑换人
- 兑换时间
## 6. 约束与实现原则
- 不加兜底分支,不用静默降级来掩盖绑定失败、绑定后 Creem 充值奖励失败或卡密兑换失败。
- 绑定邀请码必须是强约束:
- 一人最多绑定一次;
- 绑定后不可解绑;
- 禁止自绑定。
- 邀请奖励与卡密兑换都必须走幂等事件 ID。
- 积分账本与审计账本必须保持一致。
- 若新增系统审计表,不能替代 `points_audit_ledger`,而应补充业务操作审计。
## 7. 已确认口径
### 7.1 邀请页展示口径
用户已确认示例应为:
- 邀请了 `3` 个人;
- 奖励到账进度为 `80/120`
- 表示其中 `2` 个人已完成绑定后 Creem 充值,`1` 个人未完成。
因此页面至少需要稳定表达:
- 已邀请人数;
- 已达成绑定后充值人数;
- 未达成绑定后充值人数;
- 已到账邀请奖励 / 总可达邀请奖励。
按当前确认,若奖励环境变量值为 `40`,则:
- 已到账邀请奖励 = `已达成绑定后充值人数 * 40`
- 总可达邀请奖励 = `已邀请人数 * 40`
### 7.2 绑定后 Creem 充值与卡密口径
- 卡密兑换不算充值成功。
- 邀请绑定奖励达成必须以 `creem` 成功交易记录为准。
## 8. 实施清单
- [ ] 更新邀请 / 积分 / 错误码协议文档
- [ ] 设计邀请关系表、卡密表、系统审计表
- [ ] 增加邀请奖励积分环境变量配置
- [ ] 实现邀请码绑定接口与查询接口
- [ ] 在 Creem 成功支付链路接入绑定后 Creem 充值邀请奖励
- [ ] 实现卡密生成脚本与 Excel 导出
- [ ] 实现卡密兑换接口与账本/审计入库
- [ ] 完成 web 邀请页与兑换弹窗改造
- [ ] 增加后端 / web 回归测试
## 9. 建议的相关文件
- 后端:
- `backend/src/v1/invite/**`
- `backend/src/v1/points/**`
- `backend/src/v1/payments/**`
- `backend/src/core/config/settings.py`
- `backend/alembic/versions/*`
- Web
- `web/src/components/SettingsPage.tsx`
- `web/src/lib/api.ts`
- `web/src/lib/api-routes.ts`
- `web/src/lib/resources.ts`
- `web/src/i18n/utils.ts`
- 协议:
- `docs/protocols/invite/invite-protocol.md`
- `docs/protocols/common/user-points-chat-data-protocol.md`
- `docs/protocols/common/http-error-codes.md`