feat(p2): identity layer with IAM service and Teacher BFF

P2 阶段交付物:
- services/iam: 完整身份认证服务(users/roles/permissions/refresh_tokens 6 表 schema)
  - register/login/refresh/getUserInfo 4 个核心 API
  - bcrypt 密码哈希 + JWT 双 Token(access + refresh)
  - 复用 classes 黄金模板(errors/observability/middleware 三件套)
- services/teacher-bff: 教师聚合 BFF
  - Promise.allSettled 并行聚合 IAM + classes 数据
  - /teacher/dashboard 单一聚合端点
- packages/shared-proto/proto/iam.proto: IamService 契约(Register/Login/RefreshToken/GetUserInfo)
- api-gateway: 新增 IamServiceURL/TeacherBffURL 配置 + /iam/* + /teacher/* 路由
This commit is contained in:
SpecialX
2026-07-08 01:37:29 +08:00
parent 2ba4250165
commit 524204d30a
35 changed files with 1108 additions and 1 deletions

View File

@@ -0,0 +1,25 @@
import { z } from 'zod';
const envSchema = z.object({
PORT: z.string().default('3003'),
IamServiceUrl: z.string().url().default('http://localhost:3002'),
ClassesServiceUrl: z.string().url().default('http://localhost:3001'),
LOG_LEVEL: z.string().default('info'),
NODE_ENV: z.string().default('development'),
});
export type Env = z.infer<typeof envSchema>;
export function loadEnv(): Env {
const result = envSchema.safeParse({
...process.env,
IamServiceUrl: process.env.IAM_SERVICE_URL || 'http://localhost:3002',
ClassesServiceUrl: process.env.CLASSES_SERVICE_URL || 'http://localhost:3001',
});
if (!result.success) {
throw new Error('Invalid env: ' + JSON.stringify(result.error.flatten()));
}
return result.data;
}
export const env = loadEnv();