/** * config-service GraphQL 子图模块(v2.1 M3) * * Apollo Federation 2 子图,提供 4 类 Entity 查询: * - PluginRegistry(@key(fields: "pluginId")) * - RolePluginMapping * - LayoutTemplate * - UserLayoutOverride(@key(fields: "userId")) * * 强制约束: * - @key 解析器必须使用 DataLoader(ADR-035) * - RouterAuthGuard 校验 Router-Authorization Header(ADR-036) */ import { Module } from "@nestjs/common"; import { GraphQLModule } from "@nestjs/graphql"; import { ApolloFederationDriver, ApolloDriverConfig } from "@nestjs/apollo"; import { join } from "node:path"; import { GraphqlContext } from "@edu/shared-ts/federation"; import { ConfigModule } from "../config-config/config.module.js"; import { PluginResolver } from "./resolvers/plugin.resolver.js"; import { LayoutTemplateResolver } from "./resolvers/layout-template.resolver.js"; import { UserLayoutResolver } from "./resolvers/user-layout.resolver.js"; import { PluginConfigResolver } from "./resolvers/plugin-config.resolver.js"; import { DataLoaderService } from "./dataloader.service.js"; @Module({ imports: [ ConfigModule, GraphQLModule.forRoot({ driver: ApolloFederationDriver, // Federation 2 子图 autoSchemaFile: { path: join(process.cwd(), "src/graphql/generated/schema.graphql"), federation: 2, }, // /graphql 端点(Apollo Router 访问入口) path: "/graphql", // 禁用 playground(生产环境通过 Router 访问) playground: process.env.NODE_ENV === "development", introspection: process.env.NODE_ENV === "development", // Context 从 HTTP headers 构造 context: (ctx: { req: { headers: Record }; }) => ({ req: ctx.req, graphqlContext: GraphqlContext.fromHeaders(ctx.req.headers), }), }), ], providers: [ PluginResolver, LayoutTemplateResolver, UserLayoutResolver, PluginConfigResolver, DataLoaderService, ], exports: [DataLoaderService], }) export class GraphqlModule {}