Skip to content

chore(sync): 精选 cherry-pick 上游 v0.2.12–v0.2.13 并保留 fork 定制 - #277

Merged
ranxi2001 merged 25 commits into
ranxi2001:productionfrom
akihitohyh:sync/upstream-v0.2.12-v0.2.13-selective
Oct 2, 2026
Merged

ranxi2001 merged 25 commits into
ranxi2001:productionfrom
akihitohyh:sync/upstream-v0.2.12-v0.2.13-selective

Conversation

@akihitohyh

@akihitohyh akihitohyh commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

解决的问题与行为变化

  • 触发条件 / 原行为:上游 2026-10-02 发布的 v0.2.12、v0.2.13 还没有同步(其中 axios 1.20.0 升级已由 production 4f651425a 单独引入)。production 缺少三项安全加固、Grok 交互式 CLI 身份对齐、TypeSafe / Jev System One 平台、充值优惠阶梯、账号优先级快捷调整和 API Key 按分组排序。
  • 修改后行为:cherry-pick 10 个上游 PR 共 19 条提交(每条保留 -x 来源;前 17 条按上游合并顺序,fix(billing): settle usage when the API key is deleted before billing completes Wei-Shaw/sub2api#7816 的 2 条追加在分支末尾),另加 4 个 fork 整合提交,以及合并 production 后把 fix: 完善 Key 删除后的结算与 WebSocket 撤销检查 #273 的计费做法换回上游的 1 个提交(见下)。主要变化:
    • 匿名订单查询限流:POST /api/v1/payment/public/orders/verify 按客户端 IP(按 server.trusted_proxies 解析)每分钟最多 20 次,超出返回 429;Redis 出错时放行,不影响正在付款的用户。
    • 邮箱验证码(注册、通知邮箱):每次比对前先用 Redis Lua 原子预占一次尝试,并发猜测不会超过 5 次上限。
    • 重置密码令牌:Redis 只保存 SHA-256 哈希,使用时原子「比对并删除」,同一链接只能成功一次。每次申请重置邮件都会签发新令牌,之前的链接随即失效;原来在有效期内会复用同一令牌。
    • Antigravity 错误脱敏:Gemini 转发路径出错时,客户端只收到 Gemini 风格的 code、status 和脱敏后的消息,原始错误体只进运维日志。
    • Grok:CLI 版本 1.0.44 → 1.0.46。网关请求、账号测试和额度探测统一使用官方交互式 CLI 身份:
      • UA grok-pager/1.0.46 grok-shell/1.0.46 (<系统>; <架构>),系统和架构按网关所在机器生成(如 linux; x86_64);
      • x-grok-client-identifier: grok-pager、x-grok-client-mode: interactive;
      • CLI 代理请求补 x-authenticateresponse: authenticate-response,降级到官方 API 时去掉这两个新增头。
    • TypeSafe / Jev System One:
      • 新平台 typesafe,只支持 API Key 账号,默认上游 https://api.typesafe.ai;
      • 对外端点 POST /v1/systemone,原生非流式 JSON,模型 jev-latest,内置价格输入 $0.042/M、输出 $0;
      • Prompt 审计和内容审核覆盖 System One 的问题文本;TypeSafe 分组调用 Messages、Chat Completions、Responses、count_tokens 返回 404;
      • 上游错误沿用现有账号错误策略并切换账号;400、413、422 不切换、不改账号状态;
      • v0.2.13 修复:创建 TypeSafe 账号时,默认开启的上游倍率探测不再报 400。
    • 充值优惠阶梯:
      • 后台支付设置新增阶梯(赠金模式:满 X 送 Y%;折扣模式:满 X 实付减 Y%)和 Markdown 活动文案;
      • 赠金模式按到账基数加送,折扣模式到账不变、实付打折;订阅订单不参与;
      • 订单新增 bonus_amount 记录赠送额度,推广返利只按实充部分计算;
      • 未配置阶梯时,下单金额和到账与原来一致。
    • 账号优先级快捷调整:账号列表的优先级可以直接加减或输入。连续点击合并成一次只改优先级的请求,失败时回滚并提示。
    • API Key 按分组排序:用户 API Key 列表的分组列可排序,未分组的 Key 无论升降序都排在最后。
    • Key 删除后照常结算(v0.2.13 fix(billing): settle usage when the API key is deleted before billing completes Wei-Shaw/sub2api#7816,采用上游做法):请求进行中 API Key 被删除时,这把 Key 自身的额度、限速计数会因为找不到 Key(ErrAPIKeyNotFound)而更新失败,原来会让整个计费事务回滚,连用户余额和订阅都不扣。现在只跳过这把 Key 自身的计数,用户余额、订阅和账号额度照常结算;其他错误仍然让事务失败。production 现有的 9699d9ee4(来自 fix: 完善 Key 删除后的结算与 WebSocket 撤销检查 #273)会继续给软删除的 Key 累计额度和限速,本 PR 的 09d226210 把它换回上游做法。
  • 本次范围与仍未解决的问题:

关联记录与来源

本 PR 提交 上游提交 上游 PR 版本
707992efa 修复 Grok CLI 版本门槛并对齐官方无界面请求头 fdce5b8d0 #7780 v0.2.12
b79d548fa 依据正常交互式 CLI 抓包修正 Grok 身份头 ad05eda15 Wei-Shaw#7780 v0.2.12
ceb605aa9 feat: add native TypeSafe Jev System One support d1ba57977 #7425 v0.2.12
76435f057 fix(typesafe): align System One validation with upstream schema bb97ab364 Wei-Shaw#7425 v0.2.12
78067aa6c fix(typesafe): 补齐平台迁移、审计覆盖、端点隔离与错误策略 2d8a38681 Wei-Shaw#7425 v0.2.12
bcdfe9fdb fix(typesafe): 堵住校验解析差异与审计盲区,收紧模型列表口径 9eb394e3e Wei-Shaw#7425 v0.2.12
f40ba1bc4 test(model): 错误透传平台列表守卫纳入 typesafe fa49647c6 Wei-Shaw#7425 v0.2.12
0d13f19a7 feat(payment): 充值赠送阶梯(按金额档位额外赠送到账额度) 1b1039f4f #7802 v0.2.12
866cd4adf feat(payment): 充值优惠阶梯支持折扣模式,快捷金额角标改为促销价签 1aa34d478 Wei-Shaw#7802 v0.2.12
63de5fd1d fix(payment): rate-limit anonymous public order verify endpoint cf19f30d2 #7673 v0.2.12
abc604072 feat(keys): support sorting API keys by group name 0cecf3c36 #7803 v0.2.12
8b0f500cd fix(antigravity): sanitize upstream error body before returning to client d359196ad #7674 v0.2.12
13acb7409 fix(email): atomic verify-code attempts and hashed single-use reset tokens b1ce3c6d5 #7676 v0.2.12
06ea65d9a feat(admin): inline quick-adjust stepper for account priority 0da18e4a5 #7630 v0.2.12
99f51102e fix(admin): keep disabled priority stepper hidden until hover 58d605083 Wei-Shaw#7630 v0.2.12
decaf9c99 fix(billing): allow upstream billing probe for TypeSafe API-key accounts 66a9e2e6b #7813 v0.2.13
7a9859bbe test(billing): drop added comments 8b9788eeb Wei-Shaw#7813 v0.2.13
7d532bd37 fix(billing): settle usage when the API key is deleted before billing completes(分支末尾,位于整合提交之后) c2d5bbd93 #7816 v0.2.13
9bb56ce75 chore(billing): simplify comment 432a6a461 Wei-Shaw#7816 v0.2.13

fork 整合提交(不对应上游提交):

提交 内容
84e33bbbc fix(sync): adapt TypeSafe System One to fork billing and key concurrency System One 处理器按 fork 的签名把 API Key 并发上限传给 AcquireUserSlotWithWait(与其他网关入口一致);去掉上游的在途余额预占调用,保留与其他端点相同的计费资格预检和利润控制准入。ceb605aa9~7a9859bbe 的 internal/handler 包要到这一提交才能编译。
d9981137f docs(sync): document TypeSafe / Jev System One usage 上游 v0.2.13 README 的 TypeSafe 小节与 fork 的 README 结构不同,改为单独的 docs/typesafe-jev.md,并在 .gitignore 的 docs 白名单中放行。
06ded56b3 test(sync): include TypeSafe in the full platform quota payload fork 的配额弹窗会提交全部平台,加入 TypeSafe 后断言改为 11 项。
b1ad7fadd test(sync): include TypeSafe in default platform quota helpers 上游在 TypeSafe 改动中把 typesafe 加进注册默认配额,但 settings.authSourceDefaults.spec.ts 仍断言 5 个平台。该用例不在 CI 关键测试清单里,只有全量 Vitest 能发现。
f165e9589 Merge production into sync/upstream-v0.2.12-v0.2.13-selective 合入 production 新增的 9699d9ee4、502db27d2,无文本冲突。
09d226210 fix(sync): settle deleted keys the upstream Wei-Shaw#7816 way instead of counting tombstones 恢复 incrementUsageBillingAPIKeyQuota、incrementUsageBillingAPIKeyRateLimit 的 deleted_at IS NULL 条件(与上游一致),已删除的 Key 返回 ErrAPIKeyNotFound 后由 Wei-Shaw#7816 跳过。保留 #273 的结算测试,按上游语义调整:集成测试 16 个组合中,已删除 Key 的额度和限速计数保持不变,余额 / 订阅照常扣,重试不重复扣,凭据和删除状态不恢复;单测中数据库错误仍整体回滚,Key 行不存在时提交用户扣费。

冲突与适配:

交叉点 处理
Grok 版本与身份(Wei-Shaw#7780) 版本号改为 1.0.46。保留 fork 的 CLIStableVersion = CLIClientVersion:XAI_GROK_CLI_VERSION 覆盖值低于 1.0.46 时回退到 1.0.46;上游把通用下限设为 1.0.13,这里不跟进。fork 原来的测试版本号都基于 1.0.44,统一顺延 2 个补丁号。身份头采用上游最终版本;fork 原来的 xai-grok-workspace/<version> UA 本身也来自上游(9fb260439),本次随上游一起替换。
README(Wei-Shaw#7425) 保留 fork 的 README,TypeSafe 说明移到 docs/typesafe-jev.md(d9981137f)。
账号创建与更新(Wei-Shaw#7425) account_service.go、admin_account.go 保留 fork 的模型映射模式校验、Codex ticket extra 合并和长上下文计费 extra 归一化,同时加入上游「TypeSafe 只支持 API Key」的检查。
平台配额前端(Wei-Shaw#7425) typesafe 加入 fork 统一的 PLATFORM_QUOTA_PLATFORMS,不保留上游在组件里另写的平台列表;相关测试改为 11 个平台(06ded56b3、b1ad7fadd)。
API Key 排序(Wei-Shaw#7803) 只有上下文差异:fork 的并发列标题是 keys.concurrencyAndWaiting。测试保留 fork 现有用例,排序用例改用上游的 it.each,覆盖并发列升序和分组列升、降序。
迁移(Wei-Shaw#7425、Wei-Shaw#7802) 241_add_payment_order_bonus_amount.sql、241_add_typesafe_platform.sql 保留上游原文件名和原内容(先例:239、240)。fork 已有 241_add_account_group_rate_multiplier.sql 和 242~262,迁移执行器按文件名记录、执行所有未执行的文件,所以已部署实例升级时会补跑这两个文件。typesafe 的 CHECK 清单是 fork 238 号清单的超集,存量数据可以通过校验。
Ent / wire Ent(payment_orders.bonus_amount、配额平台)与 wire 重新生成,和提交内容无差异。

复现与验收

  • 环境与基线:production 502db27d2(含 feat(prism): isolate concurrent turns and select account models #269、fix(pelican): 智商测试/鹈鹕测智对 Claude 不再返回为空,并传递思考强度 #271、feat(pelican): 补齐结果 API 管理开关和用户调用信息 #272,以及维护者直接推送的 9699d9ee4、502db27d2)。最初基于 bf9405e4a 完成同步,后变基到 eceb5632b,冲突只有 .gitignore 末尾(与 production 新增的 docs 白名单行并存);之后 production 新增的两个提交用合并提交 f165e9589 合入,无冲突。Go 1.27.0、pnpm 9.15.9;在独立克隆中使用 mock、miniredis/本地 Redis 和 Docker 集成测试,没有请求生产上游、没有修改运行配置。
  • 前置条件与操作:
    1. 同一 IP 连续请求 POST /api/v1/payment/public/orders/verify 超过 20 次;并发提交错误的邮箱验证码;对同一个重置密码链接并发提交两次。
    2. 创建 TypeSafe API Key 账号(保持默认开启的上游倍率探测),用 TypeSafe 分组的 Key 调 POST /v1/systemone,再调 /v1/messages。
    3. 后台配置充值优惠阶梯,分别在赠金和折扣模式下进入充值页下单。
    4. 给 API Key 设置额度或限速,在请求进行中删除这把 Key,查看用户余额是否照常扣费、这把 Key 的计数是否变化。
  • 修复前观察:查询接口不限流;验证码并发猜测可以超过 5 次;重置令牌明文存 Redis,并发下可能被用两次;请求进行中删除带额度/限速的 Key:没有 9699d9ee4 的版本会让整笔计费回滚,当前 production(含 9699d9ee4)照常扣费但继续给已删除的 Key 计数;没有 TypeSafe 平台和充值优惠阶梯。
  • 修复后观察 / 验收标准:见「解决的问题与行为变化」。未配置充值优惠阶梯、没有 TypeSafe 账号时,现有充值和网关行为不变。
  • 回归测试位置:
协议、调度或传输改动补充
  • 端点:新增 POST /v1/systemone(TypeSafe,非流式,使用文本请求体上限);POST /api/v1/payment/public/orders/verify 加限流。
  • Grok:只改请求身份头,不改请求体、重试和故障转移。UA 中的系统和架构取网关所在机器,与官方 CLI 的生成方式一致。
  • TypeSafe 错误处理:401、402、403、429、529、5xx 和传输错误沿用现有账号错误策略(含自定义错误码与临时不可调度规则)并切换账号;400、413、422 原样返回,不切换、不改账号状态。上游已计费的成功响应在 usage/model 字段格式不规范时宽松解析,避免已计费请求不记账。
  • 并发:System One 与其他网关入口一样占用用户槽(含 API Key 并发上限)和账号槽,释放方式也相同(wrapReleaseOnDone)。

实际验证

当前 head:09d226210,经合并提交 f165e9589 基于 production 502db27d2。

检查与执行目录 / 命令 结果 覆盖范围、证据或未运行原因
backend:go vet -tags=unit ./...、go vet -tags=integration ./... 通过 当前 head
backend:go test -tags=unit -count=1 ./... 通过(以下除外) 当前 head,62 个包通过。internal/service 的 TestPriorityOAuthProfitUsesUserChargeAndTheoreticalCost(浮点 3.9999999999999996 ≠ 4)和 internal/reauthruntime 的 TestStopCancelsPreparationAndCannotRestart,在未改动的 production bf9405e4a 与 eceb5632b 上同样失败(本机 macOS arm64)。internal/mihomo 的时序用例只在全量并发时超时,单独运行该包通过。
backend:go test -tags=integration -count=1 ./... 通过(同上) 当前 head,57 个包通过,含 internal/repository(Docker 中的 Postgres / Redis)、internal/handler 和 migrations;失败项与上一行相同。此前一次全量运行中,internal/handler 的 TestHTTPKeyQueueTimeoutKeepsResponseUnwritten(fork 自有用例,排队超时只有 150ms)在机器满载时失败过一次,单独连续 5 次通过,本次全量运行通过。
删除 Key 的结算:go test -tags=unit / -tags=integration ./internal/repository/ 通过 Wei-Shaw#7816 新增的 3 个用例,以及按上游语义调整后的 #273 用例(集成测试 16 个组合、单测 4 个子用例)都实际运行并通过
backend:golangci-lint v2.13.2 ./... 通过 当前 head,0 issues
backend:go generate ./ent;backend/cmd/server:wire v0.7.0 通过 在 b1ad7fadd 上重新生成,与提交内容无差异;之后的提交只改 internal/repository,合并进来的 production 提交也不涉及 ent 和 cmd/server
仓库根目录:make test-frontend 通过 lint:check、typecheck 和关键 Vitest 53 个文件 923 项(b1ad7fadd;之后的提交和合并进来的 production 提交都只改后端)
仓库根目录:pnpm --dir frontend run test:run 通过 400 个文件 3,362 项(同上)
仓库根目录:pnpm --dir frontend run build 通过 生产构建(同上)
与 #275 叠加:把两个分支依次合并到 production 502db27d2 通过(同上 1 项) 无文本冲突;两种 tag 的 go vet 通过。两边都改到的后端包(internal/server/...、internal/handler/...、internal/service、internal/domain/...、internal/repository)单测只有上面的浮点用例失败;internal/repository、internal/handler 集成测试通过。前端 lint:check、typecheck 和全量 Vitest(400 个文件 3,371 项)通过,这一项取自之前在 eceb5632b 上的叠加检查,此后两个 PR 和 production 都没有改前端。两个 PR 先合哪个都可以。
真实 TypeSafe / Grok 上游、支付渠道 未运行 没有可用于测试的账号;不执行付费请求
UI 截图 未提供 充值优惠阶梯、优先级快捷调整、Key 排序由组件测试覆盖,未在浏览器中渲染
GitHub CI 待运行 以本 PR 当前 head 的 CI 为准

兼容性与运行影响

  • 配置 / API / 默认行为:
    • 新增支付设置 RECHARGE_BONUS_TIERS、RECHARGE_BONUS_MODE、RECHARGE_BONUS_NOTICE,默认不配置,充值行为不变;checkout-info 和订单响应新增 recharge_bonus_*、bonus_amount 字段。
    • 新增平台 typesafe 和端点 POST /v1/systemone。
    • Grok 默认身份变化见上;XAI_GROK_CLI_VERSION 低于 1.0.46 的覆盖值会被忽略。
    • 匿名订单查询接口每 IP 每分钟 20 次。
  • 数据库迁移、数据兼容与二进制回滚限制:
    • 241_add_payment_order_bonus_amount.sql:payment_orders 加 bonus_amount DECIMAL(20,2) NOT NULL DEFAULT 0,存量订单为 0。
    • 241_add_typesafe_platform.sql:重建 user_platform_quotas、composite_model_routes 的平台 CHECK 约束,加入 typesafe。
    • 回滚二进制时迁移不会回退,bonus_amount 列和放宽后的 CHECK 约束会保留。旧版本不读取 bonus_amount,也不支持 typesafe 平台;回滚前应先停用 TypeSafe 账号和分组,并关闭充值优惠阶梯。
  • 权限、凭据脱敏、日志或采集内容:
    • 升级前已发出、还没使用的重置密码链接会在升级后失效(旧令牌是明文,新逻辑按哈希比对),用户需要重新申请;链接有效期 30 分钟,重新申请的冷却时间为 30 秒。
    • 升级前发出的注册/通知验证码在 15 分钟有效期内仍然可用;升级前已累计的失败次数不并入新的原子计数,这些旧验证码最多还能再试 5 次。
    • Antigravity 上游原始错误体不再返回给客户端,仍保留在运维错误记录里。
  • 计费、资源开销、并发或性能:Key 在请求进行中被删除时,这笔请求照常扣用户余额或订阅,Key 自身的额度和限速计数不再更新。与当前 production(9699d9ee4)相比,合并后已删除 Key 的 quota_used、usage_5h/1d/7d 不再增长;与更早的版本相比,不再整笔回滚。充值优惠阶梯会改变命中档位订单的到账额度或实付金额,推广返利只按实充部分计算。jev-latest 按内置价格计费,渠道定价可覆盖。未做性能测量。
  • 灰度 / 回滚方式与残余风险:充值优惠阶梯默认关闭;TypeSafe 只有创建账号后才生效。残余风险是真实 TypeSafe、Grok 上游和支付渠道未实测。

文档与用户可见变化

  • 用户可见:
    • 后台:账号平台新增 TypeSafe;支付设置新增「充值优惠阶梯」;账号列表优先级可快捷调整。
    • 用户端:充值页显示档位角标和活动文案;订单列表、详情和支付结果显示赠送额度;API Key 列表可按分组排序。
  • 文档:新增 docs/typesafe-jev.md(中英文,整理自上游 v0.2.13 README)。PR 合并不代表已发布或部署。

Agent 使用声明

  • Agent 名称与参与范围:Claude Code(桌面 App Code 页签);差异分析、cherry-pick 与冲突适配、整合提交、测试、Issue 与本 PR 正文。未使用子 Agent。
  • 模型名称:Claude Opus 5.5(claude-opus-5-5)
  • 推理强度:max

提交前自查

  • base 分支和改动范围正确,没有夹带无关修改。
  • 正文、提交、测试数据和附件不含凭据、ticket/state 或真实用户敏感信息。
  • 实际验证结果已列出,失败、未运行和未覆盖的部分已说明。
  • 已检查配置默认值、权限、兼容性及相关文档;不适用项已说明。
  • Bug 修复有针对性回归验证,或已说明暂时无法补充的原因。
  • 已填写 Agent 使用声明,列出所有参与的 Agent、模型和推理强度;纯人工编写已注明未使用。

🤖 Generated with Claude Code

lyen1688 and others added 23 commits October 2, 2026 21:53
- 新增 241 迁移:user_platform_quotas / composite_model_routes 的 CHECK 约束
  加入 typesafe。此前设置 typesafe 默认配额会让注册时的多行配额快照整体
  违约(fail-open 后新用户所有平台配额丢失),单用户配额与 Composite 路由保存 500。
- Prompt 审计新增 typesafe_systemone 协议提取(state + 各问题 instructions/
  criteria/选项标签,键排序保证哈希稳定);此前提取为空,阻断与异步审计均被放行。
  旧内容审核同样覆盖问题文本,且不再丢弃含 <system-reminder> 的 System One 文本。
- TypeSafe 分组及路由到 TypeSafe 的 Composite 请求访问 Messages / count_tokens /
  Chat Completions / Responses 时返回 404,避免以 x-api-key 打到错误上游路径并
  污染账号状态;TypeSafe 账号 base_url 为空时不再回退 api.anthropic.com。
- SystemOne 补在途余额预留、利润控制准入终检、wrapReleaseOnDone,失败切换改用
  共享 FailoverState(同账号重试 / 池模式 / 临时封禁)。
- 上游错误沿用共享账号错误策略:402/403、自定义错误码、临时不可调度规则生效,
  记录 ops 上游错误;400/422 仍不切换且永不改变账号状态。
- 账号测试改走原生 System One 探测,可用模型只返回 jev-latest;
  响应超限显式报错,响应 Content-Type 仅透传 JSON 类型。

(cherry picked from commit 2d8a386)
- System One 校验拒绝重复键与大小写/Unicode 折叠变体键(请求顶层、
  questions、问题对象):encoding/json 大小写不敏感且取最后一个重复键,
  而原始 body 原样转发,此前 {"model":"x","MODEL":"jev-latest"} 可绕过
  jev-latest 限制、模型白名单与流式限制。
- Prompt 审计与旧审核同时收集对象键名、问题 ID 与未知扩展字段(不含规范
  字段名与已校验的 type),此前把内容放进键名即可完全绕过审计。
- 上游成功响应的 usage/model 宽松解码(浮点、数字字符串),避免上游已
  计费而网关整体 502 不记账;解码失败记录 response_error ops 事件。
- 上游 413 与 400/422 同视为请求错误:透传状态码、不切换、不改账号状态。
- TypeSafe base_url 末尾的 /v1 自动剥离,避免拼出 /v1/v1/systemone;
  /v1/systemone 改挂文本请求体上限。
- Composite 静态兜底模型列表、管理端候选列表恢复为不含 jev-latest;
  Codex 清单永不列出 TypeSafe 模型;TypeSafe 分组候选默认 jev-latest。
- 创建账号从 Grok 切到 TypeSafe 时重置为白名单模式;错误透传平台列表补 typesafe。

(cherry picked from commit 9eb394e)
- 后台支付设置新增「充值赠送阶梯」(满 X 送 Y%,RECHARGE_BONUS_TIERS)与 Markdown 活动文案
  (RECHARGE_BONUS_NOTICE):阈值按用户输入的支付金额命中(取不超过金额的最大档),
  赠送按到账基数(输入 × 充值倍率)计算;严格校验写入、宽松解析读取,订阅订单不参与
- 下单时按当时配置计算赠送并落库:payment_orders 新增 bonus_amount 列(迁移 241),
  amount 仍为到账总额,到账/兑换码/退款逻辑不变;推广返利基数改为 amount - bonus_amount
- checkout-info 下发 recharge_bonus_tiers / recharge_bonus_notice;创建订单与订单查询响应带 bonus_amount
- 充值页:快捷金额按钮右上角「+N%」角标 + 第二行到账金额,金额卡顶部渲染活动文案,
  订单摘要新增赠送额度行并在有赠送时始终显示到账余额;订单列表/详情/支付结果/成功面板显示含赠送
- 后台新增 RechargeBonusTierEditor(行内校验重复/非法阈值,自动排序并显示区间预览)
- 补后端单测、契约测试与前端 vitest,zh/en 文案

(cherry picked from commit 1b1039f)
- 新增全局模式开关 RECHARGE_BONUS_MODE(bonus / discount),接入支付配置、后台设置接口与 checkout-info
- 折扣模式:到账不变,实付基数按百分比打折(按币种精度取整),手续费 / 每日限额 / 渠道选实例沿用折后基数;
  百分比须 < 100,运行时 ≥ 100 按无优惠处理
- 充值页角标改为单行红色价签(赠金「+20%」/ 折扣「20% OFF」),第二行按模式显示到账或折后实付;
  摘要卡折扣模式显示优惠行,渠道限额校验改用折后实付
- 后台「充值优惠阶梯」拆为独立卡片:赠金 / 折扣切换、紧凑档位表格、区间预览、活动文案
- 补前后端单测与 zh/en 文案

(cherry picked from commit 1aa34d4)
POST /api/v1/payment/public/orders/verify is unauthenticated and still used
by PaymentResultView as a fallback, so keep it but cap it at 20 req/min per
client IP (fail-open on Redis errors) to make out_trade_no enumeration
impractical without affecting users mid-payment.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit cf19f30)
…ient

The antigravity Gemini forward path returned the raw upstream Google error
body to end users, which can contain consumer project numbers, GCP project
IDs and service account emails. Return a Gemini-style error body with only
code/status and a scrubbed message; raw body stays in ops logging.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit d359196)
…okens

- Verification code attempts (register + notify email) are now reserved via
  an atomic Redis INCR (Lua) before comparing, so concurrent wrong guesses
  cannot exceed the 5-attempt cap.
- Password reset tokens are stored as SHA-256 hashes and consumed with an
  atomic Lua compare-and-delete, so a token can only be used once even under
  concurrent requests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit b1ce3c6)
Replace the static priority number in the accounts table with a compact
stepper: hover reveals -/+ buttons, clicking the value allows typing
(Enter to save, Esc to cancel, arrow keys to nudge). Rapid clicks are
debounced into a single priority-only PUT, failures revert the value and
surface a toast, and the row is patched in place without a full reload.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 0da18e4)
disabled:opacity-30 overrode opacity-0, so the decrement button stayed
faintly visible on every row already at the minimum. Style disabled
buttons via text colour instead, and raise idle icon contrast.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 58d6050)
The create form shows the upstream billing auto-probe toggle for every
API-key platform and enables it by default. TypeSafe was added as an
API-key platform but not to IsUpstreamBillingProbeIdentity, so creating a
TypeSafe account with the default form state fails with
400 UPSTREAM_BILLING_PROBE_ACCOUNT_INVALID ("account is not an API key
account").

TypeSafe accounts store credentials.api_key/base_url like every other
API-key platform, which is all the probe reads. Add TypeSafe to the probe
identity set, and add typesafe.ai to the official API domains so accounts
on the default https://api.typesafe.ai base URL record "unsupported"
without sending the key to a path that cannot exist, matching the other
official providers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 66a9e2e)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 8b9788e)
- Pass the API key concurrency limit to AcquireUserSlotWithWait, like the
  other gateway entry points in this fork.
- Drop the in-flight balance reservation the upstream handler calls. The
  fork does not import upstream's reservation feature (see Wei-Shaw#253); System One
  keeps the same billing eligibility pre-check as the other endpoints.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The upstream README sections for TypeSafe (v0.2.13) do not fit this fork's
README, so the usage notes live in docs/typesafe-jev.md, which is added to
the docs allowlist in .gitignore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fork's quota modal submits every supported platform; with TypeSafe the
payload has eleven entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Upstream added typesafe to the signup default platform quota map in the
TypeSafe change but left this spec at five platforms. It is outside the
critical CI list, so the mismatch only shows in the full Vitest run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… completes

When an API key with quota or rate limits was deleted while a request was
still in flight, the key counter update matched no rows and returned
ErrAPIKeyNotFound, rolling back the whole billing transaction including the
balance/subscription charge. Skip the key-scoped counters in that case and
keep settling the user and account side as usual.

(cherry picked from commit c2d5bbd)
(cherry picked from commit 432a6a4)
akihitohyh and others added 2 commits October 2, 2026 23:06
Brings in 9699d9e and 502db27 (from Wei-Shaw#273). No textual conflicts; the
next commit replaces the soft-deleted key counting from 9699d9e with
the upstream Wei-Shaw#7816 settlement already on this branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… of counting tombstones

9699d9e (Wei-Shaw#273) and upstream Wei-Shaw#7816 fix the same rollback when a key is
deleted while its request is still being billed, in opposite ways: Wei-Shaw#273
keeps adding to the soft-deleted row's quota and rate-limit counters,
upstream skips the key's own counters. Per collaborator decision, keep
the upstream approach that this branch already cherry-picks.

- Restore the deleted_at IS NULL filters in the key counter updates, so a
  deleted (or missing) key surfaces ErrAPIKeyNotFound and Wei-Shaw#7816 skips it
  while the user's balance or subscription is still charged.
- Keep Wei-Shaw#273's settlement tests with upstream expectations: a deleted
  key's counters stay unchanged; database failures still roll back; a
  missing key row now commits the user charge instead of rolling back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ranxi2001
ranxi2001 merged commit a942afe into ranxi2001:production Oct 2, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 精选同步上游 v0.2.12–v0.2.13:三项安全加固、Grok 身份头、TypeSafe 与充值优惠阶梯

8 participants