|
|
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 |
|
|
|
765cb34019
|
feat: 添加 Redis Docker 容器编排及三级存储架构
- docker-compose.yml 新增 Redis 服务及 camtalk-net 桥接网络
- 实现 TieredManager 三级存储(L1 内存 → L2 Redis → L3 PostgreSQL)
- config.go 新增 Redis/Persistence 配置类型及环境变量绑定
- 修复 CAMTALK_REDIS_ADDR 环境变量未被 Viper 绑定的问题
- .env.example 更新为三级存储配置并标注开发/部署地址差异
|
2026-06-19 22:53:06 +08:00 |
|
|
|
4ffd84510e
|
refactor: 清理旧编排代码,新增 eino 包单元测试
删除旧代码:
- orchestrator/pipeline.go: 旧 STT→LLM→TTS 手写 goroutine 管道
- orchestrator/splitter.go: 旧句子切分器
- orchestrator/pipeline_test.go: 旧 Pipeline 测试
- ai/llm/openai.go: 旧 LLM OpenAI 实现(被 eino-ext ChatModel 替代)
- ai/llm/openai_test.go: 旧 LLM 测试
保留的接口和工具:
- orchestrator/orchestrator.go: Orchestrator 接口(ws/handler 依赖)
- orchestrator/sender.go: Sender 接口(eino/callback 依赖)
- ai/llm/llm.go: Request/Chunk/TokenUsage 类型定义
- ai/llm/prompt.go: BuildSystemPrompt(eino/nodes_history 依赖)
- ai/llm/scenarios.go: GetScenarioPrompt(eino/nodes_history 依赖)
新增测试:
- eino/graph_test.go: 13 个测试覆盖类型构建、State 并发安全、
Context 注入、延迟计算、接口实现检查等
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-19 22:04:39 +08:00 |
|
|
|
4b731b5ac0
|
feat: 实现 Eino Graph 构建与 Orchestrator 适配器,切换 main.go
- graph.go: 构建 Graph 拓扑 START→STT→History→ChatModel→Splitter→TTS→Done→END
- 创建 eino-ext ChatModel 对接 DashScope OpenAI 兼容接口
- 统一使用值类型(PipelineInput/PipelineOutput)
- Callback 在运行时通过 Stream option 传入
- adapter.go: EinoOrchestrator 实现 orchestrator.Orchestrator 接口
- 解码 base64 音频/图片,注入 context 值
- 调用 Graph.Stream() 触发惰性执行并消费输出
- 追加用户/助手消息到历史
- main.go: 移除旧 llmService + orchestrator.New()
替换为 eino.NewPipelineGraph() + eino.NewEinoOrchestrator()
- 各节点统一使用值类型,State 传递请求元数据
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-19 21:58:17 +08:00 |
|
|
|
fd5c7712f8
|
feat: 引入 Eino 框架并实现 AI 编排层基础设施与节点
- 引入 cloudwego/eino v0.9.9 和 eino-ext/components/model/openai v0.1.13
- 新增 internal/eino/ 包:
- types.go: PipelineInput/Output、STTOutput、TokenUsage 类型定义
- state.go: PipelineState 跨节点状态收集(线程安全)
- callback.go: ChatModel OnEndWithStreamOutput 回调,逐 token 推送 llm_chunk
- nodes_stt.go: STT Lambda,支持文本/语音输入模式
- nodes_history.go: 历史组装 Lambda,含多模态图片支持
- nodes_splitter.go: 句子分割 Transform Lambda
- nodes_tts.go: TTS Lambda,逐句合成推送音频
- nodes_done.go: Done Lambda,发送 llm_done 并追加历史
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-19 21:49:28 +08:00 |
|
|
|
c0b4eeda46
|
refactor: 统一配置文件系统
- 补全 backend/config.yaml 所有非敏感配置项并添加中文注释
- 重写 config.go:Load(workDir) 显式传参,BindEnv 绑定敏感字段,删除 AutomaticEnv
- setDefaults 默认值与 config.yaml 保持一致(mimo/dashscope)
- backend/.env.example 重写为纯敏感信息模板
- .env 固定在 /opt/camtalk/.env,docker-compose 通过绝对路径加载
- deploy.sh 统一使用 --env-file,移除硬编码 IP
- deploy.yml 删除 CI 写入 .env 的步骤
- Dockerfile 移除 COPY config.yaml
- 修复 deploy.yml 中 POSTGRES_PASSWORD 的 &{{ 拼写错误
|
2026-06-19 18:41:35 +08:00 |
|
|
|
6db5bef519
|
Merge pull request 'fix: 修复 Docker Compose 环境下 PostgreSQL 连接失败' (#114) from fix/actions into develop
Reviewed-on: http://8.161.227.145:3000/XEngineers/CamTalk/pulls/114
|
2026-06-14 20:48:31 +08:00 |
|
|
|
1ddd75d34f
|
fix: 修复 Docker Compose 环境下 PostgreSQL 连接失败
|
2026-06-14 20:47:00 +08:00 |
|
|
|
b60e513317
|
feat:添加对话情景功能
|
2026-06-14 20:32:30 +08:00 |
|
|
|
c3118dd72a
|
feat:语音对话优化
|
2026-06-14 19:54:22 +08:00 |
|
|
|
966b30218a
|
feat: 实现 sessions 持久化,支持会话恢复
|
2026-06-14 18:54:18 +08:00 |
|
|
|
542720695d
|
feat: 对接 PostgreSQL 存储层
|
2026-06-14 18:40:37 +08:00 |
|
|
|
c3a32ce276
|
feat: Phase 8.5 — ConversationSummary 查询优化,支持 SQL 聚合获取消息统计
|
2026-06-14 17:58:42 +08:00 |
|
|
|
7b745018c5
|
feat: Phase 8.4 — 实现 LoadSession 和 LoadSessionFromDB,支持从 PostgreSQL 恢复会话到内存
|
2026-06-14 17:56:33 +08:00 |
|
|
|
f4515ce5e4
|
feat: Phase 8.3 — Session Manager 注入 MessageRepository,AppendMessage 启用 Write-Through
|
2026-06-14 17:54:33 +08:00 |
|
|
|
96f4bc7abb
|
feat: Phase 8.2 — 实现 PostgreSQL MessageRepository
|
2026-06-14 17:53:14 +08:00 |
|
|
|
dae5722945
|
feat: Phase 8.1 — 定义 MessageRepository 接口和消息表迁移脚本
|
2026-06-14 17:52:21 +08:00 |
|
|
|
3c5c4943e8
|
feat: Phase 7.7 — 编写 WS 认证测试
- TestWS_AuthMissingToken: 无 token 返回 401
- TestWS_AuthInvalidToken: 无效 token 返回 401
- TestWS_AuthExpiredToken: 过期 token 返回 401
- TestWS_AuthValidToken: 有效 token 成功连接
- TestWS_AuthConversationIDResume: conversation_id 恢复已有对话
- TestWS_AuthConversationIDNotFound: 不存在的 conversation_id 返回 401
- TestWS_AuthConversationIDOwnership: 非 owner 访问返回 401
|
2026-06-14 17:48:47 +08:00 |
|
|
|
80c6b1b56e
|
feat: Phase 7.3 — WS conversation_id 处理
- ?conversation_id=xxx 存在时校验 session 归属(UserID 匹配)
- 校验失败返回 401 SESSION_NOT_FOUND
- 校验通过则复用已有 session;否则创建新 session
|
2026-06-14 17:47:34 +08:00 |
|
|
|
905b56640e
|
feat: Phase 7.2 — WS 连接 JWT 认证
- 从 ?token=xxx 查询参数提取 access_token
- 校验失败返回 401(missing token / invalid token)
- 校验成功后将 userID 用于创建会话
- 更新现有测试:setupTestServer 自动生成有效 token
|
2026-06-14 17:47:05 +08:00 |
|
|
|
2aa3c98ab6
|
feat: Phase 7.1 — 修改 ServeWS 签名,新增 tokenMgr 参数
- ServeWS 和 serveWS 函数新增 *auth.TokenManager 参数
- main.go 传入 tokenMgr 到 ServeWS
- handler_test.go 适配新签名
|
2026-06-14 17:46:11 +08:00 |
|
|
|
d01aeaba68
|
feat: 编写 ConversationHandler API 测试(httptest + mock SessionManager)
- List: 成功、分页参数、未认证 401
- Create: 成功、自定义配置
- Get: 成功、404 未找到、404 权限不足(隐藏信息)
- UpdateTitle: 成功、空标题校验、超长标题校验
- Delete: 成功、权限不足
- GetMessages: 成功、limit 分页、before 偏移分页、权限不足
- 共 17 个 Conversation 测试用例,全部通过
|
2026-06-14 17:41:28 +08:00 |
|
|
|
f902e05e31
|
feat: main.go 接入 ConversationHandler 路由注册
|
2026-06-14 17:39:39 +08:00 |
|
|
|
62baa656ee
|
feat: 实现 ConversationHandler(对话 CRUD + 消息查询 + 权限校验 + 路由注册)
- List: GET /api/conversations 获取当前用户对话列表(分页)
- Create: POST /api/conversations 创建新对话
- Get: GET /api/conversations/:id 获取对话详情
- UpdateTitle: PATCH /api/conversations/:id 更新对话标题
- Delete: DELETE /api/conversations/:id 删除对话
- GetMessages: GET /api/conversations/:id/messages 获取消息列表
- 所有端点通过 AuthMiddleware 认证
- getSessionForUser 校验 session.UserID == claims.UserID
- 返回 404 而非 403 避免信息泄露
|
2026-06-14 17:39:20 +08:00 |
|
|
|
ec8555d44b
|
feat: 编写 Session Manager 新方法测试(ListByUser 分页、UpdateTitle、自动标题生成)
|
2026-06-14 17:36:38 +08:00 |
|
|
|
6487a8ecab
|
feat: 扩展 Session Manager 接口,新增 ListByUser、UpdateTitle 方法
- Manager.Create 签名新增 userID 参数
- 新增 ConversationSummary 类型和 ListByUser 分页查询
- 新增 UpdateTitle 方法
- MemoryManager 实现:ListByUser 遍历+过滤+排序,UpdateTitle,自动标题生成
- RedisManager 实现:user:{id}:sessions 索引,ListByUser 通过 SMEMBERS 查询
- AppendMessage 自动更新标题(首条 user 消息时,取前 20 字符)
- 更新 ws handler、api/session.go、orchestrator mock 的 Create 调用
|
2026-06-14 17:35:20 +08:00 |
|
|
|
9ff971fd89
|
feat: 扩展 Session 模型,新增 UserID、Title、UpdatedAt 字段
|
2026-06-14 17:30:59 +08:00 |
|
|
|
c01ee1d14c
|
feat: 编写 AuthHandler API 测试(httptest + mock AuthService,覆盖全部端点)
|
2026-06-14 17:28:13 +08:00 |
|
|
|
9aaed88cc1
|
feat: main.go 接入认证服务(TokenManager + AuthService + AuthHandler 路由注册)
|
2026-06-14 17:26:50 +08:00 |
|
|
|
15b437043f
|
feat: 实现 AuthHandler(注册/登录/刷新/登出端点 + 输入校验 + 路由注册)
|
2026-06-14 17:25:50 +08:00 |
|
|
|
fdea3aa9d1
|
feat: 新增认证相关错误码(USERNAME_TAKEN, INVALID_CREDENTIALS, INVALID_TOKEN, INVALID_INPUT)
|
2026-06-14 17:24:57 +08:00 |
|
|
|
f878988048
|
feat: 编写 AuthService 单元测试(mock UserRepository)
|
2026-06-14 17:18:22 +08:00 |
|
|
|
e455af6b2d
|
feat: 编写 TokenManager 单元测试
|
2026-06-14 17:17:28 +08:00 |
|
|
|
5211d14d50
|
feat: 定义并实现 AuthService(注册/登录/刷新/登出)
|
2026-06-14 17:14:52 +08:00 |
|
|
|
5b8cbb025f
|
feat: 实现 JWT 认证中间件(AuthMiddleware)
|
2026-06-14 17:13:54 +08:00 |
|
|
|
fca9108882
|
feat: 实现密码哈希与校验工具(bcrypt)
|
2026-06-14 17:07:51 +08:00 |
|
|
|
20597101f5
|
feat: 实现 TokenManager(JWT 签发/校验/哈希)
|
2026-06-14 17:07:12 +08:00 |
|
|
|
9842b4a457
|
feat: 编写 UserRepository 单元测试
|
2026-06-14 16:56:29 +08:00 |
|
|
|
ce13e5a048
|
feat: 实现内存 UserRepository(测试用)
|
2026-06-14 16:55:44 +08:00 |
|
|
|
36827edfea
|
feat: 实现 PostgreSQL UserRepository
|
2026-06-14 16:55:12 +08:00 |
|
|
|
af73e78aa3
|
feat: 定义 UserRepository 接口及 User 数据模型
|
2026-06-14 16:54:21 +08:00 |
|