Files
NextEdu/bugs/shared_bug_v3.md
SpecialX 978d9a8309
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
feat: 新增备课模块并修复全模块 P0/P1/P2 缺陷
主要变更:

- 新增 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)
2026-06-22 01:06:16 +08:00

308 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# `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](./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.ts4 项)
#### ✅ BUG-P02`Permissions` 常量添加 `satisfies` 类型约束
- **文件**[permissions.ts:120](../src/shared/types/permissions.ts)
- **修正内容**`as const``as const satisfies Record<string, string>`
- **效果**:编译期验证所有权限点值均为字符串
#### ✅ BUG-P03`AuthContext.roles` 类型收紧为 `Role[]`
- **文件**[permissions.ts:8-14, 152-157](../src/shared/types/permissions.ts)
- **修正内容**:新增 `Role` 联合类型(`admin | teacher | student | parent | grade_head | teaching_head``AuthContext.roles``string[]` 改为 `Role[]`
- **连带修正**
- [next-auth.d.ts](../src/next-auth.d.ts)`Session.user.roles``JWT.roles` 改为 `Role[]`
- [shared/lib/permissions.ts](../src/shared/lib/permissions.ts)`ROLE_PERMISSIONS` 改为 `Record<Role, Permission[]>``resolvePermissions` 参数改为 `Role[]`
- [shared/lib/auth-guard.ts](../src/shared/lib/auth-guard.ts)`resolveDataScope` 参数改为 `Role[]`
- [auth.ts](../src/auth.ts)JWT/session callback 中使用 `.filter(isRole)` 过滤数据库返回的角色名
- **新增**`isRole()` 类型守卫函数,用于从 `string` 安全收窄到 `Role`
#### ✅ BUG-P06`DataScope.class_members` 携带 classIds
- **文件**[permissions.ts:139](../src/shared/types/permissions.ts)
- **修正内容**`{ type: "class_members" }``{ type: "class_members"; classIds: string[] }`
- **连带修正**[auth-guard.ts:116-128](../src/shared/lib/auth-guard.ts) `resolveDataScope` 学生分支预查 `classEnrollments` 表并填充 classIds消除 data-access 层 N+1 查询风险
#### ✅ NEW-01`USER_PROFILE_UPDATE` 语义分组调整
- **文件**[permissions.ts:52-59](../src/shared/types/permissions.ts)
- **修正内容**:从 `// School management` 分组移出,独立为 `// User (self-service)` 分组
---
### 1.2 tsconfig.json3 项)
#### ✅ BUG-C01`target` 升级至 ES2022
- **文件**[tsconfig.json:3](../tsconfig.json)
- **修正内容**`"target": "ES2017"``"target": "ES2022"`
#### ✅ BUG-C03启用 `noImplicitReturns` 等严格检查
- **文件**[tsconfig.json:21-23](../tsconfig.json)
- **修正内容**:新增 `noImplicitReturns``noFallthroughCasesInSwitch``forceConsistentCasingInFileNames`
#### ⚠️ BUG-C02`noUncheckedIndexedAccess` 暂缓启用(降级为已知问题)
- **文件**[tsconfig.json:20](../tsconfig.json)
- **现状**:设为 `false`
- **原因**:启用后暴露 80+ 处项目原有 `possibly undefined` 错误(涉及 exams/grades/classes/dashboard 等多个模块),修复范围远超 `shared/types`。需项目级渐进式修复。
- **建议**:创建独立技术债务任务,按模块逐步修复后启用
---
### 1.3 use-permission.ts4 项 — React 性能 + Hydration
#### ✅ PERF-01回调函数 `useCallback` memoize
- **文件**[use-permission.ts:27-42](../src/shared/hooks/use-permission.ts)
- **修正内容**`hasPermission`/`hasAnyPermission`/`hasAllPermissions`/`hasRole` 全部使用 `useCallback` 包裹
- **技能规则**`rerender-functional-setstate``rerender-memo`
#### ✅ PERF-02`permissions`/`roles` 数组 `useMemo` memoize
- **文件**[use-permission.ts:18-25](../src/shared/hooks/use-permission.ts)
- **修正内容**:使用 `useMemo` 包裹,避免每次渲染创建新数组引用
- **技能规则**`rerender-derived-state``rerender-dependencies`
#### ✅ PERF-03移除 `as` 断言
- **文件**[use-permission.ts:18-25](../src/shared/hooks/use-permission.ts)
- **修正内容**:移除 `as Permission[]``as string[]` 断言,改用 `useMemo<Permission[]>` 泛型参数标注返回类型,依赖 `next-auth.d.ts` 的类型增强
#### ✅ UI-01Hydration safety 文档化
- **文件**[use-permission.ts:7-14, 47](../src/shared/hooks/use-permission.ts)
- **修正内容**:补充 JSDoc 说明 hydration 风险,返回 `status` 字段供调用方判断 `authenticated` 状态,避免权限 UI 闪烁
- **技能规则**Web Interface Guidelines — Hydration Safety
---
### 1.4 auth-guard.ts2 项)
#### ✅ UI-03错误消息补充修复步骤
- **文件**[auth-guard.ts:13-19](../src/shared/lib/auth-guard.ts)
- **修正内容**`Permission denied: ${permission}``权限不足:需要 ${permission} 权限。请联系管理员授权或切换账号后重试。`
- **技能规则**Web Interface Guidelines — Content & Copy
#### ✅ BUG-P06 配套:学生分支预查 classIds
- **文件**[auth-guard.ts:116-128](../src/shared/lib/auth-guard.ts)
- **修正内容**:学生分支查询 `classEnrollments` 表预填 classIds`DataScope.class_members` 类型变更配套
---
### 1.5 proxy.ts1 项)
#### ✅ UI-02权限不足重定向携带 URL 状态
- **文件**[proxy.ts:73-87](../src/proxy.ts)
- **修正内容**:重定向 URL 添加 `?from=originalPath&reason=forbidden` 参数,目标页可解释重定向原因
- **技能规则**Web Interface Guidelines — Navigation & State
---
### 1.6 action-state.test.ts2 项)
#### ✅ BUG-T01补充边界测试用例
- **文件**[action-state.test.ts](../src/shared/types/action-state.test.ts)
- **修正内容**:从 3 个用例扩充至 7 个新增多字段多错误、falsy data0/""/null、空 message、无 message 成功态
#### ✅ BUG-T02测试描述体现行为意图
- **文件**[action-state.test.ts:4](../src/shared/types/action-state.test.ts)
- **修正内容**`describe("ActionState")``describe("ActionState 类型构造")`
---
### 1.7 shared/lib/permissions.ts1 项)
#### ✅ NEW-03`ROLE_PERMISSIONS` 键类型约束为 `Role`
- **文件**[permissions.ts:1, 5, 211](../src/shared/lib/permissions.ts)
- **修正内容**`Record<string, Permission[]>``Record<Role, Permission[]>``resolvePermissions` 参数改为 `Role[]`
---
### 1.8 questions/actions.ts1 项)
#### ✅ NEW-02Prettier 分号违规修复
- **文件**[questions/actions.ts](../src/modules/questions/actions.ts)
- **修正内容**:运行 `npx prettier --write` 移除全文件 62 处分号,与项目 `"semi": false` 配置一致
---
### 1.9 架构文档同步4 项)
#### ✅ DOC-01004 文件行数与权限点数更新
- **文件**[004_architecture_impact_map.md:436](../docs/architecture/004_architecture_impact_map.md)
- **修正内容**`92 | 54 个权限点常量``157 | 61 个权限点常量 + Role/DataScope/AuthContext 类型`
#### ✅ DOC-04004 权限点数量同步
- **文件**[004_architecture_impact_map.md:1541](../docs/architecture/004_architecture_impact_map.md)
- **修正内容**`54 个权限点``61 个权限点`
#### ✅ DOC-02005 JSON `DataScope` 定义同步
- **文件**[005_architecture_data.json:1047](../docs/architecture/005_architecture_data.json)
- **修正内容**:字段顺序与源码一致,`class_members` 补充 `classIds: string[]`
#### ✅ DOC-03005 JSON 新增 `Role` 类型记录 + `AuthContext` 更新
- **文件**[005_architecture_data.json:1032-1065](../docs/architecture/005_architecture_data.json)
- **修正内容**:新增 `Role` 类型节点(含 `usedBy` 列表),`AuthContext` 定义中 `roles: string[]``roles: Role[]`
---
## 二、未修正问题2 项 ❌)
### ❌ BUG-C02`noUncheckedIndexedAccess` 暂缓启用 — 严重度:中
- **位置**[tsconfig.json:20](../tsconfig.json)
- **现状**:设为 `false`
- **原因**:启用后暴露 80+ 处项目原有 `possibly undefined` 错误,涉及 exams/grades/classes/dashboard/elective 等多个模块,修复范围远超 `shared/types`
- **建议**:创建独立技术债务任务,按模块逐步修复后启用
### ❌ BUG-T01部分vitest 配置未覆盖 `src/` 单元测试 — 严重度:低
- **位置**[vitest.config.ts:13](../vitest.config.ts)
- **现状**`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](../src/proxy.ts)
- **问题**`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](../src/shared/types/permissions.ts) | 重构 | BUG-P02, BUG-P03, BUG-P06, NEW-01 |
| [src/shared/types/action-state.test.ts](../src/shared/types/action-state.test.ts) | 增强 | BUG-T01, BUG-T02 |
| [src/shared/lib/permissions.ts](../src/shared/lib/permissions.ts) | 类型收紧 | NEW-03, BUG-P03 |
| [src/shared/lib/auth-guard.ts](../src/shared/lib/auth-guard.ts) | 重构 | UI-03, BUG-P06, BUG-P03 |
| [src/shared/hooks/use-permission.ts](../src/shared/hooks/use-permission.ts) | 重写 | PERF-01/02/03, UI-01 |
| [src/next-auth.d.ts](../src/next-auth.d.ts) | 类型增强 | BUG-P03 |
| [src/auth.ts](../src/auth.ts) | 类型修复 | BUG-P03 |
| [src/proxy.ts](../src/proxy.ts) | 增强 | UI-02 |
| [src/modules/questions/actions.ts](../src/modules/questions/actions.ts) | 格式化 | NEW-02 |
| [tsconfig.json](../tsconfig.json) | 配置升级 | BUG-C01, BUG-C03 |
| [docs/architecture/004_architecture_impact_map.md](../docs/architecture/004_architecture_impact_map.md) | 文档同步 | DOC-01, DOC-04 |
| [docs/architecture/005_architecture_data.json](../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[]` |
---
## 八、验证命令
```bash
# 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 AgentGLM-5.2
> 核查方法v2 对比审查 + 直接代码修正 + lint/tsc 验证
> 版本v3.0
> 修正率90.5%19/21