# PKB个人知识库 - 超级安全迁移执行计划 > **创建日期:** 2026-01-06 > **目标:** 将PKB从旧架构迁移到新架构,确保零风险、可回滚、可验证 > **原则:** 保守、渐进、每步可验证、随时可回滚 --- ## 🎯 迁移目标 将PKB从旧架构迁移到新架构,同时: - ✅ 保持现有功能100%可用 - ✅ 不影响正在使用的用户 - ✅ 每一步都可以验证和回滚 - ✅ 数据零损失 --- ## 📊 当前状态分析 ### 旧架构位置 ``` 后端:backend/src/legacy/ ├─ controllers/knowledgeBaseController.ts ├─ services/knowledgeBaseService.ts └─ routes/knowledgeBases.ts 前端:frontend/src/ └─ pages/KnowledgePage.tsx 数据库:✅ pkb_schema(已在独立Schema,无需迁移) ``` ### 新架构位置 ``` 后端:backend/src/modules/pkb/ ├─ controllers/ ├─ services/ └─ routes/ 前端:frontend-v2/src/modules/pkb/ ├─ pages/ ├─ components/ └─ api/ ``` --- ## 🚀 分阶段执行计划 ### ⏱️ 时间估算 | 阶段 | 任务 | 预估时间 | 可回滚 | 风险 | |-----|------|---------|--------|-----| | **阶段0** | 代码审查和准备 | 0.5天 | N/A | 无 | | **阶段1** | 后端代码复制(不删除旧代码) | 0.5天 | ✅ | 极低 | | **阶段2** | 后端API路由添加(双路由共存) | 0.5天 | ✅ | 极低 | | **阶段3** | 后端功能验证 | 0.5天 | ✅ | 低 | | **阶段4** | 前端代码复制 | 0.5天 | ✅ | 极低 | | **阶段5** | 前端路由添加(双路由共存) | 0.5天 | ✅ | 极低 | | **阶段6** | 前端功能验证 | 0.5天 | ✅ | 低 | | **阶段7** | 灰度发布(功能开关) | 1天 | ✅ | 中 | | **阶段8** | 全量切换 | 0.5天 | ✅ | 低 | | **阶段9** | 清理旧代码(可选) | 0.5天 | ⚠️ | 低 | **总计:约 5-6天(保守估计)** --- ## 📝 阶段0:代码审查和准备(0.5天) ### 目标 - 理解现有代码的所有功能点 - 确认依赖关系 - 制定详细的迁移清单 ### 任务清单 #### Task 0.1:审查旧代码结构 ```bash # 后端代码审查 - [ ] 阅读 knowledgeBaseController.ts(所有API端点) - [ ] 阅读 knowledgeBaseService.ts(所有业务逻辑) - [ ] 阅读 knowledgeBases.ts(路由定义) - [ ] 列出所有API端点和功能 # 前端代码审查 - [ ] 阅读 KnowledgePage.tsx(UI和交互) - [ ] 列出所有用户操作流程 - [ ] 确认状态管理方式 ``` #### Task 0.2:确认数据库Schema ```bash - [ ] 验证pkb_schema表结构 - [ ] 确认Prisma模型定义 - [ ] 检查是否有旧数据 - [ ] 确认索引和约束 ``` #### Task 0.3:创建功能清单 ```bash - [ ] 列出所有功能(CRUD、上传、检索等) - [ ] 创建测试用例 - [ ] 准备测试数据 ``` ### 验证标准 - ✅ 所有代码已阅读并理解 - ✅ 功能清单已创建 - ✅ 测试用例已准备 ### 回滚方案 - 无需回滚(只是阅读代码) --- ## 📝 阶段1:后端代码复制(0.5天) ### 目标 - 将旧代码复制到新位置 - **不删除、不修改旧代码** - 确保新代码可以独立编译 ### 任务清单 #### Task 1.1:创建新目录结构 ```bash # 创建目录 mkdir -p backend/src/modules/pkb/controllers mkdir -p backend/src/modules/pkb/services mkdir -p backend/src/modules/pkb/routes mkdir -p backend/src/modules/pkb/types mkdir -p backend/src/modules/pkb/utils ``` #### Task 1.2:复制Controller代码 ```bash # 复制文件(保留旧文件) cp backend/src/legacy/controllers/knowledgeBaseController.ts \ backend/src/modules/pkb/controllers/knowledgeBaseController.ts # 验证:旧文件仍存在 ls -la backend/src/legacy/controllers/knowledgeBaseController.ts ``` #### Task 1.3:复制Service代码 ```bash cp backend/src/legacy/services/knowledgeBaseService.ts \ backend/src/modules/pkb/services/knowledgeBaseService.ts ``` #### Task 1.4:复制Route代码 ```bash cp backend/src/legacy/routes/knowledgeBases.ts \ backend/src/modules/pkb/routes/knowledgeBases.ts ``` #### Task 1.5:更新导入路径 ```typescript // 在新代码中,更新所有 import 路径 // 从: import { xxx } from '../../legacy/...' // 到: import { xxx } from '../services/...' // 但是:依赖common层的保持不变 import { prisma } from '../../../../common/database/prisma'; ``` #### Task 1.6:编译验证 ```bash # 编译检查(不运行) cd backend npm run build # 检查是否有编译错误 # 如果有错误,只修复导入路径问题,不修改逻辑 ``` ### 验证标准 - ✅ 新代码编译通过 - ✅ 旧代码完全未动 - ✅ 旧系统仍可正常运行 ### 回滚方案 ```bash # 如果出问题,直接删除新目录 rm -rf backend/src/modules/pkb # 旧代码完全未动,系统继续运行 ``` --- ## 📝 阶段2:后端API路由添加(双路由共存)(0.5天) ### 目标 - 在新位置添加API路由 - **旧路由保持不变,继续工作** - 新旧路由同时可用 ### 任务清单 #### Task 2.1:注册新路由(不影响旧路由) ```typescript // backend/src/index.ts 或 routes/index.ts // 旧路由(保持不变) import legacyKnowledgeRoutes from './legacy/routes/knowledgeBases'; app.use('/api/v1/knowledge', legacyKnowledgeRoutes); // 新路由(新增) import newKnowledgeRoutes from './modules/pkb/routes/knowledgeBases'; app.use('/api/v2/knowledge', newKnowledgeRoutes); // 使用v2路径 ``` #### Task 2.2:确认路由隔离 ```bash # 新路由路径:/api/v2/knowledge/* # 旧路由路径:/api/v1/knowledge/* # 两者完全独立,互不干扰 ``` #### Task 2.3:添加健康检查端点 ```typescript // 在新路由中添加健康检查 router.get('/health', (req, res) => { res.json({ status: 'ok', module: 'pkb-v2', timestamp: new Date().toISOString() }); }); ``` ### 验证标准 #### 验证新路由可用 ```bash # 启动服务器 npm run dev # 测试新路由健康检查 curl http://localhost:3000/api/v2/knowledge/health # 期望返回:{"status":"ok","module":"pkb-v2",...} # 确认旧路由仍工作 curl http://localhost:3000/api/v1/knowledge/xxx # 期望返回:正常数据 ``` #### 验证旧路由未受影响 ```bash # 使用Postman或curl测试所有旧API # 确保所有功能正常 # 例如: curl -X GET http://localhost:3000/api/v1/knowledge/list curl -X POST http://localhost:3000/api/v1/knowledge/create # ... 测试所有端点 ``` ### 回滚方案 ```typescript // 如果新路由有问题,直接注释掉新路由注册 // import newKnowledgeRoutes from './modules/pkb/routes/knowledgeBases'; // app.use('/api/v2/knowledge', newKnowledgeRoutes); // 注释掉 // 旧路由继续工作,用户无感知 ``` --- ## 📝 阶段3:后端功能验证(0.5天) ### 目标 - 验证新后端所有功能 - 对比新旧API返回结果 - 确保新后端与旧后端行为完全一致 ### 任务清单 #### Task 3.1:准备测试环境 ```bash # 创建测试用户 # 准备测试数据(知识库、文档) # 准备Postman测试集合 ``` #### Task 3.2:逐个测试API端点 ```bash 测试清单: - [ ] GET /api/v2/knowledge/list - 获取知识库列表 - [ ] POST /api/v2/knowledge/create - 创建知识库 - [ ] GET /api/v2/knowledge/:id - 获取知识库详情 - [ ] PUT /api/v2/knowledge/:id - 更新知识库 - [ ] DELETE /api/v2/knowledge/:id - 删除知识库 - [ ] POST /api/v2/knowledge/:id/upload - 上传文档 - [ ] GET /api/v2/knowledge/:id/documents - 获取文档列表 - [ ] DELETE /api/v2/knowledge/:id/documents/:docId - 删除文档 - [ ] POST /api/v2/knowledge/:id/query - RAG检索 - [ ] GET /api/v2/knowledge/:id/batch-tasks - 批处理任务列表 - [ ] POST /api/v2/knowledge/:id/batch-tasks - 创建批处理任务 ``` #### Task 3.3:对比测试(新旧API) ```bash # 对于每个API,使用相同参数同时调用新旧接口 # 对比返回结果是否一致 # 示例: curl /api/v1/knowledge/list > old_result.json curl /api/v2/knowledge/list > new_result.json diff old_result.json new_result.json ``` #### Task 3.4:边界测试 ```bash - [ ] 测试无效参数 - [ ] 测试权限控制 - [ ] 测试并发请求 - [ ] 测试大文件上传 - [ ] 测试错误处理 ``` #### Task 3.5:性能测试 ```bash # 简单的性能对比 - [ ] 测试响应时间 - [ ] 测试内存使用 - [ ] 确认无明显性能劣化 ``` ### 验证标准 - ✅ 所有API端点测试通过 - ✅ 新旧API返回结果一致 - ✅ 边界情况处理正确 - ✅ 性能无明显下降 ### 发现问题的处理 ```bash 如果发现问题: 1. 记录问题详情 2. 修复新代码 3. 重新测试 4. 不影响旧系统(旧路由继续工作) 5. 可以随时暂停迁移 ``` ### 回滚方案 - 发现严重问题时,停止使用新路由 - 旧路由继续工作 - 有时间慢慢修复新代码 --- ## 📝 阶段4:前端代码复制(0.5天) ### 目标 - 将旧前端代码复制到新位置 - **不删除、不修改旧代码** - 确保新代码可以独立编译 ### 任务清单 #### Task 4.1:创建新目录结构 ```bash mkdir -p frontend-v2/src/modules/pkb/pages mkdir -p frontend-v2/src/modules/pkb/components mkdir -p frontend-v2/src/modules/pkb/api mkdir -p frontend-v2/src/modules/pkb/types mkdir -p frontend-v2/src/modules/pkb/hooks ``` #### Task 4.2:复制页面代码 ```bash cp frontend/src/pages/KnowledgePage.tsx \ frontend-v2/src/modules/pkb/pages/KnowledgePage.tsx ``` #### Task 4.3:创建API服务 ```typescript // frontend-v2/src/modules/pkb/api/knowledgeApi.ts // 创建新的API调用层,指向 /api/v2/knowledge/* ``` #### Task 4.4:更新导入路径 ```typescript // 更新所有import路径 // 但保持调用相同的UI组件库 ``` #### Task 4.5:编译验证 ```bash cd frontend-v2 npm run build # 检查编译错误 ``` ### 验证标准 - ✅ 新代码编译通过 - ✅ 旧前端完全未动 - ✅ 旧前端仍可正常访问 ### 回滚方案 ```bash # 删除新目录 rm -rf frontend-v2/src/modules/pkb # 旧前端继续工作 ``` --- ## 📝 阶段5:前端路由添加(双路由共存)(0.5天) ### 目标 - 在新前端添加路由 - **旧路由保持不变** - 新旧页面同时可用 ### 任务清单 #### Task 5.1:注册新路由 ```typescript // frontend-v2/src/router/index.ts // 旧路由(保持不变)- 如果旧前端还在运行 // 访问:http://localhost:5173/knowledge // 新路由(新增) { path: '/pkb', // 使用新路径 component: () => import('@/modules/pkb/pages/KnowledgePage.tsx'), meta: { title: 'PKB个人知识库(新版)' } } ``` #### Task 5.2:更新API调用 ```typescript // 确保新前端调用的是 /api/v2/knowledge/* 路由 const API_BASE = '/api/v2/knowledge'; ``` #### Task 5.3:添加版本标识 ```typescript // 在页面上添加版本标识,方便区分新旧版本
V2 (新架构)
``` ### 验证标准 - ✅ 新路由可访问:http://localhost:5174/pkb - ✅ 页面正常渲染 - ✅ 无编译错误 ### 回滚方案 ```typescript // 注释掉新路由 // { // path: '/pkb', // component: ... // } ``` --- ## 📝 阶段6:前端功能验证(0.5天) ### 目标 - 验证新前端所有功能 - 确保用户体验一致 - 发现并修复UI问题 ### 任务清单 #### Task 6.1:手动功能测试 ```bash 测试流程: 1. [ ] 访问新页面:http://localhost:5174/pkb 2. [ ] 登录功能 3. [ ] 查看知识库列表 4. [ ] 创建新知识库 5. [ ] 上传文档 6. [ ] 查看文档列表 7. [ ] RAG检索功能 8. [ ] 编辑知识库 9. [ ] 删除文档 10. [ ] 删除知识库 11. [ ] 批处理功能 12. [ ] 错误提示 ``` #### Task 6.2:UI一致性检查 ```bash - [ ] 布局是否正确 - [ ] 样式是否正常 - [ ] 交互是否流畅 - [ ] 加载状态显示 - [ ] 错误提示友好 ``` #### Task 6.3:浏览器兼容性 ```bash - [ ] Chrome测试 - [ ] Firefox测试 - [ ] Safari测试(如有Mac) ``` #### Task 6.4:响应式测试 ```bash - [ ] 桌面端(1920x1080) - [ ] 平板端(768x1024) - [ ] 移动端(375x667) ``` ### 验证标准 - ✅ 所有功能正常工作 - ✅ UI显示正确 - ✅ 无明显bug - ✅ 用户体验良好 ### 发现问题的处理 - 修复新前端代码 - 旧前端继续可用 - 不影响现有用户 --- ## 📝 阶段7:灰度发布(功能开关)(1天) ### 目标 - 让部分用户使用新版本 - 收集真实使用反馈 - 发现潜在问题 ### 任务清单 #### Task 7.1:实现功能开关 ```typescript // backend/src/common/config/featureFlags.ts export const featureFlags = { usePKBv2: process.env.USE_PKB_V2 === 'true' || false, pkbV2UserWhitelist: process.env.PKB_V2_WHITELIST?.split(',') || [], }; // 中间件检查 function pkbVersionRouter(req, res, next) { const userId = req.user?.id; // 白名单用户使用新版本 if (featureFlags.pkbV2UserWhitelist.includes(userId)) { req.usePKBv2 = true; } // 或全局开关 if (featureFlags.usePKBv2) { req.usePKBv2 = true; } next(); } ``` #### Task 7.2:前端功能开关 ```typescript // frontend-v2/src/modules/pkb/config.ts export const usePKBv2 = () => { // 检查localStorage或URL参数 const forceV2 = localStorage.getItem('force-pkb-v2') === 'true'; const urlParam = new URLSearchParams(window.location.search).get('v2'); return forceV2 || urlParam === 'true'; }; // 根据开关决定使用哪个API export const getApiBase = () => { return usePKBv2() ? '/api/v2/knowledge' : '/api/v1/knowledge'; }; ``` #### Task 7.3:灰度发布策略 ```bash 阶段7.1:内部测试(1-2天) - [ ] 开发团队使用新版本 - [ ] 设置:localStorage.setItem('force-pkb-v2', 'true') - [ ] 记录所有问题 阶段7.2:小范围用户(3-5天) - [ ] 选择5-10个活跃用户 - [ ] 加入白名单 - [ ] 收集反馈 阶段7.3:扩大范围(7天) - [ ] 25%用户使用新版本 - [ ] 监控错误率 - [ ] 对比性能指标 ``` #### Task 7.4:监控和日志 ```typescript // 添加详细日志 logger.info('PKB API called', { version: req.usePKBv2 ? 'v2' : 'v1', userId: req.user.id, action: req.path, }); // 错误监控 if (req.usePKBv2) { Sentry.setTag('pkb-version', 'v2'); } ``` ### 验证标准 - ✅ 灰度用户正常使用 - ✅ 无重大bug - ✅ 错误率在可接受范围 - ✅ 用户反馈积极 ### 回滚方案 ```bash # 立即回滚灰度用户 1. 设置环境变量:USE_PKB_V2=false 2. 或清空白名单:PKB_V2_WHITELIST="" 3. 重启服务 4. 所有用户自动回到旧版本 ``` --- ## 📝 阶段8:全量切换(0.5天) ### 目标 - 所有用户切换到新版本 - 确保平滑过渡 - 保留回滚能力 ### 任务清单 #### Task 8.1:准备切换 ```bash # 提前通知 - [ ] 通知用户即将升级 - [ ] 准备回滚预案 - [ ] 备份当前配置 ``` #### Task 8.2:执行切换 ```bash # 方式1:修改默认路由 在frontend-v2中,将 /knowledge 路由指向新页面 # 方式2:全局开关 USE_PKB_V2=true # 方式3:前端重定向 if (location.pathname === '/knowledge') { location.href = '/pkb'; } ``` #### Task 8.3:密切监控(24小时) ```bash - [ ] 监控错误率 - [ ] 监控API响应时间 - [ ] 检查用户反馈 - [ ] 查看日志异常 ``` ### 验证标准 - ✅ 所有用户访问新版本 - ✅ 错误率正常 - ✅ 性能稳定 - ✅ 无重大投诉 ### 回滚方案(保留7天) ```bash # 紧急回滚 1. USE_PKB_V2=false 2. 或修改路由配置 3. 重启服务 4. 5分钟内完成回滚 ``` --- ## 📝 阶段9:清理旧代码(可选,1-2周后) ### ⚠️ 重要提示 **至少等待2周,确认新版本完全稳定后再执行!** ### 任务清单 #### Task 9.1:备份旧代码 ```bash # 创建备份分支 git checkout -b backup/pkb-legacy-code git commit -am "Backup: PKB legacy code before cleanup" git push origin backup/pkb-legacy-code ``` #### Task 9.2:删除旧代码 ```bash # 删除旧后端代码 rm -rf backend/src/legacy/controllers/knowledgeBaseController.ts rm -rf backend/src/legacy/services/knowledgeBaseService.ts rm -rf backend/src/legacy/routes/knowledgeBases.ts # 删除旧前端代码 rm -rf frontend/src/pages/KnowledgePage.tsx ``` #### Task 9.3:清理路由 ```typescript // 移除旧路由注册 // app.use('/api/v1/knowledge', legacyKnowledgeRoutes); // 可选:添加重定向 app.use('/api/v1/knowledge', (req, res) => { res.redirect(308, `/api/v2/knowledge${req.path}`); }); ``` ### 验证标准 - ✅ 代码已备份 - ✅ 新版本运行2周无问题 - ✅ 团队一致同意删除 --- ## 🔒 安全措施总结 ### 1. 始终可回滚 ```bash 每个阶段都可以立即回滚到上一个状态 回滚时间:< 5分钟 ``` ### 2. 旧系统保护 ```bash 迁移期间,旧代码完全不动 旧功能100%可用 用户无感知 ``` ### 3. 渐进式验证 ```bash 每个阶段独立验证 发现问题立即修复 不影响下一阶段 ``` ### 4. 灰度发布 ```bash 内部测试 → 小范围用户 → 大范围用户 → 全量 任何阶段发现问题都可以暂停 ``` ### 5. 监控告警 ```bash 实时监控错误率 性能指标对比 用户反馈收集 ``` --- ## 📊 检查点(Checkpoint) 在每个阶段结束时,必须通过以下检查: ### ✅ 阶段通过标准 ```bash 1. [ ] 所有测试用例通过 2. [ ] 无编译/运行时错误 3. [ ] 旧系统功能正常 4. [ ] 性能无明显下降 5. [ ] 代码已提交到Git 6. [ ] 团队评审通过 ``` ### ❌ 阶段失败处理 ```bash 1. 立即停止迁移 2. 分析失败原因 3. 修复问题 4. 重新验证 5. 通过后再继续下一阶段 ``` --- ## 🎯 成功标准 ### 最终目标 - ✅ PKB功能100%迁移到新架构 - ✅ 用户无感知切换 - ✅ 零数据丢失 - ✅ 零停机时间 - ✅ 可随时回滚(保留2周) ### KPI指标 ```bash - 错误率:< 0.1%(与旧版本对比) - 响应时间:不超过旧版本的 110% - 用户满意度:≥ 90% - 回滚次数:0次(理想情况) ``` --- ## 📞 应急联系 ### 发现严重问题时 ```bash 1. 立即停止迁移 2. 评估影响范围 3. 决定是否回滚 4. 通知团队 5. 记录问题详情 ``` ### 回滚决策 ```bash 立即回滚的情况: - 数据丢失或损坏 - 核心功能不可用 - 大量用户投诉 - 安全漏洞 可以继续的情况: - 个别边界case问题 - UI小bug - 性能轻微下降 - 用户反馈可以接受 ``` --- ## 📝 迁移日志模板 ```markdown ### [日期] 阶段X执行记录 **执行人:** XXX **开始时间:** YYYY-MM-DD HH:mm **结束时间:** YYYY-MM-DD HH:mm **执行内容:** - Task X.1: [完成/失败] [说明] - Task X.2: [完成/失败] [说明] ... **测试结果:** - 测试用例1: ✅ 通过 - 测试用例2: ✅ 通过 ... **发现的问题:** 1. [问题描述] - [状态:已修复/待修复] 2. ... **性能指标:** - API响应时间:XX ms (旧版本: XX ms) - 错误率:X% **结论:** [✅ 通过 / ❌ 失败] **下一步:** [继续下一阶段 / 暂停修复问题 / 回滚] ``` --- ## 🎓 经验总结 ### 这个计划的优势 ``` 1. ✅ 极度保守,风险最小化 2. ✅ 每步可验证,问题早发现 3. ✅ 随时可回滚,不影响业务 4. ✅ 灰度发布,逐步切换 5. ✅ 旧代码长期保留,双保险 ``` ### 与快速迁移的对比 ``` 快速迁移:1-2天完成,但风险高 安全迁移:5-6天完成,但风险极低 选择:用4天时间换取安全性和稳定性 ``` --- **准备好了吗?让我们从阶段0开始!** 🚀