|
|
6b4b033df3
|
feat: 日志级别优化(Phase 7)
- nodes_stt.go: STT 识别开始降为 Debug
- nodes_history.go: 历史组装完成降为 Debug
- nodes_tts.go: TTS 流中断降为 Debug
- 保持关键里程碑为 Info:query completed、tts synthesis started/completed
- 中间步骤详情降为 Debug,减少生产环境日志噪音
|
2026-06-21 22:37:23 +08:00 |
|
|
|
76d331c885
|
feat: Eino nodes 迁移到 trace 包(Phase 6.2)
- nodes_stt.go 使用 trace.FromContext 替换 logger.Log
- nodes_history.go 使用 trace.FromContext
- nodes_tts.go 使用 trace.FromContext
- nodes_done.go 使用 trace.FromContext
- 移除所有 nodes 中的 request_id 手动字段(自动附加)
- 所有日志消息改为英文
|
2026-06-21 22:36:15 +08:00 |
|
|
|
ad700743ef
|
feat: Eino adapter 和 callback 迁移到 trace 包(Phase 6.1)
- 移除 adapter.go 中的 ctxKeySessionID 定义
- 移除 callback.go 中的 ctxKeyRequestID 定义
- 统一使用 trace.WithSessionID/WithRequestID
- adapter.go 使用 trace.FromContext 替换 logger.Log
- callback.go 使用 trace.FromContext
- 移除双重日志,SetActiveRequest 失败直接返回错误
- 更新测试文件导入 trace 包
|
2026-06-21 22:33:49 +08:00 |
|
|
|
6ab4776e08
|
feat: WebSocket 追踪集成(Phase 5)
- 在 WebSocket 升级后生成连接级 trace_id
- 为每个 query 注入 request_id 到 context
- 使用 trace.FromContext 替换所有 logger.Log
- trace_id 贯穿整个 WebSocket 生命周期
- 自动附加 trace_id/session_id/request_id 到所有日志
|
2026-06-21 22:31:45 +08:00 |
|
|
|
c17798ec67
|
feat: 添加 HTTP 请求日志中间件(Phase 4)
实现内容:
- 创建 trace/gin_logger.go,实现 GinLogger 和 GinRecovery 中间件
- GinLogger 自动记录所有 HTTP 请求的 method/path/status/latency/client_ip
- GinRecovery 使用 zap 记录 panic 恢复信息,替代 gin.Recovery()
- 修改 main.go 注册三层中间件:TraceMiddleware -> GinLogger -> GinRecovery
- 所有日志自动附加 trace_id 和 request_id 字段
日志示例:
{
"level": "info",
"ts": "2026-06-21T22:26:07.610+0800",
"msg": "request completed",
"trace_id": "01KVN964KSY6BFDKB9S932NXB8",
"request_id": "01KVN964KSY6BFDKB9S932NXB8",
"method": "GET",
"path": "/api/health",
"status": 200,
"latency_ms": 0,
"client_ip": "::1"
}
测试:已验证健康检查接口日志正常输出
|
2026-06-21 22:26:43 +08:00 |
|
|
|
8a43f4406a
|
feat: 添加限流触发日志
|
2026-06-21 22:16:38 +08:00 |
|
|
|
065673fae2
|
feat: 添加会话接口日志(创建/销毁)
|
2026-06-21 22:15:53 +08:00 |
|
|
|
03c27e7790
|
feat: 添加对话接口错误日志(CRUD 操作)
|
2026-06-21 22:14:41 +08:00 |
|
|
|
0a59173476
|
feat: 添加 JWT 鉴权拒绝日志
|
2026-06-21 22:13:15 +08:00 |
|
|
|
939e43acd0
|
feat: 添加认证接口日志(登录/注册/刷新/登出)
|
2026-06-21 22:12:21 +08:00 |
|
|
|
87c3e7a8dd
|
refactor: OpenAI TTS 使用 trace.FromContext 支持追踪
|
2026-06-21 22:08:27 +08:00 |
|
|
|
d6e9555a97
|
refactor: MiMo TTS 使用 trace.FromContext 支持追踪
|
2026-06-21 22:08:00 +08:00 |
|
|
|
9c763ec12a
|
feat: Redis 会话历史解析错误日志截断保护
|
2026-06-21 22:06:10 +08:00 |
|
|
|
1bab02ae84
|
feat: OpenAI TTS 错误日志截断敏感文本
|
2026-06-21 22:05:35 +08:00 |
|
|
|
89d7b7c17c
|
feat: MiMo TTS 错误日志截断敏感文本
|
2026-06-21 22:05:13 +08:00 |
|
|
|
34d498510e
|
feat: STT 敏感文本降级为 Debug 并截断保护
|
2026-06-21 22:04:50 +08:00 |
|
|
|
104b28efd3
|
feat: 实现字符串截断工具函数用于敏感内容保护
|
2026-06-21 22:02:08 +08:00 |
|
|
|
a02a8bc374
|
feat: 实现 Gin trace 中间件生成并注入 trace ID
|
2026-06-21 22:01:50 +08:00 |
|
|
|
0d99d06f06
|
test: 验证 Eino Graph 正确传递 context.Value
|
2026-06-21 22:01:27 +08:00 |
|
|
|
8b18953010
|
feat: 实现 context-aware logger 自动附加 trace 字段
|
2026-06-21 22:00:32 +08:00 |
|
|
|
0108ef2064
|
feat: 实现 trace context 注入与提取功能
|
2026-06-21 22:00:12 +08:00 |
|
|
|
e0dc8272a5
|
feat: 实现并发安全的 ULID trace ID 生成器
|
2026-06-21 21:59:43 +08:00 |
|
|
|
11c3955bd6
|
feat: 添加 ULID 依赖用于 trace ID 生成
|
2026-06-21 21:59:16 +08:00 |
|
|
|
51117b43f6
|
fix: 修复 handler_test.go 中 ServeWS 缺少参数
|
2026-06-21 18:44:03 +08:00 |
|
|
|
492fb06c08
|
merge: 合并 feat/tokentime 到 develop,解决 limiter/scenarioRepo 参数冲突
|
2026-06-21 17:42:48 +08:00 |
|
|
|
1079e22699
|
feat: 实现自建情景功能
## 功能概述
- 用户可创建、编辑、删除自定义情景
- 支持自定义情景名称、图标、描述、Prompt、首句引导
- 完整的权限隔离,用户只能管理自己的情景
- 深度集成 Eino 框架,动态加载自建情景 Prompt
## 后端实现
### 数据库
- 新增 user_scenarios 表
- 支持用户配额(最多 20 个)
- 字段验证:description 可选,prompt 最小 10 字符
### API
- GET /api/scenarios - 获取用户情景列表
- POST /api/scenarios - 创建情景
- GET /api/scenarios/:id - 获取详情
- PATCH /api/scenarios/:id - 更新情景
- DELETE /api/scenarios/:id - 删除情景
### Eino 集成
- PipelineState 添加 UserID 字段
- nodes_history 动态加载用户自建情景
- GetScenarioPrompt 支持自建情景优先级
## 前端实现
### 组件
- CreateScenarioModal - 创建情景对话框
- EditScenarioModal - 编辑情景对话框
- ConfigPanel 改造 - 分组显示系统预置和自建情景
### Hook
- useScenarios - 合并系统和自建情景,提供 CRUD 接口
### 国际化
- 中文、英文、日文翻译支持
## 问题修复
- 修复 CORS 问题:使用 Vite 代理
- 统一验证规则:description 可选,prompt 最小 10 字符
- 修复数据库约束:使用 NULLIF 处理空字符串
## 文件变更
新增文件: 13 个
修改文件: 14 个
详见文档: docs/自建情景功能完整文档.md
|
2026-06-21 15:38:28 +08:00 |
|
|
|
032de796c8
|
docs: 重构文档结构,规范编号并整合冗余内容
## 主要变更
### 文档重构(减少 1199 行,-23%)
- 01-架构设计.md: 503→369 行 (-27%),删除 DDL/配置示例,精简鉴权/存储描述
- 02-接口文档.md: 1313→570 行 (-57%),删除 Go 接口/Orchestrator 实现/配置管理
- 07-成本控制.md: 65→59 行 (-9%),代码块替换为文件引用
### 文档编号规范化
- 08-功能创意.md → 删除(内容整合到 README.md "功能扩展方向")
- 10-Eino框架与编排设计.md → 08-Eino框架与编排设计.md
- 情景切换.md → 09-情景切换.md
- 12-鉴权体系.md → 10-鉴权体系.md
- 13-令牌桶限流.md → 11-令牌桶限流.md
### 交叉引用更新
- 01-架构设计.md: 更新对鉴权体系/令牌桶限流的引用为新编号
- README.md: 更新文档索引表、推荐阅读顺序、新增功能扩展方向
### 删除过时文档
- 09-技术名词解释.md(内容已整合到 03-技术选型.md)
- 10-Eino重构方案.md(历史记录,已完成)
- 11-Eino框架技术文档.md(已合并到 08)
- 情景切换功能完整文档.md(已规范化为 09)
## 重构原则
- 架构文档聚焦系统结构,移除实现细节
- 接口文档保留纯契约,删除内部实现
- 编号连续(01-11),语义清晰
- 通过交叉引用连接相关文档,避免重复
|
2026-06-21 14:48:03 +08:00 |
|
|
|
99fcd6bc29
|
fix: 修复 Dockerfile 配置文件路径
|
2026-06-21 13:27:29 +08:00 |
|
|
|
d53265755a
|
refactor: 移除生产环境配置文件中 CORS 配置
|
2026-06-21 12:39:33 +08:00 |
|
|
|
252cdcc8e7
|
refactor: 开发环境使用与生产环境相同的 AI 模型配置
- config.dev.yaml 补全 AI 服务配置(provider、model、endpoint)
- 保持开发环境超时时间较长(方便调试)
- 确保开发和生产环境使用相同的模型,避免环境差异导致的问题
|
2026-06-21 12:24:20 +08:00 |
|
|
|
515d7ae034
|
docs: 完善配置环境切换机制
- docker-compose.yml 添加 APP_ENV=prod 强制生产环境
- 更新 .env.example 的 APP_ENV 注释说明(开发/生产差异)
- CLAUDE.md 补充"配置环境切换"章节,说明本地开发和生产部署的配置切换方式
- 明确配置优先级:环境变量 > config.{env}.yaml > config.yaml > 默认值
配置差异:
- 开发环境:debug 日志、关闭限流、允许所有 CORS
- 生产环境:info/json 日志、启用限流、严格 CORS 白名单
验证通过:
- 本地开发:默认加载 config.dev.yaml(env=dev, debug 日志)
- 生产配置:APP_ENV=prod 加载 config.prod.yaml(env=prod, info 日志)
|
2026-06-21 01:14:29 +08:00 |
|
|
|
311330cea1
|
refactor: 重组配置文件到 config 目录
- 创建 backend/config/ 目录统一管理配置文件
- 移动 config.yaml 到 config/config.yaml
- 新增 config.dev.yaml 开发环境配置(debug 日志、关闭限流)
- 新增 config.prod.yaml 生产环境配置(info 日志、启用限流、严格 CORS)
- 更新配置加载逻辑,优先从 config/ 目录读取,兼容旧路径
- 更新 .gitignore,仅排除 .env,配置文件纳入版本控制
|
2026-06-21 01:07:47 +08:00 |
|
|
|
7adf81c6e5
|
feat: 集成限流器到服务
- main.go 初始化限流器(根据 Redis 可用性选择内存/Redis 实现)
- WebSocket handler 添加 query 消息限流(按 userID)
- Auth API 添加登录/注册限流(按 IP)
- refresh 和 logout 不限流(避免影响正常用户操作)
- 修复所有测试(传递 nil limiter 参数)
- 所有测试通过(包括 ws 和 api 集成测试)
|
2026-06-21 00:00:24 +08:00 |
|
|
|
ea00939c13
|
feat: 实现 Gin 限流中间件
- Middleware 函数返回 Gin 中间件
- keyFunc 参数支持灵活提取限流 key(IP/用户 ID 等)
- 限流触发时返回 HTTP 429 + Retry-After header
- 支持 nil limiter(跳过限流)和空 key(跳过限流)
- 完整单元测试(6 个测试用例,全部通过)
- 测试覆盖:允许、拒绝、nil limiter、空 key、keyFunc、Retry-After 舍入
|
2026-06-20 23:56:44 +08:00 |
|
|
|
b74fb3564d
|
feat: 实现 Redis 令牌桶限流器
- RedisLimiter 基于 Lua 脚本保证原子性
- Lua 脚本实现完整令牌桶算法(填充、消耗、TTL)
- fail-open 策略:Redis 故障时允许请求通过
- FormatKey 辅助函数格式化限流 key
- 完整单元测试(10 个测试用例,使用 miniredis)
- 测试覆盖:首次请求、耗尽、不同用户、补充、容量上限、零速率、TTL、故障降级
|
2026-06-20 23:55:37 +08:00 |
|
|
|
3b6226394b
|
feat: 实现内存令牌桶限流器
- Limiter 接口定义(Allow + Stop 方法)
- TokenBucket 实现(容量、填充速率、并发安全)
- MemoryLimiter 管理多用户令牌桶
- 后台 goroutine 定期清理不活跃桶(10 分钟)
- 完整单元测试覆盖(11 个测试用例,全部通过)
- 边界情况处理(rate=0、capacity=0、并发安全)
|
2026-06-20 23:53:36 +08:00 |
|
|
|
a6df8c9131
|
feat: 添加限流配置层
- Config 结构体新增 RateLimit 字段
- 新增 RateLimitConfig 和 BucketConfig 结构体定义
- config.yaml 新增 ratelimit 配置段(默认关闭)
- 设置默认值:query(10/0.2)、login(5/0.1)、register(3/0.05)
|
2026-06-20 23:51:45 +08:00 |
|
|
|
2fb23852ef
|
feat: 优化情景切换功能
|
2026-06-20 23:24:32 +08:00 |
|
|
|
9ba4eb4825
|
Merge pull request 'feat: 优化对话历史功能、增加首页登录页面' (#155) from feat/historychat into develop
Reviewed-on: http://8.161.227.145:3000/XEngineers/CamTalk/pulls/155
|
2026-06-20 20:06:39 +08:00 |
|
|
|
ab07e01adf
|
feat: 优化对话历史功能
|
2026-06-20 19:57:36 +08:00 |
|
|
|
12e2d24f37
|
fix: checkout 后显式 git fetch 切换触发分支,避免始终部署 main 代码;Dockerfile 添加 BuildKit cache mount 加速构建
|
2026-06-20 17:43:32 +08:00 |
|
|
|
ea70d2efc6
|
feat: main.go 注入 Redis 到 CachedUserRepository,启用 refresh token 二级缓存
- 将 rdb 变量提升到外层作用域,供 session 和 auth 共用
- Redis 启用时用 CachedUserRepository 包装 userRepo
- backfillTTL 使用 cfg.Auth.RefreshTTL 与 token 实际过期时间一致
|
2026-06-20 14:54:08 +08:00 |
|
|
|
a2a28a9f56
|
feat: CachedUserRepository — refresh token 的 Redis 缓存装饰器
- 装饰 UserRepository,仅缓存 refresh token 相关操作
- SaveRefreshToken: Write-Through,先写 DB 再写 Redis(SET + SADD)
- FindRefreshToken: Read-Through,Redis miss 时查 DB 并回填
- DeleteRefreshToken: 双删 DB + Redis
- DeleteUserRefreshTokens: 通过 Redis Set 批量清理缓存后删 DB
- Redis 操作失败时降级到纯 DB,不阻断主流程
|
2026-06-20 14:53:10 +08:00 |
|
|
|
898e30b526
|
feat: Refresh Token 复用检测 — 检测到已 rotation 的 token 被复用时吊销用户全部 refresh token
- Refresh 方法中 FindRefreshToken 返回 not found 时,检查 JWT 是否有效
- JWT 有效但 DB 不存在 → 判定为复用,调用 DeleteUserRefreshTokens 吊销该用户所有 token
- 增加 TestRefresh_ReuseDetectedRevokesAllTokens 测试覆盖复用场景
|
2026-06-20 14:51:34 +08:00 |
|
|
|
87c54b80c0
|
feat: JWT Claims 增加 TokenType 字段,ValidateAccess/ValidateRefresh 区分校验类型
- Claims 新增 TokenType 字段("access" / "refresh")
- GeneratePair 为 access/refresh token 分别设置 token_type
- ValidateAccess 校验后检查 token_type == "access"
- ValidateRefresh 校验后检查 token_type == "refresh"
- 增加 token 类型交叉校验测试
|
2026-06-20 14:50:19 +08:00 |
|
|
|
d53de4f33f
|
fix: CI/CD 部署固定到 /root/camtalk 目录,确保 compose 能正确管理容器生命周期
|
2026-06-20 13:33:05 +08:00 |
|
|
|
b8fd6a9330
|
fix: 修复 TieredManager 创建 session 时 L1/L2 ID 不一致导致 Redis 写入失败的问题
|
2026-06-20 11:54:21 +08:00 |
|
|
|
898d1474ec
|
Merge pull request 'feat: 重构用eino框架' (#128) from fea/newcode into develop
Reviewed-on: http://8.161.227.145:3000/XEngineers/CamTalk/pulls/128
|
2026-06-19 23:28:55 +08:00 |
|
|
|
eb1b90445f
|
fix: 修复 Eino Graph 类型不匹配和多模态消息问题
- 添加 msg2str 转换节点解决 ChatModel 输出 *schema.Message 与 Splitter 期望 string 的类型不匹配
- 将多模态图片内容从 system 消息移到 user 消息(DashScope API 仅支持 user/tool 角色的多模态内容)
- 修复 Content 和 UserInputMultiContent 不能同时设置的问题
- Splitter 输出改为 StreamReader[string](单句),TTS 改为 TransformableLambda 流式消费
- 修复 .env 中 PostgreSQL DSN 和 Redis ADDR 的 http:// 前缀问题
|
2026-06-19 23:24:01 +08:00 |
|
|
|
e5537aaa1e
|
fix: 修复 Dockerfile 运行阶段缺少 config.yaml 导致容器启动 panic
|
2026-06-19 23:23:30 +08:00 |
|