Files
NextEdu/bugs/shared_bug.md
SpecialX 49291fcc31 refactor: fix all P0/P1/P2 bugs and architecture issues
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.
2026-06-19 05:13:34 +08:00

14 KiB
Raw Blame History

src/shared/types 规范核查报告

核查日期2026-06-18 核查范围:src/shared/types/ 目录下所有前后端文件 依据文档:项目规则、编码规范、架构影响地图 004、架构数据 005 应用技能:vercel-react-best-practicesweb-artifacts-builderweb-design-guidelines


一、核查文件清单

文件 行数 类型 用途
action-state.ts 5 类型定义 Server Action 统一返回类型
action-state.test.ts 33 单元测试 ActionState 类型测试
permissions.ts 114 类型定义+常量 权限点常量、Permission/DataScope/AuthContext 类型

二、违规问题清单

2.1 action-state.ts — 严重度:高

BUG-A01Prettier 配置违规(使用分号)

  • 位置src/shared/types/action-state.ts:1-5
  • 问题:文件使用分号(;)结尾,但项目 .prettierrc 配置 "semi": false,应移除所有分号
  • 现状
    export type ActionState<T = void> = {
      success: boolean;
      message?: string;
      errors?: Record<string, string[]>;
      data?: T;
    };
    
  • 改进建议:移除所有分号,与 permissions.tsaction-state.test.ts 保持一致

BUG-A02缺少 JSDoc 文档注释

  • 位置src/shared/types/action-state.ts:1
  • 问题ActionState<T> 类型缺少 JSDoc 注释,未说明类型用途、泛型参数、各字段含义
  • 规范依据:编码规范 5.4「必须编写 JSDoc」
  • 改进建议:补充类型级 JSDoc说明 @template T、各 property 语义

2.2 permissions.ts — 严重度:高

BUG-P01权限点命名不一致下划线 vs 驼峰)

  • 位置src/shared/types/permissions.ts:91
  • 问题EXAM_PROCTOR_READ: "exam:proctor_read" 使用下划线分隔,而其他 READ 权限均使用单词形式(如 exam:readquestion:read
  • 改进建议:统一为 exam:proctor:read(嵌套资源用冒号分隔)

BUG-P02Permissions 常量缺少 satisfies 类型约束

  • 位置src/shared/types/permissions.ts:4-96
  • 问题:使用 as const 但未用 satisfies 验证所有值均为字符串,无法在编译期捕获值类型错误
  • 规范依据:编码规范 4.2.3「可用 satisfies 保持类型推导」
  • 改进建议as const satisfies Record<string, string>

BUG-P03AuthContext.roles 类型过于宽松

  • 位置src/shared/types/permissions.ts:111
  • 问题roles: string[] 允许任意字符串但项目角色是有限集合admin/teacher/student/parent/grade_head/teaching_head
  • 影响:拼写错误(如 "techer")无法在编译期发现;与 proxy.ts:21resolveDefaultPath(roles: string[]) 的硬编码角色判断形成隐患
  • 改进建议:定义 Role 联合类型,AuthContext.roles 改为 Role[]ROLE_PERMISSIONS 改为 Record<Role, Permission[]>

BUG-P04DataScope 缺少 JSDoc 与字段说明

  • 位置src/shared/types/permissions.ts:101-107
  • 问题6 种数据范围类型未说明各自语义、适用角色、使用场景
  • 改进建议:补充类型级 JSDoc说明每种 type 的适用角色与语义

BUG-P05AuthContext 接口缺少 JSDoc

  • 位置src/shared/types/permissions.ts:109-114
  • 问题:接口无文档说明,使用者无法快速理解字段语义
  • 规范依据:编码规范 5.4
  • 改进建议:补充接口级 JSDoc说明「认证上下文getAuthContext() 返回,贯穿所有 Server Action」

BUG-P06DataScope.class_members 缺少关联数据

  • 位置src/shared/types/permissions.ts:104
  • 问题{ type: "class_members" } 不携带 classIds导致 data-access 层每次都需要额外查询学生所在班级,存在 N+1 查询风险
  • 影响exams/data-access.tshomework/data-access.ts 等模块在过滤时需重复查询 classMembers
  • 改进建议:在 resolveDataScope 中预查并携带 classIds{ type: "class_members"; classIds: string[] }

2.3 action-state.test.ts — 严重度:中

BUG-T01测试覆盖率不足

  • 位置src/shared/types/action-state.test.ts:4-33
  • 问题:仅测试 3 种基本状态,缺少以下场景:
    1. errors 字段包含多个字段、每个字段多条错误消息
    2. datanullundefined0"" 等 falsy 值时的行为
    3. 同时存在 errorsdata(虽然语义上不应出现,但类型允许)
    4. message 为空字符串
  • 规范依据:编码规范十、测试规范「工具函数覆盖率目标 100%」

BUG-T02测试描述缺少行为意图

  • 位置src/shared/types/action-state.test.ts:4
  • 问题describe("ActionState") 过于宽泛,未说明被测行为
  • 规范依据:编码规范 10.2「描述应说明预期行为」
  • 改进建议describe("ActionState 类型构造")

2.4 跨文件违规(使用方导入问题)

BUG-X01exams/actions.ts 类型导入违规

  • 位置src/modules/exams/actions.ts:4
  • 问题import { ActionState } from "@/shared/types/action-state"ActionState 仅作为类型使用,应使用 import type
  • 规范依据:编码规范 4.2.6「所有仅用于类型的导入必须使用 import type
  • 改进建议import type { ActionState } from "@/shared/types/action-state"

BUG-X02questions/actions.ts 类型导入违规

  • 位置src/modules/questions/actions.ts:7
  • 问题:同 BUG-X01import { ActionState } 应为 import type { ActionState }
  • 改进建议import type { ActionState } from "@/shared/types/action-state"

2.5 tsconfig.json 配置不达标(影响类型安全)

BUG-C01target 低于规范要求

  • 位置tsconfig.json:3
  • 问题"target": "ES2017",编码规范 4.1 要求 "ES2022"
  • 影响:无法使用 ES2022 特性(如 Array.at()Object.hasOwn()
  • 改进建议"target": "ES2022"

BUG-C02缺少 noUncheckedIndexedAccess

  • 位置tsconfig.json
  • 问题:未启用 noUncheckedIndexedAccess,数组/对象索引访问返回 T 而非 T | undefined
  • 影响permissions.ts:198ROLE_PERMISSIONS[name]name 不存在时返回 Permission[] 而非 Permission[] | undefined,存在运行时风险
  • 规范依据:编码规范 4.1
  • 改进建议"noUncheckedIndexedAccess": true

BUG-C03缺少 noImplicitReturnsnoFallthroughCasesInSwitch

  • 位置tsconfig.json
  • 问题:未启用这两个严格检查
  • 规范依据:编码规范 4.1
  • 改进建议:补充 "noImplicitReturns": true"noFallthroughCasesInSwitch": true"forceConsistentCasingInFileNames": true

三、React 性能优化(应用 vercel-react-best-practices 技能)

PERF-01use-permission.ts 回调函数未 memoize

  • 位置src/shared/hooks/use-permission.ts:11-25
  • 问题hasPermissionhasAnyPermissionhasAllPermissionshasRole 每次渲染都创建新函数引用,导致依赖这些函数的子组件不必要重渲染
  • 违反规则rerender-functional-setstatererender-memo
  • 改进建议:使用 useCallback 包裹所有回调函数

PERF-02permissionsroles 数组未 memoize

  • 位置src/shared/hooks/use-permission.ts:8-9
  • 问题:每次渲染都执行 ?? [] 创建新数组引用,导致下游 useEffect/useMemo 依赖项失效
  • 违反规则rerender-derived-statererender-dependencies
  • 改进建议:使用 useMemo 包裹数组派生

PERF-03as 断言使用

  • 位置src/shared/hooks/use-permission.ts:8-9
  • 问题as Permission[]as string[] 使用了类型断言,违反编码规范 4.2.3
  • 改进建议:依赖 next-auth.d.ts 的类型增强(已存在),移除断言;或增加类型守卫

use-permission.ts 完整改进示例

import { useCallback, useMemo } from "react"
import { useSession } from "next-auth/react"
import type { Permission } from "@/shared/types/permissions"

export function usePermission() {
  const { data: session } = useSession()

  const permissions = useMemo(
    () => (session?.user?.permissions ?? []) as Permission[],
    [session?.user?.permissions]
  )
  const roles = useMemo(
    () => (session?.user?.roles ?? []) as string[],
    [session?.user?.roles]
  )

  const hasPermission = useCallback(
    (permission: Permission): boolean => permissions.includes(permission),
    [permissions]
  )
  const hasAnyPermission = useCallback(
    (...perms: Permission[]): boolean => perms.some((p) => permissions.includes(p)),
    [permissions]
  )
  const hasAllPermissions = useCallback(
    (...perms: Permission[]): boolean => perms.every((p) => permissions.includes(p)),
    [permissions]
  )
  const hasRole = useCallback(
    (role: string): boolean => roles.includes(role),
    [roles]
  )

  return { permissions, roles, hasPermission, hasAnyPermission, hasAllPermissions, hasRole }
}

四、Web 界面规范审查(应用 web-design-guidelines 技能)

说明:src/shared/types/ 为纯类型定义文件,无直接 UI 代码。以下审查针对类型定义所支撑的 UI 实现层(use-permission.tsproxy.tsauth-guard.ts)是否符合 Web Interface Guidelines。

UI-01权限状态可能导致 hydration mismatch

  • 位置src/shared/hooks/use-permission.ts:7
  • 问题useSession() 在服务端渲染时返回 null/loading,客户端首次渲染后才有权限数据,导致权限相关的 UI如菜单项、按钮在 hydration 后闪烁
  • 违反规则Web Interface Guidelines — Hydration Safety
  • 改进建议
    1. 服务端组件应通过 auth() 获取权限并作为 props 传递
    2. 客户端组件在 session === null 时渲染骨架屏或占位,避免权限相关 UI 闪烁
    3. 对权限相关的动态 UI 使用 suppressHydrationWarning 或延迟渲染

UI-02权限不足时的重定向未反映在 URL

  • 位置src/proxy.ts:75-76
  • 问题权限不足时直接重定向到默认页URL 中未携带原始路径信息,用户无法知道「为何被重定向」
  • 违反规则Web Interface Guidelines — Navigation & State「URL reflects state」
  • 改进建议:重定向时携带 ?from=originalPath&reason=forbidden 参数,目标页显示提示

UI-03错误消息缺少修复步骤

  • 位置src/shared/lib/auth-guard.ts:13
  • 问题Permission denied: ${permission} 仅描述问题,未提供下一步操作
  • 违反规则Web Interface Guidelines — Content & Copy「Error messages include fix/next step」
  • 改进建议权限不足:需要 ${permission} 权限。请联系管理员授权或切换账号。

五、架构文档同步问题

DOC-01004 文件行数记录过期

  • 位置docs/architecture/004_architecture_impact_map.md:408
  • 问题:记录 types/permissions.ts | 92 | 54 个权限点常量,实际文件 114 行,含 DataScopeAuthContext 类型定义
  • 改进建议:更新为 114 行 | 54 个权限点 + DataScope + AuthContext

DOC-02005 JSON 中 DataScope 定义字段顺序与代码不一致

  • 位置docs/architecture/005_architecture_data.json:993
  • 问题JSON 中字段顺序为 all, owned, class_taught, grade_managed, class_members, children,代码中为 all, owned, class_members, grade_managed, class_taught, children
  • 改进建议:同步 JSON 字段顺序与源码一致

DOC-03缺少 Role 类型定义记录

  • 问题:若按 BUG-P03 建议新增 Role 类型,需在 005 JSON 的 shared.types 数组中补充记录
  • 改进建议:新增 Role 类型节点,记录 usedBy: ["auth-guard", "permissions", "proxy"]

六、问题汇总统计

严重度 数量 问题编号
8 BUG-A01, BUG-A02, BUG-P01, BUG-P02, BUG-P03, BUG-P04, BUG-P05, BUG-P06
6 BUG-T01, BUG-T02, BUG-X01, BUG-X02, BUG-C01, BUG-C02
3 BUG-C03, DOC-01, DOC-02, DOC-03
性能 3 PERF-01, PERF-02, PERF-03
界面 3 UI-01, UI-02, UI-03
合计 23

七、修复优先级建议

P0立即修复 — 影响类型安全与一致性)

  1. BUG-A01移除 action-state.ts 分号
  2. BUG-X01、BUG-X02修正 import type 违规
  3. BUG-C01、BUG-C02、BUG-C03升级 tsconfig.json

P1本迭代修复 — 影响可维护性)

  1. BUG-P01统一权限点命名
  2. BUG-P02Permissions 添加 satisfies
  3. BUG-P03新增 Role 类型
  4. BUG-A02、BUG-P04、BUG-P05补充 JSDoc
  5. PERF-01、PERF-02、PERF-03use-permission.ts 性能优化

P2下迭代修复 — 增强健壮性)

  1. BUG-T01、BUG-T02补充测试用例
  2. BUG-P06DataScope.class_members 携带 classIds
  3. UI-01、UI-02、UI-03界面规范改进

P3文档同步

  1. DOC-01、DOC-02、DOC-03同步架构文档

八、验证命令

修复完成后应运行以下命令确保零错误:

npm run lint
npx tsc --noEmit
npm run test:unit -- action-state

报告生成人AI AgentGLM-5.2 核查方法:人工逐行审查 + 架构图比对 + 技能规则匹配