feat: 金额 decimal 精确计费、failover 按失败类型封顶、渠道小时桶预聚合、分层守护测试

- 计费:19 个金额字段 float64→decimal.Decimal,DB 列保持 numeric(20,8) 零迁移;
  API 金额仍为 JSON number(MarshalJSONWithoutQuotes),前端零改动
- failover:保留时间预算,新增 OT_PROXY_FAILOVER_CAPS_NET/SERVER/RATE/QUOTA
  按失败类型封顶换渠道次数(429/配额类瞬时失败时间预算形同虚设)
- 预聚合:新增 usage_channel_hourlies(schema v10),记账事务内同步 upsert,
  长窗口渠道统计走桶不再扫明细,spent_last_30d 改扫 usage_daily,v10 一次性回填幂等
- 守护:internal/arch_test.go 用 go/parser 强制分层依赖(fail-closed)
This commit is contained in:
Sakurasan committed 2026-11-09 00:41:48 +08:00
1 parent 5d6e5bdb04
commit b2e500ff51
25 files changed
+841 -253

No files matched your search

+7
View File
@@ -38,6 +38,13 @@ OT_PROXY_MAX_BODY_MB=32
# 故障转移给"第二个及以后的渠道"留的时间预算(0=不限)。
# 首个渠道不受它约束——长回答本就要跑几分钟,但不能让坏渠道把客户端拖到 N×timeout。
OT_PROXY_FAILOVER_BUDGET=30s
# 按失败类型限制"换渠道"次数(0=不限):net=网络错误/超时、server=5xx、
# rate=429 限流、quota=余额/配额。429/配额类失败瞬时返回,上面的时间预算对它们
# 形同虚设,按次数封顶才有意义(如全渠道欠费时不至于把候选逐个打一遍)。
OT_PROXY_FAILOVER_CAPS_NET=4
OT_PROXY_FAILOVER_CAPS_SERVER=3
OT_PROXY_FAILOVER_CAPS_RATE=2
OT_PROXY_FAILOVER_CAPS_QUOTA=3
# 流式空闲多久补一行 SSE 注释心跳(0=关闭)。挂在 nginx/Cloudflare 后面时,
# 上游长时间不出字(长思考)会被对端的空闲超时掐掉,心跳用来续住这条流。
OT_PROXY_STREAM_HEARTBEAT=15s