augmenttoolkit / server /src /bootstrap.ts
Leon4gr45's picture
Complete deployment configuration (part 2)
46a0a8a verified
Raw
History Blame Contribute Delete
2.9 kB
import { NestFactory } from '@nestjs/core';
import { ExpressAdapter } from '@nestjs/platform-express';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import type { INestApplication } from '@nestjs/common';
import { AppModule } from './nest/app.module';
import { applyGlobalMiddleware } from './middleware/globalMiddleware';
import { applyPlatformUploads, applyPlatformTransport, applyPlatformStatic } from './nest/platform/platform.routes';
/**
* Builds the unified TREK NestJS application that serves the ENTIRE surface β€” the
* former Express app is gone. One builder is shared by the production bootstrap
* (index.ts) and the integration-test harness so the two can never drift.
*
* Composition order is load-bearing. Everything except the SPA index.html fallback
* is registered on the underlying Express instance BEFORE `app.init()`, because
* Nest's router terminates an unmatched request by throwing NotFoundException β€” it
* does NOT fall through to a route registered after init, so a post-init Express
* route is unreachable. The platform routes are all specific paths (/uploads/*,
* /api/health, /mcp, /.well-known/*, /oauth/{authorize,register,consent}) so they
* match their own requests and `next()` everything else through to the Nest
* controllers registered during init.
*
* 1. applyGlobalMiddleware β€” helmet/CSP, CORS, HSTS, forced-HTTPS, the global MFA
* policy, request logging + cookie-parser. `bodyParser: false` so Nest does its
* own parsing and the raw /mcp body reaches the MCP handler unparsed.
* 2. applyPlatformUploads β€” the static + guarded /uploads/* routes.
* 3. applyPlatformTransport β€” /api/health, the OAuth/MCP SDK + /.well-known
* metadata, the /mcp routes, the /oauth/consent COOP header.
* 4. applyPlatformStatic β€” the production built-client static assets (so a real
* asset request returns the file before the Nest router 404s it).
* 5. app.init() β€” registers every migrated /api domain (the Nest controllers).
*
* The SPA index.html fallback (unmatched GET β†’ index.html in production) is the
* SpaFallbackFilter (APP_FILTER in AppModule); the global error envelope is the
* TrekExceptionFilter (also APP_FILTER).
*/
export async function buildApp(): Promise<INestApplication> {
const app = await NestFactory.create(AppModule, new ExpressAdapter());
const instance = app.getHttpAdapter().getInstance();
applyGlobalMiddleware(instance, { bodyParser: false });
applyPlatformUploads(instance);
applyPlatformTransport(instance);
applyPlatformStatic(instance);
const config = new DocumentBuilder()
.setTitle('TREK API')
.setDescription('The TREK API documentation')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api-docs', app, document);
await app.init();
return app;
}