Files
Edu/services/msg/src/config/env.ts
SpecialX a6b0c54fba fix: 修复登录路由 + 端口冲突 + Prometheus 配置 + outbox 表结构 + 补充监控基础设施
1. teacher-portal 登录 JSON 解析错误修复
   - 根因:next.config.js rewrites /api/auth/* → gateway /api/auth/*,
     但 gateway 只在 /api/v1 路由组下注册代理,/api/auth/* 返回 404 纯文本
   - 修复:rewrites 映射 /api/auth/* → /api/v1/iam/*(对齐 iam controller @Controller("v1/iam"))

2. msg / data-ana 端口冲突修复
   - 根因:msg env.ts PORT 默认 3006,与 data-ana(config.py http_port=3006)冲突
   - 修复:msg PORT 默认 3006→3007(对齐端口分配表 msg=3007, data-ana=3006)

3. Prometheus classes-service 3001 DOWN 修复
   - 根因:classes 已合并入 core-edu(P3 裁决 C1),但 prometheus.yml 仍有 classes-service scrape 配置
   - 修复:从 prometheus.yml 删除 classes-service job

4. iam outbox 表 aggregate_id 列长度修复
   - 根因:iam_outbox.aggregate_id VARCHAR(32),但 UUID 是 36 字符,导致 "Data too long" 错误
   - 修复:DDL 中 VARCHAR(32) → VARCHAR(36);ALTER TABLE 修复现有数据库

5. 补充未搭建的监控基础设施
   - docker-compose.yml 新增 Alertmanager(9093)/ Loki(3100)/ Promtail(observability profile)
   - prometheus.yml alertmanager target 更新为 edu-alertmanager:9093

验证:
- TS typecheck 19 项目全部通过
- 登录链路 teacher-portal → gateway → iam 验证通过
- Prometheus targets 不再有 classes-service
- 3 个新基础设施容器(alertmanager/loki/promtail)启动成功

AI identity: trae-main(基础设施修复会话)
2026-07-11 09:22:09 +08:00

50 lines
1.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { z } from "zod";
/**
* msg 服务环境变量 schema。
*
* 仲裁依据:
* - G2 /readyz 多依赖检查DB/ES/Redis/Kafka/PushGateway
* - M2 PushGateway 软失败PUSH_GATEWAY_URL 可选)
* - M4 HTTP POST /internal/push豁免 gRPC
* - REDIS_URL 可选,未配置时降级到 DB 唯一索引去重
*/
const envSchema = z.object({
PORT: z.string().default("3007"),
GRPC_PORT: z.string().default("50056"),
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"),
KAFKA_CLIENT_ID: z.string().default("msg-service"),
KAFKA_CONSUMER_GROUP_ID: z.string().default("msg-service-group"),
ES_URL: z.string().url().optional(),
PUSH_GATEWAY_URL: z.string().url().optional(),
PUSH_INTERNAL_TOKEN: z.string().optional(),
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();