/** * iam User Resolver(v2.1 M1) * * Apollo Federation 子图:User Entity * - @key(fields: "userId") 支持跨子图引用 * - @ResolveReference 使用 DataLoader 批量加载(ADR-035) * - Query 入口供 Apollo Router 直接查询 */ import { Resolver, Query, Args, ID, ResolveReference, ObjectType, Field, Directive, } from "@nestjs/graphql"; import { DataLoaderService, type UserEntity } from "../dataloader.service.js"; /** * User ObjectType(Federation @key) * 对应 iam.users 表 */ @ObjectType() @Directive(`@key(fields: "userId")`) export class User { @Field(() => ID) userId!: string; @Field() email!: string; @Field() name!: string; @Field() status!: string; @Field() dataScope!: string; } @Resolver(() => User) export class UserResolver { constructor(private readonly loader: DataLoaderService) {} /** * Federation Reference Resolver * * 当其他子图通过 @key 引用 User 时,Router 调用此方法解析。 * 使用 DataLoader 批量加载,消除 N+1 查询(ADR-035)。 */ @ResolveReference() async resolveReference(ref: { userId: string }): Promise { return this.loader.userLoader.load(ref.userId); } /** * Query: user(userId) → User * 通过 Apollo Router 访问,直连被 RouterAuthGuard 拒绝(ADR-036) */ @Query(() => User, { nullable: true }) async user( @Args("userId", { type: () => ID }) userId: string, ): Promise { return this.loader.userLoader.load(userId); } }