IanShaw027
d851818035
fix(lint): 修复 gofmt 格式问题
...
修复 golangci-lint 检查失败的问题:
- gemini_token_provider.go: 删除 import 后多余空行
- gemini_token_refresher.go: 删除 import 后多余空行
Fixes CI golangci-lint check for PR #37
2025-12-26 22:24:22 +08:00
IanShaw027
576bf4639c
refactor: 统一使用 mergeMap 函数提升代码一致性
...
根据 Gemini CLI 代码审查建议:
## 修改内容
- 将 Gemini OAuth 同步中的 `mergeJSONB` 调用替换为 `mergeMap`
- 删除不再使用的 `mergeJSONB` 函数定义
## 原因
- 其他平台(OpenAI、Anthropic)的账户同步都使用 `mergeMap`
- `mergeJSONB` 是为旧的 `model.JSONB` 类型设计,与重构后的架构不一致
- 统一函数命名提高代码可读性和可维护性
## 影响范围
- backend/internal/service/crs_sync_service.go (4处替换)
- backend/internal/service/account.go (删除 mergeJSONB 函数)
## 验证
✓ 编译通过
✓ 功能逻辑无变化(mergeMap 和 mergeJSONB 实现相同)
2025-12-26 22:15:15 +08:00
IanShaw027
9db52838b5
fix(backend): 适配重构后的架构修复 Gemini OAuth 集成
...
## 主要修改
1. **移除 model 包引用**
- 删除所有 `internal/model` 包的 import
- 使用 service 包中的类型定义(Account, Platform常量等)
2. **修复类型转换**
- JSONB → map[string]any
- 添加 mergeJSONB 辅助函数
- 添加 Account.IsGemini() 方法
3. **更新中间件调用**
- GetUserFromContext → GetAuthSubjectFromContext
- 适配新的并发控制签名(传递 ID 和 Concurrency 而不是完整对象)
4. **修复 handler 层**
- 更新 gemini_v1beta_handler.go
- 修正 billing 检查和 usage 记录
## 影响范围
- backend/internal/service/gemini_*.go
- backend/internal/service/account_test_service.go
- backend/internal/service/crs_sync_service.go
- backend/internal/handler/gemini_v1beta_handler.go
- backend/internal/handler/gateway_handler.go
- backend/internal/handler/admin/account_handler.go
2025-12-26 22:07:55 +08:00
IanShaw027
bfcd9501c2
merge: 合并 upstream/main 解决 PR #37 冲突
...
- 删除 backend/internal/model/account.go 符合重构方向
- 合并最新的项目结构重构
- 包含 SSE 格式解析修复
- 更新依赖和配置文件
2025-12-26 21:56:08 +08:00
shaw
2d89f36687
Merge PR #42 : fix(sse): 修复非标准 SSE 格式解析问题
2025-12-26 21:31:34 +08:00
shaw
3d608c2625
Merge branch 'refactor/redis-key-helpers'
2025-12-26 21:26:18 +08:00
shaw
739d0ee61e
fix: admin handlers 添加 DTO 转换修复 JSON 序列化
...
修复 PR #36 合并后部分 admin handler 直接返回 service 层对象导致
JSON 字段名为 PascalCase 而非期望的 snake_case 问题。
修复内容:
- account_handler: Refresh 接口添加 dto.AccountFromService
- openai_oauth_handler: RefreshAccountToken/CreateAccountFromOAuth 添加 dto 转换
- subscription_handler: BulkAssign 添加 dto.BulkAssignResultFromService
- usage_handler: List 接口添加 dto.UsageLogFromService 转换
- 新增 dto.BulkAssignResult 类型和对应的 mapper 函数
2025-12-26 21:22:48 +08:00
ianshaw
16eec4eb41
fix(sse): 修复非标准 SSE 格式解析问题
...
部分上游 API 返回的 SSE 格式不符合标准规范:
- 标准格式: `data: {...}`(冒号后有空格)
- 非标准格式: `data:{...}`(冒号后无空格)
使用预编译正则 `^data:\s*` 统一处理两种格式。
2025-12-26 03:49:55 -08:00
Forest
06d5876b02
refactor: 封装 Redis key 生成函数
2025-12-26 16:47:44 +08:00
Forest
e5a77853b0
refactor: 调整项目结构为单向依赖
2025-12-26 16:45:40 +08:00
ianshaw
9780f0fd9d
fix(backend): 修复 rebase 后的代码集成问题
...
- 更新 middleware import 路径到 internal/server/middleware
- 修复 api_key_auth_google.go 使用正确的 service 类型
- 更新 router.go 和 http.go 支持 Gemini v1beta 路由
- 在 routes/gateway.go 中添加 Gemini v1beta API 端点
- 在 routes/admin.go 中添加 Gemini OAuth 路由
- 更新 wire.go 添加 GeminiOAuthService cleanup
- 重新生成 wire_gen.go
2025-12-26 00:17:55 -08:00
ianshaw
3559830882
fix(service): 应用德摩根定律修复 staticcheck QF1001 警告
2025-12-26 00:11:04 -08:00
ianshaw
632318ad33
feat(backend): 添加 OAuth 能力查询接口,改进 OAuth 客户端选择逻辑
...
Handler 改进:
- 添加 GET /api/v1/admin/gemini/oauth/capabilities 接口
- 简化 GenerateAuthURL,redirect_uri 由服务层决定
Repository 改进:
- ExchangeCode/RefreshToken 根据 oauthType 选择正确的 OAuth 客户端
- Code Assist 始终使用内置客户端,AI Studio 使用用户配置的客户端
2025-12-26 00:11:03 -08:00
ianshaw
456e8984b0
feat(service): 改进 Gemini OAuth 服务层,区分 Code Assist 和 AI Studio 客户端
...
OAuth 服务改进:
- 添加 GetOAuthConfig 返回 AI Studio OAuth 可用性
- Code Assist 强制使用内置 Gemini CLI 客户端
- AI Studio OAuth 要求用户配置自定义 OAuth 客户端
- ExchangeCode/RefreshToken 接口添加 oauthType 参数
- 添加 unauthorized_client 错误的向后兼容重试逻辑
兼容层改进:
- 403 重试逻辑仅对 Code Assist OAuth 生效
- 添加 insufficient-scope 错误检测,避免无效重试
- 上游错误消息脱敏处理(隐藏 API key 等敏感信息)
- 改进错误提示,显示更多上游错误详情
2025-12-26 00:11:03 -08:00
ianshaw
eea949853a
feat(geminicli): 添加内置 Gemini CLI OAuth 客户端常量和改进配置逻辑
...
- 添加 GeminiCLIOAuthClientID/Secret 常量(Gemini CLI 公开 OAuth 客户端)
- 更新 DefaultAIStudioScopes 使用 generative-language.retriever(符合 Google 文档)
- EffectiveOAuthConfig 支持自动回退到内置客户端
- 内置客户端自动过滤受限 scope(如 generative-language)
- 添加 scope 向后兼容性处理
2025-12-26 00:11:03 -08:00
ianshaw
85fd1e4a2c
fix(backend): 移除对已删除 ports 包的依赖
...
适配 main 分支的 ports 目录删除重构:
- 将 ports 包中的接口移至 service 包
- 更新 repository 层的导入路径
2025-12-26 00:11:03 -08:00
ianshaw
6682d06c99
fix(backend): 修复 golangci-lint 报告的格式和代码规范问题
...
- gofmt: 修复 account_handler.go, models.go, gemini_messages_compat_service.go 的格式
- staticcheck ST1005: 将 error strings 改为小写开头
2025-12-26 00:11:03 -08:00
ianshaw
efa470efc7
fix(backend): 修复 golangci-lint 报告的问题
...
- gofmt: 修复代码格式问题
- errcheck: 处理 WriteString 和 Close 返回值
- staticcheck: 错误信息改为小写开头
- staticcheck: 移除无效的 nil 检查
- staticcheck: 使用 append 替换循环
- staticcheck: 使用无条件的 TrimPrefix
- ineffassign: 移除无效赋值
- unused: 移除未使用的 geminiOAuthService 字段
- 重新生成 wire_gen.go
2025-12-26 00:11:03 -08:00
ianshaw
46cb82bac0
feat(backend): 添加 Gemini V1beta Handler 和路由
...
- 新增 gemini_v1beta_handler.go: 代理原生 Google API 格式
- 更新 gemini_oauth_handler.go: 移除 redirectUri,新增 oauthType
- 更新 account_handler.go: 账户 Handler 增强
- 更新 router.go: 注册 v1beta 路由
- 更新 config.go: Gemini OAuth 通过环境变量配置
- 更新 wire_gen.go: 依赖注入
2025-12-26 00:11:03 -08:00
ianshaw
b2d71da2a2
feat(backend): 实现 Gemini AI Studio OAuth 和消息兼容服务
...
- gemini_oauth_service.go: 新增 AI Studio OAuth 类型支持
- gemini_token_provider.go: Token 提供器增强
- gemini_messages_compat_service.go: 支持 AI Studio 端点
- account_test_service.go: Gemini 账户可用性检测
- gateway_service.go: 网关服务适配
- openai_gateway_service.go: OpenAI 兼容层调整
2025-12-26 00:11:03 -08:00
ianshaw
2d6e1d26c0
feat(backend): 扩展 Gemini OAuth Repository 层
...
- 更新 gemini_oauth_client.go: 支持 AI Studio OAuth 客户端
- 更新 geminicli_codeassist_client.go: 适配新的认证流程
2025-12-26 00:11:03 -08:00
ianshaw
50734c5edc
feat(backend): 添加 Google API Key 认证中间件
...
- 新增 api_key_auth_google.go: 支持 x-goog-api-key 格式认证
- 更新 api_key_auth.go: 适配 Gemini 原生 API 格式
2025-12-26 00:11:03 -08:00
ianshaw
040dc27ea5
feat(backend): 添加 Gemini/Google API 基础包
...
- 新增 pkg/gemini: 模型定义与回退列表
- 新增 pkg/googleapi: Google API 错误状态处理
- 新增 pkg/geminicli/models.go: CLI 模型结构
- 更新 constants.go: AI Studio 相关常量
- 更新 oauth.go: 支持 AI Studio OAuth 流程,凭据通过环境变量配置
2025-12-26 00:10:44 -08:00
ianshaw
03a8ae62e5
feat(backend): 完善 Gemini OAuth Token 处理
...
- 修复 account_handler 中 token 字段类型转换(int64 转 string)
- 增强 Account.GetCredential 支持多种数值类型(float64, int, json.Number 等)
- 添加 Account.IsGemini() 方法用于平台判断
- 优化 refresh_token 和 scope 的空值处理
2025-12-26 00:09:46 -08:00
ianshaw
e36fb98fb9
feat(handler): 添加 Gemini OAuth Handler 和完善依赖注入
...
- 新增 Gemini OAuth 授权处理器
- 扩展账号和网关处理器支持 Gemini
- 注册 Gemini 相关路由
- 更新 Wire 依赖注入配置(所有层)
- 更新 Docker Compose 配置
2025-12-26 00:09:46 -08:00
ianshaw
55258bf099
feat(service): 扩展 CRS 同步和定价服务支持 Gemini
...
- CRS 同步服务新增 Gemini 账号同步逻辑(+273行)
- 定价服务扩展 Gemini 模型定价计算(+99行)
- 更新 Token 刷新服务集成 Gemini
- 更新相关单元测试
2025-12-26 00:09:04 -08:00
ianshaw
dc109827b7
feat(service): 实现 Gemini OAuth 和 Token 管理服务
...
- 实现 OAuth 授权流程服务
- 添加 Token 提供者和自动刷新机制
- 实现 Gemini Messages API 兼容层
- 更新服务容器注册
2025-12-26 00:09:04 -08:00
ianshaw
71c28e436a
feat(service): 定义 Gemini 服务端口接口
...
- 定义 OAuth 服务接口
- 定义 Token 缓存服务接口
- 定义 Code Assist 服务接口
2025-12-26 00:08:27 -08:00
ianshaw
2bafc28a9b
feat(repository): 实现 Gemini OAuth 和 Token 缓存客户端
...
- 添加 Gemini OAuth 客户端实现
- 实现 Redis 基础的 Token 缓存
- 添加 gemini-cli Code Assist 客户端封装
2025-12-26 00:08:27 -08:00
ianshaw
aea48ae1ab
feat(config): 新增 Gemini 配置项和 geminicli 核心包
...
- 添加 Gemini OAuth 配置结构
- 实现 geminicli 包(OAuth、Token、CodeAssist 类型)
- 更新配置示例文件
2025-12-26 00:08:27 -08:00
shaw
b3463769dc
chore: 调整403重试次数跟间隔
2025-12-26 14:19:57 +08:00
Forest
57fd172287
refactor: 调整 server 目录结构
2025-12-26 10:42:35 +08:00
NepetaLemon
8d7a497553
refactor: 自定义业务错误 ( #33 )
...
* refactor: 自定义业务错误
* refactor: 隐藏服务器错误与统一 panic 响应
2025-12-26 08:47:00 +08:00
shaw
b31698b9f2
fix: 修复账户代理ip编辑保存不生效的bug
2025-12-25 21:58:09 +08:00
Forest
eeaff85e47
refactor: 自定义业务错误
2025-12-25 21:06:40 +08:00
Forest
f51ad2e126
refactor: 删除 ports 目录
2025-12-25 17:15:01 +08:00
hi_yueban
f57f12c6cc
fix: 修复 OpenAI 账号 5h/7d 使用限制显示错误的问题 ( #30 )
...
* fix: 修复 OpenAI 账号 5h/7d 使用限制显示错误的问题
问题描述:
- 账号管理页面中,OpenAI OAuth 账号的 5h 列显示 7 天的剩余时间
- 7d 列却显示几小时的剩余时间
- 根本原因: OpenAI 响应头中 primary/secondary 的实际含义与代码假设相反
修复方案:
1. 后端归一化 (openai_gateway_service.go):
- 根据 window_minutes 动态判断哪个是 5h/7d 限制
- 新增规范字段 codex_5h_* 和 codex_7d_*
- 保留旧字段以兼容性
2. 前端适配 (AccountUsageCell.vue):
- 优先使用新的规范字段
- Fallback 到旧字段时基于 window_minutes 动态判断
- 更新 computed 属性命名
3. 类型定义更新 (types/index.ts):
- 添加新的规范字段定义
- 更新注释说明实际语义由 window_minutes 决定
🤖 Generated with Claude Code and Codex collaboration
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
Co-Authored-By: OpenAI Codex <noreply@openai.com >
* fix: 改进窗口判断逻辑,修复两个窗口都小于阈值时的bug
问题:
当两个窗口都小于360分钟时(如 primary=180分钟,secondary=300分钟),
之前的逻辑会导致:
- primary5h = true, secondary5h = true
- 5h 字段会使用 primary(错误)
- 7d 字段没有数据(bug)
修复方案:
改用比较策略:
1. 当两个窗口都存在时:较小的分配给5h,较大的分配给7d
2. 当只有一个窗口时:根据大小(<=360分钟)判断是5h还是7d
3. 确保数据不会丢失,逻辑更健壮
示例:
- Primary: 180分钟, Secondary: 300分钟
→ 5h 使用 Primary(180分钟), 7d 使用 Secondary(300分钟) ✓
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
* fix: 修正窗口大小判断逻辑 - 不能用剩余时间判断窗口类型
**严重bug修复:**
之前的 fallback 逻辑错误地使用 reset_after_seconds 来判断窗口大小。
问题示例:
- 周限制(7d)剩余 2h → reset_after_seconds = 7200秒
- 5h限制 剩余 4h → reset_after_seconds = 14400秒
- 错误逻辑:7200/60 < 14400/60,把周限制当成5h ❌
根本问题:
- window_minutes = 窗口的总大小(300 or 10080)
- reset_after_seconds = 距离重置的剩余时间(变化的)
- 不能用剩余时间来判断窗口类型!
修复方案:
1. **只使用 window_minutes** 来判断窗口大小
2. 移除错误的 reset_after_seconds fallback
3. 如果 window_minutes 都不存在,使用传统假设
4. 添加详细注释说明这个陷阱
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
* fix: 修复 lint 问题 - 改进 fallback 逻辑的变量赋值
问题:
第882-883行的简单布尔赋值可能触发 ineffassign 或 staticcheck 警告:
use5hFromSecondary = snapshot.SecondaryUsedPercent != nil
use7dFromPrimary = snapshot.PrimaryUsedPercent != nil
修复:
改用明确的 if 语句检查任意字段是否存在,更符合代码意图:
- 如果 secondary 的任意字段存在,将其视为 5h
- 如果 primary 的任意字段存在,将其视为 7d
这样逻辑更清晰,也避免了 lint 警告。
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com >
Co-authored-by: OpenAI Codex <noreply@openai.com >
2025-12-25 17:00:02 +08:00
shaw
8fbe1ad70d
chore: 调整403重试次数跟间隔
2025-12-25 16:23:31 +08:00
Forest
25a304c231
test: 增加 repository 测试
2025-12-25 16:01:17 +08:00
刀刀
9d30ceae8d
CC 400 返回具体错误信息 && 非 CC 请求时增加 system prompt ( #26 )
...
* feat: http 400 返回具体错误
* 更新 workflows
* 优化打包/docker 构建流程
* 400 是返回 原始错误 - json 格式
* feat: 非 cc请求时补充 system
* go mod tidy
2025-12-25 14:47:19 +08:00
IanShaw
60f6ed6bf6
feat: CRS 同步增强 - 自动刷新 OAuth token 和修复测试配置 ( #27 )
...
* fix(service): 修复 OpenAI Responses API 测试负载配置
- 所有账号类型统一添加 instructions 字段(不再仅限 OAuth)
- Responses API 要求所有请求必须包含 instructions 参数
* feat(crs-sync): CRS 同步时自动刷新 OAuth token 并保留完整 extra 字段
**核心功能**:
- CRSSyncService 注入 OAuth 服务依赖(Anthropic + OpenAI)
- 账号创建/更新后自动刷新 OAuth token,确保可用性
- 完整保留 CRS extra 字段,避免数据丢失
**Extra 字段增强**:
- 保留 CRS 所有原始 extra 字段
- 新增同步元数据: crs_account_id, crs_kind, crs_synced_at
- Claude 账号: 从 credentials 提取 org_uuid/account_uuid 到 extra
- OpenAI 账号: 映射 crs_email -> email
**Token 刷新逻辑**:
- 新增 refreshOAuthToken() 方法处理 Anthropic/OpenAI 平台
- 保留原有 credentials 字段,仅更新 token 相关字段
- 刷新失败静默处理,不中断同步流程
**依赖注入**:
- wire_gen.go: CRSSyncService 新增 oAuthService/openaiOAuthService
* style(crs-sync): 使用 switch 替代 if-else 修复 golangci-lint 警告
- 将 refreshOAuthToken 中的 if-else 改为 switch 语句
- 符合 staticcheck 规范
- 添加 default 分支处理未知平台
2025-12-25 14:45:17 +08:00
ianshaw
372a01290b
fix(backend): handle defer Close() errors in crs_sync_service
...
修复 golangci-lint 错误检查问题
- 使用匿名函数包装 defer Close() 并忽略错误
- 符合 Go 最佳实践
2025-12-24 17:58:47 -08:00
ianshaw
62ed5422dd
feat(account): 优化批量更新实现,使用统一 SQL 合并 JSONB 字段
...
- 新增 BulkUpdate 仓储方法,使用单条 SQL 更新所有账户
- credentials/extra 使用 COALESCE(...) || ? 合并,只更新传入的 key
- name/proxy_id/concurrency/priority/status 只在提供时更新
- 分组绑定仍逐账号处理(需要独立操作)
- 前端优化:Base URL 留空则不修改,按勾选字段更新
- 完善 i18n 文案:说明留空不修改、批量更新行为
2025-12-24 17:16:19 -08:00
ianshaw
2e76302af7
feat(account): 添加批量编辑账户凭据功能并优化 CRS 同步
...
- 新增批量更新账户凭据接口(account_uuid/org_uuid/intercept_warmup_requests)
- 新增前端批量编辑模态框组件
- 优化 CRS 同步逻辑,改进 extra 字段处理
- 优化 CRS 同步 UI,添加更详细的结果展示
- 完善国际化文案(中英文)
2025-12-24 16:56:48 -08:00
ianshaw
6553828008
feat(account): 添加从 CRS 同步账户功能
...
- 添加账户同步 API 接口 (account_handler.go)
- 实现 CRS 同步服务 (crs_sync_service.go)
- 添加前端同步对话框组件 (SyncFromCrsModal.vue)
- 更新账户管理界面支持同步操作
- 添加账户仓库批量创建方法
- 添加中英文国际化翻译
- 更新依赖注入配置
2025-12-24 08:48:58 -08:00
ianshaw
adcb7bf00e
chore: 更新 .gitignore 忽略配置文件并还原 Makefile
...
- 添加 backend/config.yaml 到 .gitignore(包含敏感信息)
- 添加 deploy/config.yaml 到 .gitignore(包含敏感信息)
- 添加 backend/.installed 到 .gitignore
- 还原 Makefile 到原始版本
2025-12-24 08:48:49 -08:00
shaw
876e85e7ad
Merge branch 'feat/rename-go-module'
2025-12-24 21:34:37 +08:00
shaw
2e7818d688
feat(settings): 添加文档链接配置功能
...
- 后台系统设置新增文档链接(doc_url)配置项
- 首页顶部导航栏显示文档链接图标(条件渲染)
- Footer区域添加文档链接和GitHub链接
- 支持中英文国际化
2025-12-24 21:30:19 +08:00
Forest
836c4dda2b
refactor: 重命名 go module
2025-12-24 21:07:21 +08:00
shaw
e65e9587b4
fix(concurrency): 重构并发管理使用独立Key+原生TTL
...
问题:旧方案使用计数器模式,每次acquire都刷新TTL,导致僵尸数据永不过期
解决方案:
- 每个槽位使用独立Redis Key: concurrency:account:{id}:{requestID}
- 利用Redis原生TTL,每个槽位独立5分钟过期
- 服务崩溃后僵尸数据自动清理,无需手动干预
- 兼容多实例K8s部署
技术改动:
- 新增SCAN脚本统计活跃槽位数量
- 移除冗余的releaseScript,直接使用DEL命令
- Wait队列TTL只在首次创建时设置,避免刷新
2025-12-24 21:00:29 +08:00