Files
Edu/packages/shared-ts/src/federation/context.ts
SpecialX 5fcb831a18 feat(shared-ts): federation shared utilities for apollo subgraphs
- RouterAuthGuard: validate Router-Authorization header (ADR-036)

- DataLoader factory: request-scoped batching (ADR-035)

- ScopeTokenService: Redis-backed scope token (ADR-041)

- GraphqlContext: build context from HTTP headers

- FederationExceptionFilter: HTTP-to-GraphQL error mapping
2026-07-14 23:46:51 +08:00

61 lines
1.7 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.
/**
* GraphQL Context - Apollo Router 下传的请求上下文
*
* Apollo Router 通过 headers 传递以下信息到子图:
* - authorization: JWT token透传
* - x-user-id: 已认证用户 ID
* - x-user-role: 用户角色
* - x-dataScope: 数据范围ALL / SCHOOL / GRADE / CLASS / STUDENT
* - x-request-id: 请求追踪 ID
*
* 子图从 HTTP headers 提取后构造 GraphqlContext注入 Resolver。
*/
export type DataScope = "ALL" | "SCHOOL" | "GRADE" | "CLASS" | "STUDENT";
export interface GraphqlContextInput {
userId?: string;
userRole?: string;
dataScope?: DataScope;
requestId?: string;
jwt?: string;
}
export class GraphqlContext {
readonly userId?: string;
readonly userRole?: string;
readonly dataScope: DataScope;
readonly requestId: string;
readonly jwt?: string;
constructor(input: GraphqlContextInput) {
this.userId = input.userId;
this.userRole = input.userRole;
this.dataScope = input.dataScope ?? "ALL";
this.requestId = input.requestId ?? "unknown";
this.jwt = input.jwt;
}
/** 是否管理员(全量可见) */
get isAdmin(): boolean {
return this.dataScope === "ALL" || this.userRole === "admin";
}
/** 是否已认证 */
get isAuthenticated(): boolean {
return !!this.userId;
}
/** 从 HTTP headers 构造NestJS @Context 提取) */
static fromHeaders(
headers: Record<string, string | undefined>,
): GraphqlContext {
return new GraphqlContext({
userId: headers["x-user-id"],
userRole: headers["x-user-role"],
dataScope: headers["x-datapscope"] as DataScope | undefined,
requestId: headers["x-request-id"],
jwt: headers["authorization"]?.replace(/^Bearer\s+/i, ""),
});
}
}