构建产品
组织积分账本
选择产品如何计量用量,并安全地发放、消费、过期与退还组织共享积分。
已根据启动模板提交
2a1a04a验证。
积分是一种可选的产品打包方式,并非所有功能都必须使用。当一次方案内操作的成本可变,或客户购买的用量需要结转时使用积分;如果只需判断客户能否操作,使用简单的 entitlement 或 limit 即可。
需要做出的决定
| 问题 | 默认选择 | 可选方案 |
|---|---|---|
| 积分归谁? | 归组织所有,成员共享一个池 | 在保留组织账本的同时增加成员预算 |
| 如何保存余额? | 只追加流水 | 除非同时重建审计与重放保证,否则不要换成可变计数器 |
| 先消费什么? | 最早过期的发放 | 只有补齐过期测试后才更换分配规则 |
| 下游失败怎么办? | 追加关联原消费的退款 | 只有合同明确失败任务也计费时才保留扣款 |
积分属于组织,成员共享同一余额。账本只追加:不要更新或删除记录,也不要绕过 src/services/credit.ts 直接写 SQL。
发放会写入带唯一交易号、可选过期时间的正数行。消费在组织 advisory lock 内重放完整账本,优先使用最早过期的发放记录,仅在可用余额充足时写入负数行。一次消费可能拆成多个 :part:n 物理行,API 会合并为一笔逻辑交易;退款通过关联原消费的补偿行实现。
balance_after 是插入时的会计账本总额,不一定等于扣除过期记录后的当前可用额。请使用组织积分摘要获取可用、发放、消费和过期总量。
所有影响积分或金额的调用都要有稳定的业务幂等键。同一 key 调用两次只能产生一次账本效果,测试会验证 replay。订阅月度发放和 Stripe 履约也使用确定性交易号。管理端发放有上限并被审计。
新增付费功能时,在配置层计算成本,检查套餐 entitlement,通过积分服务消费,在领域记录保留根交易号,并在后续操作失败时追加退款。
当两个并发消费无法透支、相同业务 key 的重试只产生一次效果、过期发放不计入可用余额、UI 展示逻辑交易而非内部拆分行,且失败任务留下可审计的补偿退款时,积分功能才算完成。