Files
AIclinicalresearch/docs/08-项目管理/PKB迁移-超级安全执行计划.md
HaHafeng 2481b786d8 deploy: Complete 0126-27 deployment - database upgrade, services update, code recovery
Major Changes:
- Database: Install pg_bigm/pgvector plugins, create test database
- Python service: v1.0 -> v1.1, add pymupdf4llm/openpyxl/pypandoc
- Node.js backend: v1.3 -> v1.7, fix pino-pretty and ES Module imports
- Frontend: v1.2 -> v1.3, skip TypeScript check for deployment
- Code recovery: Restore empty files from local backup

Technical Fixes:
- Fix pino-pretty error in production (conditional loading)
- Fix ES Module import paths (add .js extensions)
- Fix OSSAdapter TypeScript errors
- Update Prisma Schema (63 models, 16 schemas)
- Update environment variables (DATABASE_URL, EXTRACTION_SERVICE_URL, OSS)
- Remove deprecated variables (REDIS_URL, DIFY_API_URL, DIFY_API_KEY)

Documentation:
- Create 0126 deployment folder with 8 documents
- Update database development standards v2.0
- Update SAE deployment status records

Deployment Status:
- PostgreSQL: ai_clinical_research_test with plugins
- Python: v1.1 @ 172.17.173.84:8000
- Backend: v1.7 @ 172.17.173.89:3001
- Frontend: v1.3 @ 172.17.173.90:80

Tested: All services running successfully on SAE
2026-01-27 08:13:27 +08:00

19 KiB
Raw Blame History

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:审查旧代码结构

# 后端代码审查
- [ ] 阅读 knowledgeBaseController.ts所有API端点
- [ ] 阅读 knowledgeBaseService.ts所有业务逻辑
- [ ] 阅读 knowledgeBases.ts路由定义
- [ ] 列出所有API端点和功能

# 前端代码审查
- [ ] 阅读 KnowledgePage.tsxUI和交互
- [ ] 列出所有用户操作流程
- [ ] 确认状态管理方式

Task 0.2确认数据库Schema

- [ ] 验证pkb_schema表结构
- [ ] 确认Prisma模型定义
- [ ] 检查是否有旧数据
- [ ] 确认索引和约束

Task 0.3:创建功能清单

- [ ] 列出所有功能CRUD、上传、检索等
- [ ] 创建测试用例
- [ ] 准备测试数据

验证标准

  • 所有代码已阅读并理解
  • 功能清单已创建
  • 测试用例已准备

回滚方案

  • 无需回滚(只是阅读代码)

📝 阶段1后端代码复制0.5天)

目标

  • 将旧代码复制到新位置
  • 不删除、不修改旧代码
  • 确保新代码可以独立编译

任务清单

Task 1.1:创建新目录结构

# 创建目录
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代码

# 复制文件(保留旧文件)
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代码

cp backend/src/legacy/services/knowledgeBaseService.ts \
   backend/src/modules/pkb/services/knowledgeBaseService.ts

Task 1.4复制Route代码

cp backend/src/legacy/routes/knowledgeBases.ts \
   backend/src/modules/pkb/routes/knowledgeBases.ts

Task 1.5:更新导入路径

// 在新代码中,更新所有 import 路径
// 从: import { xxx } from '../../legacy/...'
// 到: import { xxx } from '../services/...'

// 但是依赖common层的保持不变
import { prisma } from '../../../../common/database/prisma';

Task 1.6:编译验证

# 编译检查(不运行)
cd backend
npm run build

# 检查是否有编译错误
# 如果有错误,只修复导入路径问题,不修改逻辑

验证标准

  • 新代码编译通过
  • 旧代码完全未动
  • 旧系统仍可正常运行

回滚方案

# 如果出问题,直接删除新目录
rm -rf backend/src/modules/pkb
# 旧代码完全未动,系统继续运行

📝 阶段2后端API路由添加双路由共存0.5天)

目标

  • 在新位置添加API路由
  • 旧路由保持不变,继续工作
  • 新旧路由同时可用

任务清单

Task 2.1:注册新路由(不影响旧路由)

// 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:确认路由隔离

# 新路由路径:/api/v2/knowledge/*
# 旧路由路径:/api/v1/knowledge/*
# 两者完全独立,互不干扰

Task 2.3:添加健康检查端点

// 在新路由中添加健康检查
router.get('/health', (req, res) => {
  res.json({ 
    status: 'ok', 
    module: 'pkb-v2',
    timestamp: new Date().toISOString() 
  });
});

验证标准

验证新路由可用

# 启动服务器
npm run dev

# 测试新路由健康检查
curl http://localhost:3000/api/v2/knowledge/health
# 期望返回:{"status":"ok","module":"pkb-v2",...}

# 确认旧路由仍工作
curl http://localhost:3000/api/v1/knowledge/xxx
# 期望返回:正常数据

验证旧路由未受影响

# 使用Postman或curl测试所有旧API
# 确保所有功能正常

# 例如:
curl -X GET http://localhost:3000/api/v1/knowledge/list
curl -X POST http://localhost:3000/api/v1/knowledge/create
# ... 测试所有端点

回滚方案

// 如果新路由有问题,直接注释掉新路由注册
// import newKnowledgeRoutes from './modules/pkb/routes/knowledgeBases';
// app.use('/api/v2/knowledge', newKnowledgeRoutes);  // 注释掉

// 旧路由继续工作,用户无感知

📝 阶段3后端功能验证0.5天)

目标

  • 验证新后端所有功能
  • 对比新旧API返回结果
  • 确保新后端与旧后端行为完全一致

任务清单

Task 3.1:准备测试环境

# 创建测试用户
# 准备测试数据(知识库、文档)
# 准备Postman测试集合

Task 3.2逐个测试API端点

测试清单:
- [ ] 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

# 对于每个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:边界测试

- [ ] 测试无效参数
- [ ] 测试权限控制
- [ ] 测试并发请求
- [ ] 测试大文件上传
- [ ] 测试错误处理

Task 3.5:性能测试

# 简单的性能对比
- [ ] 测试响应时间
- [ ] 测试内存使用
- [ ] 确认无明显性能劣化

验证标准

  • 所有API端点测试通过
  • 新旧API返回结果一致
  • 边界情况处理正确
  • 性能无明显下降

发现问题的处理

如果发现问题:
1. 记录问题详情
2. 修复新代码
3. 重新测试
4. 不影响旧系统(旧路由继续工作)
5. 可以随时暂停迁移

回滚方案

  • 发现严重问题时,停止使用新路由
  • 旧路由继续工作
  • 有时间慢慢修复新代码

📝 阶段4前端代码复制0.5天)

目标

  • 将旧前端代码复制到新位置
  • 不删除、不修改旧代码
  • 确保新代码可以独立编译

任务清单

Task 4.1:创建新目录结构

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:复制页面代码

cp frontend/src/pages/KnowledgePage.tsx \
   frontend-v2/src/modules/pkb/pages/KnowledgePage.tsx

Task 4.3创建API服务

// frontend-v2/src/modules/pkb/api/knowledgeApi.ts
// 创建新的API调用层指向 /api/v2/knowledge/*

Task 4.4:更新导入路径

// 更新所有import路径
// 但保持调用相同的UI组件库

Task 4.5:编译验证

cd frontend-v2
npm run build
# 检查编译错误

验证标准

  • 新代码编译通过
  • 旧前端完全未动
  • 旧前端仍可正常访问

回滚方案

# 删除新目录
rm -rf frontend-v2/src/modules/pkb
# 旧前端继续工作

📝 阶段5前端路由添加双路由共存0.5天)

目标

  • 在新前端添加路由
  • 旧路由保持不变
  • 新旧页面同时可用

任务清单

Task 5.1:注册新路由

// 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调用

// 确保新前端调用的是 /api/v2/knowledge/* 路由
const API_BASE = '/api/v2/knowledge';

Task 5.3:添加版本标识

// 在页面上添加版本标识,方便区分新旧版本
<div className="version-badge">V2 (新架构)</div>

验证标准

回滚方案

// 注释掉新路由
// {
//   path: '/pkb',
//   component: ...
// }

📝 阶段6前端功能验证0.5天)

目标

  • 验证新前端所有功能
  • 确保用户体验一致
  • 发现并修复UI问题

任务清单

Task 6.1:手动功能测试

测试流程:
1. [ ] 访问新页面http://localhost:5174/pkb
2. [ ] 登录功能
3. [ ] 查看知识库列表
4. [ ] 创建新知识库
5. [ ] 上传文档
6. [ ] 查看文档列表
7. [ ] RAG检索功能
8. [ ] 编辑知识库
9. [ ] 删除文档
10. [ ] 删除知识库
11. [ ] 批处理功能
12. [ ] 错误提示

Task 6.2UI一致性检查

- [ ] 布局是否正确
- [ ] 样式是否正常
- [ ] 交互是否流畅
- [ ] 加载状态显示
- [ ] 错误提示友好

Task 6.3:浏览器兼容性

- [ ] Chrome测试
- [ ] Firefox测试
- [ ] Safari测试如有Mac

Task 6.4:响应式测试

- [ ] 桌面端1920x1080
- [ ] 平板端768x1024
- [ ] 移动端375x667

验证标准

  • 所有功能正常工作
  • UI显示正确
  • 无明显bug
  • 用户体验良好

发现问题的处理

  • 修复新前端代码
  • 旧前端继续可用
  • 不影响现有用户

📝 阶段7灰度发布功能开关1天

目标

  • 让部分用户使用新版本
  • 收集真实使用反馈
  • 发现潜在问题

任务清单

Task 7.1:实现功能开关

// 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:前端功能开关

// 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:灰度发布策略

阶段7.1内部测试1-2天
- [ ] 开发团队使用新版本
- [ ] 设置localStorage.setItem('force-pkb-v2', 'true')
- [ ] 记录所有问题

阶段7.2小范围用户3-5天
- [ ] 选择5-10个活跃用户
- [ ] 加入白名单
- [ ] 收集反馈

阶段7.3扩大范围7天
- [ ] 25%用户使用新版本
- [ ] 监控错误率
- [ ] 对比性能指标

Task 7.4:监控和日志

// 添加详细日志
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
  • 错误率在可接受范围
  • 用户反馈积极

回滚方案

# 立即回滚灰度用户
1. 设置环境变量USE_PKB_V2=false
2. 或清空白名单PKB_V2_WHITELIST=""
3. 重启服务
4. 所有用户自动回到旧版本

📝 阶段8全量切换0.5天)

目标

  • 所有用户切换到新版本
  • 确保平滑过渡
  • 保留回滚能力

任务清单

Task 8.1:准备切换

# 提前通知
- [ ] 通知用户即将升级
- [ ] 准备回滚预案
- [ ] 备份当前配置

Task 8.2:执行切换

# 方式1修改默认路由
在frontend-v2中将 /knowledge 路由指向新页面

# 方式2全局开关
USE_PKB_V2=true

# 方式3前端重定向
if (location.pathname === '/knowledge') {
  location.href = '/pkb';
}

Task 8.3密切监控24小时

- [ ] 监控错误率
- [ ] 监控API响应时间
- [ ] 检查用户反馈
- [ ] 查看日志异常

验证标准

  • 所有用户访问新版本
  • 错误率正常
  • 性能稳定
  • 无重大投诉

回滚方案保留7天

# 紧急回滚
1. USE_PKB_V2=false
2. 或修改路由配置
3. 重启服务
4. 5分钟内完成回滚

📝 阶段9清理旧代码可选1-2周后

⚠️ 重要提示

至少等待2周确认新版本完全稳定后再执行

任务清单

Task 9.1:备份旧代码

# 创建备份分支
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:删除旧代码

# 删除旧后端代码
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:清理路由

// 移除旧路由注册
// app.use('/api/v1/knowledge', legacyKnowledgeRoutes);

// 可选:添加重定向
app.use('/api/v1/knowledge', (req, res) => {
  res.redirect(308, `/api/v2/knowledge${req.path}`);
});

验证标准

  • 代码已备份
  • 新版本运行2周无问题
  • 团队一致同意删除

🔒 安全措施总结

1. 始终可回滚

每个阶段都可以立即回滚到上一个状态
回滚时间:< 5分钟

2. 旧系统保护

迁移期间,旧代码完全不动
旧功能100%可用
用户无感知

3. 渐进式验证

每个阶段独立验证
发现问题立即修复
不影响下一阶段

4. 灰度发布

内部测试 → 小范围用户 → 大范围用户 → 全量
任何阶段发现问题都可以暂停

5. 监控告警

实时监控错误率
性能指标对比
用户反馈收集

📊 检查点Checkpoint

在每个阶段结束时,必须通过以下检查:

阶段通过标准

1. [ ] 所有测试用例通过
2. [ ] 无编译/运行时错误
3. [ ] 旧系统功能正常
4. [ ] 性能无明显下降
5. [ ] 代码已提交到Git
6. [ ] 团队评审通过

阶段失败处理

1. 立即停止迁移
2. 分析失败原因
3. 修复问题
4. 重新验证
5. 通过后再继续下一阶段

🎯 成功标准

最终目标

  • PKB功能100%迁移到新架构
  • 用户无感知切换
  • 零数据丢失
  • 零停机时间
  • 可随时回滚保留2周

KPI指标

- 错误率:< 0.1%(与旧版本对比)
- 响应时间:不超过旧版本的 110%
- 用户满意度:≥ 90%
- 回滚次数0次理想情况

📞 应急联系

发现严重问题时

1. 立即停止迁移
2. 评估影响范围
3. 决定是否回滚
4. 通知团队
5. 记录问题详情

回滚决策

立即回滚的情况:
- 数据丢失或损坏
- 核心功能不可用
- 大量用户投诉
- 安全漏洞

可以继续的情况:
- 个别边界case问题
- UI小bug
- 性能轻微下降
- 用户反馈可以接受

📝 迁移日志模板

### [日期] 阶段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开始 🚀