feat(backend): Day 5 - backend basic architecture setup completed

This commit is contained in:
AI Clinical Dev Team
2025-10-10 15:56:45 +08:00
parent 1fac0b5cbf
commit 39e14cfb97
14 changed files with 3616 additions and 26 deletions

View File

@@ -0,0 +1,35 @@
import { PrismaClient } from '@prisma/client';
// 创建Prisma Client实例
export const prisma = new PrismaClient({
log: process.env.NODE_ENV === 'development' ? ['query', 'info', 'warn', 'error'] : ['error'],
});
// 数据库连接测试
export async function testDatabaseConnection(): Promise<boolean> {
try {
await prisma.$connect();
console.log('✅ 数据库连接成功!');
// 获取数据库信息
const result = await prisma.$queryRaw<Array<{ version: string }>>`SELECT version()`;
console.log('📊 数据库版本:', result[0]?.version.split(' ')[0], result[0]?.version.split(' ')[1]);
return true;
} catch (error) {
console.error('❌ 数据库连接失败:', error);
return false;
}
}
// 优雅关闭数据库连接
export async function closeDatabaseConnection() {
await prisma.$disconnect();
console.log('👋 数据库连接已关闭');
}
// 进程退出时关闭连接
process.on('beforeExit', async () => {
await closeDatabaseConnection();
});

36
backend/src/config/env.ts Normal file
View File

@@ -0,0 +1,36 @@
import { config as dotenvConfig } from 'dotenv';
dotenvConfig();
export const config = {
// 服务器配置
nodeEnv: process.env.NODE_ENV || 'development',
port: parseInt(process.env.PORT || '3001', 10),
host: process.env.HOST || '0.0.0.0',
// 数据库配置
databaseUrl: process.env.DATABASE_URL || '',
// Redis配置
redisUrl: process.env.REDIS_URL || 'redis://localhost:6379',
// JWT配置
jwtSecret: process.env.JWT_SECRET || 'your-secret-key',
// 大模型API Keys
deepseekApiKey: process.env.DEEPSEEK_API_KEY || '',
qwenApiKey: process.env.QWEN_API_KEY || '',
geminiApiKey: process.env.GEMINI_API_KEY || '',
// Dify配置
difyApiUrl: process.env.DIFY_API_URL || 'http://localhost:5001',
difyApiKey: process.env.DIFY_API_KEY || '',
// 文件上传配置
uploadMaxSize: parseInt(process.env.UPLOAD_MAX_SIZE || '10485760', 10),
uploadDir: process.env.UPLOAD_DIR || './uploads',
// 日志配置
logLevel: process.env.LOG_LEVEL || 'info',
};

87
backend/src/index.ts Normal file
View File

@@ -0,0 +1,87 @@
import Fastify from 'fastify';
import cors from '@fastify/cors';
import { config } from './config/env.js';
import { testDatabaseConnection, prisma } from './config/database.js';
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,
});
// 健康检查路由
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,
};
});
// 启动服务器
const start = async () => {
try {
// 测试数据库连接
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();