feat(teacher-bff): 完整实现 teacher-bff GraphQL 聚合层

包含 clients/graphql/middleware、health probes、shared-ts contracts 等
This commit is contained in:
SpecialX
2026-07-10 19:10:07 +08:00
parent b82593aac2
commit 99155a5ea1
37 changed files with 2862 additions and 324 deletions

View File

@@ -0,0 +1,37 @@
// GraphQL 上下文构建B1 裁决P2 起直接 GraphQL
// 从 Express 请求提取 userId / traceId注入下游 CallContext
import type { Request } from "express";
import type { CallContext } from "../clients/types.js";
import { UnauthorizedError } from "../shared/errors/application-error.js";
export interface GraphQLOperationContext {
/** 当前请求的 CallContext注入下游 gRPC 调用) */
callCtx: CallContext;
}
/**
* 从 Express 请求构建 GraphQL 上下文
* P2: 从 x-user-id header 提取 userIdapi-gateway 注入)
* P3+: 从 JWT 提取api-gateway 校验后注入 x-user-id + x-user-roles
*/
export function buildGraphQLContext(req: Request): GraphQLOperationContext {
const userIdHeader = req.headers["x-user-id"];
const userId = typeof userIdHeader === "string" ? userIdHeader : undefined;
if (!userId) {
throw new UnauthorizedError("Missing x-user-id header");
}
const requestIdHeader = req.headers["x-request-id"];
const traceId =
typeof requestIdHeader === "string" ? requestIdHeader : undefined;
const rolesHeader = req.headers["x-user-roles"];
const roles =
typeof rolesHeader === "string"
? rolesHeader.split(",").filter(Boolean)
: undefined;
return {
callCtx: { userId, traceId, roles },
};
}