database.ts 导出 db 常量替代 getDb() env.ts JWT_SECRET 改 optional 并新增 DEV_MODE kafka.ts connectKafka 加 try/catch 不阻塞启动 main.ts 去全局前缀 connectKafka 改非阻塞 app.module 移除未用模块加 HealthModule controller 路由去前缀去 UseGuards 从 x-user-id 读身份 service datetime ISO 字符串转 Date 修复 drizzle 错误 修正相对 import 路径 health/lifecycle 改用 Drizzle 原生查询 新增 core-edu-init.sql 初始化 4 张表 端到端验证: exams/homework/grades 全部 201/200 Outbox 事件正确写入 core_edu_outbox 表
35 lines
1005 B
TypeScript
35 lines
1005 B
TypeScript
import { z } from "zod";
|
|
|
|
const envSchema = z.object({
|
|
PORT: z.string().default("3004"),
|
|
DATABASE_URL: z.string().url(),
|
|
REDIS_URL: z.string().url().optional(),
|
|
JWT_SECRET: z.string().optional(),
|
|
JWT_ISSUER: z.string().default("next-edu-cloud"),
|
|
KAFKA_BROKERS: z.string().default("localhost:9092"),
|
|
OTEL_EXPORTER_OTLP_ENDPOINT: z.string().url().optional(),
|
|
LOG_LEVEL: z
|
|
.enum(["fatal", "error", "warn", "info", "debug", "trace"])
|
|
.default("info"),
|
|
NODE_ENV: z
|
|
.enum(["development", "production", "test"])
|
|
.default("development"),
|
|
DEV_MODE: z.string().optional().default("false"),
|
|
});
|
|
|
|
export type Env = z.infer<typeof envSchema>;
|
|
|
|
export function loadEnv(): Env {
|
|
const result = envSchema.safeParse(process.env);
|
|
if (!result.success) {
|
|
console.error(
|
|
"❌ Invalid environment variables:",
|
|
result.error.flatten().fieldErrors,
|
|
);
|
|
throw new Error("Invalid environment configuration");
|
|
}
|
|
return result.data;
|
|
}
|
|
|
|
export const env = loadEnv();
|