# 后端架构增量演进方案 > **版本:** V1.0 > **创建日期:** 2025-11-14 > **策略:** 新旧并存,增量演进 > **原则:** 零风险改造,新模块新架构 --- ## 🎯 核心策略 ### "绞杀者模式"(Strangler Fig Pattern) **不改造旧代码,新功能新架构** ``` ┌─────────────────────────────────────────────────────┐ │ AI临床研究平台 - Backend │ ├─────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ ┌──────────────────┐ │ │ │ 现有模块 │ │ 新模块 │ │ │ │ (旧架构) │ │ (新架构) │ │ │ ├──────────────┤ ├──────────────────┤ │ │ │ • AIA │ │ • ASL (新) │ │ │ │ • PKB │ │ • 未来模块... │ │ │ │ • RVW │ │ │ │ │ └──────────────┘ └──────────────────┘ │ │ ↓ ↓ │ │ 平铺结构 platform/common/modules │ │ 保持不变 标准化三层架构 │ └─────────────────────────────────────────────────────┘ ``` --- ## 📁 新的目录结构(并存版) ``` backend/ ├── src/ │ ├── index.ts # 主入口(注册所有模块) │ │ │ ├── config/ # 【共用】配置层 │ │ ├── env.ts │ │ └── database.ts │ │ │ ├── legacy/ # 🔸 现有代码(旧架构) │ │ ├── routes/ │ │ │ ├── agents.ts # AIA 路由 │ │ │ ├── conversations.ts │ │ │ ├── chatRoutes.ts │ │ │ ├── projects.ts │ │ │ ├── knowledgeBases.ts # PKB 路由 │ │ │ ├── batchRoutes.ts │ │ │ └── reviewRoutes.ts # RVW 路由 │ │ │ │ │ ├── controllers/ │ │ │ ├── agentController.ts │ │ │ ├── conversationController.ts │ │ │ ├── chatController.ts │ │ │ ├── knowledgeBaseController.ts │ │ │ └── reviewController.ts │ │ │ │ │ ├── services/ │ │ │ ├── agentService.ts │ │ │ ├── conversationService.ts │ │ │ ├── knowledgeBaseService.ts │ │ │ └── reviewService.ts │ │ │ │ │ └── templates/ │ │ └── clinicalResearch.ts │ │ │ ├── common/ # 【共用】通用能力层 │ │ ├── llm/ # LLM 适配器 │ │ │ └── adapters/ │ │ │ ├── DeepSeekAdapter.ts │ │ │ ├── QwenAdapter.ts │ │ │ ├── LLMFactory.ts │ │ │ └── types.ts │ │ │ │ │ ├── rag/ # RAG 能力 │ │ │ ├── DifyClient.ts │ │ │ └── types.ts │ │ │ │ │ ├── document/ # 文档处理 │ │ │ ├── ExtractionClient.ts │ │ │ └── TokenService.ts │ │ │ │ │ ├── middleware/ # 中间件 │ │ │ └── validateProject.ts │ │ │ │ │ └── utils/ # 工具函数 │ │ └── jsonParser.ts │ │ │ └── modules/ # 🌟 新架构模块(标准化) │ │ │ ├── asl/ # ⭐ AI智能文献(新模块) │ │ ├── index.ts # 模块导出 │ │ ├── routes/ │ │ │ ├── index.ts # 路由统一导出 │ │ │ ├── projects.ts # 项目管理 │ │ │ ├── screening.ts # 文献筛选 │ │ │ ├── extraction.ts # 数据提取 │ │ │ └── analysis.ts # 综合分析 │ │ │ │ │ ├── controllers/ │ │ │ ├── projectController.ts │ │ │ ├── screeningController.ts │ │ │ ├── extractionController.ts │ │ │ └── analysisController.ts │ │ │ │ │ ├── services/ │ │ │ ├── projectService.ts │ │ │ ├── screeningService.ts │ │ │ ├── extractionService.ts │ │ │ └── analysisService.ts │ │ │ │ │ └── types/ # 模块类型定义 │ │ └── index.ts │ │ │ └── [未来模块]/ # 未来的新模块都按此结构 │ ├── package.json ├── tsconfig.json # TypeScript 配置 └── .env ``` --- ## 🔄 主入口文件(index.ts) ```typescript /** * AI临床研究平台 - 统一入口 * * 架构演进策略:新旧并存 * - Legacy 模块:保持现有结构 * - New 模块:采用标准化三层架构 */ import Fastify from 'fastify'; import cors from '@fastify/cors'; import multipart from '@fastify/multipart'; import { config, validateEnv } from './config/env.js'; import { testDatabaseConnection, prisma } from './config/database.js'; // ============================================ // 【旧架构】Legacy 模块 - 保持不变 // ============================================ import { projectRoutes } from './legacy/routes/projects.js'; import { agentRoutes } from './legacy/routes/agents.js'; import { conversationRoutes } from './legacy/routes/conversations.js'; import { chatRoutes } from './legacy/routes/chatRoutes.js'; import knowledgeBaseRoutes from './legacy/routes/knowledgeBases.js'; import batchRoutes from './legacy/routes/batchRoutes.js'; import reviewRoutes from './legacy/routes/reviewRoutes.js'; // ============================================ // 【新架构】标准化模块 // ============================================ import { aslRoutes } from './modules/asl/routes/index.js'; // ASL 模块(新) const fastify = Fastify({ logger: true }); // 注册插件 await fastify.register(cors, { origin: true }); await fastify.register(multipart, { limits: { fileSize: 10 * 1024 * 1024 } }); // 健康检查 fastify.get('/health', async () => ({ status: 'ok', architecture: 'hybrid', // 混合架构 modules: { legacy: ['aia', 'pkb', 'rvw'], modern: ['asl'], }, })); // ============================================ // 注册 Legacy 模块路由(旧架构) // ============================================ console.log('\n📦 加载 Legacy 模块...'); await fastify.register(projectRoutes, { prefix: '/api/v1/aia' }); await fastify.register(agentRoutes, { prefix: '/api/v1/aia' }); await fastify.register(conversationRoutes, { prefix: '/api/v1/aia' }); await fastify.register(chatRoutes, { prefix: '/api/v1/aia' }); await fastify.register(knowledgeBaseRoutes, { prefix: '/api/v1/pkb' }); await fastify.register(batchRoutes, { prefix: '/api/v1/pkb' }); await fastify.register(reviewRoutes, { prefix: '/api/v1/rvw' }); console.log('✅ Legacy 模块加载完成(AIA, PKB, RVW)'); // ============================================ // 注册新架构模块路由 // ============================================ console.log('\n🌟 加载新架构模块...'); await fastify.register(aslRoutes, { prefix: '/api/v1/asl' }); console.log('✅ 新架构模块加载完成(ASL)'); // 启动服务器 async function start() { try { validateEnv(); await testDatabaseConnection(); await fastify.listen({ port: config.port, host: config.host }); console.log('\n' + '='.repeat(60)); console.log('🚀 AI临床研究平台启动成功!'); console.log('='.repeat(60)); console.log(`📍 服务地址: http://${config.host}:${config.port}`); console.log('\n📦 模块架构:'); console.log(' 🔸 Legacy 架构: AIA, PKB, RVW (稳定运行)'); console.log(' 🌟 新架构: ASL (标准化模块)'); console.log('='.repeat(60) + '\n'); } catch (error) { console.error('❌ 启动失败:', error); await prisma.$disconnect(); process.exit(1); } } start(); ``` --- ## 🌟 新模块开发指南(ASL 为例) ### 1. 创建模块骨架 ```bash # 一次性创建所有目录 mkdir -p backend/src/modules/asl/{routes,controllers,services,types} ``` ### 2. 创建模块导出(index.ts) ```typescript // backend/src/modules/asl/index.ts /** * ASL 模块统一导出 */ export { aslRoutes } from './routes/index.js'; export * from './types/index.js'; ``` ### 3. 创建路由统一导出 ```typescript // backend/src/modules/asl/routes/index.ts import { FastifyInstance } from 'fastify'; import { projectRoutes } from './projects.js'; import { screeningRoutes } from './screening.js'; import { extractionRoutes } from './extraction.js'; import { analysisRoutes } from './analysis.js'; /** * ASL 模块路由注册 */ export async function aslRoutes(fastify: FastifyInstance) { // 注册各子模块路由 await fastify.register(projectRoutes); // /projects await fastify.register(screeningRoutes); // /screening await fastify.register(extractionRoutes); // /extraction await fastify.register(analysisRoutes); // /analysis console.log('✅ ASL 模块路由注册完成'); } ``` ### 4. 标准化的 Controller 模式 ```typescript // backend/src/modules/asl/controllers/projectController.ts import { FastifyRequest, FastifyReply } from 'fastify'; import * as projectService from '../services/projectService.js'; export class ProjectController { /** * 获取项目列表 */ async getProjects(request: FastifyRequest, reply: FastifyReply) { try { const projects = await projectService.getProjects(); return reply.send({ success: true, data: projects }); } catch (error) { console.error('获取项目列表失败:', error); return reply.status(500).send({ success: false, message: error instanceof Error ? error.message : '服务器错误' }); } } // ... 其他方法 } export const projectController = new ProjectController(); ``` --- ## 🔧 TSConfig 路径别名配置 ```json { "compilerOptions": { "baseUrl": ".", "paths": { "@config/*": ["src/config/*"], "@common/*": ["src/common/*"], "@legacy/*": ["src/legacy/*"], "@modules/*": ["src/modules/*"] } } } ``` **使用示例:** ```typescript // 新模块中导入通用能力 import { LLMFactory } from '@common/llm/adapters/LLMFactory.js'; import { DifyClient } from '@common/rag/DifyClient.js'; import { config } from '@config/env.js'; // Legacy 模块保持原有导入不变 import { agentService } from '../services/agentService.js'; ``` --- ## 📋 实施步骤(零风险) ### 第 1 步:文件重组(5分钟)⭐ ```bash # 1. 创建 legacy 目录 mkdir backend/src/legacy # 2. 移动现有代码到 legacy(保持相对路径不变) mv backend/src/routes backend/src/legacy/ mv backend/src/controllers backend/src/legacy/ mv backend/src/services backend/src/legacy/ mv backend/src/templates backend/src/legacy/ # 3. 创建新架构目录 mkdir -p backend/src/modules/asl/{routes,controllers,services,types} ``` **验证:** 无需修改任何代码,只是移动目录位置 --- ### 第 2 步:更新主入口(5分钟) 只修改 `src/index.ts` 的导入路径: ```typescript // 旧:from './routes/agents.js' // 新:from './legacy/routes/agents.js' ``` **验证:** `npm run dev` 服务器正常启动 --- ### 第 3 步:配置 TSConfig(2分钟) 添加路径别名配置。 **验证:** IDE 能识别 `@legacy/*`, `@modules/*` 等路径 --- ### 第 4 步:开发 ASL 模块(新功能) 按新架构标准开发,完全不影响现有模块。 --- ## ✅ 方案优势 ### 1. **零风险改造** - ✅ 现有代码只移动目录,不修改内容 - ✅ 只改一个文件的导入路径 - ✅ 可随时回滚 ### 2. **清晰的架构边界** ``` legacy/ ← 旧代码,明确标识 modules/ ← 新代码,标准化 ``` ### 3. **新模块新架构** - ✅ ASL 直接按标准实施 - ✅ 成为未来模块的范本 - ✅ 不受旧代码约束 ### 4. **平滑演进路径** ``` 现在:7个旧模块 + 0个新模块 未来:7个旧模块 + 1个新模块(ASL) 更远:7个旧模块 + N个新模块 最终:按需逐步迁移旧模块(可选) ``` --- ## 🎯 演进时间轴 | 阶段 | 时间 | 工作内容 | 风险 | |------|------|---------|------| | **今天** | 15分钟 | 重组目录+更新入口 | 极低 | | **Week 3** | - | 开发 ASL 模块(新架构) | 无(新功能) | | **Week 4+** | - | 继续开发新模块 | 无 | | **未来** | 按需 | 逐步迁移旧模块(可选) | 可控 | --- ## 📝 开发规范 ### Legacy 模块规范 - ⚠️ **不主动修改**,除非修复bug - ⚠️ 保持现有结构不变 - ⚠️ 可以引用 `common/` 层的能力 ### 新模块规范 - ✅ 必须按标准三层架构 - ✅ 必须使用路径别名 - ✅ 必须独立可部署 - ✅ 必须有完整的类型定义 --- ## 🚀 下一步行动 1. **今天(15分钟)**:执行第1-3步,完成目录重组 2. **明天**:开始 ASL 模块开发(新架构) 3. **Week 3**:ASL 模块上线 4. **未来**:新模块持续按标准开发 --- **最后更新:** 2025-11-14 **维护者:** 开发团队