Files

255 lines
9.0 KiB
Markdown
Raw Permalink Normal View History

2026-05-21 16:26:58 +08:00
# 恢复邀请体系并新增兑换卡密系统
## 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`