import type { JSX } from "react" import { notFound } from "next/navigation" import { Stethoscope } from "lucide-react" import { requirePermission } from "@/shared/lib/auth-guard" import { Permissions } from "@/shared/types/permissions" import { getStudentMasterySummary, getKnowledgePointStats, } from "@/modules/diagnostic/data-access" import { getDiagnosticReports } from "@/modules/diagnostic/data-access-reports" import { getStudentActiveClassId } from "@/modules/classes/data-access" import { StudentDiagnosticView } from "@/modules/diagnostic/components/student-diagnostic-view" import { WidgetBoundary } from "@/modules/grades/components/widget-boundary" import type { MasteryRadarPoint } from "@/modules/diagnostic/types" export const dynamic = "force-dynamic" export default async function StudentDiagnosticPage({ params, }: { params: Promise<{ studentId: string }> }): Promise { const { studentId } = await params const ctx = await requirePermission(Permissions.DIAGNOSTIC_READ) // DataScope 二次校验:学生只能看自己,家长只能看子女 if (ctx.dataScope.type === "class_members" && ctx.userId !== studentId) { notFound() } if (ctx.dataScope.type === "children" && !ctx.dataScope.childrenIds.includes(studentId)) { notFound() } // v4-P1-2: class_taught scope 校验师生关系 // 教师只能查看自己所教班级的学生诊断 if (ctx.dataScope.type === "class_taught") { const studentClassId = await getStudentActiveClassId(studentId) if (!studentClassId || !ctx.dataScope.classIds.includes(studentClassId)) { notFound() } } // 先查询学生所属班级,再用 classId 调用 getKnowledgePointStats // 否则无参调用会导致 studentIds=[] 直接返回空数组,班级平均对比功能失效 const studentClassId = await getStudentActiveClassId(studentId) const [summary, reportsResult, classStats] = await Promise.all([ getStudentMasterySummary(studentId), // v4-P1-3: 教师视角可查看所有状态报告(含草稿),便于审核 getDiagnosticReports({ studentId }, ctx.dataScope), studentClassId ? getKnowledgePointStats(studentClassId) : Promise.resolve([]), ]) const reports = reportsResult.reports // 班级平均掌握度(用于雷达图对比) let classAverageMastery: MasteryRadarPoint[] | undefined if (summary) { classAverageMastery = classStats.map((k) => ({ knowledgePoint: k.knowledgePointName, student: 0, classAverage: k.averageMastery, })) } return (

Knowledge point mastery analysis and diagnostic reports.

) }