fix: 添加.gitignore规则排除编译产物 + 添加10轮持续调试报告
- 排除 voice-service/main, main2, voice-svc-new (各8.5MB) - 排除 gateway/cmd/gateway (15MB) - 添加 docs/fixes/2026-05-19-round7-continuous-debugging-report.md 10轮持续调试汇总: 19个Bug (5 P0, 5 P1, 4 P2, 5 P3)
This commit is contained in:
@@ -36,6 +36,14 @@ backend/tool-engine/tool-engine
|
||||
backend/voice-service/voice-service
|
||||
backend/voice-service/cmd/voice-service
|
||||
|
||||
# Compiled binaries (voice-service)
|
||||
backend/voice-service/main
|
||||
backend/voice-service/main2
|
||||
backend/voice-service/voice-svc-new
|
||||
|
||||
# Compiled binaries (gateway)
|
||||
backend/gateway/cmd/gateway
|
||||
|
||||
# Stale build artifact (legacy)
|
||||
backend/cmd
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,225 @@
|
||||
# Cyrene 持续性调试报告 — 10轮汇总
|
||||
|
||||
**日期**: 2026-05-19
|
||||
**时间范围**: UTC+8 约21:30 — 23:35
|
||||
**总轮次**: 10
|
||||
**环境**: 本地开发 (非Docker),7个核心服务 + PostgreSQL + DevTools
|
||||
|
||||
---
|
||||
|
||||
## 一、调试轮次总览
|
||||
|
||||
| 轮次 | 角度 | 关键发现数 |
|
||||
|------|------|-----------|
|
||||
| 第1轮 | 服务间通信与API契约验证 | 4 |
|
||||
| 第2轮 | IoT设备控制与工具链验证 | 2 |
|
||||
| 第3轮 | 端到端功能测试与安全验证 | 2 |
|
||||
| 第4轮 | LLM思维记忆优化与工具扩展 | 3 |
|
||||
| 第5轮 | 独立服务抽取与调用记录 | 4 |
|
||||
| 第6轮 | 多会话架构、自主思考重构与综合Bug修复 | 8 |
|
||||
| 第7轮 | 认证安全与前端消息类型完整性 | 2 |
|
||||
| 第8轮 | 并发安全与跨服务韧性 | 3 |
|
||||
| 第9轮 | 部署配置与Docker完整性 | 4 |
|
||||
| 第10轮 | 编译产物与构建完整性 | 2 |
|
||||
|
||||
---
|
||||
|
||||
## 二、所有Bug汇总 (按优先级)
|
||||
|
||||
### 🔴 P0 — 严重/阻塞 (5个)
|
||||
|
||||
| # | 来源轮次 | 问题 | 文件位置 | 影响 |
|
||||
|---|---------|------|---------|------|
|
||||
| 1 | R6 | Session [`randomID()`](backend/gateway/internal/handler/session_handler.go:576-582) 确定性输出导致ID冲突 | [`session_handler.go:576-582`](backend/gateway/internal/handler/session_handler.go:576) | 使用 `letters[i%len(letters)]` 而非 `crypto/rand`,每次生成相同序列;会话/消息ID可预测且可能碰撞 |
|
||||
| 2 | R6 | TTS fallback不可达 | [`tts_handler.go:55-65`](backend/voice-service/internal/handler/tts_handler.go:55) | handler层 [`IsAvailable()`](backend/voice-service/internal/handler/tts_handler.go:55) 检查在第55行就返回503,导致 [`voice_handler.go`](backend/gateway/internal/handler/voice_handler.go) 中Gateway配置的fallback逻辑永远不会被触发 |
|
||||
| 3 | R8 | 编排器/子会话goroutine缺少 `defer recover()` | [`orchestrator.go:81`](backend/ai-core/internal/orchestrator/orchestrator.go:81), [`manager.go:90/137`](backend/ai-core/internal/subsession/manager.go:90) | 3处 `go func()` 启动的goroutine中任何panic都会导致整个进程崩溃,无优雅恢复机制 |
|
||||
| 4 | R9 | 管理员权限中间件逻辑错误 | [`router.go:231`](backend/gateway/internal/router/router.go:231) | [`adminAuth()`](backend/gateway/internal/router/router.go:231) 检查 `admin_` 前缀但实际 user_id 为 `user_admin` 格式([`auth_handler.go:97`](backend/gateway/internal/handler/auth_handler.go:97)),导致管理员永远无法通过中间件鉴权 |
|
||||
| 5 | R10 | 40MB编译产物被Git追踪 | [`voice-service/main`](backend/voice-service/main), [`voice-service/main2`](backend/voice-service/main2), [`voice-service/voice-svc-new`](backend/voice-service/voice-svc-new), [`gateway/cmd/gateway`](backend/gateway/cmd/gateway) | [`.gitignore`](.gitignore) 未覆盖 `voice-service/main`、`voice-service/main2`、`voice-service/voice-svc-new`、`gateway/cmd/gateway` 四个二进制文件;每次提交携带约40MB无用二进制 |
|
||||
|
||||
### 🟡 P1 — 高优先级 (5个)
|
||||
|
||||
| # | 来源轮次 | 问题 | 文件位置 | 影响 |
|
||||
|---|---------|------|---------|------|
|
||||
| 6 | R6 | Gateway缺少IoT代理路由 | [`router.go`](backend/gateway/internal/router/router.go) | Gateway未注册IoT设备查询/控制的代理路由,前端无法通过Gateway统一入口访问IoT功能 |
|
||||
| 7 | R7 | 普通用户登录不验证密码 | [`auth_handler.go:99-101`](backend/gateway/internal/handler/auth_handler.go:99) | MVP阶段注释写明"简化逻辑",任意用户名无需密码即可登录获取JWT Token;需实现bcrypt密码哈希验证 |
|
||||
| 8 | R8 | IoT Client不使用context | [`iot_client.go:71`](backend/ai-core/internal/tools/iot_client.go:71) | 使用 [`client.Get()`](backend/ai-core/internal/tools/iot_client.go:71) 而非 `NewRequestWithContext`,无法传递超时/取消信号;IoT服务不可用时调用方会无限阻塞 |
|
||||
| 9 | R8 | 跨服务HTTP调用无重试/熔断 | Gateway → ai-core / memory-service / tool-engine 等多处 | 所有跨服务HTTP调用均为单次请求,无重试策略、无熔断器、无降级逻辑;下游服务短暂不可用即导致请求失败 |
|
||||
| 10 | R9 | 登录用户名无输入校验 | [`auth_handler.go:91`](backend/gateway/internal/handler/auth_handler.go:91) | 用户名接受任意字符包括SQL注入payload (`'; DROP TABLE--`);虽然使用参数化查询但无长度/字符白名单限制,存在潜在风险 |
|
||||
|
||||
### 🟢 P2 — 中优先级 (4个)
|
||||
|
||||
| # | 来源轮次 | 问题 | 文件位置 | 影响 |
|
||||
|---|---------|------|---------|------|
|
||||
| 11 | R6 | Briefing AI摘要降级 | AI-Core `/api/v1/briefing/summarize` 端点 | AI-Core返回404时前端无友好降级提示;摘要生成失败静默 |
|
||||
| 12 | R7 | 前端缺少 `multi_message`/`stream_segments` 消息类型 | [`types/chat.ts`](frontend/web/src/types/chat.ts), [`MessageBubble.tsx`](frontend/web/src/components/chat/MessageBubble.tsx) | 第6轮引入的子会话架构产生的 [`MultiMessage`](backend/ai-core/internal/model/sub_session.go) 和 [`StreamEvent`](backend/ai-core/internal/model/sub_session.go) 类型在前端无对应渲染组件;多段消息被当作普通文本显示 |
|
||||
| 13 | R9 | Docker Compose缺少3个服务 | [`docker-compose.dev.yml`](docker-compose.dev.yml), [`docker-compose.yml`](docker-compose.yml) | memory (8091)、tool (8092)、voice (8093) 三个服务未加入Compose编排;无法一键启动完整环境 |
|
||||
| 14 | R10 | PWA缺少192x192图标 | [`manifest.json`](frontend/web/public/manifest.json), [`public/images/`](frontend/web/public/images/) | PWA manifest中引用的192x192图标文件不存在;影响PWA安装体验 |
|
||||
|
||||
### 🔵 P3 — 低优先级/改进建议 (5个)
|
||||
|
||||
| # | 来源轮次 | 问题 | 文件位置 | 影响 |
|
||||
|---|---------|------|---------|------|
|
||||
| 15 | R5 | 2个fire-and-forget goroutine无错误处理 | [`thinker.go`](backend/ai-core/internal/background/thinker.go), [`hub.go`](backend/gateway/internal/ws/hub.go) | 后台goroutine中的错误仅log.Printf,无告警/重试/降级;出现问题后运维难以发现 |
|
||||
| 16 | R5 | .gitignore需添加gateway编译产物 | [`.gitignore`](.gitignore) | 缺失 `backend/gateway/cmd/gateway` 条目;已在P0#5中汇总 |
|
||||
| 17 | R6 | Reminder `created_at` 为零值 | [`reminder_store.go`](backend/gateway/internal/store/reminder_store.go) | 创建提醒时未设置 `created_at` 字段,数据库中为 `0001-01-01`;影响提醒列表排序和展示 |
|
||||
| 18 | R9 | voice-service无Dockerfile | [`voice-service/`](backend/voice-service/) | 其他5个Go服务均有Dockerfile,voice-service缺失;无法通过Docker部署 |
|
||||
| 19 | R9 | Dockerfile Go版本与go.mod不一致 | [`ai-core/Dockerfile`](backend/ai-core/Dockerfile), [`gateway/Dockerfile`](backend/gateway/Dockerfile) 等多处 | 部分Dockerfile使用 `golang:1.22` 但 [`go.mod`](backend/go.work) 声明 `go 1.26`;可能导致编译失败或运行时行为差异 |
|
||||
|
||||
---
|
||||
|
||||
## 三、已验证通过的功能清单
|
||||
|
||||
### 编译验证 (6/6 Go服务 + 1前端)
|
||||
|
||||
| 模块 | 命令 | 结果 |
|
||||
|------|------|------|
|
||||
| `backend/ai-core` | `go vet ./...` | ✅ 通过 |
|
||||
| `backend/gateway` | `go vet ./...` | ✅ 通过 |
|
||||
| `backend/iot-debug-service` | `go vet ./...` | ✅ 通过 |
|
||||
| `backend/memory-service` | `go vet ./...` | ✅ 通过 |
|
||||
| `backend/tool-engine` | `go vet ./...` | ✅ 通过 |
|
||||
| `backend/voice-service` | `go vet ./...` | ✅ 通过 |
|
||||
| `frontend/web` | `tsc --noEmit` | ✅ 通过 |
|
||||
| `frontend/web` | `vite build` | ✅ 构建成功 |
|
||||
|
||||
### API端点测试 (已验证通过)
|
||||
|
||||
- ✅ Gateway 健康检查: `GET /api/v1/health`
|
||||
- ✅ 管理员登录: `POST /api/v1/auth/login` → 正确校验密码
|
||||
- ✅ 错误密码拒绝: `POST /api/v1/auth/login` → 401
|
||||
- ✅ 创建/列出/获取/删除会话
|
||||
- ✅ 消息持久化 (分页加载)
|
||||
- ✅ 管理员端点 (所有会话/活跃会话)
|
||||
- ✅ Memory-Service 记忆 CRUD + 语义查询 + 合并 + 衰减
|
||||
- ✅ Tool-Engine 工具列表 (13个工具) + 调用记录 + 统计
|
||||
- ✅ IoT Debug Service 设备列表 + 属性设置 (8种操作)
|
||||
- ✅ DevTools 仪表盘 + 数据库管理 + STT日志面板
|
||||
- ✅ WebSocket 实时通信 + SSE流式降级
|
||||
- ✅ 前端URL哈希路由 + 会话切换 + 竞态条件修复
|
||||
|
||||
### 架构功能验证
|
||||
|
||||
- ✅ 子会话并行分发架构 (IntentAnalyzer → Manager.Dispatch → Synthesizer)
|
||||
- ✅ 事件驱动自主思考 (`post_chat` + `silence` 触发)
|
||||
- ✅ 记忆三层注入 (核心/常用/其他)
|
||||
- ✅ Gateway代理层 (memory + tool-engine)
|
||||
- ✅ ai-core HTTP客户端调用外部服务
|
||||
- ✅ 前端MediaRecorder降级方案 (STT)
|
||||
- ✅ 前端双重WebSocket修复
|
||||
- ✅ 数据库模式演化 (ALTER TABLE ADD COLUMN IF NOT EXISTS)
|
||||
|
||||
---
|
||||
|
||||
## 四、统计
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| 测试覆盖的API端点 | 30+ |
|
||||
| 通过的API测试 | 25+ |
|
||||
| 发现Bug总数 | 19 (P0: 5, P1: 5, P2: 4, P3: 5) |
|
||||
| Go服务编译 | 6/6 通过 |
|
||||
| 前端TypeScript编译 | 通过 |
|
||||
| 前端Vite构建 | 通过 |
|
||||
| 涉及Go源文件 | 50+ |
|
||||
| 涉及前端文件 | 20+ |
|
||||
|
||||
---
|
||||
|
||||
## 五、建议优先修复路线
|
||||
|
||||
### 第一阶段: 安全与稳定性 (P0)
|
||||
|
||||
1. **R9-P0#4 — 管理员权限中间件**: 修改 [`router.go:231`](backend/gateway/internal/router/router.go) `adminAuth()` 的 `HasPrefix` 检查,使其匹配 [`auth_handler.go:97`](backend/gateway/internal/handler/auth_handler.go:97) 生成的 `admin_` 前缀格式;当前因 `user_admin` 格式不匹配导致管理员鉴权完全失效
|
||||
2. **R6-P0#1 — Session randomID**: 将 [`session_handler.go:576-582`](backend/gateway/internal/handler/session_handler.go:576) 的确定性伪随机替换为 `crypto/rand` 或 `uuid.New()`
|
||||
3. **R8-P0#3 — Goroutine panic recovery**: 在 [`orchestrator.go:81`](backend/ai-core/internal/orchestrator/orchestrator.go:81)、[`manager.go:90`](backend/ai-core/internal/subsession/manager.go:90)、[`manager.go:137`](backend/ai-core/internal/subsession/manager.go:137) 三处 `go func()` 开头添加 `defer recover()`
|
||||
4. **R6-P0#2 — TTS fallback**: 将 [`tts_handler.go:55`](backend/voice-service/internal/handler/tts_handler.go:55) 的 `IsAvailable()` 检查移除或改为返回特定错误码,让Gateway [`voice_handler.go`](backend/gateway/internal/handler/voice_handler.go) 的fallback逻辑可触发
|
||||
5. **R10-P0#5 — 二进制文件清理**: 在 [`.gitignore`](.gitignore) 添加缺失条目并使用 `git rm --cached` 移除已追踪的二进制文件
|
||||
|
||||
### 第二阶段: 功能完善 (P1)
|
||||
|
||||
6. **R7-P1#7 — 普通用户密码验证**: 在 [`auth_handler.go:99`](backend/gateway/internal/handler/auth_handler.go:99) 实现bcrypt密码哈希存储与验证
|
||||
7. **R8-P1#8 — IoT Client context传递**: 修改 [`iot_client.go:71`](backend/ai-core/internal/tools/iot_client.go:71) 使用 `NewRequestWithContext`
|
||||
8. **R8-P1#9 — HTTP重试/熔断**: 引入重试库 (如 `go-resiliency`) 包装跨服务HTTP调用
|
||||
9. **R6-P1#6 — Gateway IoT代理路由**: 在 [`router.go`](backend/gateway/internal/router/router.go) 注册IoT代理端点
|
||||
10. **R9-P1#10 — 用户名输入校验**: 在 [`auth_handler.go:91`](backend/gateway/internal/handler/auth_handler.go:91) 添加长度和字符白名单验证
|
||||
|
||||
### 第三阶段: 体验与运维 (P2/P3)
|
||||
|
||||
11. **R9-P2#13 — Docker Compose补全**: 在 [`docker-compose.dev.yml`](docker-compose.dev.yml) 和 [`docker-compose.yml`](docker-compose.yml) 添加 memory/tool/voice 三个服务
|
||||
12. **R7-P2#12 — 前端多消息类型渲染**: 在 [`types/chat.ts`](frontend/web/src/types/chat.ts) 和 [`MessageBubble.tsx`](frontend/web/src/components/chat/MessageBubble.tsx) 添加 `multi_message`/`stream_segments` 渲染支持
|
||||
13. **R10-P2#14 — PWA 192x192图标**: 生成并放置缺失的图标文件
|
||||
14. **R9-P3#18 — voice-service Dockerfile**: 参照其他服务为voice-service创建Dockerfile
|
||||
15. **R6-P2#11、R6-P3#17、R9-P3#19、R5-P3#15** — 其余P2/P3项择机修复
|
||||
|
||||
---
|
||||
|
||||
## 六、附录: 各轮次详细发现
|
||||
|
||||
### 第1轮 — 服务间通信与API契约验证
|
||||
|
||||
- **发现1**: WebSocket [`Message`](backend/gateway/internal/ws/hub.go:37) 结构体缺少 `ID` 字段 → 前端React key为空无法渲染
|
||||
- **发现2**: [`chat_handler.go`](backend/gateway/internal/handler/chat_handler.go:163) 缓存消息时未生成ID
|
||||
- **发现3**: 前端 `sessionStore` 和 `useWebSocket` 缺少消息fallback ID生成
|
||||
- **发现4**: 跨会话切换时旧消息闪现 (缺少 `activeSessionRef`)
|
||||
|
||||
### 第2轮 — IoT设备控制与工具链验证
|
||||
|
||||
- **发现1**: AI-Core只注册了 [`IoTQueryTool`](backend/ai-core/internal/tools/iot_tools.go) 未注册控制工具
|
||||
- **发现2**: IoT Debug Service [`Toggle()`](backend/iot-debug-service/cmd/main.go:212) 写锁内调用读锁导致死锁
|
||||
|
||||
### 第3轮 — 端到端功能测试与安全验证
|
||||
|
||||
- **发现1**: [`auth_handler.go:89`](backend/gateway/internal/handler/auth_handler.go:89) 管理员密码错误时静默降级为普通用户
|
||||
- **发现2**: 会话列表查询 `user_id` 匹配方式与存储不一致
|
||||
|
||||
### 第4轮 — LLM思维记忆优化与工具扩展
|
||||
|
||||
- **发现1**: 记忆表缺少 `importance`/`keywords`/`source` 列 → AutoMigrate不自动补列
|
||||
- **发现2**: [`iot_tools.go:88`](backend/ai-core/internal/tools/iot_tools.go:88) `fmt.Sprintf` 格式字符串参数不足
|
||||
- **发现3**: DevTools数据库管理缺少预检和重连机制
|
||||
|
||||
### 第5轮 — 独立服务抽取与调用记录
|
||||
|
||||
- **发现1**: Gateway代理记忆失败 → 缺少 `MEMORY_SERVICE_URL` 和 `TOOL_ENGINE_URL` 环境变量
|
||||
- **发现2**: 前端会话切换3个竞态条件
|
||||
- **发现3**: 二进制文件未被 `.gitignore` 完全覆盖
|
||||
- **发现4**: DevTools `startAllSequential` 未包含新服务
|
||||
|
||||
### 第6轮 — 多会话架构、自主思考重构与综合Bug修复
|
||||
|
||||
- **发现1**: 前端双重WebSocket → [`ChatContainer.tsx`](frontend/web/src/components/chat/ChatContainer.tsx) 和 [`App.tsx`](frontend/web/src/App.tsx) 各自调用 `useChat()`
|
||||
- **发现2**: Memory-Service数据库迁移失败 → `CREATE TABLE IF NOT EXISTS` 不补列
|
||||
- **发现3**: 语音STT不可用 → MediaRecorder降级方案
|
||||
- **发现4**: DevTools仪表盘数据库按钮失效 → 缺少 `id` 属性
|
||||
- **发现5**: Session `randomID()` 确定性输出 (P0#1)
|
||||
- **发现6**: TTS fallback不可达 (P0#2)
|
||||
- **发现7**: Gateway缺少IoT代理路由 (P1#6)
|
||||
- **发现8**: Briefing AI摘要降级 (P2#11)
|
||||
|
||||
### 第7轮 — 认证安全与前端消息类型完整性
|
||||
|
||||
- **发现1**: 普通用户登录不验证密码 (P1#7)
|
||||
- **发现2**: 前端缺少 `multi_message`/`stream_segments` 消息类型 (P2#12)
|
||||
|
||||
### 第8轮 — 并发安全与跨服务韧性
|
||||
|
||||
- **发现1**: 编排器/子会话goroutine缺少 `defer recover()` (P0#3)
|
||||
- **发现2**: IoT Client不使用context (P1#8)
|
||||
- **发现3**: 跨服务HTTP调用无重试/熔断 (P1#9)
|
||||
|
||||
### 第9轮 — 部署配置与Docker完整性
|
||||
|
||||
- **发现1**: 管理员权限中间件逻辑错误 (P0#4)
|
||||
- **发现2**: 登录用户名无输入校验 (P1#10)
|
||||
- **发现3**: Docker Compose缺少3个服务 (P2#13)
|
||||
- **发现4**: voice-service无Dockerfile (P3#18)
|
||||
- **发现5**: Dockerfile Go版本与go.mod不一致 (P3#19)
|
||||
|
||||
### 第10轮 — 编译产物与构建完整性
|
||||
|
||||
- **发现1**: 40MB编译产物被Git追踪 (P0#5)
|
||||
- **发现2**: PWA缺少192x192图标 (P2#14)
|
||||
|
||||
---
|
||||
|
||||
*报告由Cyrene持续性调试流程自动生成 — 2026-05-19*
|
||||
Reference in New Issue
Block a user