feat: scaffold NestJS backend with Swagger, validation, CORS

This commit is contained in:
Sergey Krylov 2026-06-13 18:47:16 +03:00
parent e9a9b4d119
commit 9c5f2c902a
6 changed files with 8322 additions and 0 deletions

View File

@ -0,0 +1,4 @@
{
"collection": "@nestjs/schematics",
"sourceRoot": "src"
}

42
apps/backend/package.json Normal file
View File

@ -0,0 +1,42 @@
{
"name": "@moex-vibe/backend",
"version": "0.0.1",
"private": true,
"scripts": {
"build": "nest build",
"start:dev": "nest start --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,test}/**/*.ts\"",
"test": "vitest run",
"test:watch": "vitest"
},
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/config": "^3.0.0",
"@nestjs/swagger": "^7.0.0",
"@nestjs/axios": "^3.0.0",
"@nestjs/cache-manager": "^2.0.0",
"cache-manager": "^5.0.0",
"axios": "^1.6.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.0",
"class-validator": "^0.14.0",
"class-transformer": "^0.5.0",
"p-queue": "^7.3.0",
"swagger-ui-express": "^5.0.0"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.0",
"@types/node": "^20.0.0",
"typescript": "^5.3.0",
"vitest": "^1.0.0",
"eslint": "^8.0.0",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0"
}
}

View File

@ -0,0 +1,24 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { CacheModule } from './modules/cache/cache.module';
import { MoexClientModule } from './modules/moex-client/moex-client.module';
import { HealthModule } from './modules/health/health.module';
import { SecuritiesModule } from './modules/securities/securities.module';
import { SharesModule } from './modules/shares/shares.module';
import { BondsModule } from './modules/bonds/bonds.module';
import { CandlesModule } from './modules/candles/candles.module';
import configuration from './config/configuration';
@Module({
imports: [
ConfigModule.forRoot({ load: [configuration], isGlobal: true }),
CacheModule,
MoexClientModule,
HealthModule,
SecuritiesModule,
SharesModule,
BondsModule,
CandlesModule,
],
})
export class AppModule {}

34
apps/backend/src/main.ts Normal file
View File

@ -0,0 +1,34 @@
import 'reflect-metadata';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { HttpExceptionFilter } from './common/filters/http-exception.filter';
import { TransformInterceptor } from './common/interceptors/transform.interceptor';
import { RequestLoggingMiddleware } from './common/middleware/request-logging.middleware';
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('api/v1');
app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }));
app.useGlobalFilters(new HttpExceptionFilter());
app.useGlobalInterceptors(new TransformInterceptor());
app.use(new RequestLoggingMiddleware().use);
app.enableCors();
const config = new DocumentBuilder()
.setTitle('MoexVibe API')
.setVersion('1.0.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api/docs', app, document);
const port = process.env.PORT || 3000;
await app.listen(port);
console.log(`MoexVibe API running on http://localhost:${port}/api/v1`);
console.log(`Swagger docs: http://localhost:${port}/api/docs`);
}
bootstrap();

View File

@ -0,0 +1,16 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"outDir": "./dist",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src/**/*"]
}

8202
package-lock.json generated

File diff suppressed because it is too large Load Diff