feat(web): T-WEB-001 NestJS 骨架 + 连接现有 MySQL 实例
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import { Logger, ValidationPipe } from '@nestjs/common';
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { NestExpressApplication } from '@nestjs/platform-express';
|
||||
import { existsSync, mkdirSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import { AppModule } from './app.module';
|
||||
import { AppConfig, configuration, validateEnv } from './config/configuration';
|
||||
|
||||
async function bootstrap(): Promise<void> {
|
||||
const logger = new Logger('Bootstrap');
|
||||
|
||||
// 启动前校验环境变量(生产环境禁止 DB_SYNCHRONIZE=true 等)
|
||||
const problems = validateEnv(configuration());
|
||||
if (problems.length > 0) {
|
||||
for (const problem of problems) logger.warn(`环境变量问题:${problem}`);
|
||||
if ((process.env.NODE_ENV ?? 'development') === 'production') {
|
||||
logger.error('生产环境配置校验失败,启动中止');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
|
||||
logger: ['error', 'warn', 'log'],
|
||||
});
|
||||
|
||||
const config = app.get(AppConfig);
|
||||
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({
|
||||
transform: true,
|
||||
whitelist: true,
|
||||
forbidNonWhitelisted: false,
|
||||
transformOptions: { enableImplicitConversion: false },
|
||||
}),
|
||||
);
|
||||
|
||||
// Windows 客户端与管理端跨源访问
|
||||
app.enableCors({
|
||||
origin: true,
|
||||
credentials: false,
|
||||
exposedHeaders: ['Content-Disposition'],
|
||||
});
|
||||
|
||||
// 上传文件静态访问:/static/<kind>/<yyyy>/<mm>/<sha256>.<ext>
|
||||
const storageDir = resolve(config.storageDir);
|
||||
if (!existsSync(storageDir)) mkdirSync(storageDir, { recursive: true });
|
||||
app.useStaticAssets(storageDir, { prefix: '/static/', index: false, fallthrough: true });
|
||||
|
||||
// 契约快照静态访问(若存在):/contracts/rest-api.yaml 等
|
||||
if (config.contractsDir && existsSync(config.contractsDir)) {
|
||||
app.useStaticAssets(resolve(config.contractsDir), { prefix: '/contracts/', index: false });
|
||||
}
|
||||
|
||||
app.enableShutdownHooks();
|
||||
|
||||
const db = config.db;
|
||||
await app.listen(config.port, '0.0.0.0');
|
||||
|
||||
logger.log(`OpenDance Studio Web 服务端已启动:http://0.0.0.0:${config.port}`);
|
||||
logger.log(`健康检查:http://0.0.0.0:${config.port}/health`);
|
||||
logger.log(`数据库:${db.host}:${db.port}/${db.name}(现有实例,本服务不管理 MySQL)`);
|
||||
logger.log(`文件存储:${storageDir}`);
|
||||
logger.log(`契约版本:${JSON.stringify(config.contractVersions)}`);
|
||||
}
|
||||
|
||||
void bootstrap().catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('服务启动失败:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user