NestJS (6 services): implement @RequirePermission decorator with SetMetadata+Reflector, register APP_GUARD globally, fix as assertions to type guards, add explicit return types, fix import type for express, fix /metrics implicit any, replace native Error with ApplicationError, remove typeorm remnants, register LifecycleService. teacher-bff: add logger, ApplicationError, GlobalErrorFilter, forward real userId to downstream, log downstream failures, migrate health controller to shared/health. Go (2 services): interface to any, doc comments, CORS dev whitelist, JWT secret fail-fast, push-gateway internal API auth, metrics and readyz endpoints, remove dead code. Python (2 services): lifespan return type, dev_mode to bool, data-ana APIRouter, ai POST body model, ClickHouse async wrapping.
41 lines
1.4 KiB
TypeScript
41 lines
1.4 KiB
TypeScript
import "reflect-metadata";
|
||
import { NestFactory } from "@nestjs/core";
|
||
import { AppModule } from "./app.module.js";
|
||
import { GlobalErrorFilter } from "./shared/errors/global-error.filter.js";
|
||
import { initTracer, shutdownTracer } from "./shared/observability/tracer.js";
|
||
import { env } from "./config/env.js";
|
||
import { logger } from "./shared/observability/logger.js";
|
||
import { metricsRegistry } from "./shared/observability/metrics.js";
|
||
import type { Request, Response } from "express";
|
||
|
||
async function bootstrap(): Promise<void> {
|
||
initTracer();
|
||
|
||
const app = await NestFactory.create(AppModule, {
|
||
logger: ["log", "error", "warn"],
|
||
});
|
||
|
||
app.useGlobalFilters(new GlobalErrorFilter());
|
||
app.enableShutdownHooks();
|
||
|
||
// Prometheus 指标端点:不鉴权,供 Prometheus 抓取。
|
||
// 返回 register.metrics()(Promise<string>,含 Content-Type text/plain; version=0.0.4; charset=utf-8)。
|
||
app.getHttpAdapter().get("/metrics", async (_req: Request, res: Response) => {
|
||
res.set("Content-Type", metricsRegistry.contentType);
|
||
res.end(await metricsRegistry.metrics());
|
||
});
|
||
|
||
await app.listen(env.PORT);
|
||
logger.info({ port: env.PORT }, "IAM service started");
|
||
|
||
process.on("SIGTERM", async () => {
|
||
await app.close();
|
||
await shutdownTracer();
|
||
});
|
||
}
|
||
|
||
bootstrap().catch((err: unknown) => {
|
||
logger.error({ err }, "Failed to start IAM service");
|
||
process.exit(1);
|
||
});
|