AIAI SaaS

积分系统

批次、过期与 FEFO 扣减如何协作。

双表设计

  • credit_grant — 每次发放是一个批次,含 amountremaining 和可选 expiresAt
  • credit_transaction — 只增不改的流水账,直接展示给用户

余额恒等于 SUM(credit_grant.remaining),没有会漂移的缓存计数器。

过期机制

不同来源可以有不同有效期:注册赠分可能 30 天过期,购买的积分包永不过期。每日任务(默认走 GitHub Actions 定时)清零过期批次并写入 expiration 流水。

FEFO 扣减

消耗时优先扣最快过期的批次(First-Expired, First-Out),用户的积分绝不白白浪费。并发扣减由乐观锁 + 重试保护。

接入你自己的功能

import { consumeCredits, InsufficientCreditsError } from "@/credits/service";

try {
  await consumeCredits({
    userId,
    amount: 1,
    description: "我的 AI 功能",
  });
} catch (e) {
  if (e instanceof InsufficientCreditsError) {
    // 返回 402,引导用户升级
  }
}

人工调整

管理员可在用户表里加/扣积分——每笔调整都会带备注写入流水记录。