mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-14 03:52:26 +08:00
#4850 的用量刷新调度有三个问题,本次一并修复。 jsonpath .datetime() 直到 PostgreSQL 17 才接受 ISO-8601 的 Z 标识符, 而服务写入的快照时间戳全部是 UTC(即 Z 形式)。在 PG 14/15/16 上 ollamaCloudUsageParseRFC3339SQL 因此把 fetched_at / last_attempt_at / next_refresh_at 全部解析成 NULL,due 判定整条退化为 fail-open 分支: 每轮 20 个刷新额度被 id 最小的非 due 组占满,id 更大的组永远不会刷新—— 正是该 PR 声称修复的饥饿场景。项目文档声明支持 PG 14/15/16,而集成测试 harness 固定使用 postgres:18.1,因此现有测试无法发现。 修法是在送入 jsonpath 前把结尾的 Z 改写为 +00:00。仍保留 jsonpath 而不 直接 ::timestamptz,因为通过形状正则但日历非法的值(如 2026-02-30)需要 fail-open 成 NULL 而非中断整条查询。已在真实 PG 14/15/16/17/18 上验证 五个版本行为一致,且非法日历与垃圾输入仍正确 fail-open。 成功路径不再查阅 next_refresh_at,而 nextOllamaCloudUsageDelay 的 15 分钟下限正作用于该字段,导致同组对 ollama.com 的抓取下限从 15 分钟 降到一个 runner 周期。请求间隔略大于 debounce 的交互式流量(典型 Claude Code 用法)会把单组 24 小时抓取次数从 24-96 抬高到数百次。改为对成功路径 显式施加 fetched_at + OllamaCloudUsageMinFetchInterval 的下限,Go 与 SQL 两侧同步;空闲账号不再轮询这一主要收益不受影响。 debounce_minutes 与 interval_minutes 此前各自独立校验,因此 debounce >= interval 是合法组合;此时 min(lastUsed+debounce, fetchedAt+maxWait) 中的 debounce 项恒为死项,管理员配置被静默忽略。 改为在写入时拒绝该组合。 另修复 refreshAccount 中 ListOllamaCloudUsageGroupAccounts 的错误被 静默吞掉(违反 CLAUDE.md 禁止忽略错误):失败时回退到更窄的活动信号会 改变 due 语义,现在记录日志。 测试: - 恢复被删除的 7/8/9 位小数秒解析覆盖,并改写为可判别形式(断言"不应 返回",解析失败会落入 fail-open 而被捕获)。已验证该测试在 PG 15 上 无此修复时失败、有修复时通过。 - 新增 min fetch interval 下限与 debounce/interval 交叉校验的单元测试。 - integration harness 新增 SUB2API_TEST_POSTGRES_IMAGE 覆盖,使套件可 针对最低受支持版本运行。