refactor(api): version routes and externalize client base url
- serve REST endpoints under /api/v1 with root exceptions for health and mcp - move swagger UI to /docs and allow direct frontend calls via CORS - remove Vite proxy/hash routing and rely on env-driven VITE_API_URL
This commit is contained in:
@@ -23,7 +23,7 @@ export class AppConfig {
|
||||
KEYS_DIR: string = "keys";
|
||||
|
||||
@IsString()
|
||||
DB_PATH: string = "data/sessions.db";
|
||||
DB_PATH: string = "data/liqa.db";
|
||||
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
|
||||
@@ -4,6 +4,13 @@ import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
|
||||
@ApiTags("health")
|
||||
@Controller()
|
||||
export class HealthController {
|
||||
@Get("health")
|
||||
@ApiOperation({ summary: "Health check" })
|
||||
@ApiResponse({ status: 200, description: "Service is healthy" })
|
||||
health(): { status: string } {
|
||||
return { status: "ok" };
|
||||
}
|
||||
|
||||
@Get("healthz")
|
||||
@ApiOperation({ summary: "Health check" })
|
||||
@ApiResponse({ status: 200, description: "Service is healthy" })
|
||||
|
||||
+21
-3
@@ -1,7 +1,7 @@
|
||||
import { NestFactory } from "@nestjs/core";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import { AppConfig } from "./config/app.config";
|
||||
import { ValidationPipe } from "@nestjs/common";
|
||||
import { RequestMethod, ValidationPipe } from "@nestjs/common";
|
||||
import { TraceLogger } from "./common/trace-logger";
|
||||
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
|
||||
import { AppModule } from "./app.module";
|
||||
@@ -11,11 +11,20 @@ import { LoggingInterceptor } from "./interceptors/logging.interceptor";
|
||||
import { name as pkgName, version as pkgVersion } from "../package.json";
|
||||
|
||||
async function bootstrap() {
|
||||
const API_PREFIX = "api/v1";
|
||||
const logger = new TraceLogger("Bootstrap");
|
||||
const app = await NestFactory.create(AppModule, {
|
||||
logger: new TraceLogger("Bootstrap", { timestamp: true }),
|
||||
});
|
||||
|
||||
app.setGlobalPrefix(API_PREFIX, {
|
||||
exclude: [
|
||||
{ path: "health", method: RequestMethod.ALL },
|
||||
{ path: "healthz", method: RequestMethod.ALL },
|
||||
{ path: "mcp", method: RequestMethod.ALL },
|
||||
],
|
||||
});
|
||||
|
||||
app.useGlobalPipes(new ValidationPipe({ transform: true }));
|
||||
app.useGlobalFilters(new HttpExceptionFilter());
|
||||
app.useGlobalInterceptors(new TraceInterceptor(), new LoggingInterceptor());
|
||||
@@ -24,6 +33,15 @@ async function bootstrap() {
|
||||
const port = config.get("PORT");
|
||||
const nodeEnv = config.get("NODE_ENV");
|
||||
|
||||
app.enableCors({
|
||||
origin: [
|
||||
"http://localhost:5173",
|
||||
"http://127.0.0.1:5173",
|
||||
],
|
||||
methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE", "OPTIONS"],
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
const swaggerConfig = new DocumentBuilder()
|
||||
.setTitle(pkgName)
|
||||
.setDescription(`${pkgName} API`)
|
||||
@@ -31,14 +49,14 @@ async function bootstrap() {
|
||||
.build();
|
||||
|
||||
const document = SwaggerModule.createDocument(app, swaggerConfig);
|
||||
SwaggerModule.setup("api", app, document);
|
||||
SwaggerModule.setup("docs", app, document);
|
||||
|
||||
await app.listen(port);
|
||||
|
||||
logger.log(
|
||||
`Application "${pkgName}" v${pkgVersion} running on port ${port} [${nodeEnv}]`,
|
||||
);
|
||||
logger.log(`Swagger UI available at http://localhost:${port}/api`);
|
||||
logger.log(`Swagger UI available at http://localhost:${port}/docs`);
|
||||
logger.log(`MCP endpoint available at http://localhost:${port}/mcp`);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user