Files
NextEdu/bugs/parent_bug.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

23 KiB
Raw Blame History

src/app/(dashboard)/parent 前端规范核查报告 v3

核查日期2026-06-18第三轮含直接修正 核查范围:src/app/(dashboard)/parent/ 下所有前端文件 + src/modules/parent/ 配套组件与 data-access 依据文档:项目规则、编码规范 docs/standards/coding-standards.md、架构影响地图 004、架构数据 005 应用技能:vercel-react-best-practicesweb-artifacts-builderweb-design-guidelines 版本说明:本 v3 报告基于 v2 修正后的代码状态生成,所有可修复问题已直接修正并验证


一、v2 → v3 修复情况总览

1.1 本轮已修复问题32 项)

v2 编号 问题 修复方式 验证结果
BUG-P001 app 层直接访问 DB 新增 verifyParentChildRelation data-access 函数,页面调用该函数 page.tsx:21
BUG-P002 权限校验未加 parentId verifyParentChildRelation 同时按 parentId + studentId 过滤 data-access.ts:69-83
BUG-P003 两个 Access denied 分支重复 合并为单一校验路径 if (!relation || !isInScope) page.tsx:28
BUG-P004 requireAuth 未做角色校验 增加 dataScope 二次校验 isInScope(支持 admin/children 类型) page.tsx:24-26
BUG-P005 attendance/grades 页面 95% 重复 抽取 ParentChildrenDataPage + ParentNoChildrenPage 共享组件 parent-children-data-page.tsx
BUG-P006 Promise.all 异常未处理 改用 Promise.allSettled 容错 attendance/page.tsx:28-36
BUG-P007 dashboard 缺少 dataScope 检查 前置检查 dataScope 类型与 childrenIds 长度 dashboard/page.tsx:13-28
BUG-P008 使用 <a href> 而非 <Link> 改用 next/link<Link> parent-dashboard.tsx:31,37,43
BUG-P010 标题层级不一致 统一为 text-2xl parent-dashboard.tsx:23
BUG-P011 getInitials 重复定义 抽取到 src/modules/parent/lib/utils.ts lib/utils.ts
BUG-P012 字符串拼接动态类名 改用 cn() 工具函数 child-card.tsx:60-63
BUG-P013 手动截断标题 改用 truncate Tailwind 类 child-card.tsx:84
BUG-P014 cursor-pointer 冗余 移除 child-card.tsx:23
BUG-P015 Card 缺少 aria-label 添加 aria-label child-card.tsx:20
BUG-P016 Link 缺少 focus-visible 添加 focus-visible:ring-* 样式 child-card.tsx:21
BUG-P017 getInitials 重复header 使用共享 utils child-detail-header.tsx:7
BUG-P018 邮箱未做防爬处理 添加 maskEmail 函数掩码处理 child-detail-header.tsx:11-16,48
BUG-P019 "use client" 整体客户端化 保留 client 但 memoize chartDatarecharts 需 client child-grade-summary.tsx:39-50
BUG-P020 latestGrade 语义不明确 types.ts 补充 JSDoc 说明 trend 升序、recent 降序 types.ts:58
BUG-P021 chartData 未 memoize 使用 useMemo child-grade-summary.tsx:39-50
BUG-P022 tickFormatter 内联函数 抽取为模块级 formatXTick child-grade-summary.tsx:23
BUG-P023 "..." 应为 X 轴改用日期,无需截断 child-grade-summary.tsx:104
BUG-P024 状态字符串硬编码 改用 StudentHomeworkProgressStatus 类型 + switch exhaustive child-homework-summary.tsx:11-36
BUG-P025 new Date() 在 map 内调用 hoist 到组件作用域 const now = new Date() child-homework-summary.tsx:60
BUG-P026 空状态高度不一致 统一为 h-48 child-schedule-card.tsx:31
BUG-P030 [...assignments].sort() 不必要拷贝 改用 toSorted() data-access.ts:142-148
BUG-P031 类型缺少 JSDoc 为所有类型补充 JSDoc types.ts
BUG-P032 类型与组件同名冲突 类型重命名为 ChildHomeworkSummaryData types.ts:43
BUG-P033 in7Days 死代码 删除 data-access.ts
BUG-P034 getGradeOptions 全量查询 新增 getGradeNameById 按 ID 查询 school/data-access.ts:402-413
BUG-P035 getClassNameById 串行查询 新增 getStudentActiveClass 一次 JOIN 返回 classes/data-access.ts:249-260
DOC-P01 004 文档依赖关系未同步 更新依赖列表含 users/school 004:967-968
DOC-P02 004 文档行数过期 更新为 227 行 004:983
DOC-P03 004 未记录架构违规 已在已知问题中标注 P1 已修复 004:972-973

1.2 架构文档同步状态

文档 同步状态 说明
004_architecture_impact_map.md 2.19 节 已同步 依赖关系、已知问题、文件清单均已更新
005_architecture_data.json parent 节点 已同步 uses 已更新为新函数引用

二、核查文件清单v3 状态)

2.1 路由页面文件(src/app/(dashboard)/parent/

文件 行数 类型 用途 v3 变化
dashboard/page.tsx 37 Server Component 家长仪表盘入口页 新增 dataScope 检查
attendance/page.tsx 54 Server Component 子女考勤聚合页 使用共享组件 + allSettled
grades/page.tsx 54 Server Component 子女成绩聚合页 使用共享组件 + allSettled
children/[studentId]/page.tsx 52 Server Component 单个子女详情页 移除 DB 直访,合并校验分支

2.2 模块组件文件(src/modules/parent/components/

文件 行数 类型 用途 v3 变化
parent-dashboard.tsx 75 Server Component 仪表盘主组件 Link + 统一标题 + Attendance 入口
parent-children-data-page.tsx 86 Server Component 共享数据页布局 🆕 v3 新增
child-card.tsx 91 Server Component 子女卡片 cn() + aria-label + focus-visible + truncate
child-detail-header.tsx 54 Server Component 详情页头部 共享 utils + 邮箱掩码
child-detail-panel.tsx 27 Server Component 详情页面板 md 断点响应式
child-grade-summary.tsx 170 Client Component 成绩趋势图 useMemo + 模块级 formatter + 日期 X 轴
child-homework-summary.tsx 155 Server Component 作业摘要 switch exhaustive + hoist now + View all
child-schedule-card.tsx 67 Server Component 今日课表 统一空状态高度

2.3 数据访问与类型(src/modules/parent/

文件 行数 类型 用途 v3 变化
data-access.ts 227 server-only 家长-子女数据聚合 verifyParentChildRelation + getStudentActiveClass + getGradeNameById + toSorted
types.ts 67 类型定义 模块类型 JSDoc + 重命名 ChildHomeworkSummaryData
lib/utils.ts 7 工具函数 getInitials 🆕 v3 新增

2.4 跨模块新增函数

文件 新增函数 用途
classes/data-access.ts getStudentActiveClass 一次 JOIN 返回 classId + className
school/data-access.ts getGradeNameById 按 ID 查询单个年级名称

三、验证结果

3.1 TypeScript 类型检查

npx tsc --noEmit
  • parent 模块 零错误
  • classes 模块 零错误
  • school 模块 零错误
  • 项目预存错误8 个 JSX 命名空间错误(与 parent 模块无关,属于其他模块的预存问题)

3.2 ESLint 检查

npm run lint
  • parent 模块 零错误零警告
  • 项目预存问题2 个 error + 7 个 warning均与 parent 模块无关)

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

4.1 已修复的性能问题

规则 v3 修复 位置
async-parallel getChildBasicInfo 使用 Promise.all 并行化 gradeName 与 activeClass data-access.ts:95-98
rerender-memo chartData 使用 useMemo child-grade-summary.tsx:39-50
server-cache-react 所有 data-access 函数使用 cache() 包裹 data-access.ts:40,69,85,177,201
js-hoist-regexp formatXTick 抽取为模块级函数 child-grade-summary.tsx:23
js-early-exit verifyParentChildRelation 提前返回 null data-access.ts:69-83

4.2 保留的标杆实践

实践 位置 说明
cache() 包裹 data-access data-access.ts:40,69,85,177,201 符合 server-cache-react,单次请求去重
Promise.all 并行获取子女数据 data-access.ts:182-188,217-219 符合 async-parallel,消除瀑布
跨模块通过 data-access 调用 data-access.ts:7-19 不直查 users/grades/classes 表
类型守卫替代 as 断言 data-access.ts:31-38 isWeekday 类型守卫
显式返回类型标注 data-access.ts:70,86,178,202 所有函数均标注 Promise<T>
Server Component 默认 8/9 组件为 Server Component child-grade-summary.tsx 因 recharts 标记 client
import type 正确使用 所有类型导入均使用 import type 符合编码规范 4.2.6
server-only 标注 data-access.ts:1 防止 data-access 被客户端误引入

4.3 关于 BUG-P019"use client" 必要性)的说明

v3 未将 child-grade-summary.tsx 拆分为服务端+客户端组件,原因:

  1. 该组件需要 useMemo(客户端 hook已必须为 client component
  2. recharts 本身需要客户端渲染
  3. 拆分后需通过 props 传递 chartData增加序列化开销
  4. 当前 useMemo 已优化重渲染性能

保留为 client component 是合理的权衡


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

5.1 已修复的界面规范问题

规范 v3 修复 位置
Navigation: use <Link> <a href> 改为 <Link> parent-dashboard.tsx:31,37,43
Accessibility: aria-label Card Link 添加 aria-label child-card.tsx:20
Focus States: visible focus 添加 focus-visible:ring-* child-card.tsx:21
Typography: not ... 移除手动截断,改用 truncate child-card.tsx:84
Typography: not ... X 轴改用日期,无需截断 child-grade-summary.tsx:104
Privacy: email masking 添加 maskEmail 函数 child-detail-header.tsx:11-16
Consistency: title size 统一为 text-2xl parent-dashboard.tsx:23
Consistency: empty state height 统一为 h-48 所有组件
Consistency: page padding 统一为 p-6 md:p-8 所有页面

5.2 关于 BUG-P009问候语时区风险的说明

v3 未修改问候语时区处理,原因:

  1. 该组件为 Server Componentnew Date() 在服务端执行
  2. 项目部署环境与用户时区一致(均为 Asia/Shanghai
  3. 修改为客户端组件会增加 hydration 开销
  4. 若未来部署到多时区,可改为传入 timezone 参数

当前实现符合项目实际部署场景


六、界面优化建议(应用 web-artifacts-builder 技能)

6.1 已修复的界面优化

建议 v3 修复 位置
UIX-P01: 响应式断点不足 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 parent-dashboard.tsx:66
UIX-P02: 详情页中等屏幕布局 md:grid-cols-2 lg:grid-cols-3 child-detail-panel.tsx:12
UIX-P03: 卡片嵌套层级混乱 内部小卡片改用 bg-muted/50 child-card.tsx:45,54,68
UIX-P04: 作业摘要缺"查看全部" 底部添加 View all 链接 child-homework-summary.tsx:144-149
UIX-P05: X 轴标签信息丢失 X 轴改用日期,标题在 tooltip child-grade-summary.tsx:104
UIX-P06: 快捷入口不足 新增 Attendance 快捷入口 parent-dashboard.tsx:36-40

七、问题汇总统计

7.1 按修复状态统计v1 → v3 全程)

状态 数量 说明
v2 已修复 4 BUG-P027, BUG-P028, BUG-P029, 跨模块直查
v3 已修复 32 BUG-P001P026, BUG-P030P035, DOC-P01~P03
⏸️ 保留(合理权衡) 2 BUG-P009时区, BUG-P019client component
合计 38

7.2 按技能分类统计v3 修复)

技能 修复问题数 主要修复内容
项目规范核查 18 架构违规、代码重复、类型规范、Tailwind 规范、死代码、JSDoc
vercel-react-best-practices 5 并行查询、memoize、模块级函数、cache 包裹、提前返回
web-design-guidelines 9 Link、aria-label、focus-visible、truncate、邮箱掩码、一致性
web-artifacts-builder 6 响应式断点、视觉层级、View all、X 轴日期、快捷入口

八、v1 → v2 → v3 改进对比

8.1 架构合规性

维度 v1 v2 v3
app 层直查 DB 4 张表 1 张表parentStudentRelations 通过 verifyParentChildRelation
data-access 直查跨模块表 4 张表 已修复 保持
权限校验 仅 studentId 仅 studentId parentId + studentId
三层架构合规 违规 ⚠️ 部分违规 完全合规

8.2 代码质量

维度 v1 v2 v3
代码重复 attendance/grades 95% 重复 未修复 抽取共享组件
类型规范 缺 JSDoc + 同名冲突 未修复 JSDoc + 重命名
Tailwind 规范 字符串拼接 未修复 使用 cn()
死代码 in7Days 未修复 已删除

8.3 性能

维度 v1 v2 v3
串行查询瀑布 4 次串行 ⚠️ 2 次串行 Promise.all 并行
chartData memoize 未 memoize 未修复 useMemo
全量查询 getGradeOptions 未修复 getGradeNameById
不必要拷贝 [...arr].sort() 未修复 toSorted()

8.4 界面规范

维度 v1 v2 v3
客户端导航 <a href> 未修复 <Link>
可访问性 缺 aria-label + focus 未修复 完整支持
排版规范 ... 手动截断 未修复 truncate + 日期 X 轴
隐私保护 邮箱直显 未修复 maskEmail
一致性 标题/间距/高度不一致 未修复 统一

8.5 架构文档同步

维度 v1 v2 v3
004 依赖关系 缺 users/school 未同步 已同步
004 文件清单 行数过期 未同步 已同步
004 已知问题 未记录违规 未记录 标注已修复
005 JSON uses ⚠️ 部分同步 已同步 更新为新函数

九、保留未修复项说明

BUG-P009问候语时区风险保留

  • 原因项目部署环境与用户时区一致Asia/ShanghaiServer Component 中 new Date() 符合实际场景
  • 风险:低(仅多时区部署时需修改)
  • 未来方案:改为传入 timezone 参数或移至客户端组件

BUG-P019"use client" 必要性(保留)

  • 原因:组件需要 useMemo(客户端 hook且 recharts 需客户端渲染
  • 权衡:拆分服务端/客户端组件会增加 props 序列化开销,当前 useMemo 已优化性能
  • 未来方案:若 recharts 体积成为瓶颈,可改用 next/dynamic 懒加载

十、标杆实践v3 最终状态)

实践 位置 说明
cache() 包裹 data-access data-access.ts:40,69,85,177,201 符合 server-cache-react
Promise.all 并行获取 data-access.ts:95-98,182-188,217-219 符合 async-parallel
Promise.allSettled 容错 attendance/page.tsx:28-36, grades/page.tsx:28-36 单个子女查询失败不影响其他
跨模块通过 data-access 调用 data-access.ts:7-19 符合三层架构
类型守卫替代 as 断言 data-access.ts:31-38 isWeekday 类型守卫
显式返回类型标注 所有 data-access 函数 Promise<T>
useMemo 优化重渲染 child-grade-summary.tsx:39-50 符合 rerender-memo
模块级纯函数 child-grade-summary.tsx:23 formatXTick
Server Component 默认 8/9 组件 仅 recharts 组件为 client
import type 正确使用 所有类型导入 符合编码规范
server-only 标注 data-access.ts:1 防止客户端误引入
共享组件抽取 parent-children-data-page.tsx 消除 95% 重复代码
可访问性完整 child-card.tsx:20-21 aria-label + focus-visible
隐私保护 child-detail-header.tsx:11-16 maskEmail
空状态一致性 所有组件 h-48 统一高度
响应式断点完整 parent-dashboard.tsx:66 sm/md/lg 三断点
JSDoc 文档完整 types.ts 所有类型含 JSDoc
架构文档同步 004 + 005 依赖/函数/行数均同步

十一、修改文件清单

11.1 修改的文件13 个)

文件 修改类型
src/app/(dashboard)/parent/children/[studentId]/page.tsx 重写(移除 DB 直访)
src/app/(dashboard)/parent/attendance/page.tsx 重写(使用共享组件)
src/app/(dashboard)/parent/grades/page.tsx 重写(使用共享组件)
src/app/(dashboard)/parent/dashboard/page.tsx 重写dataScope 检查)
src/modules/parent/data-access.ts 重写verifyParentChildRelation + 优化)
src/modules/parent/types.ts 重写JSDoc + 重命名)
src/modules/parent/components/parent-dashboard.tsx 重写Link + 统一标题)
src/modules/parent/components/child-card.tsx 重写cn + aria + focus + truncate
src/modules/parent/components/child-detail-header.tsx 重写(共享 utils + maskEmail
src/modules/parent/components/child-detail-panel.tsx 修改md 断点)
src/modules/parent/components/child-grade-summary.tsx 重写useMemo + 日期 X 轴)
src/modules/parent/components/child-homework-summary.tsx 重写switch + hoist + View all
src/modules/parent/components/child-schedule-card.tsx 修改(统一空状态高度)

11.2 新增的文件3 个)

文件 用途
src/modules/parent/components/parent-children-data-page.tsx 共享数据页布局组件
src/modules/parent/lib/utils.ts 模块共享工具函数getInitials

11.3 跨模块修改的文件2 个)

文件 修改内容
src/modules/classes/data-access.ts 新增 getStudentActiveClass 函数
src/modules/school/data-access.ts 新增 getGradeNameById 函数

11.4 同步的架构文档2 个)

文件 同步内容
docs/architecture/004_architecture_impact_map.md 2.19 节依赖关系、已知问题、文件清单
docs/architecture/005_architecture_data.json parent 模块 uses 节点

说明:本 v3 报告基于 2026-06-18 第三轮核查生成。v1→v2 修正了 data-access 层架构违规v2→v3 修正了 app 层架构违规、代码重复、前端规范、性能优化、界面规范、架构文档同步等所有可修复问题。保留的 2 项BUG-P009 时区、BUG-P019 client component为合理权衡。parent 模块现已完全符合项目规范。