/** * Next.js Instrumentation 钩子 * * 在应用启动时执行一次性初始化操作。 * 文档:https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation * * V3-3: 注册 ExamHomeworkServicePort 实现 * 将 modules 层的 data-access 函数注入到 shared 层的 ServicePort, * 使 app 层可以通过 EXAM_HOMEWORK_SERVICE_PROVIDER.get() 调用, * 而不直接依赖 modules 内部实现。 */ import { registerExamHomeworkService } from "@/shared/services/exam-homework-port" import { getExamById, getExams, getExamCreatorId, getExamTitleById } from "@/modules/exams/data-access" import { getHomeworkAssignmentById, getHomeworkAssignments, getAssignmentMaxScoreById, } from "@/modules/homework/data-access" import { getExamWithQuestionsForHomework } from "@/modules/exams/data-access" import type { DataScope } from "@/shared/types/permissions" import type { Exam } from "@/modules/exams/types" import type { HomeworkAssignmentListItem } from "@/modules/homework/types" /** * 适配器:将 getExamById 的返回值补全为 Exam 类型 * data-access 返回的对象包含 questions 数组但缺少 questionCount 字段 */ const adaptExam = (raw: Awaited>): Exam | null => { if (!raw) return null return { ...raw, questionCount: raw.questions?.length ?? 0, } } /** * 适配器:将 getHomeworkAssignmentById 的返回值补全为 HomeworkAssignmentListItem 类型 * data-access 返回的对象缺少 averageScore 和 overdueCount 字段 */ const adaptAssignment = (raw: Awaited>): HomeworkAssignmentListItem | null => { if (!raw) return null return { id: raw.id, sourceExamId: raw.sourceExamId, sourceExamTitle: raw.sourceExamTitle, title: raw.title, status: raw.status, availableAt: raw.availableAt, dueAt: raw.dueAt, allowLate: raw.allowLate, lateDueAt: raw.lateDueAt, maxAttempts: raw.maxAttempts, createdAt: raw.createdAt, updatedAt: raw.updatedAt, targetCount: raw.targetCount, submittedCount: raw.submittedCount, gradedCount: raw.gradedCount, averageScore: null, overdueCount: 0, } } export async function register(): Promise { registerExamHomeworkService({ // 考试 getExamById: async (id: string, scope?: DataScope) => adaptExam(await getExamById(id, scope)), getExams, getExamCreatorId, getExamTitleById, // 作业 getHomeworkAssignmentById: async (id: string, scope?: DataScope) => adaptAssignment(await getHomeworkAssignmentById(id, scope)), getHomeworkAssignments, getAssignmentMaxScoreByIds: getAssignmentMaxScoreById, // 跨模块 getExamWithQuestionsForHomework, }) }