INSIGHT-MVP/packages/crm-service/src/main.ts
Thomas Reitz 8783d01fc0 feat(crm): scaffold CRM service with full CRUD modules
Eigenstaendiger NestJS-Service unter packages/crm-service/ mit:
- Prisma Schema (app_crm): Contact, Activity, Pipeline, PipelineStage, Deal
- JWT RS256 Auth mit shared Public Key und Token-Revocation
- Multi-Tenancy: TenantGuard + tenantId-Filter auf allen Queries
- CRUD-Module: Contacts, Activities, Pipelines, Deals
- Docker-Integration: docker-compose.crm.yml (Port 3100, Traefik-Route /api/v1/crm)
- Health-Check, Swagger, GlobalExceptionFilter, Pagination

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:54:13 +01:00

81 lines
2.2 KiB
TypeScript

import { NestFactory } from '@nestjs/core';
import { ValidationPipe, Logger } from '@nestjs/common';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import cookieParser from 'cookie-parser';
import helmet from 'helmet';
import { json } from 'express';
import { AppModule } from './app.module';
async function bootstrap(): Promise<void> {
const logger = new Logger('Bootstrap');
const app = await NestFactory.create(AppModule, {
logger: ['error', 'warn', 'log', 'debug', 'verbose'],
});
// Security
app.use(helmet());
app.use(cookieParser());
// Body size limit (12MB fuer Base64-Uploads)
app.use(json({ limit: '12mb' }));
// CORS
const corsOrigins = process.env.CORS_ORIGINS?.split(',') ?? [
'http://172.20.10.59',
];
app.enableCors({
origin: corsOrigins,
credentials: true,
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
allowedHeaders: [
'Content-Type',
'Authorization',
'X-Tenant-ID',
'X-Request-ID',
],
});
// Global Validation Pipe (whitelist + forbidNonWhitelisted)
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
transform: true,
transformOptions: { enableImplicitConversion: true },
}),
);
// Global Prefix: /api/v1/crm (NICHT /api/v1 — das ist der Core!)
app.setGlobalPrefix('api/v1/crm', {
exclude: ['health'],
});
// Swagger (nur Development)
if (process.env.NODE_ENV !== 'production') {
const config = new DocumentBuilder()
.setTitle('INSIGHT CRM API')
.setDescription('CRM Module API for INSIGHT Platform')
.setVersion('0.1.0')
.addBearerAuth(
{
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
description: 'Access Token (RS256)',
},
'access-token',
)
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api/v1/crm/docs', app, document);
logger.log('Swagger UI: /api/v1/crm/docs');
}
const port = process.env.APP_PORT ?? 3100;
await app.listen(port);
logger.log(`CRM-Service laeuft auf Port ${port}`);
logger.log(`Umgebung: ${process.env.NODE_ENV ?? 'development'}`);
}
bootstrap();