Balance 服务

全局钱包模型

为什么 @downcity/services 按 user 维护余额,而不是按 town 拆很多份余额。

@downcity/services 的核心是:余额按用户维护,不按 town 维护。

也就是说:

  • user A 在 town X 消费
  • user A 在 town Y 消费
  • 扣的都是同一份全局余额

为什么这样更适合 Downcity

Downcity 的典型场景是:

  • 一套 City runtime 服务多个产品
  • 同一个用户可能在多个产品之间切换
  • 你希望这些产品复用同一套 AI 账户能力

如果余额再按 town 拆成很多份,用户体验和运营逻辑都会更碎。

town 还重要吗

重要,但它更适合出现在流水 metadata 里,而不是余额账户主键里。

比如一次扣费可以记录:

await balance.sub(ctx.user!.user_id, 10, {
  note: "agent chat",
  meta: {
    town_id: ctx.town?.town_id,
    model_id: ctx.variant?.id,
  },
});

这样你同时得到两件事:

  • 余额仍然是全局的
  • 历史记录里仍然知道这笔钱花在哪个 town

账户里保存什么

最小账户只需要:

  • user_id
  • balance
  • unit

这里的 unit 可以是:

  • credits
  • points
  • tokens

这种模型最适合什么场景

  • 多个产品共用一套 AI 能力
  • 你想做统一账户余额
  • 你不想把钱包切碎到每个 town 各算一份

继续阅读