Bug fixes (from bugs/ directory): - Fix cross-module DB queries in 9 modules (homework, grades, parent, diagnostic, elective, proctoring, notifications, scheduling, classes) by routing through data-access functions - Fix shared/lib <-> auth circular dependency via new session.ts module - Fix divide-by-zero guard in grades data-access - Fix audit export data truncation (paginated fetch for full datasets) - Fix missing transactions in homework grading and elective lottery - Fix missing revalidatePath in course-plans actions - Fix frontend permission checks using requirePermission instead of requireAuth - Fix dashboard role routing using session.user.roles - Fix student auth pattern (migrate getDemoStudentUser to users module) - Fix ActionState return type handling in components Code quality fixes: - Remove 60+ as type assertions (replace with type guards) - Remove non-null assertions (use optional chaining or explicit checks) - Convert dynamic imports to static imports (grades, diagnostic) - Add React.cache() wrapping for read functions - Parallelize independent queries with Promise.all - Add explicit return types to 30+ arrow functions - Replace any with unknown + type guards - Fix import type for type-only imports - Add Zod validation schemas for classes and diagnostic modules - Extract duplicate code (normalizeRoleName, normalizeBcryptHash, logger IP extraction) - Add console.error to silent catch blocks - Fix permission naming consistency (exam:proctor_read -> exam:proctor:read) Architecture doc sync: - Update 004_architecture_impact_map.md and 005_architecture_data.json - Update management-modules-audit.md for P0-7 cross-module fix Moved deleted proctoring event route to deletes/ folder.
25 KiB
Admin 前端文件规范核查报告
核查范围:
src/app/(dashboard)/admin/下全部 26 个page.tsx文件 核查依据:
.trae/rules/project_rules.md(项目规则)docs/standards/coding-standards.md(编码规范 v1.0)docs/architecture/004_architecture_impact_map.md(架构影响地图)- React / Next.js 16 最佳实践
- Web 界面设计规范(WCAG 2.2 AA) 核查日期:2026-06-18
一、核查概览
| 维度 | 文件数 | 通过 | 待改进 |
|---|---|---|---|
| 架构分层 | 26 | 24 | 2 |
| TypeScript 规范 | 26 | 4 | 22 |
| 安全与权限 | 26 | 3 | 23 |
| UI 一致性与设计令牌 | 26 | 18 | 8 |
| 错误与加载边界 | 26 | 0 | 26 |
| 代码复用(DRY) | 26 | 0 | 26 |
结论:整体架构清晰、服务端组件使用规范、并行数据获取到位,但在返回类型标注、权限校验一致性、加载/错误边界、代码复用、UI 文案一致性方面存在系统性问题,需统一整改。
二、问题清单(按严重程度排序)
P0 严重问题(必须立即修复)
P0-1 全部 26 个页面缺少 error.tsx 与 loading.tsx
违反规范:
- 编码规范 §2.3:「每个路由段应提供
loading.tsx(骨架屏)和error.tsx(错误边界)」 - 编码规范 §2.4:「每个路由段都必须提供
error.tsx,不得出现未捕获异常导致白屏」 - 编码规范 §2.4:「
loading.tsx必须提供骨架屏或最小可感知的加载状态,不得使用全局 spin 遮罩」
现状:src/app/(dashboard)/admin/ 及其所有子路由(dashboard/、announcements/、school/*、audit-logs/*、scheduling/*、course-plans/*、elective/*、attendance/、files/、users/import/)均未提供 loading.tsx 和 error.tsx。
对比:teacher/、student/ 路由组在关键页面已提供 loading.tsx(如 teacher/exams/all/loading.tsx、student/dashboard/loading.tsx),admin 路由组完全缺失。
影响:
- 数据获取失败时整页白屏,用户体验差
- 无加载态感知,用户误以为页面卡死
- 不符合 Next.js 16 App Router 最佳实践(Suspense 流式渲染)
修复建议:
- 在
src/app/(dashboard)/admin/根目录新增error.tsx(具名导出,客户端组件,含重试按钮) - 在
src/app/(dashboard)/admin/根目录新增loading.tsx(骨架屏,匹配各页面布局) - 对数据量大的页面(
audit-logs/*、school/grades/insights、attendance)单独提供loading.tsx - 对动态路由(
[id]/page.tsx)单独提供error.tsx处理notFound以外的异常
P0-2 attendance/page.tsx 缺少权限校验
文件:src/app/(dashboard)/admin/attendance/page.tsx
违反规范:
- 项目规则:「Server Action 必须使用
requirePermission()进行权限校验」 - 编码规范 §8.3:「权限校验:Server Action 必须使用
requirePermission()」
现状:第 26 行仅调用 getAuthContext() 获取上下文,未调用 requirePermission() 验证用户是否有考勤查看权限。
// 当前代码(第 26 行)
const ctx = await getAuthContext()
对比:同类 admin 页面均做了权限校验:
audit-logs/page.tsx第 22 行:await requirePermission(Permissions.AUDIT_LOG_READ)audit-logs/login-logs/page.tsx第 22 行:await requirePermission(Permissions.AUDIT_LOG_READ)audit-logs/data-changes/page.tsx第 26 行:await requirePermission(Permissions.AUDIT_LOG_READ)files/page.tsx第 12 行:await requirePermission(Permissions.FILE_READ)
影响:越权风险——无考勤查看权限的用户可直接访问 /admin/attendance 查看全校考勤数据。
修复建议:在 getAuthContext() 前增加权限校验:
await requirePermission(Permissions.ATTENDANCE_READ)
const ctx = await getAuthContext()
P1 重要问题(应尽快修复)
P1-1 全部 26 个页面组件缺少返回类型标注
违反规范:
- 编码规范 §4.2:「函数返回值必须显式标注,特别是
Promise<T>」 - 项目规则:「函数返回值必须显式标注」
现状:所有 page.tsx 的默认导出函数均未标注返回类型,例如:
// dashboard/page.tsx
export default async function AdminDashboardPage() { // ❌ 缺少 : Promise<JSX.Element>
const data = await getAdminDashboardData()
return <AdminDashboardView data={data} />
}
影响:26 个文件全部不合规,类型推导依赖 TS 隐式推断,不利于代码审查与维护。
修复建议:统一补充返回类型:
export default async function AdminDashboardPage(): Promise<JSX.Element> {
// ...
}
涉及文件:admin 目录下全部 26 个 page.tsx。
P1-2 getParam 工具函数在 27 个文件中重复定义
违反规范:
- 编码规范 §一:「单一职责」「工具函数 ≤ 40 行」
- DRY 原则
现状:以下 admin 文件各自重复定义了相同的 getParam / SearchParams 类型与函数:
| 文件 | 行号 |
|---|---|
announcements/page.tsx |
8-13 |
audit-logs/page.tsx |
10-15 |
audit-logs/login-logs/page.tsx |
10-15 |
audit-logs/data-changes/page.tsx |
14-19 |
scheduling/changes/page.tsx |
16-21 |
course-plans/page.tsx |
7-12 |
elective/page.tsx |
7-12 |
attendance/page.tsx |
13-18 |
school/grades/insights/page.tsx |
15-22 |
全项目共 27 个文件重复(含 teacher / student / management 路由组)。
影响:维护成本高,任何一处逻辑变更需同步修改 27 处。
修复建议:
- 在
src/shared/lib/utils.ts新增共享工具:
export type SearchParams = { [key: string]: string | string[] | undefined }
export function getSearchParam(params: SearchParams, key: string): string | undefined {
const v = params[key]
return Array.isArray(v) ? v[0] : v
}
- 全部页面改为
import { getSearchParam, type SearchParams } from "@/shared/lib/utils" - 同步更新架构文档 004 / 005
P1-3 多个页面使用 as 类型断言违反 TypeScript 规范
违反规范:
- 编码规范 §4.2:「不使用
as断言,除非从unknown强制转换或在测试中(需注释原因)」 - 项目规则:「禁止
as断言(除非从unknown转换或测试中,需注释原因)」
现状:以下文件使用 as 进行类型断言而非类型守卫:
| 文件 | 行号 | 问题代码 |
|---|---|---|
audit-logs/page.tsx |
28 | (getParam(params, "status") as AuditLogStatus | undefined) |
audit-logs/login-logs/page.tsx |
26-27 | as LoginLogAction | undefined、as LoginLogStatus | undefined |
audit-logs/data-changes/page.tsx |
31 | as DataChangeAction | undefined |
attendance/page.tsx |
39 | as "present" | "absent" | "late" | "early_leave" | "excused" |
对比(正确示例):以下文件已使用类型守卫,应作为模板推广:
announcements/page.tsx第 15-16 行:isValidStatus类型守卫scheduling/changes/page.tsx第 23-24 行:isValidStatus类型守卫course-plans/page.tsx第 14-15 行:isValidStatus类型守卫elective/page.tsx第 14-15 行:isValidStatus类型守卫
影响:运行时无法捕获非法枚举值,类型安全被绕过。
修复建议:为每个枚举类型补充类型守卫,替换 as 断言:
const isValidAuditLogStatus = (v?: string): v is AuditLogStatus =>
v === "success" || v === "failure" || v === "pending"
const status = isValidAuditLogStatus(statusParam) ? statusParam : undefined
P1-4 UI 文案语言不统一(中英文混用)
违反规范:
- 编码规范 §一:「可读性优先」
- 项目定位为「Next_Edu K12 智慧教务系统」(中文用户)
现状:
| 文件 | 文案语言 |
|---|---|
users/import/page.tsx |
中文("批量导入用户"、"返回") |
announcements/[id]/page.tsx |
英文("Edit Announcement") |
school/schools/page.tsx |
英文("Schools"、"Manage schools...") |
school/classes/page.tsx |
英文("Classes"、"Manage classes...") |
school/grades/page.tsx |
英文("Grades"、"Manage grades...") |
school/grades/insights/page.tsx |
英文("Grade Insights"、"Filters") |
school/academic-year/page.tsx |
英文("Academic Year") |
school/departments/page.tsx |
英文("Departments") |
audit-logs/page.tsx |
英文("Audit Logs") |
audit-logs/login-logs/page.tsx |
英文("Login Logs") |
audit-logs/data-changes/page.tsx |
英文("Data Change Logs") |
scheduling/auto/page.tsx |
英文("Auto Schedule") |
scheduling/changes/page.tsx |
英文("Schedule Change Requests") |
scheduling/rules/page.tsx |
英文("Scheduling Rules") |
course-plans/page.tsx |
英文("Course Plans") |
course-plans/create/page.tsx |
英文("New Course Plan") |
course-plans/[id]/edit/page.tsx |
英文("Edit Course Plan") |
elective/page.tsx |
英文("Elective Courses") |
elective/create/page.tsx |
英文("New Elective Course") |
elective/[id]/edit/page.tsx |
英文("Edit Elective Course") |
attendance/page.tsx |
英文("Attendance Overview") |
影响:用户体验割裂,admin 区仅 users/import 为中文,其余全英文,与系统定位不符。
修复建议:统一为中文(与 users/import/page.tsx 保持一致),或引入 i18n 方案统一管理。建议优先统一为中文。
P2 一般问题(建议修复)
P2-1 school/grades/insights/page.tsx 使用原生 <select> 而非共享组件
文件:src/app/(dashboard)/admin/school/grades/insights/page.tsx
现状:第 57-68 行使用原生 <select> 元素,而项目已提供 @/shared/components/ui/select.tsx(shadcn Select)。
<select
name="gradeId"
defaultValue={selected || "all"}
className="h-10 w-full rounded-md border bg-background px-3 text-sm md:w-[360px]"
>
影响:
- UI 风格与其他页面不一致(其他页面使用 shadcn Select)
- 原生
<select>样式难以跨浏览器统一 - 可访问性较弱(缺少 ARIA 属性)
修复建议:替换为 @/shared/components/ui/select.tsx 的 Select / SelectTrigger / SelectContent / SelectItem 组合。
P2-2 users/import/page.tsx 使用原生 <table> 而非共享组件
文件:src/app/(dashboard)/admin/users/import/page.tsx
现状:第 93-128 行使用原生 <table> 元素手写表格,而项目已提供 @/shared/components/ui/table.tsx(shadcn Table)。
影响:与 school/grades/insights/page.tsx 等使用 shadcn Table 的页面风格不一致。
修复建议:替换为 Table / TableHeader / TableBody / TableRow / TableHead / TableCell 组合。
P2-3 Tailwind 任意值违规
违反规范:
- 编码规范 §6.2:「禁止使用任意值(
w-[137px]),除非有充分理由并注释说明」 - 项目规则:「禁止使用任意值(
w-[137px]),除非有充分理由并注释」
现状:
| 文件 | 行号 | 问题类名 |
|---|---|---|
school/grades/insights/page.tsx |
60 | md:w-[360px] |
school/grades/insights/page.tsx |
82, 89, 96 | h-[360px] |
users/import/page.tsx |
16 | h-full flex-1 flex-col(flex-1 合理,但整体布局类应复用) |
修复建议:
md:w-[360px]→ 使用设计令牌宽度类(如md:w-72或md:w-80)或在 globals.css 定义--filter-width变量h-[360px]→ 使用h-80(320px)或h-96(384px)等标准档位
P2-4 users/import/page.tsx 使用硬编码颜色
违反规范:
- 编码规范 §6.3:「所有视觉设计决策(颜色、字号、间距)必须体现在设计令牌中,组件中不使用硬编码值」
文件:src/app/(dashboard)/admin/users/import/page.tsx
现状:第 67 行使用 text-amber-500 硬编码颜色:
<Info className="h-5 w-5 text-amber-500" />
修复建议:使用设计令牌颜色,如 text-warning(若存在)或在 globals.css 定义 --warning 变量。如暂无 warning 令牌,可使用 text-primary 或 text-muted-foreground 保持一致。
P2-5 school/grades/insights/page.tsx 导入顺序违规
违反规范:
- 编码规范 §4.3:「导入顺序:React → 第三方 → 内部绝对路径 → 相对路径 → 类型导入」
- 项目规则引用的 ESLint
import/order规则
文件:src/app/(dashboard)/admin/school/grades/insights/page.tsx
现状:第 1-11 行导入顺序混乱,lucide-react(第三方库)被放在所有 @/ 内部导入之后:
import Link from "next/link" // next(外部)
import { getGrades } from "@/modules/school/data-access" // 内部
import { getGradeHomeworkInsights } from "@/modules/classes/data-access"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { Badge } from "@/shared/components/ui/badge"
import { Button } from "@/shared/components/ui/button"
import { Table, TableBody, ... } from "@/shared/components/ui/table"
import { formatDate } from "@/shared/lib/utils"
import { BarChart3 } from "lucide-react" // ❌ 第三方应在前
修复建议:调整为 next → lucide-react → @/ 内部导入,分组间空一行:
import Link from "next/link"
import { BarChart3 } from "lucide-react"
import { getGrades } from "@/modules/school/data-access"
// ...
P2-6 course-plans/[id]/edit/page.tsx 同模块重复导入
文件:src/app/(dashboard)/admin/course-plans/[id]/edit/page.tsx
现状:第 3-4 行从同一模块 @/modules/course-plans/data-access 分两行导入:
import { getCoursePlanById } from "@/modules/course-plans/data-access"
import { getSubjectOptions } from "@/modules/course-plans/data-access"
修复建议:合并为单行:
import { getCoursePlanById, getSubjectOptions } from "@/modules/course-plans/data-access"
P2-7 scheduling/* 页面从 actions 而非 data-access 获取数据
违反规范:
- 编码规范 §7.1:「服务端数据获取通过模块的
data-access.ts函数」 - 架构影响地图:「actions.ts(编排层:权限 + 调用 data-access + revalidate)」
现状:以下页面从 @/modules/scheduling/actions 导入数据查询函数:
| 文件 | 导入函数 |
|---|---|
scheduling/auto/page.tsx |
getAdminClassesForScheduling |
scheduling/changes/page.tsx |
getAdminClassesForScheduling、getScheduleChanges |
scheduling/rules/page.tsx |
getAdminClassesForScheduling、getSchedulingRules |
说明:规范允许 app/ 调用 Server Actions,但 Server Actions 的职责是「编排:权限 + 调用 data-access + revalidate」,主要用于变更操作。纯读取操作应通过 data-access.ts 暴露,避免在 Server Component 中触发不必要的 revalidate 逻辑。
修复建议:将 getAdminClassesForScheduling、getScheduleChanges、getSchedulingRules 等纯查询函数迁移到 scheduling/data-access.ts,或在 actions 中明确标注其为只读封装。需同步更新架构文档 004 / 005。
三、React 性能优化建议(基于最佳实践)
R1 利用 Suspense 流式渲染提升首屏感知性能
现状:所有页面使用 export const dynamic = "force-dynamic" 整页动态渲染,数据获取完成前无任何内容呈现。
建议:对数据量大的页面(audit-logs/*、school/grades/insights、attendance)拆分为多个 Suspense 边界,优先渲染页面骨架,慢查询部分流式注入:
import { Suspense } from "react"
export default async function AuditLogsPage(): Promise<JSX.Element> {
return (
<div className="flex h-full flex-col space-y-8 p-8">
<Header />
<Suspense fallback={<FilterSkeleton />}>
<Filters />
</Suspense>
<Suspense fallback={<TableSkeleton />}>
<AuditTable />
</Suspense>
</div>
)
}
R2 school/grades/insights/page.tsx 串行查询可优化为并行
文件:src/app/(dashboard)/admin/school/grades/insights/page.tsx
现状:第 30-33 行先 await getGrades() 再条件 await getGradeHomeworkInsights(),两次串行查询:
const grades = await getGrades()
const selected = gradeId && gradeId !== "all" ? gradeId : ""
const insights = selected ? await getGradeHomeworkInsights({ gradeId: selected, limit: 50 }) : null
说明:insights 依赖 selected(来自 URL 参数,非 grades 结果),两者无数据依赖,可并行:
const selected = gradeId && gradeId !== "all" ? gradeId : ""
const [grades, insights] = await Promise.all([
getGrades(),
selected ? getGradeHomeworkInsights({ gradeId: selected, limit: 50 }) : Promise.resolve(null),
])
R3 列表页 classOptions 映射可下沉至 data-access
现状:scheduling/auto、scheduling/changes、scheduling/rules、attendance、course-plans/create、course-plans/[id]/edit、elective/create、elective/[id]/edit 等页面均在组件内 .map() 转换数据形状:
const classOptions = classes.map((c) => ({ id: c.id, name: c.name, grade: c.grade }))
建议:在对应 data-access.ts 提供 getClassOptions()、getStaffOptions() 等轻量查询函数,仅返回 { id, name } 形状,减少传输数据量与组件层转换逻辑。
四、Web 界面设计规范建议(基于 WCAG 2.2 AA)
W1 表单 <label> 与控件关联不规范
文件:src/app/(dashboard)/admin/school/grades/insights/page.tsx
现状:第 56-57 行 <label> 与 <select> 未通过 htmlFor / id 关联:
<label className="text-sm font-medium">Grade</label>
<select name="gradeId" ...>
违反:WCAG 2.2 SC 1.3.1(信息与关系)、SC 3.3.2(标签或指令)。
修复建议:
<label htmlFor="grade-filter" className="text-sm font-medium">Grade</label>
<select id="grade-filter" name="gradeId" ...>
W2 users/import/page.tsx 表格缺少 <caption> 与语义化标注
文件:src/app/(dashboard)/admin/users/import/page.tsx
现状:原生 <table> 缺少 <caption> 描述表格用途,屏幕阅读器无法快速理解表格主题。
修复建议:增加 <caption className="sr-only">模板字段说明</caption>,或替换为 shadcn Table 后通过 aria-label 补充。
W3 页面标题层级不统一
现状:
- 部分页面使用
<h2>作为页面主标题(如school/schools、audit-logs) users/import/page.tsx也使用<h2>- 但页面布局中未见统一的
<h1>主标题层级
建议:确认 (dashboard)/layout.tsx 是否提供 <h1> 或页面 <main> 的 accessible name,若无,建议各页面统一使用 <h1> 作为页面主标题,<h2> 用于区块标题,保持标题层级连贯。
W4 交互式筛选器缺少 aria-live 反馈
文件:school/grades/insights/page.tsx、attendance/page.tsx、audit-logs/*
现状:筛选器提交后表格数据刷新,但屏幕阅读器用户无法感知数据已更新。
违反:WCAG 2.2 SC 4.1.3(状态消息)。
建议:在表格容器添加 aria-live="polite" 或使用项目已有的 useAriaLive Hook 通知「已加载 N 条记录」。
W5 EmptyState 组件使用一致但图标语义可优化
现状:scheduling/*、attendance、school/grades/insights 均使用 EmptyState 组件,图标统一使用 ClipboardList / BarChart3,体验一致(优点)。
建议:BarChart3 用于「无数据」与「选择年级」两种语义略显混淆,建议「等待操作」类空状态使用 MousePointerClick 或 Filter 图标区分。
五、优秀实践(已符合规范,应保持)
- 服务端组件默认化:全部 26 个页面均为 async 服务端组件,未滥用
"use client",符合 §5.2。 - 并行数据获取:
announcements/page.tsx、audit-logs/*、course-plans/create、course-plans/[id]/edit、elective/create、elective/[id]/edit、school/grades、scheduling/rules等均使用Promise.all并行查询,性能良好。 - 类型守卫正确使用:
announcements/page.tsx、scheduling/changes/page.tsx、course-plans/page.tsx、elective/page.tsx使用isValidStatus类型守卫,是as断言的正确替代方案。 - 404 处理:
announcements/[id]/page.tsx、course-plans/[id]/page.tsx、course-plans/[id]/edit/page.tsx、elective/[id]/edit/page.tsx使用notFound()处理资源不存在场景。 - 权限校验到位:
audit-logs/*(3 个文件)、files/page.tsx正确调用requirePermission()。 - 模块化组合:页面仅负责数据获取与组合,UI 逻辑下沉至
modules/*/components/,符合三层架构。 force-dynamic标注:需要实时数据的页面均显式声明export const dynamic = "force-dynamic"。metadata导出:users/import/page.tsx正确导出metadata用于 SEO(建议其他页面补充)。
六、修复优先级与建议执行顺序
| 优先级 | 问题编号 | 建议执行顺序 | 影响范围 |
|---|---|---|---|
| P0 | P0-2 | 立即修复 attendance 权限 | 1 文件 |
| P0 | P0-1 | 补充 error.tsx / loading.tsx | 新增 ~6 文件 |
| P1 | P1-1 | 补充返回类型标注 | 26 文件 |
| P1 | P1-2 | 抽取共享 getSearchParam | 27 文件 |
| P1 | P1-3 | 替换 as 断言为类型守卫 | 4 文件 |
| P1 | P1-4 | 统一 UI 文案语言 | ~20 文件 |
| P2 | P2-1 ~ P2-7 | 逐步整改 | 单文件级 |
| R1 ~ R3 | 性能优化 | 迭代优化 | 关键页面 |
| W1 ~ W5 | 可访问性 | 迭代优化 | 关键页面 |
七、附:文件清单与合规状态
| 文件 | P0 | P1 | P2 | 备注 |
|---|---|---|---|---|
dashboard/page.tsx |
- | 缺返回类型 | - | 整体合规 |
announcements/page.tsx |
- | 缺返回类型、getParam 重复 | - | 类型守卫正确 |
announcements/[id]/page.tsx |
- | 缺返回类型、英文文案 | - | - |
users/import/page.tsx |
- | 缺返回类型 | 原生 table、硬编码颜色 | 文案为中文(正确) |
school/page.tsx |
- | 缺返回类型 | - | 仅 redirect |
school/schools/page.tsx |
- | 缺返回类型、英文文案 | - | - |
school/classes/page.tsx |
- | 缺返回类型、英文文案 | - | - |
school/grades/page.tsx |
- | 缺返回类型、英文文案 | - | - |
school/grades/insights/page.tsx |
- | 缺返回类型、英文文案 | 原生 select、任意值、导入顺序、label 未关联 | 问题最多 |
school/academic-year/page.tsx |
- | 缺返回类型、英文文案 | - | - |
school/departments/page.tsx |
- | 缺返回类型、英文文案 | - | - |
audit-logs/page.tsx |
- | 缺返回类型、as 断言、英文文案、getParam 重复 | - | 权限校验正确 |
audit-logs/login-logs/page.tsx |
- | 缺返回类型、as 断言、英文文案、getParam 重复 | - | 权限校验正确 |
audit-logs/data-changes/page.tsx |
- | 缺返回类型、as 断言、英文文案、getParam 重复 | - | 权限校验正确 |
scheduling/auto/page.tsx |
- | 缺返回类型、英文文案 | 从 actions 取数 | - |
scheduling/changes/page.tsx |
- | 缺返回类型、英文文案、getParam 重复 | 从 actions 取数 | 类型守卫正确 |
scheduling/rules/page.tsx |
- | 缺返回类型、英文文案 | 从 actions 取数 | - |
course-plans/page.tsx |
- | 缺返回类型、英文文案、getParam 重复 | - | 类型守卫正确 |
course-plans/create/page.tsx |
- | 缺返回类型、英文文案 | - | - |
course-plans/[id]/page.tsx |
- | 缺返回类型 | - | - |
course-plans/[id]/edit/page.tsx |
- | 缺返回类型、英文文案 | 重复导入 | - |
elective/page.tsx |
- | 缺返回类型、英文文案、getParam 重复 | - | 类型守卫正确 |
elective/create/page.tsx |
- | 缺返回类型、英文文案 | - | - |
elective/[id]/edit/page.tsx |
- | 缺返回类型、英文文案 | - | - |
attendance/page.tsx |
缺权限校验 | 缺返回类型、as 断言、英文文案、getParam 重复 | - | 最高优先级 |
files/page.tsx |
- | 缺返回类型 | - | 权限校验正确、整体合规 |
报告生成完毕。建议按「六、修复优先级」顺序整改,每完成一批次后运行
npm run lint与npx tsc --noEmit验证,并同步更新架构文档 004 / 005。