feat(content): graphql subgraph with dataloader for textbook/chapter/kp/question
- GraphQLModule: Apollo Federation 2 at /graphql - Textbook/Chapter/KnowledgePoint/Question @key with @ResolveReference - RouterAuthGuard: validate Router-Authorization header (ADR-036) - batchFind methods added to 4 repositories - Domain modules export repositories for GraphqlModule injection
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* content KnowledgePoint Resolver(v2.1 M1)
|
||||
*
|
||||
* Apollo Federation 子图:KnowledgePoint Entity
|
||||
* - @key(fields: "id") 支持跨子图引用
|
||||
* - @ResolveReference 使用 DataLoader 批量加载(ADR-035)
|
||||
*/
|
||||
import {
|
||||
Resolver,
|
||||
Query,
|
||||
Args,
|
||||
ID,
|
||||
ResolveReference,
|
||||
ObjectType,
|
||||
Field,
|
||||
Directive,
|
||||
} from "@nestjs/graphql";
|
||||
import {
|
||||
DataLoaderService,
|
||||
type KnowledgePointEntity,
|
||||
} from "../dataloader.service.js";
|
||||
|
||||
/**
|
||||
* KnowledgePoint ObjectType(Federation @key)
|
||||
* 对应 content_knowledge_points 表
|
||||
*/
|
||||
@ObjectType()
|
||||
@Directive(`@key(fields: "id")`)
|
||||
export class KnowledgePoint {
|
||||
@Field(() => ID)
|
||||
id!: string;
|
||||
|
||||
@Field()
|
||||
chapterId!: string;
|
||||
|
||||
@Field()
|
||||
title!: string;
|
||||
|
||||
@Field({ nullable: true })
|
||||
description: string | null = null;
|
||||
|
||||
@Field()
|
||||
difficulty!: number;
|
||||
|
||||
@Field()
|
||||
createdAt!: Date;
|
||||
|
||||
@Field()
|
||||
updatedAt!: Date;
|
||||
}
|
||||
|
||||
@Resolver(() => KnowledgePoint)
|
||||
export class KnowledgePointResolver {
|
||||
constructor(private readonly loader: DataLoaderService) {}
|
||||
|
||||
/**
|
||||
* Federation Reference Resolver
|
||||
*
|
||||
* 当其他子图通过 @key 引用 KnowledgePoint 时,Router 调用此方法解析。
|
||||
* 使用 DataLoader 批量加载,消除 N+1 查询(ADR-035)。
|
||||
*/
|
||||
@ResolveReference()
|
||||
async resolveReference(ref: {
|
||||
id: string;
|
||||
}): Promise<KnowledgePointEntity | null> {
|
||||
return this.loader.knowledgePointLoader.load(ref.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query: knowledgePoint(id) → KnowledgePoint
|
||||
* 通过 Apollo Router 访问,直连被 RouterAuthGuard 拒绝(ADR-036)
|
||||
*/
|
||||
@Query(() => KnowledgePoint, { nullable: true })
|
||||
async knowledgePoint(
|
||||
@Args("id", { type: () => ID }) id: string,
|
||||
): Promise<KnowledgePointEntity | null> {
|
||||
return this.loader.knowledgePointLoader.load(id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user