200 lines
12 KiB
Markdown
200 lines
12 KiB
Markdown
# 经验记录(Knowledge Base)
|
||
|
||
> 本文件按代码编纂工作流规范,以四段式记录项目修改过程中遇到的关键问题及解决方案。
|
||
> 格式: A. 具体问题 / B. 产生原因 / C. 解决方案 / D. 后续如何避免
|
||
|
||
---
|
||
|
||
## 2026-04-28-22-55-15 — 建立代码编纂工作流
|
||
|
||
### A. 具体问题
|
||
项目缺少标准化的代码修改流程,导致需求管理、方案设计、测试验证、知识沉淀等环节可能遗漏,影响项目质量和可维护性。
|
||
|
||
### B. 产生原因
|
||
项目初期以快速原型为主,未建立正式的工程化管理流程;随着功能增加,需要更严谨的变更管理机制。
|
||
|
||
### C. 解决方案
|
||
建立完整的代码编纂工作流,包含 10 个阶段:时间戳记录、工程分析、需求分析、实现方案(人工审核)、测试方案(人工审核)、执行前准备(阅读经验记录)、方案执行、经验沉淀、Gitea 备份、重新部署。
|
||
|
||
### D. 后续如何避免问题
|
||
- 后续所有项目修改严格按工作流执行
|
||
- 每次修改前检查工作流检查表
|
||
- 定期回顾经验记录,提取共性预防措施
|
||
|
||
---
|
||
|
||
## 2026-04-28-22-55-15 — 执行环境 Node.js 缺失
|
||
|
||
### A. 具体问题
|
||
执行 `npm run lint` 和 `npm run build` 时提示 `npm: command not found`,当前 Shell 环境未安装 Node.js 运行时。
|
||
|
||
### B. 产生原因
|
||
AI 助手运行的容器/环境与项目实际开发环境分离,后者才装有 Node.js 和 npm。
|
||
|
||
### C. 解决方案
|
||
- 文档创建和 git 操作可在 AI 环境中完成
|
||
- 构建验证(`npm run lint`、`npm run build`、`npm start`)需由用户在本地开发环境执行,或 AI 提供精确命令由用户自行运行
|
||
- **实际解决**: 用户提供了 sudo 权限和密码后,AI 通过 NodeSource 安装了 Node.js 22.x(`curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash` + `sudo apt install -y nodejs`),随后成功执行了完整部署流程
|
||
- 在经验记录中标注此限制和解决方案,提醒后续流程
|
||
|
||
### D. 后续如何避免问题
|
||
- 每次执行阶段 6 和阶段 9 前,先检查 `which npm`
|
||
- 如 npm 不可用,向用户申请 sudo 权限安装 Node.js,或使用项目预设的容器/CI 环境
|
||
- 如用户无法提供 sudo,则提供精确的手动执行命令清单
|
||
- 考虑在 CI/CD 流程中统一构建环境
|
||
|
||
---
|
||
|
||
## 2026-04-29-21-27-10 — 组件目录扁平化重构
|
||
|
||
### A. 具体问题
|
||
将 `src/components/` 下 7 个子目录共 11 个组件文件扁平化到根目录时,需要同步更新多处 import 相对路径,存在遗漏风险。
|
||
|
||
### B. 产生原因
|
||
组件文件在子目录中时,引用 `lib/utils.ts` 的路径为 `../../lib/utils`,引用其他组件的路径为 `../workspace/XXX`;扁平化到根目录后,这些路径需分别变更为 `../lib/utils` 和 `./XXX`。涉及文件多、路径变体多,手工逐一修改容易遗漏。
|
||
|
||
### C. 解决方案
|
||
- 重构前先通过 `grep` 全局扫描所有 import 语句,建立完整的"文件-旧路径-新路径"映射表
|
||
- 移动文件和修改路径分两步执行,每步完成后都用 grep 验证旧路径模式是否完全消失
|
||
- 最后运行 `npm run lint` 和 `npm run build` 作为最终校验,TypeScript 编译器会捕获任何遗漏的路径错误
|
||
|
||
### D. 后续如何避免问题
|
||
- 任何涉及文件移动的 refactoring,都必须先全局 grep 所有相对路径引用,形成清单后再执行
|
||
- 执行后立即用 grep 反向验证旧路径模式残留
|
||
- 始终将 `npm run lint` 作为路径重构后的强制检查步骤
|
||
|
||
---
|
||
|
||
## 2026-04-29-21-51-19 — 全栈系统改造(FastAPI + SAM2 + PostgreSQL + Redis + MinIO)
|
||
|
||
### A. 具体问题
|
||
1. 将纯前端 React 应用改造为全栈系统时,工程涉及后端框架替换、数据库设计、对象存储、AI 推理引擎、前端状态管理重构等多个复杂模块,单次执行工程量大。
|
||
2. 系统磁盘空间(24G)不足,PyTorch CUDA 版本(>2GB)和 sam2 pip 包编译(需下载 CUDA 工具链 + 编译 C++ 扩展)均因 `OSError: No space left on device` 失败。
|
||
3. MinIO 对象存储在磁盘紧张时报 `XMinioStorageFull`,导致文件上传失败。
|
||
4. 前端 Agent 执行时因目录扁平化后子目录不存在,产生多次 `File not found` 错误。
|
||
|
||
### B. 产生原因
|
||
1. 项目改造范围超出单次会议合理容量,涉及 15+ 后端文件、10+ 前端文件、4 个基础设施服务、1 个 AI 模型栈。
|
||
2. 系统盘仅有 24GB,conda 环境(2GB)、node_modules(222MB)、模型权重(1.5GB)、MinIO 帧文件(1.4GB)叠加后迅速耗尽空间。
|
||
3. sam2 的 pip 包依赖 torch>=2.5.1,pip 会尝试重新下载完整 torch wheel(530MB)作为 build dependency,即使 torch 已安装。
|
||
4. 前端 Agent 的 prompt 中未明确说明组件目录已扁平化,Agent 仍尝试读取旧的子目录路径。
|
||
|
||
### C. 解决方案
|
||
1. **任务拆分 + 并行 Agent**: 将后端和前端代码编写拆分为两个独立 Agent 并行执行,基础设施安装与代码编写并行推进,显著缩短总耗时。
|
||
2. **磁盘管理策略**:
|
||
- 安装 PyTorch CPU 版本替代 CUDA 版本(占用更小)
|
||
- 只保留 sam2_hiera_tiny.pt(149MB),删除其他大模型
|
||
- 清理 conda pkgs 缓存(释放 600MB+)
|
||
- 删除 MinIO 中解析生成的临时帧文件(释放 1.4GB)
|
||
3. **sam2 安装降级**: 当前环境以 stub 模式运行,提供 `install_sam2.sh` 脚本供用户在扩展磁盘后执行真实安装。
|
||
4. **API 路径修复**: 后端添加 `/api/auth/login` 路由,修复前端 api.ts 中 `/api/predict` → `/api/ai/predict` 的路径不匹配。
|
||
5. **MinIO API 适配**: minio 7.2.x 中 `presigned_url()` 已改为 `get_presigned_url()`,需从 `datetime.timedelta` 传入 expires。
|
||
|
||
### D. 后续如何避免问题
|
||
1. **大型改造前先做磁盘评估**: 执行 `df -h` 确认可用空间 > 5GB 再开始安装大型依赖。
|
||
2. **AI 模型依赖延迟加载**: 所有 AI 推理引擎必须实现 graceful fallback,模型缺失时不阻塞系统启动。
|
||
3. **Agent prompt 需同步最新目录结构**: 给 Agent 的上下文必须包含当前真实的文件路径,避免 `File not found`。
|
||
4. **构建依赖隔离**: 使用 `--no-build-isolation` 或 `--no-deps` 安装源码包,避免 pip 重复下载已安装的依赖。
|
||
5. **MinIO 空间监控**: 定期清理解析产生的临时帧文件,或配置 MinIO 使用独立大容量数据盘。
|
||
|
||
---
|
||
|
||
## 2026-04-29-22-29-26 — README.md 完善
|
||
|
||
### A. 具体问题
|
||
项目全栈改造完成后,README.md 仍为旧版 AI Studio 模板,未反映真实系统架构和部署流程,新用户无法按文档独立完成部署。
|
||
|
||
### B. 产生原因
|
||
前期聚焦功能开发,文档滞后;改造涉及后端/前端/基础设施/AI 模型多个层级,文档编写工作量大。
|
||
|
||
### C. 解决方案
|
||
按代码编纂工作流,编写需求分析→实现方案→测试方案,然后一次性重写 README.md,涵盖系统架构、技术栈、目录结构、分步部署命令、环境变量、访问凭证、常见问题。
|
||
|
||
### D. 后续如何避免问题
|
||
- 任何架构级变更后,同步更新 README.md
|
||
- 将 README 纳入代码审查清单
|
||
- 新成员入职时按 README 走通部署流程作为验收标准
|
||
|
||
---
|
||
|
||
## 2026-04-29-22-37-36 — 登录报错 ERR_CONNECTION_REFUSED
|
||
|
||
### A. 具体问题
|
||
用户通过浏览器访问前端并点击登录时,控制台报错 `POST http://localhost:8000/api/auth/login net::ERR_CONNECTION_REFUSED`,登录失败。
|
||
|
||
### B. 产生原因
|
||
1. 前端 `api.ts` 中 `baseURL` 硬编码为 `http://localhost:8000`
|
||
2. 用户通过局域网 IP(如 `http://192.168.3.11:3000`)访问前端,而非 `http://localhost:3000`
|
||
3. 浏览器运行前端代码时,将 `localhost` 解析为**用户本地机器**(而非服务器),向用户本地 8000 端口发请求
|
||
4. 用户本地 8000 端口无服务,TCP 连接被拒绝
|
||
5. 同时后端 CORS 配置仅允许 `http://localhost:3000`,未允许 IP 地址访问
|
||
|
||
### C. 解决方案
|
||
1. 将 `src/lib/api.ts` 的 `baseURL` 从 `http://localhost:8000` 改为服务器实际 IP `http://192.168.3.11:8000`
|
||
2. 将 `backend/config.py` 的 `cors_origins` 从 `["http://localhost:3000"]` 扩展为 `["http://localhost:3000", "http://192.168.3.11:3000"]`
|
||
3. 重启后端服务使 CORS 生效,重新构建前端使 baseURL 生效
|
||
|
||
### D. 后续如何避免问题
|
||
1. 部署时统一使用服务器实际 IP 替代 localhost,避免浏览器端解析歧义
|
||
2. 前端 baseURL 应支持环境变量配置(如 `VITE_API_BASE_URL`),不同环境注入不同值
|
||
3. 后端 CORS origins 应使用配置化列表,支持开发/测试/生产多环境
|
||
4. 在 README 中明确说明访问地址,提醒用户必须使用服务器 IP 而非 localhost
|
||
|
||
---
|
||
|
||
## 2026-04-29-22-49-38 — WebSocket 404 + 项目状态异常 + 导入按钮无响应
|
||
|
||
### A. 具体问题
|
||
1. 控制台报错 `WebSocket connection to 'ws://localhost:8000/ws/progress' failed`
|
||
2. 项目库中"测试视频项目"状态显示为"异常"(红色)
|
||
3. "导入多媒体资源"按钮点击无反应
|
||
|
||
### B. 产生原因
|
||
1. `websocket.ts` 仍为 `ws://localhost:8000/ws/progress`,未随前端 baseURL 一起改为服务器 IP
|
||
2. FastAPI 后端未实现 `/ws/progress` WebSocket 路由
|
||
3. Uvicorn 缺少 WebSocket 支持库(`websockets` 或 `wsproto` 未安装)
|
||
4. 后端 `Project` 模型默认状态为 `"pending"`,前端只识别 `"Ready"` / `"Parsing"`,其他状态均显示"异常"
|
||
5. `ProjectLibrary.tsx` 中"导入多媒体资源"按钮为纯静态 `<button>`,无 `onClick` 事件和隐藏的 `<input type="file">`
|
||
|
||
### C. 解决方案
|
||
1. `websocket.ts` URL 改为 `ws://192.168.3.11:8000/ws/progress`
|
||
2. `backend/main.py` 添加 `@app.websocket("/ws/progress")` 路由 + `ConnectionManager` 连接管理
|
||
3. `pip install websockets` 为 Uvicorn 提供 WebSocket 协议支持
|
||
4. 后端 `Project.status` 默认值从 `"pending"` 改为 `"Ready"`
|
||
5. 前端增加 `'pending'` / `'Pending'` 状态分支显示"待处理"
|
||
6. 为导入按钮添加 `onClick` + `useRef<HTMLInputElement>` + 隐藏文件输入框,调用 `uploadMedia` API
|
||
|
||
### D. 后续如何避免问题
|
||
1. 任何涉及网络地址的配置(HTTP / WebSocket)必须同步修改,不能遗漏
|
||
2. 新增 WebSocket 功能时,同步检查 Uvicorn 是否安装了协议支持库
|
||
3. 前后端状态枚举值必须对齐,或后端返回时做映射转换
|
||
4. 所有按钮类 UI 元素必须绑定事件处理器,禁止纯装饰性按钮
|
||
|
||
---
|
||
|
||
## 2026-04-29-23-02-56 — Logo 部署 + Favicon 404
|
||
|
||
### A. 具体问题
|
||
1. `Sidebar.tsx` 引用 `/Logo.png` 但文件不存在,logo 无法显示
|
||
2. 浏览器控制台报 `favicon.ico 404`
|
||
|
||
### B. 产生原因
|
||
1. `logo_square.png` 位于项目根目录,但 Vite 不会自动将根目录文件暴露为静态资源
|
||
2. 前端代码引用路径为 `/Logo.png`(首字母大写),与实际文件名 `logo_square.png` 不匹配
|
||
3. `index.html` 无 favicon 声明,浏览器默认请求 `/favicon.ico`
|
||
|
||
### C. 解决方案
|
||
1. 创建 `public/` 目录(Vite 原生支持,自动暴露到根 URL)
|
||
2. 将 `logo_square.png` 复制为 `public/logo.png`
|
||
3. `Sidebar.tsx` 引用路径改为 `/logo.png`
|
||
4. `index.html` 添加 `<link rel="icon" type="image/png" href="/logo.png" />`
|
||
|
||
### D. 后续如何避免问题
|
||
1. 静态资源(图片、字体、favicon)统一放入 `public/` 目录
|
||
2. 资源文件名与代码引用严格保持大小写一致
|
||
3. 每个项目初始化时都配置好 favicon,避免浏览器自动请求不存在的 .ico
|
||
|
||
---
|
||
|
||
> 新增经验请追加到文件末尾,保持时间倒序或正序均可,但需确保每条经验包含完整的 A/B/C/D 四段。
|