Commit Graph

49 Commits

Author SHA1 Message Date
shaw
0b6371174e fix(settings): 保存 Turnstile 设置时验证参数有效性 2025-12-31 21:11:10 +08:00
yangjianbo
7efa8b54c4 perf(后端): 完成性能优化与连接池配置
新增 DB/Redis 连接池配置与校验,并补充单测

网关请求体大小限制与 413 处理

HTTP/req 客户端池化并调整上游连接池默认值

并发槽位改为 ZSET+Lua 与指数退避

用量统计改 SQL 聚合并新增索引迁移

计费缓存写入改工作池并补测试/基准

测试: 在 backend/ 下运行 go test ./...
2025-12-31 08:50:12 +08:00
yangjianbo
aacbc98aec fix(仓储): 修复查询关闭错误并迁移集成测试
修复 rows.Close 失败时的错误返回逻辑
迁移网关路由集成测试到 ent 事务基建
补齐仓储接口变更对应的测试桩方法
新增 backend/Makefile 统一测试命令
测试: GOTOOLCHAIN=go1.24.11 go test ./...
测试: golangci-lint run ./... --timeout=5m
测试: make test-integration
2025-12-30 16:41:45 +08:00
yangjianbo
809ea23587 Merge branch 'main' of https://github.com/mt21625457/aicodex2api 2025-12-30 14:15:52 +08:00
shaw
2004230b66 Merge branch 'fix/token-invalidation-on-password-change' 2025-12-30 11:19:58 +08:00
yangjianbo
e83f0ee307 Merge branch 'main' into test-dev 2025-12-30 09:07:55 +08:00
Junming Chen
19d0ee130d fix: implement token invalidation on password change 2025-12-29 17:18:17 -05:00
song
21a04332ec fix: 修复 golangci-lint 检查错误
- SA1029: 创建 ctxkey 包定义类型安全的 context key
- ST1005: 错误字符串首字母改小写
- errcheck: 显式忽略 bytes.Buffer.Write 返回值
- 修复单元测试中 GatewayService 缺少 cfg 字段的问题
2025-12-29 17:46:52 +08:00
song
2bd288a677 Merge branch 'main' into feature/antigravity_auth 2025-12-29 17:04:40 +08:00
song
b31bfd53ab feat(antigravity): 添加专用路由,支持仅使用 antigravity 账户
添加 /antigravity/v1/* 和 /antigravity/v1beta/* 路由:
- 通过 ForcePlatform 中间件强制使用 antigravity 平台
- 跳过混合调度逻辑,仅调度 antigravity 账户
- 支持按分组优先查找,找不到时回退查询全部 antigravity 账户

修复 context key 类型不匹配问题:
- middleware 和 service 统一使用字符串常量 "ctx_force_platform"
- 解决 Go context.Value() 类型+值匹配导致的读取失败

其他改动:
- 嵌入式前端中间件白名单添加 /antigravity/ 路径
- e2e 测试 Gemini 端点 URL 添加 endpointPrefix 支持
2025-12-29 16:52:55 +08:00
yangjianbo
f6de36cb04 test(删除): 添加删除单测并修复中间件测试
新增 AdminService 删除路径单元测试与规范场景更新\n同步调整 Google API Key 中间件测试桩与签名
2025-12-29 15:01:19 +08:00
yangjianbo
3c3419475d Merge branch 'main' into test-dev 2025-12-29 10:50:46 +08:00
yangjianbo
3d617de577 refactor(数据库): 迁移持久层到 Ent 并清理 GORM
将仓储层/基础设施改为 Ent + 原生 SQL 执行路径,并移除 AutoMigrate 与 GORM 依赖。
重构内容包括:
- 仓储层改用 Ent/SQL(含 usage_log/account 等复杂查询),统一错误映射
- 基础设施与 setup 初始化切换为 Ent + SQL migrations
- 集成测试与 fixtures 迁移到 Ent 事务模型
- 清理遗留 GORM 模型/依赖,补充迁移与文档说明
- 增加根目录 Makefile 便于前后端编译

测试:
- go test -tags unit ./...
- go test -tags integration ./...
2025-12-29 10:03:27 +08:00
shaw
32b4b139a4 fix: 修复因移除 SimpleMode 导致的测试编译错误
- 移除 api_contract_test.go 中的 SettingKeySimpleMode 引用
- 移除期望响应中的 simple_mode 字段
- 修复 NewSettingHandler 调用参数数量
2025-12-29 09:24:21 +08:00
IanShaw027
ecfad788d9 feat(全栈): 实现简易模式核心功能
**功能概述**:
实现简易模式(Simple Mode),为个人用户和小团队提供简化的使用体验,隐藏复杂的分组、订阅、配额等概念。

**后端改动**:
1. 配置系统
   - 新增 run_mode 配置项(standard/simple)
   - 支持环境变量 RUN_MODE
   - 默认值为 standard

2. 数据库初始化
   - 自动创建3个默认分组:anthropic-default、openai-default、gemini-default
   - 默认分组配置:无并发限制、active状态、非独占
   - 幂等性保证:重复启动不会重复创建

3. 账号管理
   - 创建账号时自动绑定对应平台的默认分组
   - 如果未指定分组,自动查找并绑定默认分组

**前端改动**:
1. 状态管理
   - authStore 新增 isSimpleMode 计算属性
   - 从后端API获取并同步运行模式

2. UI隐藏
   - 侧边栏:隐藏分组管理、订阅管理、兑换码菜单
   - 账号管理页面:隐藏分组列
   - 创建/编辑账号对话框:隐藏分组选择器

3. 路由守卫
   - 限制访问分组、订阅、兑换码相关页面
   - 访问受限页面时自动重定向到仪表板

**配置示例**:
```yaml
run_mode: simple

run_mode: standard
```

**影响范围**:
- 后端:配置、数据库迁移、账号服务
- 前端:认证状态、路由、UI组件
- 部署:配置文件示例

**兼容性**:
- 简易模式和标准模式可无缝切换
- 不需要数据迁移
- 现有数据不受影响
2025-12-29 03:24:15 +08:00
song
995adaeee4 test: 添加 Claude signature 场景 e2e 测试
- 新增 TestClaudeMessagesWithClaudeSignature 测试
- 验证历史 thinking block 带有 Claude signature 时的处理
- 修复配额刷新服务的次要问题
2025-12-29 00:44:07 +08:00
shaw
25b8a22648 fix(test): 测试用例添加 simple_mode 字段
API 响应新增 simple_mode 字段,同步更新测试期望值
2025-12-28 22:51:22 +08:00
shaw
0084da9ca5 fix: 修复 NewSettingHandler 参数不足导致的编译错误
- 测试文件添加第三个参数 userService(nil)
- Handler 添加 userService 空指针检查,防止测试环境 panic
2025-12-28 22:45:13 +08:00
song
ff06583c5d Merge branch 'main' into feature/antigravity_auth 2025-12-28 18:46:18 +08:00
song
6648e6506c feat: 添加 Antigravity (Cloud AI Companion) OAuth 授权支持 2025-12-28 15:54:42 +08:00
yangjianbo
fd51ff6970 fix: 代码的核心问题是判错条件用错了层级:
- apiKeyService.GetByKey(...) 返回的“找不到 API key”在这个项目里通常会被翻译成业务错误(比如
    service.ErrApiKeyNotFound 这类 ApplicationError),而不是直接把 gorm.ErrRecordNotFound 透传到中
    间件层。
  - 因此你在中间件里用 errors.Is(err, gorm.ErrRecordNotFound) 去判断“无效 key”,很容易匹配不到(尤其
    是:后面加 Redis 缓存、换存储实现、或测试里用 stub repo 时,根本不会出现 gorm 的错误)。
  - 匹配不到时就会走到 500 Failed to validate API key,导致无效 API key 被错误地当成服务端故障返回
    500(应该是 401)。

  修复思路:中间件不要依赖 gorm 的错误,改成判断业务层错误,例如:

  if errors.Is(err, service.ErrApiKeyNotFound) {
      abortWithGoogleError(c, 401, "Invalid API key")
      return
  }

  如果你把 GetByKey 的“not found”统一封装成业务错误,这样才不会被底层实现(gorm/redis/mock)影响。
2025-12-28 14:34:05 +08:00
shaw
0743652d92 Merge branch 'feature/ui-and-backend-improvements' 2025-12-27 16:33:57 +08:00
IanShaw027
96bec5c9b1 fix(test): 实现GetUserStatsAggregated方法以支持新的统计查询
- 在stubUsageLogRepo中实现GetUserStatsAggregated方法
- 根据userLogs计算统计数据而不是返回错误
- 修复类型转换问题(int转int64)
2025-12-27 16:20:59 +08:00
IanShaw027
cfeb6b8b14 fix(test): 添加缺失的GetUserStatsAggregated方法 2025-12-27 16:15:32 +08:00
IanShaw027
481310dea0 fix(test): 修复CI测试失败
- 修复gofmt格式问题
- 为stubUsageLogRepo添加缺失的GetApiKeyStatsAggregated方法
2025-12-27 16:12:06 +08:00
IanShaw027
227d506c53 feat(backend): 增强使用统计和API密钥功能
- 优化使用统计处理逻辑
- 增强API密钥仓储层功能
- 改进账户使用服务
- 完善API契约测试覆盖
2025-12-27 16:03:57 +08:00
IanShaw
3f92a43170 test: 完善 UsageLogRepo 测试 stub 的过滤逻辑 (#50) 2025-12-27 13:53:47 +08:00
IanShaw
254f12543c feat(frontend): 前端界面优化与使用统计功能增强 (#46)
* feat(frontend): 前端界面优化与使用统计功能增强

主要改动:

1. 表格布局统一优化
   - 新增 TablePageLayout 通用布局组件
   - 统一所有管理页面的表格样式和交互
   - 优化 DataTable、Pagination、Select 等通用组件

2. 使用统计功能增强
   - 管理端: 添加完整的筛选和显示功能
   - 用户端: 完善 API Key 列显示
   - 后端: 优化使用统计数据结构和查询

3. 账户组件优化
   - 优化 AccountStatsModal、AccountUsageCell 等组件
   - 统一进度条和统计显示样式

4. 其他改进
   - 完善中英文国际化
   - 统一页面样式和交互体验
   - 优化各视图页面的响应式布局

* fix(test): 修复 stubUsageLogRepo.ListWithFilters 测试 stub

测试用例 GET /api/v1/usage 返回 500 是因为 stub 方法未实现,
现在正确返回基于 UserID 过滤的日志数据。

* feat(frontend): 统一日期时间显示格式

**主要改动**:
1. 增强 utils/format.ts:
   - 新增 formatDateOnly() - 格式: YYYY-MM-DD
   - 新增 formatDateTime() - 格式: YYYY-MM-DD HH:mm:ss

2. 全局替换视图中的格式化函数:
   - 移除各视图中的自定义 formatDate 函数
   - 统一导入使用 @/utils/format 中的函数
   - created_at/updated_at 使用 formatDateTime
   - expires_at 使用 formatDateOnly

3. 受影响的视图 (8个):
   - frontend/src/views/user/KeysView.vue
   - frontend/src/views/user/DashboardView.vue
   - frontend/src/views/user/UsageView.vue
   - frontend/src/views/user/RedeemView.vue
   - frontend/src/views/admin/UsersView.vue
   - frontend/src/views/admin/UsageView.vue
   - frontend/src/views/admin/RedeemView.vue
   - frontend/src/views/admin/SubscriptionsView.vue

**效果**:
- 日期统一显示为 YYYY-MM-DD
- 时间统一显示为 YYYY-MM-DD HH:mm:ss
- 提升可维护性,避免格式不一致

* fix(frontend): 补充遗漏的时间格式化统一

**补充修复**(基于 code review 发现的遗漏):

1. 增强 utils/format.ts:
   - 新增 formatTime() - 格式: HH:mm

2. 修复 4 个遗漏的文件:
   - src/views/admin/UsersView.vue
     * 删除 formatExpiresAt(),改用 formatDateTime()
     * 修复订阅过期时间 tooltip 显示格式不一致问题

   - src/views/user/ProfileView.vue
     * 删除 formatMemberSince(),改用 formatDate(date, 'YYYY-MM')
     * 统一会员起始时间显示格式

   - src/views/user/SubscriptionsView.vue
     * 修改 formatExpirationDate() 使用 formatDateOnly()
     * 保留天数计算逻辑

   - src/components/account/AccountStatusIndicator.vue
     * 删除本地 formatTime(),改用 utils/format 中的统一函数
     * 修复 rate limit 和 overload 重置时间显示

**验证**:
- TypeScript 类型检查通过 ✓
- 前端构建成功 ✓
- 所有剩余的 toLocaleString() 都是数字格式化,属于正确用法 ✓

**效果**:
- 订阅过期时间统一为 YYYY-MM-DD HH:mm:ss
- 会员起始时间统一为 YYYY-MM
- 重置时间统一为 HH:mm
- 消除所有不规范的原生 locale 方法调用
2025-12-27 10:50:25 +08:00
IanShaw
cf8a64528c fix: 修复 Gemini API 认证和 /responses 端点路由问题 (#45)
* fix(middleware): 修复 Gemini API Key 认证中间件用户上下文类型错误

修复了 ApiKeyAuthWithSubscriptionGoogle 中间件中设置用户上下文时的类型错误。

**问题:**
- 中间件直接设置 `apiKey.User` 对象到上下文
- 导致 handler 中获取 `AuthSubject` 时类型断言失败
- 所有 Gemini v1beta 端点返回 500 "User context not found"

**修复:**
- 改为设置 `AuthSubject` 结构体,与 `api_key_auth.go` 保持一致
- 添加 `ContextKeyUserRole` 设置以完整支持角色检查

**影响范围:**
- Gemini v1beta API 端点 (generateContent, streamGenerateContent)
- 使用 Google API Key 认证的所有请求

**测试:**
- 验证 Gemini CLI 调用成功返回 200
- 确认用户上下文正确传递到 handler

* fix(web): 修复 /responses 端点被前端中间件拦截的问题

- 将 /responses 路径添加到 API 白名单,防止其被当作前端路由处理
- 修复 /responses 端点返回 HTML 而非 API 响应的 BUG
- 解决 codex CLI stream 在远程服务器上断开连接的问题

根本原因:
在 6c469b4 提交中添加了 /responses 路由,但未同步更新前端嵌入中间件
的 API 白名单,导致该路由被拦截并返回 index.html 而非 API 响应。
2025-12-27 10:50:15 +08:00
IanShaw027
bfcd9501c2 merge: 合并 upstream/main 解决 PR #37 冲突
- 删除 backend/internal/model/account.go 符合重构方向
- 合并最新的项目结构重构
- 包含 SSE 格式解析修复
- 更新依赖和配置文件
2025-12-26 21:56:08 +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
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
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
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
e36fb98fb9 feat(handler): 添加 Gemini OAuth Handler 和完善依赖注入
- 新增 Gemini OAuth 授权处理器
- 扩展账号和网关处理器支持 Gemini
- 注册 Gemini 相关路由
- 更新 Wire 依赖注入配置(所有层)
- 更新 Docker Compose 配置
2025-12-26 00:09:46 -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
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
Forest
836c4dda2b refactor: 重命名 go module 2025-12-24 21:07:21 +08:00
dexcoder6
0b8e84f942 feat: 增强用户管理功能,添加用户名、微信号和备注字段
- 新增User模型字段:username(用户名)、wechat(微信号)、notes(备注)
- 扩展用户搜索功能,支持通过用户名和微信号搜索
- 添加用户个人资料更新功能,用户可自行编辑用户名和微信号
- 管理员用户列表新增用户名、微信号、备注显示列
- 备注字段仅对管理员可见,增强数据安全性
- 完善中英文国际化翻译
- 修复国际化文件中重复属性的TypeScript错误

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 11:26:22 +08:00
shaw
6c469b42ed feat: 新增支持codex转发 2025-12-22 22:58:31 +08:00
shaw
587012396b feat: 支持创建管理员APIKEY 2025-12-20 15:11:43 +08:00
shaw
ee86dbca9d feat(account): 账号测试支持选择模型
- 新增 GET /api/v1/admin/accounts/:id/models 接口获取账号可用模型
- 账号测试弹窗新增模型选择下拉框
- 测试时支持传入 model_id 参数,不传则默认使用 Sonnet
- API Key 账号支持根据 model_mapping 映射测试模型
- 将模型常量提取到 claude 包统一管理
2025-12-19 16:00:09 +08:00
shaw
52d2ae9708 feat(gateway): 添加 /v1/messages/count_tokens 端点
实现 Claude API 的 token 计数功能,支持 OAuth、SetupToken 和 ApiKey 三种账号类型。

特点:
- 校验订阅/余额(不扣费)
- 不计算用户和账号并发
- 不记录使用量
- 支持模型映射(ApiKey 账号)
- 支持 OAuth 账号的指纹管理和 401 重试
2025-12-19 11:12:41 +08:00
shaw
c15b419c4c feat(backend): 添加 event_logging 接口直接返回200
将原本在nginx处理的遥测日志请求移至后端,
忽略Claude Code客户端发送的日志数据。
2025-12-19 09:39:57 +08:00
Forest
236908c03d refactor(backend): 拆分 Wire ProviderSet 2025-12-19 00:03:29 +08:00