- Day 21-22: fix CORS and file upload issues - Day 23-24: implement @knowledge base search and conversation integration - Backend: integrate Dify RAG into conversation system - Frontend: load knowledge base list and @ reference feature
128 lines
3.6 KiB
TypeScript
128 lines
3.6 KiB
TypeScript
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';
|
||
import { projectRoutes } from './routes/projects.js';
|
||
import { agentRoutes } from './routes/agents.js';
|
||
import { conversationRoutes } from './routes/conversations.js';
|
||
import knowledgeBaseRoutes from './routes/knowledgeBases.js';
|
||
|
||
|
||
// 全局处理BigInt序列化
|
||
(BigInt.prototype as any).toJSON = function() {
|
||
return Number(this);
|
||
};
|
||
|
||
const fastify = Fastify({
|
||
logger: {
|
||
level: config.logLevel,
|
||
transport: {
|
||
target: 'pino-pretty',
|
||
options: {
|
||
colorize: true,
|
||
translateTime: 'HH:MM:ss Z',
|
||
ignore: 'pid,hostname',
|
||
},
|
||
},
|
||
},
|
||
});
|
||
|
||
// 注册CORS插件 - 完整配置
|
||
await fastify.register(cors, {
|
||
origin: true, // 开发环境允许所有来源
|
||
credentials: true,
|
||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'], // 明确允许的HTTP方法
|
||
allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'Accept', 'Origin'], // 允许的请求头
|
||
exposedHeaders: ['Content-Range', 'X-Content-Range'], // 暴露的响应头
|
||
maxAge: 600, // preflight请求缓存时间(秒)
|
||
preflightContinue: false, // Fastify处理preflight请求
|
||
});
|
||
console.log('✅ CORS已配置: 允许所有HTTP方法 (GET, POST, PUT, DELETE, PATCH, OPTIONS)');
|
||
|
||
// 注册文件上传插件
|
||
await fastify.register(multipart, {
|
||
limits: {
|
||
fileSize: 10 * 1024 * 1024, // 10MB
|
||
},
|
||
});
|
||
console.log('✅ 文件上传插件已配置: 最大文件大小 10MB');
|
||
|
||
|
||
// 健康检查路由
|
||
fastify.get('/health', async () => {
|
||
// 检查数据库连接
|
||
let dbStatus = 'unknown';
|
||
try {
|
||
await prisma.$queryRaw`SELECT 1`;
|
||
dbStatus = 'connected';
|
||
} catch {
|
||
dbStatus = 'disconnected';
|
||
}
|
||
|
||
return {
|
||
status: 'ok',
|
||
database: dbStatus,
|
||
timestamp: new Date().toISOString(),
|
||
uptime: process.uptime(),
|
||
};
|
||
});
|
||
|
||
// API路由前缀
|
||
fastify.get('/api/v1', async () => {
|
||
return {
|
||
message: 'AI Clinical Research Platform API',
|
||
version: '1.0.0',
|
||
environment: config.nodeEnv,
|
||
};
|
||
});
|
||
|
||
// 注册项目管理路由
|
||
await fastify.register(projectRoutes, { prefix: '/api/v1' });
|
||
|
||
// 注册智能体管理路由
|
||
await fastify.register(agentRoutes, { prefix: '/api/v1' });
|
||
|
||
// 注册对话管理路由
|
||
await fastify.register(conversationRoutes, { prefix: '/api/v1' });
|
||
|
||
// 注册知识库管理路由
|
||
await fastify.register(knowledgeBaseRoutes, { prefix: '/api/v1' });
|
||
|
||
// 启动服务器
|
||
const start = async () => {
|
||
try {
|
||
// 验证环境变量
|
||
validateEnv();
|
||
|
||
// 测试数据库连接
|
||
console.log('🔍 正在测试数据库连接...');
|
||
const dbConnected = await testDatabaseConnection();
|
||
|
||
if (!dbConnected) {
|
||
console.error('❌ 数据库连接失败,无法启动服务器');
|
||
process.exit(1);
|
||
}
|
||
|
||
// 启动Fastify服务器
|
||
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 === '0.0.0.0' ? 'localhost' : config.host}:${config.port}`);
|
||
console.log(`🔍 健康检查: http://localhost:${config.port}/health`);
|
||
console.log(`📡 API入口: http://localhost:${config.port}/api/v1`);
|
||
console.log(`🌍 运行环境: ${config.nodeEnv}`);
|
||
console.log('='.repeat(60) + '\n');
|
||
} catch (err) {
|
||
fastify.log.error(err);
|
||
process.exit(1);
|
||
}
|
||
};
|
||
|
||
start();
|