feat(teacher-bff): 完整实现 teacher-bff GraphQL 聚合层
包含 clients/graphql/middleware、health probes、shared-ts contracts 等
This commit is contained in:
37
services/teacher-bff/src/graphql/context.ts
Normal file
37
services/teacher-bff/src/graphql/context.ts
Normal 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 提取 userId(api-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 },
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user