Files
meida_backend/packages/billing
xsl 76a0502ea3 feat(billing): 任务换额度定稿闭环——claim 凭据校验(40311)+ 定稿 4 任务目录
- claim_task_bonus 在幂等快捷路径前做完成凭据校验:report_feedback 查当日 rp_feedback、first_report 查 succeeded rp_report,无凭据 40311 且不打流水;sign_in/share_report 不校验(产品决策:签到行为即领取,分享内测期接受端侧自报,hard_cap 锁死刷量收益)
- task_bonus_rules 默认值与 .env.example 同步产品定稿(产品方案 §3.2,2026-09-11):sign_in 对话+10/day、report_feedback 发型+2/day、share_report 换装+3/day、first_report 重生成+1/lifetime;下架 invite_friend/profile_complete
- billing/repo 新增只读凭据探测 has_feedback_between/has_completed_report(import-linter 禁 billing→report,直查 shared.models 的 rp_* 表,永远只读)
- 测试:test_task_bonus_eligibility 5 用例(40311 两分支/凭据后 200/40910/40410/零流水)

偏差说明:test_task_bonus 与 test_task_bonus_rules 断言数值随定稿更新(发放/幂等/封顶语义未动);quota.py docstring「占位值」说法顺手更正。
2026-09-12 00:23:43 +08:00
..

packages/billing/ — 配额与计量(V1)

⚠️ V1 不收费(TD-28)。本域在 V1 的职责是配额限制 + 计量, 不含任何支付、订单、购买、会员能力。

已实现

  • bl_quota_rule(规则配置化,改配置不发版,FR-BILL-04)
  • bl_quota(按 period_key 自然重置,无需定时任务清零)
  • bl_ledger(流水是真相,余额是缓存)
  • 预扣三段式 reserve → commit → refund(架构 §7.4,FR-BILL-05)
  • 服务端硬校验(FR-BILL-06);退还幂等(refund 键由 reserve 键派生)

架构约束(不可妥协)

V1 的配额账本与 V2 的点数账本必须是同一张表。 V1 只用 system_grant / consume / refund 三种 tx_type,V2 增加 purchase / gift。这样 V2 上 支付时不需要数据迁移,也不需要重写扣减逻辑。不要为了"V1 更简单"把表拆开。

为什么是预扣不是直接扣

长耗时任务可能失败,直接扣会产生「扣了额度没拿到结果」的客诉。V1 虽不涉及 金钱,用户对"次数被白扣"的敏感度不比扣钱低,而且 V1 没有客服退款兜底手段, 只能靠机制保证。

待实现

  • FR-BILL-03 任务奖励发放(签到/完善资料/反馈/邀请/分享,同任务同周期幂等)
  • 每日对账:余额由流水重算校验,不一致则告警。V1 就要做,否则 V2 上支付时 对账逻辑得从零开发且无历史数据验证。
  • 设备/账号/IP 三重限流(FR-BILL-06)
  • Redis 配额计数器 + PG 落账的两级结构(架构 §10)

文案约束(FR-BILL-07)

额度相关提示里不得出现任何价格、购买、会员、升级字样,只提供「等待恢复」 与「做任务换额度」两条路径。tests/unit/test_response_envelope.py 会扫描全部 错误码文案。