feat(billing): 完成计费正确性 v2 闭环 #10

Merged
chengcheng merged 13 commits from codex/billing-v2 into main 2026-07-21 11:00:21 +08:00
Owner

变更摘要

  • 以 Gateway PostgreSQL 钱包为唯一账务事实源,统一估价、最大候选冻结、计价快照与最终结算
  • 增加独立计费状态、异步结算 Outbox、幂等重试、人工复核与管理端处理界面
  • 增加生成请求 Idempotency-Key、执行租约和上游提交状态保护,避免重复任务、重复调用和重复扣费
  • 前端参数变化后 350ms 即时估价,取消旧请求并阻止乱序响应或陈旧估价放行生产提交
  • 使用 9 位十进制定点金额,补强显式免费、规则优先级、Token 别名、视频 5 秒单位、动态权重与溢出校验

数据库与兼容性

  • 新增迁移 0069_billing_correctness_v2.sql;未修改历史迁移
  • 历史已扣费任务只分类为 settled,不产生新扣款
  • 历史成功未扣费任务进入 manual_review,由 Manager 明确确认后才结算
  • 失败任务遗留冻结进入 release 队列;上游结果不明保留冻结并进入人工复核
  • 新钱包约束先以 NOT VALID 落地,存量清理后再由后续迁移验证

风险控制

  • 上游提交状态不明时禁止租约接管后自动重放
  • 任务成功与计费状态相互独立;结算失败不覆盖成功结果
  • 管理端人工复核动作需要确认、Manager 权限、Idempotency-Key 与审计记录
  • 可通过 BILLING_ENGINE_MODE=observe|enforce|hold 分阶段发布;回滚使用 hold,保留结算 Worker 处理已存在账务

验证结果

  • PostgreSQL 16 全新库迁移 0001-0069:通过
  • go vet ./...、go test ./...、go build ./cmd/gateway:通过
  • govulncheck ./...:0 个可调用漏洞
  • gofmt -l:无输出
  • pnpm install --frozen-lockfile、pnpm openapi、pnpm lint、pnpm test、pnpm build:通过
  • pnpm audit --audit-level high 与 --prod:无已知漏洞
  • docker compose config、镜像构建、迁移、流水线、SemVer 门禁:通过
  • 生产基线迁移安全检查:通过

发布顺序

  1. 精确 ci / verify (pull_request) 通过后合并
  2. 验证同一 main SHA 的 ci / verify (push)
  3. 创建稳定 SemVer 标签并验证 release-ci / verify-tag (push)
  4. observe 运行 24 小时,清理缺价与非法规则
  5. 排空运行任务后 10% enforce,再扩到 100%
  6. 任一账务异常立即切换 hold,并保留结算 Worker
## 变更摘要 - 以 Gateway PostgreSQL 钱包为唯一账务事实源,统一估价、最大候选冻结、计价快照与最终结算 - 增加独立计费状态、异步结算 Outbox、幂等重试、人工复核与管理端处理界面 - 增加生成请求 Idempotency-Key、执行租约和上游提交状态保护,避免重复任务、重复调用和重复扣费 - 前端参数变化后 350ms 即时估价,取消旧请求并阻止乱序响应或陈旧估价放行生产提交 - 使用 9 位十进制定点金额,补强显式免费、规则优先级、Token 别名、视频 5 秒单位、动态权重与溢出校验 ## 数据库与兼容性 - 新增迁移 0069_billing_correctness_v2.sql;未修改历史迁移 - 历史已扣费任务只分类为 settled,不产生新扣款 - 历史成功未扣费任务进入 manual_review,由 Manager 明确确认后才结算 - 失败任务遗留冻结进入 release 队列;上游结果不明保留冻结并进入人工复核 - 新钱包约束先以 NOT VALID 落地,存量清理后再由后续迁移验证 ## 风险控制 - 上游提交状态不明时禁止租约接管后自动重放 - 任务成功与计费状态相互独立;结算失败不覆盖成功结果 - 管理端人工复核动作需要确认、Manager 权限、Idempotency-Key 与审计记录 - 可通过 BILLING_ENGINE_MODE=observe|enforce|hold 分阶段发布;回滚使用 hold,保留结算 Worker 处理已存在账务 ## 验证结果 - PostgreSQL 16 全新库迁移 0001-0069:通过 - go vet ./...、go test ./...、go build ./cmd/gateway:通过 - govulncheck ./...:0 个可调用漏洞 - gofmt -l:无输出 - pnpm install --frozen-lockfile、pnpm openapi、pnpm lint、pnpm test、pnpm build:通过 - pnpm audit --audit-level high 与 --prod:无已知漏洞 - docker compose config、镜像构建、迁移、流水线、SemVer 门禁:通过 - 生产基线迁移安全检查:通过 ## 发布顺序 1. 精确 ci / verify (pull_request) 通过后合并 2. 验证同一 main SHA 的 ci / verify (push) 3. 创建稳定 SemVer 标签并验证 release-ci / verify-tag (push) 4. observe 运行 24 小时,清理缺价与非法规则 5. 排空运行任务后 10% enforce,再扩到 100% 6. 任一账务异常立即切换 hold,并保留结算 Worker
chengcheng added 10 commits 2026-07-21 10:25:09 +08:00
新增 ADR-002、计费流程说明和 0069 增量迁移,建立独立计费状态、结算 Outbox、显式免费与钱包约束。历史成功未扣费任务仅进入人工复核,不执行追扣。\n\n验证:迁移安全验证与 tests/ci/migrations-test.sh 通过。
新增 effective-pricing-v2、9 位十进制定点计算、显式免费校验和结构化缺价错误。估价与生产预处理覆盖全部可用候选,并按最大候选费用冻结;规则优先级为平台模型、平台、基准模型。\n\n同步计价契约和 OpenAPI,补充 Token 参数别名、视频五秒向上取整及缺价回归测试。\n\n验证:go test ./...、pnpm openapi、Web 测试与构建通过。
估价请求统一使用 350ms 防抖、AbortController 和请求序号,区分免费、计算中、价格不可用与失败状态,并展示候选冻结上限。价格未就绪时阻止生产提交。\n\n计价规则编辑器新增显式免费开关和 9 位价格步进。\n\n验证:Web 88 项测试和生产构建通过。
统一任务成功、Attempt 与结算 Outbox 的事务边界,增加多实例安全结算、人工复核、请求幂等与执行租约。钱包决策使用九位精确金额,并通过审计保护约束保留流水事实;同时补充管理接口、指标与 PostgreSQL 集成测试。
管理端支持按状态查看结算与释放记录,展示精确到九位的小数金额、错误分类和重试次数,并使用一次性 Idempotency-Key 发起审计化重试。
重新生成 OpenAPI,补充估价字段、任务计费状态、管理员结算查询与审计重试接口。
CI verify 启动 PostgreSQL 16、应用全部迁移并注入 AI_GATEWAY_TEST_DATABASE_URL,使钱包、Outbox、幂等和租约集成测试不再因缺少数据库而跳过。
PostgreSQL HTTP 集成测试验证估价新增字段且不创建任务、冻结余额或写流水,并验证非流式重放只执行一次、异请求冲突及流式重复冲突。
pnpm audit 新增报告 Nx 构建链中的 axios、brace-expansion 和 js-yaml 高危漏洞。通过最小 overrides 将其固定到已修复版本,并同步锁文件。\n\n影响:仅调整开发与构建依赖解析,不改变生产运行时计费逻辑。\n\n验证:pnpm install --frozen-lockfile、pnpm audit --audit-level high、pnpm lint、pnpm test、pnpm build 及仓库完整 CI 门禁均已通过。
fix(billing): 封住发布前计费竞态
ci / verify (pull_request) Failing after 8s
8beb8501fa
阻止上游提交状态不明的任务被租约接管后重复执行,并为人工复核保留可操作的结算记录。

将生产提交绑定到当前估价签名,统一复用预处理快照,并补强规则形状、定点溢出与历史规则兼容校验。

已通过 PostgreSQL 16 集成测试、Go 全量测试与静态检查、前端测试与构建、OpenAPI、依赖审计、镜像、迁移、流水线和 SemVer 门禁。
chengcheng added 1 commit 2026-07-21 10:34:19 +08:00
fix(ci): 为集成测试提供固定 Docker CLI
ci / verify (pull_request) Failing after 8s
b7bb9ed8d5
从固定 digest 的 Runner 镜像提取 Docker CLI 29.6.0,校验二进制 SHA-256 后通过只读工具链挂载给 Job。

同步 PR 与 Tag 工作流的版本探针,并增加流水线契约测试,避免 PostgreSQL 集成测试再次因缺少 docker 命令失败。
chengcheng added 1 commit 2026-07-21 10:37:03 +08:00
fix(ci): 允许复用固定摘要的 Runner 镜像
ci / verify (pull_request) Failing after 8s
3561efa7da
本地已存在完全相同 digest 的 Runner 镜像时跳过外部拉取,继续执行二进制校验与隔离探针;仅在镜像缺失时访问仓库。

避免 Docker Hub 瞬时不可达导致专用 CI Runner 无法恢复。
chengcheng added 1 commit 2026-07-21 10:46:00 +08:00
fix(ci): 使用隔离服务运行 PostgreSQL 集成库
ci / verify (pull_request) Successful in 11m30s
0aa9b3e88f
将 PostgreSQL 16 改为固定 digest 的 Actions service container,并通过专用 Job 网络向 Go migrator 和集成测试提供数据库。

移除 PR Job 对 Docker CLI 的依赖,继续禁止宿主及内层 Docker API 暴露;同步发布工作流、契约测试和镜像代理恢复说明。
chengcheng merged commit 1e55f7df8b into main 2026-07-21 11:00:21 +08:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: BCAI/easyai-ai-gateway#10