44 Commits
Author SHA1 Message Date
Sakurasan 5cb428bba9 feat: increase default timeout to 5 minutes 2026-08-31 16:56:18 +08:00
Sakurasan 3a836bf0e9 fix: curl 示例复制按钮逃逸到页头叠加在退出按钮上
上轮移动端修复误删容器 relative,absolute 按钮向上冒泡定位到
页面顶端。加回 relative 使按钮回到代码块右上角。
2026-08-28 21:22:40 +08:00
Sakurasan faf38e2fd3 fix: 修复移动端仪表盘横向溢出
375px 视口下页面被撑到 763px:快速开始卡片的 curl 示例 <pre>
固有宽度沿 flex/grid 链层层撑破祖先(子项默认 min-width:auto
不可收缩,overflow-x-auto 形同虚设)。

- ShellLayout:flex-1 容器与 main 加 min-w-0 切断宽度传播(所有页面受益)
- DashboardView:快速开始卡片各块加 min-w-0,pre 的边框/背景
  移入 overflow-hidden 容器、自身横滚

Playwright 实测 375px 视口滚动宽度 763 → 375,与视口齐平
2026-08-28 20:12:08 +08:00
Sakurasan 939a98d389 feat: show channel name in admin usage logs 2026-08-28 16:40:23 +08:00
Sakurasan 305b3ed731 refactor: 删除无用的模型展示名(display_name)字段
该字段仅存取、从不展示:管理列表只渲染 name,/v1/models 与用户侧
均不返回它。与渠道绑定 upstream_model 的名字映射职责重叠且悬空。
- store.Model 结构体、admin CRUD、seed 数据移除 display_name
- 前端编辑弹窗输入框、表单状态、types.ts 同步移除
- 本地库已 ALTER TABLE DROP COLUMN;生产残留列无害
2026-08-27 09:57:30 +08:00
Sakurasan a45a6e16bd fix: API Key 前缀调整为 sk-ot- 2026-08-26 15:57:04 +08:00
Sakurasan c78a473e59 feat: API Key 前缀改为 sk-ot
- apikey 包 prefix 常量 sk- → sk-ot(生成/校验/展示前缀统一驱动)
- 鉴权错误提示同步更新为 sk-ot 格式
- 测试断言改用常量,避免硬编码长度
- 前端 curl 示例与 README/PLANNING 文档同步
2026-08-25 00:34:50 +08:00
Sakurasan 8430ecc6c6 fix: use inline style for enabled channel highlight 2026-08-22 12:21:48 +08:00
Sakurasan 4aa8b79156 fix: use bg-accent-soft for enabled channel highlight 2026-08-22 12:17:45 +08:00
Sakurasan 94fd7fd40a feat: add highlight for enabled channels 2026-08-22 12:09:33 +08:00
Sakurasan 048de4c9a8 feat: add enable/disable toggle for channels 2026-08-22 02:12:10 +08:00
Sakurasan 42214d6f5e 管理后台用量统计支持按用户筛选:用户名输入 + datalist 自动补全,精确匹配解析为 user_id
- types: UsageLog 补 user_id 字段
- UsageView: 新增用户筛选输入框,防抖 300ms 拉取 admin/users 候选做下拉补全
- search 时将用户名经 admin/users 精确解析为 user_id 再过滤 admin/usage;未找到用户时 toast 报错
- 支持清除筛选一键还原
2026-08-20 01:58:02 +08:00
Sakurasan 10f51cbdae 请求明细支持查看原始请求/响应:OT_PROXY_LOG_RAW 开关控制,仅管理员记录与可见,流式全量捕获
- 配置: ProxyConfig.LogRaw (OT_PROXY_LOG_RAW, 默认 false)
- 存储: usage_logs 新增 raw_request/raw_response 文本列 (AutoMigrate)
- 网关: NewGateway 接收 logRaw 参数
- handlers: 三个协议入口按 开关+管理员 条件记录原始请求体
- passthrough: 非流式 copyAndCapture 捕获响应, 流式 streamCopy 累积全部原始 SSE 行, finishUsage 统一写入
- admin API: AdminUsage 返回 raw_request/raw_response (仅管理员)
- 前端: 用量页新增查看入口, 弹窗 tab 切换请求/响应
- gitignore: 修正 server/web/ 忽略规则(尾随空格导致未生效)
2026-08-20 00:37:48 +08:00
SakurasanandClaude fcaafdc807 前端: Base URL 输入限长 + 列表截断防撑破
- Input 组件支持 maxlength 透传
- 渠道表单 4 个 Base URL 输入框限 255 字符
- 渠道列表 Base URL 单元格截断显示(max-w-220px)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-17 20:30:09 +08:00
SakurasanandClaude 74424d980c 前端: 仪表盘快速开始卡片 + 移动端适配 + 主页 curl 用浏览器 host
- 仪表盘底部新增「快速开始」:Base URL(浏览器 host)+ 协议徽标 + curl 示例(可复制)
- 最近请求改为响应式两行(模型+状态 / token·成本·时间),窄屏不再挤压
- 主页调用演示改用 window.location.origin,去掉写死的 api.openteam.dev

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-17 20:30:03 +08:00
SakurasanandClaude c3dc28fb5b 前端: 仪表盘最近请求 canceled 显示灰色
- 控制台/管理后台仪表盘「最近请求」的 canceled 状态改为 neutral 灰色
- 与用量页保持一致的三态判断(success=ok / canceled=neutral / err)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 18:55:10 +08:00
SakurasanandClaude 4137b6fe20 渠道: 远程候选按渠道过滤 + key 掩码 + 移除批量导入端点
- 远程模型候选只排除本渠道已允许的模型,同名模型可被多个渠道各自允许
- 渠道 key 掩码统一 xxxxxxx******Mq4Y(保留前 7 位与后 4 位)
- 移除已弃用的批量导入端点 POST /channels/:id/models/import

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 18:55:05 +08:00
SakurasanandClaude d0c879a2ed 模型定价: 悬空模型标记 + 一键清除 + 允许渠道只读
- 无渠道绑定的模型以「悬空」琥珀色徽标 + 卡片着色标记
- 新增「清除悬空」一键删除未绑定渠道的模型(DELETE /models/unused)
- 移除页面内「绑定渠道」弹窗与 chips 的解除按钮,渠道支持列表只在渠道抽屉管理
- 缺失提示带上渠道真实模型名(upstream_model)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 18:54:59 +08:00
SakurasanandClaude 8194edb63d 前端: 用量页移动端卡片优化 + canceled 灰色 + 接口类型短标识
- 移动端卡片重排: 成本/状态右置, 协议在模型下方, 元信息分隔行
- canceled 状态徽章由 warn 改为 neutral(与成功/失败区分)
- 接口类型列改用短标识 chat/completions | responses | messages
- 管理后台页头搜索框移动端纵向排列

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 09:04:26 +08:00
SakurasanandClaude 6f895acf63 前端: API Keys 移动端卡片布局 + 复制兼容
- 移动端(md 以下)以卡片列表替代横向滚动表格, 展示配额/过期/最近使用
- 桌面表格补充配额/过期列, 移除创建时间列
- copyText 支持 Clipboard API + execCommand 回退(HTTP 环境可用)
- 删除文案由"吊销"改为"删除(不可恢复)"

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 09:04:26 +08:00
SakurasanandClaude db83972b6f 渠道: 分协议 Base URL + 模型抽屉/远程拉取/操作图标
- 渠道支持分协议 base_url(chat/responses/messages 各一), 网关按协议选 base 直通
  (如智谱三种格式不同 base, 一个渠道即可), UpstreamURL 按 proto 拼接
- 渠道模型改为下方抽屉: 当前绑定列表(内联改上游/解除)、从接口拉取(remote 预览+勾选添加)、手动添加
- 新增 /channels/:id/models/remote 预览接口; 操作按钮加 Phosphor 图标
- 修复 formats jsonb 更新未序列化问题; 手机端渠道卡片化

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 04:31:28 +08:00
SakurasanandClaude 7c4e80afac 前端: 移动端适配 + 模型定价手动添加入口
- 表格加 min-w 窄屏横向滚动; 弹窗/资料网格窄屏换列; 顶栏/头部防溢出
- 渠道页移动卡片化、其余页面头部换行、Toast 自适应宽
- 模型定价页顶部加快捷输入(模型名直接进创建弹窗), 接口导入不全可手动补

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 04:31:14 +08:00
SakurasanandClaude 9324a782d5 Passkey: 账户设置绑定 + 免密登录(WebAuthn)
- 引入 go-webauthn, Passkey 表存凭据, challenge 会话内存存储(带过期)
- API: /webauthn/register|login begin/complete, /webauthn/passkeys 列表/删除
- 配置 OT_WEBAUTHN_RP_ID/RP_ORIGIN/RP_NAME;登录成功发 JWT+refresh cookie
- 前端 lib/webauthn(编解码+凭据序列化+安全上下文检测), 账户设置绑定区, 登录页免密按钮
- 需 HTTPS 或 localhost(安全上下文)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 02:00:08 +08:00
SakurasanandClaude 057b1b2c0b 侧栏: 导航项加 Phosphor 图标
- 用户菜单(仪表盘/API密钥/用量/账户设置/管理)与管理后台菜单(总览/渠道/模型/用户/用量/配置)
  均加对应图标, 跨区跳转项(管理→/返回控制台→)用常规字重+箭头区分

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 01:59:58 +08:00
SakurasanandClaude 40c1ae43e9 模型定价: 一致性检查与提示(渠道可用模型应全部纳入定价)
- /admin/models 返回每模型 used/needs_pricing/denied + summary(total/unpriced/missing)
- missing 检测孤儿绑定(渠道提供但目录缺失)
- 模型定价页: 缺失警告、在用未定价提示、已禁止/未定价徽章

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 01:34:22 +08:00
SakurasanandClaude b365779188 模型限制: 系统配置全局开放/禁止 + 用户级限制 + 网关拦截
- User 新增 allowed_models/denied_models(用户级模型限制)
- 系统配置 model_allowlist/model_denylist 全局策略, 保存即时失效网关缓存
- 网关 checkModelAllowed: 用户级 > 全局(禁止命中→403, 白名单非空→仅白名单)
- 三个协议处理器均校验, 错误按客户端协议格式返回
- 配置页"模型限制"卡片(全局允许/禁止多选); 用户编辑支持允许/禁止模型

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 01:34:12 +08:00
SakurasanandClaude 866690b7ce 用户管理: 编辑按钮高亮 + 图标
- "编辑"按钮改为高亮(accent 边框/浅底/强调色) + PhNotePencil 图标
- "调余额"按钮加 PhCoins 图标

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 01:34:00 +08:00
SakurasanandClaude 298bf89c90 用户管理: 编辑用户信息(用户名/邮箱/重置密码/角色/状态)
- AdminPatchUser 扩展 username/email/password 更新, 含唯一性与格式校验
- 编辑弹窗补充用户名/邮箱/重置密码字段(留空不改密码)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 00:57:15 +08:00
SakurasanandClaude 79f3f4395c 渠道: 支持手工录入模型(无 /models) + 模型映射自定义名称
- AdminChannelAddModel 改为 upstream_model + custom_name:
  无 /models 接口的渠道直接填上游模型名, 可选自定义名作为客户端调用名,
  全局模型不存在时自动创建
- "支持的模型"弹窗: 手工添加 + 建议下拉(自建,紧贴输入框)/水平排列/交换位置
- 网关仍按绑定映射改写请求 model 字段

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 00:57:06 +08:00
SakurasanandClaude 4d4d09ba58 渠道: 模型名称映射(网关生效 + 渠道侧管理)
- 候选渠道携带 upstream_model, prepareUpstream 改写请求体 model 字段为上游名
- 新增渠道视角绑定 CRUD: GET/POST/PATCH/DELETE /admin/channels/:id/models
- 前端渠道页新增"模型映射": 列出绑定、内联改上游名、解除、添加
- rewriteModel 三种协议通用(model 均在顶层)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 00:09:01 +08:00
SakurasanandClaude 8d9940ad5a 渠道: Base URL 智能识别前缀/完整端点 + API 格式垂直堆叠
- upstreamURL 按内容智能拼接: 完整端点直接用 / 含 /v1 只拼资源路径 / 纯域名拼全路径
- resolveBaseURL 不再去 /v1, 交网关识别
- 渠道表 API 格式改垂直堆叠, 显示短标识 chat/completions / responses / messages
- 前端 Base URL 提示支持前缀或完整端点

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 00:08:52 +08:00
SakurasanandClaude 512e46664c 导航: 统一分区侧栏 + 新增用量统计页
- ShellLayout 按所在分区显示独立菜单:
  用户控制台(/console) 与 管理后台(/admin) 不混排, 各带跨区跳转(管理→/返回控制台→)
- /console 与 /admin 共用 ShellLayout, 移除 ConsoleLayout/AdminLayout 薄包装
- 新增 /admin/usage 用量统计页(全局请求明细, 按模型过滤+分页)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 20:55:56 +08:00
SakurasanandClaude a8e2cd214c 账户: 修改密码接口 + 账户设置页
- 后端 POST /auth/password: 校验旧密码(argon2id)后重哈希更新
- 前端 /console/settings 账户设置页: 个人资料卡 + 修改密码表单

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 20:55:45 +08:00
SakurasanandClaude eb57a09c5d API 密钥: 支持编辑与高级选项, 修复 jsonb 白名单更新
- 前端密钥页新增"编辑": 改名/每日配额/模型白名单/状态切换
- 新建密钥展开"高级选项": 每日 Token/请求上限、模型白名单
- 修复 PATCH 更新 allowed_models(jsonb)不走序列化导致失败,
  改为 JSON 字符串写入, 跨 SQLite/Postgres 可靠

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 20:55:26 +08:00
SakurasanandClaude d0bc28a4fe 渠道: 移除主页/favicon 特性, Base URL 可选+完整地址
- 回退渠道 homepage/favicon 字段与代理接口(未采用)
- Base URL 改为可选: 留空按供应商默认(openai/anthropic),
  兼容兼容型渠道必须填; 填完整地址(含 /v1)时归一化去尾
- 网关 upstreamURL 兜底去 /v1, 避免路径重复

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 20:55:17 +08:00
SakurasanandClaude 4f92d7e0a4 渠道: 新增主页字段 + 表格展示 favicon
- Channel 新增 homepage 字段(渠道主页)
- 后端 /admin/channels/:id/favicon 代理抓取 {homepage}/favicon.ico, 内存缓存 1h;
  服务端抓取可解析 localhost/内网主页, 避免浏览器跨域
- 前端渠道表单加"渠道主页"输入; 表格新增主页列(favicon + 域名), 加载失败回退灰色地球图标
- mock 上游提供 /favicon.ico 演示

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 17:01:45 +08:00
SakurasanandClaude d9dcbc4fb3 渠道: 移除供应商下拉, 格式多选为唯一配置
- 前端渠道表单去掉"供应商"下拉, 只保留"支持的 API 格式"多选(默认 chat)
- 后端 provider 改为可选字段: 为空时按 formats 推断(仅 messages→anthropic,
  含 responses→openai, 否则 compatible), 兼容旧数据
- 保存时校验至少选择一种格式

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 16:55:48 +08:00
SakurasanandClaude 5eff32afd8 渠道支持多 API 格式 + 协议全名展示
- Channel 新增 formats(jsonb: chat|responses|messages), 一个渠道可同时声明
  支持 OpenAI Chat Completions / OpenAI Responses API / Anthropic Messages
- 路由改为按渠道声明的 formats 决定直通/转换: 客户端协议在 formats 内直通,
  否则转换为其首选支持格式(chat > messages > responses)
- 兼容旧数据: formats 为空时按 provider 推断(openai→chat+responses, anthropic→messages, compatible→chat)
- 前端: 渠道表/表单展示 API 格式(支持多选), usage 明细显示协议全名
  (OpenAI Chat Completions / OpenAI Responses API / Anthropic Messages)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 16:47:03 +08:00
SakurasanandClaude 6adadebaf0 前端: 修复浅色模式白字 + 主题优化
- 修 nav 激活态残留 text-zinc-50 导致浅色下白字白底
- @theme 令牌改实色字面量, 浅色用 [data-theme=light] 覆盖同一批 --color-*
- 新增 soft 令牌(accent/ok/warn/err, color-mix 运行时解析)替代烘焙的透明度修饰符,
  修复 badge 实色底、focus ring 实线等问题
- ThemeToggle 改三选下拉(浅色/深色/跟随系统), 系统自动为显式选项
- 浅色强调色调深保证 WCAG 对比度, 全量复查无残留硬编码颜色类

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 16:30:11 +08:00
SakurasanandClaude a422034b2b 前端: 浅色模式 + 系统自动主题
- 引入语义化 CSS 变量令牌(bg/surface/edge/ink/muted/accent 等), data-theme 三态切换
- theme store(localStorage + 系统偏好跟随), 首屏内联脚本防主题闪烁
- ThemeToggle 组件(浅色/深色/跟随系统) 置于导航与控制台顶栏
- 全量替换硬编码 zinc/emerald/red 类为令牌, 图表基线/状态色随主题适配
- 浅色对比度校准(accent/err/warn 深浅各一套)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 16:20:43 +08:00
SakurasanandClaude 4846db9293 M3 收尾: 限流/配额 + 前端骨架屏 + 单端口托管前端
- ratelimit(内存计数): 密钥级每日请求数/Token 配额、用户级每秒速率
  (OT_RATELIMIT_USER_RPS), 超限返回 429
- 网关 Auth 前置配额/限流检查, finishUsage 累计密钥 token 用量
- 前端 Skeleton 组件 + Dashboard/管理总览加载态
- Go 服务托管 web/dist 静态资源(SPA 回退), 单端口即可访问前后端

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 16:13:09 +08:00
SakurasanandClaude ec4de8d913 M0-M4: 推倒重来基线(基建+用户/密钥/核心代理+前端+管理后台+三协议互转)
- 后端 Go+Gin+GORM: 配置(OT_ env)/SQLite/Postgres 双驱动、用户体系(argon2id+JWT access/refresh)、
  API Key(sk- 48位, 仅存 SHA-256 哈希)
- 代理网关: /v1/chat/completions、/v1/responses、/v1/messages、/v1/models;错误按客户端协议返回
- 三协议互转(convert 包): Chat↔Messages↔Responses 请求/响应 + 流式 SSE 逐事件转换(直通优先)
- 用量计费: 异步批量记账、余额扣减、balance_logs、usage_daily 日聚合
- 管理 API: 用户/渠道 CRUD+测试+模型导入/模型定价+绑定/统计/系统配置
- 前端 Vue3+TS+Tailwind(taste-skill 设计 tokens): Landing/登录注册/控制台/管理后台,
  自建组件+Phosphor 图标+自建 SVG 趋势图, 已过 web-design-guidelines 复查
- mock 上游: OpenAI+Anthropic 双协议模拟(含流式)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 15:34:06 +08:00
Sakurasan b25e9ec8a7 前端: 按 Web Interface Guidelines 全面重做
组件:
- Button: transition-all→明确属性列表, touch-action, aria-busy
- Input: name/spellcheck/inputmode/aria-invalid/aria-describedby, focus-visible ring,
  label 关联, 暴露 focus() 供错误定位, required 标记
- Modal: Escape 关闭 + focus trap + 焦点归还, overscroll-behavior: contain,
  aria-labelledby, body 滚动锁, touch-action
- 新增 Toast(aria-live polite) + pinia toast store

页面:
- ConsoleLayout: skip link, <main> 语义标签, aside/nav aria-label, aria-current,
  装饰 SVG aria-hidden, Intl 金额, translate=no 品牌/代码
- Dashboard: Intl.NumberFormat, 骨架屏 loading, aria-live 错误
- Keys: 字段级错误+焦点定位, toast 反馈(复制/吊销), name 属性
- Usage: select 加 label, 分页/筛选同步 URL(可深链), Intl 日期/金额, 表格 caption
- Login/Register: 字段级校验+错误定位, spellcheck=false, inputmode, autocomplete
- Landing: router-link 替换 href, aria-hidden, text-balance, scroll-mt
- index.html: theme-color + color-scheme

验证: playwright 22 项断言全过, WCAG AA 对比度 9 组全过, 零控制台错误
2026-08-15 13:32:18 +08:00
Sakurasan 360c6b33a6 M0+M1: 基建 + 用户/密钥/核心代理
后端 (Go/Gin/GORM):
- 配置(viper+env)、SQLite/Postgres 迁移、argon2id、AES-GCM 渠道密钥、JWT+refresh cookie
- 用户注册/登录/刷新/登出、API Key CRUD(仅存哈希、明文一次展示)
- 代理网关: /v1/chat/completions、/v1/responses、/v1/models 直通 OpenAI 渠道
  非流式+流式(SSE 零缓冲转发), 用量捕获(chat 末块/responses completed 嵌套),
  OpenAI 错误格式(401/402/404/502), 余额检查
- 异步批量记账 + 余额流水 + 日聚合, admin 用户/余额/配置 API
- 单测: crypto/jwt/apikey/流式 usage 提取

前端 (Vue3+TS+Vite+Tailwind v4):
- taste-skill 设计 tokens: 深色仪表盘, 石墨+信号铜色, Outfit+JetBrains Mono
- Landing/登录/注册, 控制台(仪表盘图表/密钥管理/用量明细)
- 基础组件 Button/Input/Badge/Modal, ECharts 用量图

部署: docker-compose(nginx+api+postgres), 双 Dockerfile, nginx SSE 反代
联调: scripts/mockupstream 本地 mock 上游, 端到端验证通过
2026-08-15 13:10:47 +08:00