duoqi-api/docs/gamification-server-plan.md

14 KiB
Raw Blame History

游戏化服务端实施计划

来源设计文档:docs/GAMIFICATION_DESIGN.md 创建时间2026-05-11 状态标记:[ ] 未开始,[~] 进行中,[x] 已完成,[!] 阻塞或需产品确认

目标

把第一版游戏化规则落到服务端可裁决、可持久化、可审计的实现中。客户端负责展示和交互,服务端负责挑战组、资源消耗、奖励结算、背包库存、周榜统计和广告恢复幂等。

当前差异

  • 当前挑战接口以单题为单位,设计要求一组挑战 5 题。
  • 当前每日挑战次数更接近“可挑战次数”,设计要求改为“每日高奖励挑战次数”,次数耗尽后仍可继续学习。
  • 当前等级为固定 400 XP 一级,设计要求 50 级分段曲线。
  • 当前已有红心、订阅、广告恢复 session、基础 XP、连对 XP 和排行榜底座,但还缺金币、道具、背包、任务、挑战组完成奖励和本周 XP 榜。
  • 当前排行榜仍按累计 XP 排名,设计要求按本周 XP 排名,每周一刷新。

执行原则

  • 先更新 src/db/schema.ts,再通过 bun run db:generate 生成迁移文件。
  • 服务端奖励统一通过一个奖励结算层发放,避免 UI 或单个 route 直接修改资源。
  • 所有资源变更必须有幂等边界或流水记录,尤其是广告恢复、购买、挑战完成和排行榜结算。
  • 保留现有 /v1/rewards/ad-recovery/session/v1/rewards/ad-recovery/complete 作为广告恢复主入口。
  • 调整公开接口后同步更新 docs/api-reference.md
  • 每完成一个阶段至少运行 bun run typecheckbun run test;涉及 lint 规则时运行 bun run lint

Phase G0规则常量与数据模型

# 任务 状态 验收标准
G0-1 梳理游戏化规则常量模块 [x] 新增集中规则定义覆盖红心、挑战组、XP、等级、金币、道具、广告恢复、周榜周期
G0-2 新增挑战组数据模型 [x] 支持 challenge session、session answers、组状态、正确数、完成时间、幂等提交
G0-3 新增钱包和道具库存模型 [x] 支持金币余额、道具库存、道具获得/消耗流水
G0-4 新增奖励流水模型 [x] 记录奖励来源、幂等 key、奖励快照、发放前后状态
G0-5 新增每日任务或每日进度模型 [x] 可统计每日首组挑战、每日任务完成、每日高奖励次数
G0-6 新增周 XP 统计模型或扩展周榜快照 [x] 可按自然周统计 XP支持每周一刷新和历史快照
G0-7 生成并提交数据库迁移 [x] db/migrations/ 包含 schema 变更,迁移文件不被 .gitignore 遗漏

Phase G1挑战组与答题结算

# 任务 状态 验收标准
G1-1 实现创建挑战组服务 [x] 一次返回 5 题,题目不泄露正确答案,绑定 track/node/chapter
G1-2 实现挑战组答题提交 [x] 单题提交可幂等记录,重复提交不会重复扣资源或发奖励
G1-3 实现挑战组完成结算 [x] 组内 5 题完成后统一计算完成奖励、全对奖励、主题节点进度和每日高奖励状态
G1-4 调整红心扣除边界 [x] 答错扣 1 颗Plus 用户不被红心阻断;新用户前 3 天最低保留 1 颗
G1-5 调整每日高奖励挑战次数 [x] 免费用户每日 3 组Plus 8 组或按产品确认无限;次数为 0 后仍可继续学习但高价值奖励降级
G1-6 更新挑战 API DTO [x] /challenges/next 或新增 session API 能表达组、题、组进度、资源状态
G1-7 添加挑战组测试 [x] 覆盖创建、答对、答错、重复提交、完成结算、资源不足和 Plus 分支

Phase G2XP、等级、连续学习和知识卡奖励

# 任务 状态 验收标准
G2-1 实现 50 级等级曲线 [x] Lv.1-50 按设计表计算,xpToNextLevel 准确,超过 50 级有明确封顶或溢出策略
G2-2 扩展 XP 奖励来源 [x] 支持普通题 10、困难题 15、看解析 3、完成挑战 20、全对 30、首次知识卡 15、每日任务、主题节点奖励
G2-3 修正连对奖励 [x] 3 连对 +55 连对 +1010 连对 +25并返回客户端可展示奖励
G2-4 将连续学习改为按挑战组完成计算 [x] 每天至少完成 1 组挑战才更新 streak不再依赖当天正确题数阈值
G2-5 实现连续学习里程碑奖励 [x] 3/7/14/30/100 天奖励可发放且不可重复领取
G2-6 实现每日首次进入送红心 [x] 每日首次 bootstrap 或专用 check-in 最多补 1 颗,不超过上限
G2-7 添加 XP/streak 测试 [x] 覆盖等级边界、首次知识卡、完成组奖励、全对奖励、看解析奖励、连续学习保护

验证记录2026-05-13G2-2 已通过 ./node_modules/.bin/tsc --noEmit./node_modules/.bin/eslint .bun 当前 shell 不在 PATH./node_modules/.bin/vitest run 启动阶段被 macOS 拒绝加载未签名的 @rolldown/binding-darwin-x64 原生 binding需修复本地依赖安装或签名后复跑。 验证记录2026-05-13G2-3 已通过 ./node_modules/.bin/tsc --noEmit./node_modules/.bin/eslint .;定向运行 ./node_modules/.bin/vitest run src/__tests__/services/progress/xp-service.test.ts src/__tests__/services/learning/challenge-service.test.ts 仍在启动阶段被同一个 @rolldown/binding-darwin-x64 原生 binding 签名问题阻塞。 验证记录2026-05-13G2-4 已通过 ./node_modules/.bin/tsc --noEmit./node_modules/.bin/eslint .;定向运行 ./node_modules/.bin/vitest run src/__tests__/services/progress/streak-service.test.ts src/__tests__/services/learning/challenge-service.test.ts 仍在启动阶段被同一个 @rolldown/binding-darwin-x64 原生 binding 签名问题阻塞。 验证记录2026-05-13G2-5 已通过 ./node_modules/.bin/tsc --noEmit./node_modules/.bin/eslint .;定向运行 ./node_modules/.bin/vitest run src/__tests__/services/progress/streak-service.test.ts src/__tests__/services/learning/challenge-service.test.ts 仍在启动阶段被同一个 @rolldown/binding-darwin-x64 原生 binding 签名问题阻塞。 验证记录2026-05-13G2-6 已通过 ./node_modules/.bin/tsc --noEmit./node_modules/.bin/eslint .;定向运行 ./node_modules/.bin/vitest run src/__tests__/services/learning/progress-summary-service.test.ts 仍在启动阶段被同一个 @rolldown/binding-darwin-x64 原生 binding 签名问题阻塞。 验证记录2026-05-13G2-7 已通过 ./node_modules/.bin/tsc --noEmit./node_modules/.bin/eslint .;定向运行 ./node_modules/.bin/vitest run src/__tests__/services/progress/xp-service.test.ts src/__tests__/services/progress/streak-service.test.ts src/__tests__/services/learning/challenge-service.test.ts src/__tests__/services/learning/progress-summary-service.test.ts 仍在启动阶段被同一个 @rolldown/binding-darwin-x64 原生 binding 签名问题阻塞。

Phase G3金币、商店和道具

# 任务 状态 验收标准
G3-1 实现金币发放服务 [x] 支持每日首组挑战 20、每日任务 30-80、升级 100、主题节点 50、宝箱 20-200
G3-2 实现宝箱奖励服务 [x] 支持基础概率、10 连对概率提升、高奖励次数耗尽后的概率降级
G3-3 实现道具库存服务 [x] 支持连胜护盾、双倍 XP 药水、爱心补给、提示羽毛的获得和消耗
G3-4 实现商店商品和购买接口 [x] 商品价格符合设计:提示羽毛 80、爱心补给 150、双倍 XP 250、连胜护盾 400、装扮 800-3000
G3-5 实现道具使用接口 [x] 爱心补给恢复满心,双倍 XP 药水 15 分钟生效,提示羽毛返回可排除选项,连胜护盾可保护断签
G3-6 更新 bootstrap/shop DTO [ ] 客户端能拿到金币、库存、可购买商品、广告商品、订阅权益
G3-7 添加金币/商店测试 [ ] 覆盖余额不足、重复购买、使用道具、药水时效、库存扣减和流水记录

验证记录2026-05-13G3-1 已通过 ./node_modules/.bin/tsc --noEmit./node_modules/.bin/eslint .git diff --check;定向运行 ./node_modules/.bin/vitest run src/__tests__/services/gamification/coin-service.test.ts src/__tests__/services/learning/challenge-service.test.ts 仍在启动阶段被 @rolldown/binding-darwin-x64 原生 binding 未签名问题阻塞。 验证记录2026-05-13G3-2 已通过 ./node_modules/.bin/tsc --noEmit./node_modules/.bin/eslint .git diff --check;定向运行 ./node_modules/.bin/vitest run src/__tests__/services/gamification/chest-service.test.ts src/__tests__/services/gamification/coin-service.test.ts src/__tests__/services/gamification-rules.test.ts 仍在启动阶段被同一个 @rolldown/binding-darwin-x64 原生 binding 未签名问题阻塞。 验证记录2026-05-13G3-3 已通过 ./node_modules/.bin/tsc --noEmit./node_modules/.bin/eslint .git diff --check;定向运行 ./node_modules/.bin/vitest run src/__tests__/services/gamification/inventory-service.test.ts 仍在启动阶段被同一个 @rolldown/binding-darwin-x64 原生 binding 未签名问题阻塞。 验证记录2026-05-13G3-4 已通过 ./node_modules/.bin/tsc --noEmit./node_modules/.bin/eslint .git diff --check;定向运行 ./node_modules/.bin/vitest run src/__tests__/services/shop/shop-service.test.ts src/__tests__/services/gamification/coin-service.test.ts src/__tests__/services/gamification/inventory-service.test.ts 仍在启动阶段被同一个 @rolldown/binding-darwin-x64 原生 binding 未签名问题阻塞。 验证记录2026-05-13G3-5 已通过 ./node_modules/.bin/tsc --noEmit./node_modules/.bin/eslint .git diff --check;定向运行 ./node_modules/.bin/vitest run src/__tests__/services/gamification/item-use-service.test.ts src/__tests__/services/gamification/inventory-service.test.ts 仍在启动阶段被同一个 @rolldown/binding-darwin-x64 原生 binding 未签名问题阻塞。

Phase G4广告恢复与订阅权益对齐

# 任务 状态 验收标准
G4-1 对齐广告恢复奖励到统一奖励服务 [ ] session complete 后通过统一奖励结算层发放,记录奖励流水
G4-2 确认恢复爱心规则 [ ] 免费用户广告恢复直接恢复至 5 颗,每日最多 3 次
G4-3 确认恢复高奖励挑战规则 [ ] 每次只恢复 1 组高奖励挑战,每日最多 3 次
G4-4 确认连续学习保护规则 [ ] 每 7 天最多广告恢复 1 次,当天补一次保护
G4-5 收敛旧恢复接口用途 [ ] 旧的直接恢复接口仅保留内部、测试或明确废弃,并在 API 文档中说明
G4-6 明确 Plus 分支 [ ] Plus 用户无需看广告;同入口返回订阅权益或已订阅原因,不消耗广告次数
G4-7 添加广告恢复回归测试 [ ] 覆盖 idempotency、过期、provider token 缺失、每日上限、Plus、重复 complete

Phase G5本周排行榜与周期结算

# 任务 状态 验收标准
G5-1 改造排行榜数据源为本周 XP [ ] 排行榜不再按累计 XP 排名,展示本周 XP
G5-2 实现每周一刷新逻辑 [ ] 自然周边界清晰UTC/本地时区策略写入代码注释和文档
G5-3 实现 20-30 人分组 [ ] 每个用户进入稳定榜组,分页和我的排名基于组内排名
G5-4 实现前三奖励结算 [ ] 周结算给前 3 名发金币、徽章碎片或头像框奖励,幂等执行
G5-5 暴露周榜元信息 [ ] API 返回 weekStart、weekEnd、nextRefreshAt、groupId、rank、rewardPreview
G5-6 添加排行榜测试 [ ] 覆盖周 XP 累加、分组、我的排名、周结算、重复结算

Phase G6API 文档、Admin 和运维

# 任务 状态 验收标准
G6-1 更新 docs/api-reference.md [ ] 文档只保留最终客户端契约,包含挑战组、奖励、商店、背包、周榜、错误码
G6-2 更新 docs/implementation-plan.md [ ] 将本计划作为 Phase 1d 或 Game Economy 阶段索引进去
G6-3 增加 Admin 配置或只读查看能力 [ ] 管理端至少能查看用户金币、道具、奖励流水、广告恢复记录
G6-4 增加 E2E 或集成测试 [ ] 覆盖游客登录、完成挑战组、广告恢复、购买道具、周榜查询
G6-5 增加定时任务入口 [ ] 周榜结算和订阅/资源周期任务有可部署入口,支持手动 dry-run
G6-6 完成最终验证 [ ] bun run typecheckbun run testbun run lint 通过或记录明确环境阻塞

推荐执行顺序

  1. G0 数据模型与规则常量。
  2. G1 挑战组会话与完成结算。
  3. G2 XP、等级、连续学习规则。
  4. G3 金币、道具、商店。
  5. G4 广告恢复接入统一奖励服务。
  6. G5 本周排行榜与周期结算。
  7. G6 文档、Admin、E2E 和运维入口。

需要产品确认的决策点

  • Plus 用户的每日高奖励挑战次数采用 8 组还是无限。
  • 等级达到 Lv.50 后是否继续累计 XP以及 xpToNextLevel 如何展示。
  • 宝箱概率和高奖励次数耗尽后的降级比例。
  • 排行榜前三奖励的具体数值:金币、徽章碎片、头像框是否第一版都上线。
  • 吉祥物装扮、头像框、称号是否第一版需要完整库存模型,还是先作为奖励流水中的展示型权益。

完成定义

  • 服务端可以独立裁决所有第一版游戏化资源和奖励。
  • 客户端不能通过直接改本地状态绕过红心、挑战次数、金币、道具和广告恢复限制。
  • 所有可重复触发的奖励都有幂等保护。
  • 所有资源变更可追踪来源和结果。
  • API 文档与真实路由、DTO、错误码保持一致。