Some checks failed
Security / deep-security-scan (push) Failing after 20m5s
DR Drill / dr-drill (push) Failing after 1m31s
CI / scheduled-backup (push) Failing after 1m31s
CI / backup-verify (push) Has been skipped
CI / weekly-dr-drill (push) Failing after 0s
CI / build-deploy (push) Has been cancelled
CI / security-scan (push) Has been cancelled
主要变更: - 新增 lesson-preparation 模块: 备课编辑器、节点编辑、AI 建议、知识点选择、版本历史、作业发布 - 新增 shared 通用组件: charts/question-bank-filters/schedule-list/ui (chip-nav/filter-bar/page-header/stat-card/stat-item) - 新增 student/admin 端 loading.tsx 与 error.tsx, 优化加载与错误态体验 - 新增 teacher/lesson-plans 页面 (列表/新建/编辑) - 新增 drizzle 迁移 0002_tiny_lionheart 及 snapshot - 新增 textbooks/schema.ts 与 exams/utils/normalize-structure.ts - 修复 Tiptap v3 SSR hydration 崩溃 (rich-text-block immediatelyRender: false) - 重构多模块 data-access/actions/组件, 修复权限校验与类型规范 - 同步架构文档 004/005 反映新增模块、导出、依赖关系 - 归档 bugs/* 测试报告与 e2e 测试脚本 (admin/parent/student/teacher web_test)
15 KiB
15 KiB
src/shared/types 规范核查与修正报告 v3
核查日期:2026-06-18(第三轮) 核查范围:
src/shared/types/目录下所有前后端文件 + 关联使用方 依据文档:项目规则、编码规范、架构影响地图 004、架构数据 005 应用技能:vercel-react-best-practices、web-artifacts-builder、web-design-guidelines前置版本:shared_bug_v2.md
〇、修正进度总览
| 类别 | v2 问题数 | v3 已修正 | v3 未修正 | v3 新发现 | v3 合计 |
|---|---|---|---|---|---|
| 高危违规 | 3 | 3 | 0 | 0 | 0 |
| 中危违规 | 5 | 4 | 1 | 1 | 2 |
| 低危违规 | 3 | 2 | 1 | 0 | 1 |
| React 性能 | 3 | 3 | 0 | 0 | 0 |
| Web 界面 | 3 | 3 | 0 | 0 | 0 |
| 文档同步 | 4 | 4 | 0 | 0 | 0 |
| 合计 | 21 | 19 | 2 | 1 | 3 |
修正率:19/21 = 90.5%
一、本轮已修正问题(19 项 ✅)
1.1 permissions.ts(4 项)
✅ BUG-P02:Permissions 常量添加 satisfies 类型约束
- 文件:permissions.ts:120
- 修正内容:
as const→as const satisfies Record<string, string> - 效果:编译期验证所有权限点值均为字符串
✅ BUG-P03:AuthContext.roles 类型收紧为 Role[]
- 文件:permissions.ts:8-14, 152-157
- 修正内容:新增
Role联合类型(admin | teacher | student | parent | grade_head | teaching_head),AuthContext.roles从string[]改为Role[] - 连带修正:
- next-auth.d.ts:
Session.user.roles和JWT.roles改为Role[] - shared/lib/permissions.ts:
ROLE_PERMISSIONS改为Record<Role, Permission[]>,resolvePermissions参数改为Role[] - shared/lib/auth-guard.ts:
resolveDataScope参数改为Role[] - auth.ts:JWT/session callback 中使用
.filter(isRole)过滤数据库返回的角色名
- next-auth.d.ts:
- 新增:
isRole()类型守卫函数,用于从string安全收窄到Role
✅ BUG-P06:DataScope.class_members 携带 classIds
- 文件:permissions.ts:139
- 修正内容:
{ type: "class_members" }→{ type: "class_members"; classIds: string[] } - 连带修正:auth-guard.ts:116-128
resolveDataScope学生分支预查classEnrollments表并填充 classIds,消除 data-access 层 N+1 查询风险
✅ NEW-01:USER_PROFILE_UPDATE 语义分组调整
- 文件:permissions.ts:52-59
- 修正内容:从
// School management分组移出,独立为// User (self-service)分组
1.2 tsconfig.json(3 项)
✅ BUG-C01:target 升级至 ES2022
- 文件:tsconfig.json:3
- 修正内容:
"target": "ES2017"→"target": "ES2022"
✅ BUG-C03:启用 noImplicitReturns 等严格检查
- 文件:tsconfig.json:21-23
- 修正内容:新增
noImplicitReturns、noFallthroughCasesInSwitch、forceConsistentCasingInFileNames
⚠️ BUG-C02:noUncheckedIndexedAccess 暂缓启用(降级为已知问题)
- 文件:tsconfig.json:20
- 现状:设为
false - 原因:启用后暴露 80+ 处项目原有
possibly undefined错误(涉及 exams/grades/classes/dashboard 等多个模块),修复范围远超shared/types。需项目级渐进式修复。 - 建议:创建独立技术债务任务,按模块逐步修复后启用
1.3 use-permission.ts(4 项 — React 性能 + Hydration)
✅ PERF-01:回调函数 useCallback memoize
- 文件:use-permission.ts:27-42
- 修正内容:
hasPermission/hasAnyPermission/hasAllPermissions/hasRole全部使用useCallback包裹 - 技能规则:
rerender-functional-setstate、rerender-memo
✅ PERF-02:permissions/roles 数组 useMemo memoize
- 文件:use-permission.ts:18-25
- 修正内容:使用
useMemo包裹,避免每次渲染创建新数组引用 - 技能规则:
rerender-derived-state、rerender-dependencies
✅ PERF-03:移除 as 断言
- 文件:use-permission.ts:18-25
- 修正内容:移除
as Permission[]和as string[]断言,改用useMemo<Permission[]>泛型参数标注返回类型,依赖next-auth.d.ts的类型增强
✅ UI-01:Hydration safety 文档化
- 文件:use-permission.ts:7-14, 47
- 修正内容:补充 JSDoc 说明 hydration 风险,返回
status字段供调用方判断authenticated状态,避免权限 UI 闪烁 - 技能规则:Web Interface Guidelines — Hydration Safety
1.4 auth-guard.ts(2 项)
✅ UI-03:错误消息补充修复步骤
- 文件:auth-guard.ts:13-19
- 修正内容:
Permission denied: ${permission}→权限不足:需要 ${permission} 权限。请联系管理员授权或切换账号后重试。 - 技能规则:Web Interface Guidelines — Content & Copy
✅ BUG-P06 配套:学生分支预查 classIds
- 文件:auth-guard.ts:116-128
- 修正内容:学生分支查询
classEnrollments表预填 classIds,与DataScope.class_members类型变更配套
1.5 proxy.ts(1 项)
✅ UI-02:权限不足重定向携带 URL 状态
- 文件:proxy.ts:73-87
- 修正内容:重定向 URL 添加
?from=originalPath&reason=forbidden参数,目标页可解释重定向原因 - 技能规则:Web Interface Guidelines — Navigation & State
1.6 action-state.test.ts(2 项)
✅ BUG-T01:补充边界测试用例
- 文件:action-state.test.ts
- 修正内容:从 3 个用例扩充至 7 个,新增:多字段多错误、falsy data(0/""/null)、空 message、无 message 成功态
✅ BUG-T02:测试描述体现行为意图
- 文件:action-state.test.ts:4
- 修正内容:
describe("ActionState")→describe("ActionState 类型构造")
1.7 shared/lib/permissions.ts(1 项)
✅ NEW-03:ROLE_PERMISSIONS 键类型约束为 Role
- 文件:permissions.ts:1, 5, 211
- 修正内容:
Record<string, Permission[]>→Record<Role, Permission[]>,resolvePermissions参数改为Role[]
1.8 questions/actions.ts(1 项)
✅ NEW-02:Prettier 分号违规修复
- 文件:questions/actions.ts
- 修正内容:运行
npx prettier --write移除全文件 62 处分号,与项目"semi": false配置一致
1.9 架构文档同步(4 项)
✅ DOC-01:004 文件行数与权限点数更新
- 文件:004_architecture_impact_map.md:436
- 修正内容:
92 | 54 个权限点常量→157 | 61 个权限点常量 + Role/DataScope/AuthContext 类型
✅ DOC-04:004 权限点数量同步
- 文件:004_architecture_impact_map.md:1541
- 修正内容:
54 个权限点→61 个权限点
✅ DOC-02:005 JSON DataScope 定义同步
- 文件:005_architecture_data.json:1047
- 修正内容:字段顺序与源码一致,
class_members补充classIds: string[]
✅ DOC-03:005 JSON 新增 Role 类型记录 + AuthContext 更新
- 文件:005_architecture_data.json:1032-1065
- 修正内容:新增
Role类型节点(含usedBy列表),AuthContext定义中roles: string[]→roles: Role[]
二、未修正问题(2 项 ❌)
❌ BUG-C02:noUncheckedIndexedAccess 暂缓启用 — 严重度:中
- 位置:tsconfig.json:20
- 现状:设为
false - 原因:启用后暴露 80+ 处项目原有
possibly undefined错误,涉及 exams/grades/classes/dashboard/elective 等多个模块,修复范围远超shared/types - 建议:创建独立技术债务任务,按模块逐步修复后启用
❌ BUG-T01(部分):vitest 配置未覆盖 src/ 单元测试 — 严重度:低
- 位置:vitest.config.ts:13
- 现状:
include: ["tests/integration/**/*.test.ts"],src/下的action-state.test.ts无法通过npx vitest run执行 - 原因:修改 vitest 配置影响测试基础设施,超出
shared/types范围 - 建议:新增
vitest.unit.config.ts或扩展 include 为["tests/integration/**/*.test.ts", "src/**/*.test.ts"]
三、v3 新发现问题(1 项 🆕)
🆕 NEW-V3-01:proxy.ts 中 roles 变量类型未收窄 — 严重度:低
- 位置:proxy.ts:61
- 问题:
const roles: string[] = (token.roles as string[]) ?? []仍使用as string[]断言,而token.roles已通过next-auth.d.ts增强为Role[] - 改进建议:移除断言,改为
const roles: Role[] = token.roles ?? [],resolveDefaultPath参数相应改为Role[] - 未修正原因:
resolveDefaultPath当前接受string[],改为Role[]后需同步修改函数签名,影响范围需进一步评估
四、验证结果
4.1 ESLint
npx eslint src/shared/types/permissions.ts src/shared/types/action-state.ts \
src/shared/types/action-state.test.ts src/shared/hooks/use-permission.ts \
src/shared/lib/auth-guard.ts src/shared/lib/permissions.ts \
src/auth.ts src/proxy.ts src/next-auth.d.ts
结果:✅ 零错误
4.2 TypeScript
npx tsc --noEmit
结果:
- ✅ 我修改的 9 个文件零错误
- ✅ auth.ts 原有 4 个
Role[]类型错误已修复 - ⚠️ 项目原有 42 个 tsc 错误(JSX namespace、possibly undefined 等),均为本次修正前已存在
4.3 Prettier
npx prettier --write src/modules/questions/actions.ts
结果:✅ 已格式化(移除 62 处分号)
4.4 单元测试
npx vitest run src/shared/types/action-state.test.ts
结果:⚠️ 无法执行(vitest 配置 include 未覆盖 src/ 下的测试文件,见 BUG-T01 部分)
- tsc 已验证测试文件类型正确
五、修改文件清单
| 文件 | 修改类型 | 涉及问题 |
|---|---|---|
| src/shared/types/permissions.ts | 重构 | BUG-P02, BUG-P03, BUG-P06, NEW-01 |
| src/shared/types/action-state.test.ts | 增强 | BUG-T01, BUG-T02 |
| src/shared/lib/permissions.ts | 类型收紧 | NEW-03, BUG-P03 |
| src/shared/lib/auth-guard.ts | 重构 | UI-03, BUG-P06, BUG-P03 |
| src/shared/hooks/use-permission.ts | 重写 | PERF-01/02/03, UI-01 |
| src/next-auth.d.ts | 类型增强 | BUG-P03 |
| src/auth.ts | 类型修复 | BUG-P03 |
| src/proxy.ts | 增强 | UI-02 |
| src/modules/questions/actions.ts | 格式化 | NEW-02 |
| tsconfig.json | 配置升级 | BUG-C01, BUG-C03 |
| docs/architecture/004_architecture_impact_map.md | 文档同步 | DOC-01, DOC-04 |
| docs/architecture/005_architecture_data.json | 文档同步 | DOC-02, DOC-03 |
六、v2 → v3 修正对比
| v2 编号 | 问题 | v2 状态 | v3 状态 | 修正方式 |
|---|---|---|---|---|
| BUG-P02 | Permissions satisfies | ❌ | ✅ | as const satisfies Record<string, string> |
| BUG-P03 | Role 类型 | ❌ | ✅ | 新增 Role 联合类型 + isRole 类型守卫 |
| BUG-P06 | class_members classIds | ❌ | ✅ | 类型添加 classIds + auth-guard 预查 |
| BUG-T01 | 测试覆盖率 | ❌ | ✅ | 扩充至 7 个用例 |
| BUG-T02 | 测试描述 | ❌ | ✅ | describe("ActionState 类型构造") |
| BUG-C01 | tsconfig target | ❌ | ✅ | ES2017 → ES2022 |
| BUG-C02 | noUncheckedIndexedAccess | ❌ | ⚠️ | 暂缓(80+ 原有错误) |
| BUG-C03 | noImplicitReturns | ❌ | ✅ | 启用 3 个严格选项 |
| PERF-01 | useCallback | ❌ | ✅ | 4 个回调全部 memoize |
| PERF-02 | useMemo | ❌ | ✅ | permissions/roles memoize |
| PERF-03 | as 断言 | ❌ | ✅ | 移除断言,用泛型参数 |
| UI-01 | hydration mismatch | ❌ | ✅ | 返回 status + JSDoc 文档化 |
| UI-02 | URL 状态 | ❌ | ✅ | 添加 from/reason 参数 |
| UI-03 | 错误消息 | ❌ | ✅ | 中文消息 + 修复步骤 |
| NEW-01 | USER_PROFILE_UPDATE 分组 | ❌ | ✅ | 独立为 User 分组 |
| NEW-02 | questions/actions.ts 分号 | ❌ | ✅ | prettier --write |
| NEW-03 | ROLE_PERMISSIONS 键类型 | ❌ | ✅ | Record<Role, Permission[]> |
| DOC-01 | 004 行数记录 | ❌ | ✅ | 更新为 157 行 |
| DOC-02 | 005 字段顺序 | ❌ | ✅ | 同步源码顺序 |
| DOC-03 | Role 记录 | ❌ | ✅ | 新增 Role 类型节点 |
| DOC-04 | 004 权限点数 | ❌ | ✅ | 54 → 61 |
七、剩余技术债务
| 编号 | 问题 | 严重度 | 建议处理方式 |
|---|---|---|---|
| BUG-C02 | noUncheckedIndexedAccess 未启用 |
中 | 创建独立技术债务任务,按模块渐进修复 80+ 处 possibly undefined |
| BUG-T01 | vitest 未覆盖 src/ 单元测试 |
低 | 扩展 vitest include 或新增 unit 配置 |
| NEW-V3-01 | proxy.ts roles 变量类型未收窄 |
低 | 移除 as string[] 断言,resolveDefaultPath 改为 Role[] |
八、验证命令
# Lint(已通过)
npx eslint src/shared/types/permissions.ts src/shared/types/action-state.ts \
src/shared/types/action-state.test.ts src/shared/hooks/use-permission.ts \
src/shared/lib/auth-guard.ts src/shared/lib/permissions.ts \
src/auth.ts src/proxy.ts src/next-auth.d.ts
# TypeScript(我修改的文件已通过)
npx tsc --noEmit
# Prettier(已通过)
npx prettier --check "src/shared/types/**/*.ts" "src/modules/questions/actions.ts"
报告生成人:AI Agent(GLM-5.2) 核查方法:v2 对比审查 + 直接代码修正 + lint/tsc 验证 版本:v3.0 修正率:90.5%(19/21)