feat(content): 修复服务并添加chapters/knowledge-points/questions模块

- database.ts 导出db常量替代getDb()函数

- env.ts JWT_SECRET/ES_URL/NEO4J_URL改optional加DEV_MODE

- neo4j.ts driver惰性创建+try/catch+connectionTimeout:3000

- health/lifecycle改用Drizzle原生查询

- textbooks.schema修复integer到int+导出NewTextbook类型

- 新建chapters/knowledge-points/questions三模块CRUD

- knowledge-points含Neo4j前置依赖图非阻塞查询

- content-init.sql创建4张表

端到端验证: textbooks/chapters/knowledge-points/questions全CRUD通过
This commit is contained in:
SpecialX
2026-07-09 08:52:15 +08:00
parent 033c083619
commit 921fe82771
29 changed files with 1031 additions and 246 deletions

View File

@@ -1,31 +1,46 @@
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 "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 { closeDb } from "./config/database.js";
import { closeNeo4j } from "./config/neo4j.js";
import { logger } from "./shared/observability/logger.js";
async function bootstrap(): Promise<void> {
initTracer();
const app = await NestFactory.create(AppModule, {
logger: ['log', 'error', 'warn'],
logger: ["log", "error", "warn"],
});
app.useGlobalFilters(new GlobalErrorFilter());
app.enableShutdownHooks();
await app.listen(env.PORT);
logger.info({ port: env.PORT }, 'Content service started');
logger.info({ port: env.PORT }, "Content service started");
process.on('SIGTERM', async () => {
await app.close();
process.on("SIGTERM", async () => {
logger.info("SIGTERM received, shutting down gracefully...");
await closeNeo4j();
await closeDb();
await shutdownTracer();
await app.close();
process.exit(0);
});
process.on("SIGINT", async () => {
logger.info("SIGINT received, shutting down gracefully...");
await closeNeo4j();
await closeDb();
await shutdownTracer();
await app.close();
process.exit(0);
});
}
bootstrap().catch((err: unknown) => {
logger.error({ err }, 'Failed to start content service');
logger.error({ err }, "Failed to start content service");
process.exit(1);
});