/** * content Textbook Resolver(v2.1 M1) * * Apollo Federation 子图:Textbook Entity * - @key(fields: "id") 支持跨子图引用 * - @ResolveReference 使用 DataLoader 批量加载(ADR-035) * - Query 入口供 Apollo Router 直接查询 */ import { Resolver, Query, Args, ID, ResolveReference, ObjectType, Field, Directive, } from "@nestjs/graphql"; import { DataLoaderService, type TextbookEntity, } from "../dataloader.service.js"; /** * Textbook ObjectType(Federation @key) * 对应 content_textbooks 表 */ @ObjectType() @Directive(`@key(fields: "id")`) export class Textbook { @Field(() => ID) id!: string; @Field() title!: string; @Field() subjectId!: string; @Field() gradeId!: string; @Field() version!: string; @Field() status!: string; @Field({ nullable: true }) tenantId: string | null = null; @Field() createdAt!: Date; @Field() updatedAt!: Date; } @Resolver(() => Textbook) export class TextbookResolver { constructor(private readonly loader: DataLoaderService) {} /** * Federation Reference Resolver * * 当其他子图通过 @key 引用 Textbook 时,Router 调用此方法解析。 * 使用 DataLoader 批量加载,消除 N+1 查询(ADR-035)。 */ @ResolveReference() async resolveReference(ref: { id: string }): Promise { return this.loader.textbookLoader.load(ref.id); } /** * Query: textbook(id) → Textbook * 通过 Apollo Router 访问,直连被 RouterAuthGuard 拒绝(ADR-036) */ @Query(() => Textbook, { nullable: true }) async textbook( @Args("id", { type: () => ID }) id: string, ): Promise { return this.loader.textbookLoader.load(id); } }