Blizzard
|
07955ddf07
|
feat(auth): 微信扫码登录后端 —— 网页授权 + ticket 轮询
服务号「植趣 ZeeQ」已认证,走网页授权(snsapi_base,只拿 openid、用户无感),
不接管消息推送,副作用最小。
流程:PC 建 ticket → 二维码指向 /wx/mp?t= → 用户微信扫码 → 302 到微信授权页 →
回调 /api/v1/wx/mp/callback 用 code 换 openid → 找/建用户 → ticket 置 authorized →
PC 轮询 /wx/mp/poll 拿到 authorized → 签发 JWT。ticket 一次性消费防重放。
- 配置(appid/secret/base_url)后台可改,secret AES 加密入库,与微信支付同一套 secrets;
- ticket 存 Redis(短 TTL),无 Redis 时回退进程内内存(本地单实例可用,生产必须有 Redis);
- User 加 wechat_openid。**部分唯一索引**(WHERE openid <> '')而非普通唯一:
存量邮箱用户该列是空串,普通唯一索引会让多个空串互撞、AutoMigrate 直接失败
—— 与之前 NULL 余额同类的坑,这次提前避开。
单测覆盖:授权 URL 拼接(含 #wechat_redirect 锚点必须在末尾)、secret 加密往返、
建号/查号、空 openid 不误命中存量用户。微信 API 调用依赖公网回调,本地测不了,
留待部署后真机扫码。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-21 08:44:00 +08:00 |
|
Blizzard
|
1ee1e87371
|
fix: 状态/用量回写升级 JetStream 持久 —— 堵住漏账(core NATS fire-and-forget)
问题:usage(计费)/status 回写走 core NATS,网关离线/慢消费者/NATS 抖动期间
dispatcher 发的事件直接丢——任务照跑照烧 token,但这次计费凭空消失(漏账),且零重试零对账。
(对比:提交/审批/入库本就 JetStream 持久,唯独回写是 best-effort。)
修复(照 tasks/approvals 套路):
- 新增 JetStream 流 SUNDYNIX_USAGE(MaxAge 72h) / SUNDYNIX_STATUS(24h),捕获 usage.task/status.task。
- PublishUsage/PublishTaskStatus 改 js.Publish(同步等 stream ack);dispatcher+gateway 启动各自 ensure 流。
- ConsumeUsage/ConsumeTaskStatus 持久消费者 + 显式 ack:落库成功 Ack、失败 Nak 重投自愈、脏数据 Term。
- 幂等保证 at-least-once 安全:usage_event.task_id 唯一 + 门控;SaveUsageEvent 返回 inserted,
仅新插入才累计 Redis 日计数(非幂等旁路,防重投重复累加);UpdateTaskStatus 按 task_id 覆盖幂等。
live 验证(复现原漏账场景):提交任务→立刻杀网关→dispatcher 跑完把 usage 发进持久流
(网关离线,usage_event=0 但流积压 1 条=钱没丢)→重启网关→自动补消费:任务 done、
usage_event 补上、公司A 余额扣 0.098、消费者 num_pending/ack_pending 归零。旧设计下这笔会永久丢失。
eval 回写仍 core NATS(仅观测,低价值,暂不改)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-09 17:07:31 +08:00 |
|
Blizzard
|
f6ea03b34b
|
feat(gateway): GET /me/usage —— 用户自己租户的用量明细(余额+趋势+最近消耗)
面向用户口径(非 admin,受插件按请求 ctx 租户自动隔离):返回积分余额 +
credit_enforce + 按天消耗趋势 + 区间合计 + 最近 10 条消耗明细。复用
UsageTrend/TenantBalance,新增 RecentUsage(按 tenant 取近 N 条 usage_event)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-08 09:31:12 +08:00 |
|
Blizzard
|
e2fc2d366c
|
feat(gateway): 计费规则可后台配置 —— token→积分汇率(DB) + 每模型积分权重
让「扣费按规则扣」的规则真正可后台热调(此前汇率是 env、积分权重无接口):
- sundynix_setting KV 表 + GetSetting/SetSetting;TokensPerCredit 改为
DB 设置优先 → env 回退 → 1000,SaveUsageEvent 按 ctx 读,改完即对后续任务生效。
- Pricing.credit_weight 纳入 UpsertPricing + ListPricing/SavePricing API。
- GET/PUT /admin/billing-config(token→积分汇率)。
live 验证:UI 存汇率=500 → billing-config/DB=500 → 新任务 credits_micro=214000
=107tok/500×1e6,规则→扣费联动精确成立。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-07 13:26:20 +08:00 |
|
Blizzard
|
d058a63434
|
feat(gateway): SaaS P2 计量·增量2 —— 积分账本 + 物化余额 + 用量 rollup
- credit_ledger(append-only):grant/usage/adjust 分录,扣量/充值的事实源。
- tenant.credit_balance_micro:物化余额(= 账本之和),用量扣、充值增。
- usage_rollup:租户/天 upsert 累加(配额/账单读一行,不扫明细)。
- 消费 usage_event 一个事务内:落明细 → applyUsageCredit(账本负分录+扣余额)
→ upsertRollup(累加)。幂等锚在 usage_event.task_id 唯一:RowsAffected==0(重投)
则跳过账本/余额/rollup,绝不重复计费。软扣:余额可为负(不拦,硬闸留 P4)。
- GrantCredits 充值/发放 API(记 grant 分录+增余额;增量3 admin 接)。
live 验证:ledger 负分录(ref=task_id) / 余额递减 / rollup 两任务累加(count=2,tok/credits求和)
/ **balance==seed+SUM(ledger) 不变量成立**(物化余额 == 账本真值)。
增量3(GET /admin/usage 趋势+余额)待做。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-07 11:26:27 +08:00 |
|
Blizzard
|
d032c198c8
|
feat: SaaS P2 计量·增量1 —— 用量按租户落持久明细 + 积分/成本折算
链路打通 tenant → 计费事实源:
- 契约:Task.Meta 加 MetaTenantID;UsageEvent 加 TenantID。
- 提交:网关 task.Meta[MetaTenantID]=tenantID(c);dispatcher emitUsage 带租户。
- 明细表 sundynix_usage_event(追加式,task_id 唯一→幂等防重投重复计费):
tenant/owner/model/tokens + credits_micro + cost_micros。
- 折算:credits=total_tok/TOKENS_PER_CREDIT×credit_weight(token 基准,设 1 即 token 直计);
cost 按 Pricing 折算;Pricing 加 credit_weight 列(每模型积分权重,缺省 1)。
模型名空则回退激活 chat 模型(近似,忽略 failover 备用模型,已在设计标注)。
- 网关 SubscribeUsage 折算落明细(保留 Redis 日计数作快速配额校验)。
live 验证:提交任务→一行 usage_event,tenant 匹配用户租户、
credits=89tok/1000×2×1e6=178000 微积分、cost=45/1000×1+44/1000×2=133000 微元 CNY,
折算数学与幂等键均正确。
设计见 SAAS_P2_DESIGN.md。增量2(credit_ledger 余额软扣 + rollup)待做。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-07 10:54:29 +08:00 |
|