SpecialX
ccf6c03096
fix(exams): preserve selected text when wrapIn fails in isolating nodes
...
When wrapIn fails inside isolating nodes (e.g. composite question block),
the previous fallback used insertContent which replaced the entire
selection with an empty questionBlock, causing other sub-questions to
disappear and content to be cleared.
New approach: when wrapIn fails, extract the selected text, delete the
selection, then insert a new node (questionBlock/groupBlock/sectionBlock)
containing the selected text as paragraphs. This preserves the content
and converts it into the desired structure.
Applied to all three wrap operations:
- insertQuestion (questionBlock)
- insertGroup (groupBlock)
- insertSection (sectionBlock)
2026-06-24 14:24:04 +08:00
SpecialX
df9561128b
fix(exams): fix duplicate React keys and composite question marking
...
- Fix parseOptions: deduplicate option ids within a single question to
avoid multiple "A" keys when a question contains multiple lists
- Fix ExamPreview: use composite keys (questionId-optId, questionId-sub-id)
to ensure global uniqueness across questions
- Fix selection-toolbar: when wrapInQuestion fails inside isolating nodes
(e.g. composite question block), fall back to insertQuestion instead of
silently doing nothing
2026-06-24 14:19:46 +08:00
SpecialX
1f28efbeb6
feat(exams): add section/group structure nodes with auto stats
...
Distinguish structural levels from questions:
- sectionBlock (new): top-level volume like "第Ⅰ卷 选择题(共24分)"
- groupBlock (enhanced): section like "一、选择题" with instruction field
- questionBlock (composite): reserved for reading comprehension
Key changes:
- New section-block.tsx extension with level attr (1=卷, 2=部分) and
auto-computed question count + total score in NodeView
- group-block.tsx: add instruction field ("每小题3分"), auto stats display
- editor-to-structure.ts: recursive buildStructureNode supports arbitrary
nesting (section > group > question), computeStats accumulates scores
- exam-rich-form.tsx ExamPreview: render section/group/question with
distinct styles and stats badges
- selection-toolbar.tsx: add "分卷" button (Layers icon)
- exam-rich-editor.tsx: register SectionBlock, expose insertSection/
wrapInSection via ref
- actions.ts: AI prompt now outputs volumes[] + groups[] structure with
instruction; buildTiptapDocFromAiResponse generates nested sectionBlock
- i18n: add markSection keys (zh-CN/en)
Structural nodes are NOT questions: their question count and total score
are automatically computed from child questions, not manually set.
2026-06-24 14:07:29 +08:00
SpecialX
f260720443
fix(exams): fix composite question sub-questions not showing in preview
...
- Fix buildQuestion in editor-to-structure.ts: recursively detect nested
questionBlock nodes as subQuestions (composite questions now properly
extract child questions instead of treating them as plain text)
- Fix buildQuestionBlock in actions.ts: AI auto-mark now generates nested
questionBlock nodes for sub-questions instead of plain paragraphs, so
they are properly structured and detectable by the parser
- Rewrite ExamPreview component with proper layout:
- Question header: number + type label badge + score
- Indented question text and options
- Composite sub-questions shown in nested block with left border
- Image thumbnails
- Empty state message
- Title centered at top
- Group titles with bottom border
2026-06-24 13:54:24 +08:00
SpecialX
7380f1e6c8
fix(exams): fix rich editor crashes and redesign form layout
...
- Fix groupBlock/questionBlock insertContent error: empty content violates
schema "block+", now provide default empty paragraph
- Fix buildTiptapDocFromAiResponse: ensure groupBlock/questionBlock always
have content (fallback to empty paragraph)
- Add wrapInGroup/wrapInQuestion commands to wrap selected text into
question/group blocks (vs insert which creates empty blocks)
- Update SelectionToolbar: use wrap when text selected, insert when not
- Redesign exam-rich-form layout:
- Merge basic info into single-row toolbar (title/subject/grade/difficulty/score/duration)
- Remove separate "source text" textarea (user pastes directly in editor)
- AI auto-mark now reads from editor content via getText()
- Editor + preview takes full height (calc(100vh-180px))
- Enhance AI prompt for Chinese exam papers:
- Support reading material (阅读理解选段)
- Support dotted chars (加点字注音)
- Support sub-questions (阅读理解小题)
- Better type detection (single/multiple choice, judgment, fill, essay, composite)
- Add splitByDottedTexts helper to mark dotted chars in Tiptap doc
- Add i18n keys for titlePlaceholder, editorArea description
2026-06-24 13:41:39 +08:00
SpecialX
d1e4ccbf98
refactor(exams): redesign exam creation page with 3-mode selector
...
- Replace cramped 3-column grid with vertical layout
- Add 3 large selectable cards at top: Manual / AI / Rich Text Editor
- Rich Text Editor mode redirects to /teacher/exams/new
- Basic info form is now always visible (not hidden in AI mode)
- Exam mode config always visible at bottom
- Add "rich" to mode enum with validation bypass
- Replace all hardcoded English/Chinese strings with i18n keys
- Add 20+ new i18n keys to zh-CN and en (mode labels, descriptions, actions)
- Clean up mixed-language UI text
2026-06-24 13:23:13 +08:00
SpecialX
6114607c1e
feat(exams,homework): add rich text exam editor and scan-based grading
...
- Add Tiptap-based rich text editor with custom extensions (dotted-mark,
blank-node, image-node, group-block, question-block) for exam creation
- Add AI auto-marking action to convert pasted exam text to structured editor doc
- Add resizable split-panel layout for editor + live preview
- Add student scan upload (photo of paper answers) with drag-drop and reorder
- Add scan image viewer with zoom/rotate/fullscreen for teachers
- Add scan grading view with side-by-side questions and scan images
- Add /teacher/exams/new and /teacher/homework/submissions/[id]/scan-grading routes
- Fix getScansAction to support both teacher (HOMEWORK_GRADE) and student
(HOMEWORK_SUBMIT) permission scopes
- Add i18n keys for rich editor, scan upload, and scan grading (zh-CN/en)
- Sync architecture diagrams (004/005) with new modules, routes, and deps
2026-06-24 13:16:33 +08:00
SpecialX
8c2fe14c20
refactor(modules): update classes, course-plans, diagnostic, questions, settings, student, layout
...
- Update classes data-access (invitations, main) for invitation management
- Update course-plans actions, data-access, and types
- Update diagnostic data-access for report queries
- Update questions data-access for question bank queries
- Update settings actions, ai-provider-settings-card, data-access, and types
- Update student course-filters, student-courses-view, student-schedule-filters, student-schedule-view
- Update layout app-sidebar, site-header, and navigation config
2026-06-24 12:03:35 +08:00
SpecialX
c9e46f9f80
feat(school): add grade dashboard and insights filters
...
- Add grade-dashboard components directory for school-wide grade analytics
- Add grade-insights-filters component for filtering grade insights
- Update grades-view and data-access
2026-06-24 12:03:22 +08:00
SpecialX
f0f713ff33
feat(exams,homework): add error collection data-access for error book integration
...
- Add data-access-error-collection in exams module for collecting wrong exam answers
- Add data-access-error-collection in homework module for collecting wrong homework answers
- Update exams actions, exam-ai-generator, data-access, and types
- Update homework actions and data-access-write
2026-06-24 12:03:03 +08:00
SpecialX
0cee93676b
feat(grades): add scope-check and update analytics
...
- Add scope-check lib for grade data access scope validation
- Update actions, actions-analytics, data-access, data-access-analytics
- Update batch-grade-entry, schema, and types
2026-06-24 12:02:50 +08:00
SpecialX
6bc113eaff
feat(lesson-preparation): add readonly view, anchor node selector, and type guards
...
- Add lesson-plan-readonly-view for viewing published plans
- Add anchor-node-selector and textbook-segments for canvas anchor positioning
- Add i18n-errors and type-guards lib utilities
- Add lesson-plan-provider-setup for provider initialization
- Update actions, data-access (knowledge, versions, main), publish-service
- Update blocks (blackboard, exercise, homework, import, key-point, objective, reflection)
- Update editor, node-editor, node-edit-panel, pickers, and providers
2026-06-24 12:02:42 +08:00
SpecialX
a48e7d0e27
feat(ai): add chart renderer, floating ball hook, and provider updates
...
- Add ai-chart-renderer for rendering charts in AI responses
- Add use-floating-ball hook for draggable AI assistant widget
- Update ai-assistant-widget, ai-chat-panel, ai-markdown-renderer, ai-provider-selector
- Update use-ai-chat-stream hook and prompt-templates service
2026-06-24 12:02:29 +08:00
SpecialX
61e76f0d67
feat(error-book): add analytics stats, charts, and error collection
...
- Add analytics-stats-cards, chapter-weakness-chart, class-error-bar-chart
- Add knowledge-point-weakness-chart, subject-distribution-chart, subject-tabs
- Add class-filter and grouped-student-error-table components
- Add data-access-collection for error aggregation from multiple sources
- Update error-book-detail-dialog, data-access, and types
2026-06-24 12:02:16 +08:00
SpecialX
d7876c5854
feat(adaptive-practice): add new adaptive practice module
...
- Add adaptive practice module with data-access, schema, types, and components
- Provides personalized practice based on student performance and error patterns
2026-06-24 12:02:04 +08:00
SpecialX
7e320d78c1
feat(ai): 统一 AI 配置入口到 /admin/ai-settings
...
## 新增
- 创建 /admin/ai-settings 统一配置页(AiProviderSettingsCard + AiUsageDashboard)
- admin 侧边栏新增"AI 配置"菜单项(权限 AI_CONFIGURE,图标 Sparkles)
- 新增 deleteAiProvider 数据访问层(事务删除 + 自动转移默认)
- 新增 deleteAiProviderAction Server Action(Zod 校验 + 权限校验)
- AiProviderSettingsCard 新增删除按钮(AlertDialog 确认 + destructive 变体)
- 新增 i18n 翻译键(delete/deleteConfirm/deleteSuccess 等,zh-CN + en)
## 移除
- 从 /settings 移除 AI 标签页(原 VALID_TABS 含 "ai",现仅 4 标签页)
- 从考试页面移除 AI 配置弹窗(Dialog + AiProviderSettingsCard 内嵌)
- 从 ai-provider-selector.tsx 移除配置弹窗(managePanel/manageOpen props)
- 移除 settings-view.tsx 中 canConfigureAi 逻辑和未使用 import
## 变更
- 考试页面"管理"按钮改为 Link 跳转到 /admin/ai-settings
- ai-provider-selector.tsx"管理"按钮改为 Link 跳转到 /admin/ai-settings
- exam-form.tsx 移除 providerDialogOpen/providerDialogKey 状态
- 修正架构文档 004 中 Action 命名(getAiProvidersAction → getAiProviderSummaries 等)
## 架构文档同步
- 004 更新 settings 模块章节(V3 标记/修正 Action 名称/新增 deleteAiProvider)
- 005 新增 deleteAiProviderAction 节点 + /admin/ai-settings 路由
2026-06-23 19:33:28 +08:00
SpecialX
4f0ef217a0
refactor(modules): update existing module implementations across attendance, audit, auth, classes, course-plans, exams, files, homework, layout, proctoring, questions, scheduling, textbooks, users
...
- Update attendance components and data-access for record management
- Update audit log views, filters, and data-access
- Update auth login and register forms
- Update classes actions, components, and data-access (admin, schedule, stats)
- Update course-plans actions, form, list, progress, and schema
- Update exams actions, AI pipeline, preview components, and hooks
- Update files components (icon, list, preview, upload) and data-access
- Update homework assignment form, review view, auto-save hook, and stats-service
- Update layout sidebar, header, and navigation config
- Update proctoring actions, anti-cheat monitor, and data-access
- Update questions actions, components (dialog, actions, columns, filters), and data-access
- Update scheduling actions, auto-scheduler, components, and schema
- Update textbooks constants and text-selection hook
- Update users class-registration, import-dialog, data-access, and user-service
2026-06-23 17:38:56 +08:00
SpecialX
1a9377222c
feat(app): add error/loading boundaries and update dashboard routes
...
- Add error.tsx and loading.tsx boundaries for admin, parent, student, teacher routes
- Add dashboard-error-fallback and dashboard-loading-skeleton components
- Add student/learning page, parent/leave routes, teacher textbook components
- Update existing app routes across auth, dashboard, and API endpoints
- Update proxy middleware and next-auth type declarations
2026-06-23 17:38:28 +08:00
SpecialX
9ceb2b7b67
feat(diagnostic): add export, stats service, and confidence utils
...
- Add export module for diagnostic report data export
- Add stats-service for diagnostic analytics aggregation
- Add confidence-utils for diagnostic confidence score calculations
2026-06-23 17:37:58 +08:00
SpecialX
1abf58c0b6
feat(parent): add attention banner, export button, and grade detail
...
- Add parent-attention-banner for highlighting items needing attention
- Add parent-export-button for data export capability
- Add child-grade-detail component for detailed grade viewing
- Update existing child-card, child-detail-header, child-grade-summary, child-schedule-card
- Update parent-children-data-page and data-access
2026-06-23 17:37:49 +08:00
SpecialX
95145cd03b
feat(grades): add ranking trend, school-wide summary, score cell, and scope filter
...
- Add ranking-trend-card and school-wide-summary-card for broader analytics
- Add score-cell and grade-filters components for table rendering
- Add scope-filter and type-guards lib utilities for grade data filtering
- Update actions, data-access (analytics, ranking, main), stats-service, export
- Update schema, types, and grade-utils lib
- Update all grade chart and report components (distribution, trend, comparison, query)
2026-06-23 17:37:32 +08:00
SpecialX
2197e68069
feat(lesson-preparation): add anchor canvas design, new blocks, and textbook content node
...
- Add anchor injector for canvas-based anchor positioning
- Add new block components: blackboard, homework, import, key-point, new-teaching, objective, summary
- Add textbook content node for React Flow canvas
- Update actions (kp, publish, main), data-access (templates, versions, main)
- Update editor, node-editor, block-renderer, and picker components
- Update schema, types, hooks, and lib utilities (document-migration, node-summary, rf-mappers)
2026-06-23 17:37:19 +08:00
SpecialX
1fcef5c3aa
feat(settings): add security center, 2FA/TOTP, avatar upload, system settings
...
- Add TOTP implementation and two-factor data-access for 2FA enrollment
- Add security center card with password policy and session management
- Add avatar upload action and component
- Add system settings actions and data-access (actions-system-settings, data-access-system-settings)
- Add notification preferences and service actions
- Add security-utils and student-overview-data with tests
- Update existing settings views, data-access, and types for new features
2026-06-23 17:37:06 +08:00
SpecialX
242a770cc9
feat(onboarding): add onboarding module with actions and data access
...
- Add server actions for onboarding flow orchestration
- Add data-access layer for onboarding state persistence
- Add type definitions for onboarding module
2026-06-23 17:36:56 +08:00
SpecialX
bf056399c6
feat(error-book): implement error book module with SM2 spaced repetition
...
- Add SM2 algorithm implementation with tests for spaced repetition review scheduling
- Add data-access, schema, types, and server actions for error book CRUD
- Add components: add dialog, class overview, filters, item card, stats cards, review buttons, top wrong questions
- Add error-book routes for admin, teacher, parent, and student roles
- Add i18n messages (en, zh-CN) for error book module
2026-06-23 17:36:42 +08:00
SpecialX
276577b66c
feat(messaging,announcements): 前端 UI 集成星标/草稿/置顶/已读回执
...
- 消息星标:MessageList 卡片星标按钮(乐观更新+回滚)、MessageDetail 头部星标切换
- 消息草稿:MessageCompose 自动保存(2s 防抖)+ 手动保存按钮 + 状态指示器 + 发送后清理草稿
- 公告置顶:AnnouncementCard 管理端置顶按钮、AnnouncementDetail 置顶切换、置顶 Badge
- 公告已读回执:用户端详情页自动标记已读 + 已读/未读 Badge、管理端已读人数显示
- i18n:新增 announcements.meta.readCount 翻译键
2026-06-23 17:24:26 +08:00
SpecialX
f75602d14e
feat(announcements,messaging,notifications): 实现所有长期问题 — SSE 实时推送 + 通知日志持久化 + 优先级/归档 + 消息星标/草稿 + 公告已读回执/置顶 + 分类筛选/桌面推送 + 测试覆盖
...
P1-8 通知实时推送(SSE):
- 新增 /api/notifications/stream SSE 端点(15 秒推送,5 分钟超时)
- 新增 useNotificationStream Hook(SSE + 轮询降级)
- NotificationDropdown 改用 SSE 实时推送
P2-12 测试覆盖:
- notifications/dispatcher.test.ts(6 个测试,渠道选择逻辑)
- notifications/channels/in-app-channel.test.ts(9 个测试,类型映射)
- messaging/schema.test.ts(34 个测试,Zod 校验)
- tests/e2e/messages.spec.ts(消息模块 E2E 测试)
- vitest.unit.config.ts 添加 server-only stub
P2-13a 通知发送日志持久化:
- 新增 notification_logs 表(userId/title/channel/status/messageId/error/sentAt)
- logNotificationSend 改为 async 写入 DB(失败降级 console)
- dispatcher 传递 payload 用于持久化
P2-13b 通知优先级和归档:
- messageNotifications 表新增 priority(low/normal/high/urgent)和 isArchived 字段
- getNotifications 支持归档和优先级筛选
- 新增 archiveNotificationAction
- NotificationList 显示优先级 Badge 和归档按钮
P2-13c 消息星标和草稿:
- messages 表新增 isStarred 字段
- 新增 message_drafts 表
- 新增 toggleMessageStar + 草稿 CRUD Server Actions
- 新增 5 个草稿 data-access 函数
P2-13d 公告已读回执和置顶:
- announcements 表新增 isPinned 字段
- 新增 announcement_reads 表(唯一索引保证幂等)
- 新增 toggleAnnouncementPinAction + markAnnouncementAsReadAction
- getAnnouncements 排序置顶优先
P2-13e 通知分类筛选和桌面推送:
- NotificationList 添加按类型筛选按钮组
- 新增 useDesktopNotifications Hook(浏览器 Notification API)
- NotificationDropdown 集成桌面推送(新通知触发)
架构图同步:
- 004 和 005 均已更新(新增表、Action、Hook、组件描述)
2026-06-23 10:13:57 +08:00
SpecialX
696346dc08
fix(ai): V3 长期问题修复+规则合规+竞品对标
...
## P1 安全加固
- 原子化每日限额(tryConsumeDailyQuota)解决 TOCTOU 竞态
- 流式端点补齐 Zod 校验 + rate limit + 服务端强制 systemPrompt
- 配额回退机制(refundDailyQuota):过滤/失败不扣配额
- PII 最小化:移除 AI prompt 中的学生姓名
## P1 数据一致性
- 修复 capability 埋点缺失 child_summary/study_path 类型
- 创建 data-access.ts:真实统计聚合替代硬编码零
- 修复 generateChildSummary/recommendStudyPath 的 capability 标记
## P2 可靠性
- AI 调用重试机制(withRetry 指数退避,429/5xx,2 次重试)
- 30s 超时配置
- 流式 controller 安全 enqueue(防已关闭抛错)
- localStorage 防抖持久化(500ms,流式过程中跳过)
## P2 TypeScript/规则合规
- 移除 as 断言(VariantType 类型守卫、Permission 类型、StreamErrorKey)
- 补齐返回类型标注(POST/getStatusFromError/DashboardLayout)
- 拆分 use-ai-chat-stream hook(190→107 行,函数体≤80 行)
- 抽取 stream-utils.ts(SSE 解析/错误映射/消息工具)
- Tailwind 任意值添加注释说明(max-w-[80%] 聊天气泡)
## P3 竞品对标
- 苏格拉底式辅导强化(对标 Khanmigo):
- SOCRATIC_TUTOR_SYSTEM_PROMPT 3 级提示升级
- 强化 STUDENT_BLOCKED_PATTERNS 正则(中英文答案拦截)
- validateSocraticOutput 服务端校验(问号结尾+连续陈述句限制)
- socratic_warning SSE 事件类型
- 知识图谱集成(对标 Squirrel AI):
- StudyPathInput 新增 knowledgeGraph/textbookId 字段
- recommendStudyPathAction 自动从 textbooks 模块获取图谱+掌握度
- STUDY_PATH_SYSTEM_PROMPT 增加前置依赖链规则
- WEAKNESS_ANALYSIS_SYSTEM_PROMPT 增加 rootCause 字段
## 架构文档同步
- 004 更新 AI 模块章节(V3 标记/新导出/依赖关系/安全机制/文件清单)
- 005 更新 modules.ai 节点(dependsOn/exports/dataAccess/streamUtils/dependencyMatrix)
2026-06-23 09:39:18 +08:00
SpecialX
036a2f2839
feat(exams,homework,proctoring): 长期问题修复与竞品差距补齐
...
P1-1 跨模块直查消除:
- homework/data-access-classes.ts 移除对 exams/subjects 表的 JOIN 直查
- 改为调用 exams/data-access.getExamSubjectIdMap + school/data-access.getSubjectNameMapByIds
- school/data-access.ts 新增 getSubjectNameMapByIds 批量科目名称映射函数
P1-2 as 断言消除(exam-mode-config.tsx):
- 移除全部 10 处 as 类型断言
- 改用 useFormContext 替代 Control prop,避免 Control<T> 不变型问题
- exam-form.tsx 调用方简化为 <ExamModeConfig />(已集成到考试表单)
P1-3 as 断言消除(proctoring-dashboard.tsx):
- 用类型守卫函数 isProctoringEventType + toProctoringEventTypes
替代 Object.keys(...) as ProctoringEventType[] 断言
P0-竞品倒计时(对标智学网/猿题库):
- 新增 hooks/use-exam-countdown.ts 考试倒计时 Hook
- homework-take-view.tsx 集成限时/监考模式倒计时显示与到时自动提交
- data-access.ts 的 getStudentHomeworkTakeData 新增 examModeConfig + startedAt 字段
- types.ts 扩展 StudentHomeworkTakeData 类型
- i18n 补充 timedExam/timeRemaining/timeUpAutoSubmit 翻译键
架构文档同步:
- 004/005 更新 homework/proctoring/school/exams 模块导出与依赖关系
- 005 新增 homework.hooks.useExamCountdown 与 school.dataAccess.getSubjectNameMapByIds
- 005 依赖矩阵 homework→school 补充 getSubjectNameMapByIds
验证:tsc --noEmit 零错误,eslint 零错误(3 个预存 warning 无关)
2026-06-23 09:34:24 +08:00
SpecialX
2c0f81391b
feat(dashboard): 实现所有长期问题修复(P2-1/P2-5/P2-7/P2-9)
...
P2-9: TeacherSchedule 重复渲染优化
- 将移动端(lg:hidden)和桌面端(hidden lg:block)的双实例渲染改为单实例
- 使用 CSS flex order + grid col-start/row-start 实现响应式布局重排序
- 消除服务端 HTML 负载翻倍问题
P2-5: StudentTodayScheduleCard 时间过时修复
- 新增 useCurrentTime hook(src/shared/hooks/use-current-time.ts)
- 每分钟自动更新当前时间,useMemo 依赖 [items, now] 确保徽章不过时
- SSR 安全:初始渲染用 new Date(),挂载后 setInterval 更新
P2-1: 流式/Suspense 架构改造
- 新增 getAdminDashboardStreams(streams.ts):返回各独立数据源的未解析 Promise
- Admin dashboard:7 个分区组件用 React use() 独立消费 Promise,各 Suspense 边界独立流式渲染
- Teacher/Student/Parent dashboard:传入未解析 Promise,视图用 use() 消费,启用 Suspense 流式
- 页面外壳(标题 + 快捷操作)立即渲染,数据到达后各分区按各自速度填充
P2-7: 组件测试 + 路由测试修复
- 修复 dashboard-routing.test.ts:移除误导性的 permissions 字段(实际用 resolvePermissions(roles))
- 新增 fallback 路由测试(未知角色 → teacher dashboard)
- 新增 DashboardSection 组件测试(6 个测试:骨架屏变体 + 错误边界 + 正常渲染)
- 新增 useCurrentTime hook 测试(3 个测试:初始值 + 间隔更新 + 清理)
同步更新:
- docs/architecture/005_architecture_data.json 新增 7 个流式组件 + useCurrentTime hook + getAdminDashboardStreams 条目
2026-06-23 09:04:40 +08:00
SpecialX
e2e0487a3b
feat(attendance,elective): 实现所有 P2 长期改进项
...
P2 修复(来自审计报告):
- 2.4.4: Server Action 错误消息 i18n 化(attendance/elective 全部 Action)
- 2.5.3: 抽取 AttendancePageLayout 组件复用(admin/teacher 页面)
- 2.5.4: 抽取 ElectivePageLayout 组件复用(admin/teacher 列表页)
- 2.6.3: 考勤月历键盘导航(tabIndex + 方向键 + Home/End + role=grid)
- 2.8.2: getStudentAttendanceSummary 分页优化(SQL 聚合统计 + LIMIT 分页)
- 2.8.3: resolveCourseDisplayNames 缓存优化(React cache 去重)
- 2.1.4: elective data-access 跨模块依赖接口抽象(resolvers.ts 可注入)
P2 建议项:
- 选课时间冲突检测(parseSchedule + isScheduleConflict 纯函数 + checkScheduleConflict)
- 学分上限校验(MAX_CREDIT_PER_TERM + checkCreditLimit)
- 考勤/选课数据导出 Excel(export.ts + API 路由扩展)
新增文件:
- src/modules/attendance/components/attendance-page-layout.tsx
- src/modules/elective/components/elective-page-layout.tsx
- src/modules/elective/resolvers.ts
- src/modules/attendance/export.ts
- src/modules/elective/export.ts
校验:
- npm run lint 通过(exit 0)
- npx tsc --noEmit attendance/elective/parent 相关零错误
2026-06-23 09:02:41 +08:00
SpecialX
c766951374
feat(school,classes): 实现 P2 长期问题全量改进项
...
P2-2: 新增 OrgTreeNav 组件(学校→年级→班级三级树形导航,支持搜索过滤/选中高亮/展开折叠)
P2-3: 新增 promoteGradesAction 年级升级功能(中文数字/阿拉伯数字识别,按 order 降序避免冲突)
P2-4: 新增 bulkEnrollStudentsAction(CSV 批量导入学生)+ bulkAssignSubjectTeachersAction(CSV 批量分配教师)
P2-5: 为 department/academicYear/grade 的 9 个 CRUD Action 补充 logAudit 审计日志
同步更新架构图文档 004/005
2026-06-23 08:55:21 +08:00
SpecialX
4da9194a5e
feat(ai): V2 深度增强 — SSE 流式/全局助手/内容安全/多角色覆盖
...
对标 Khanmigo/Duolingo Max/Squirrel AI/Century Tech 实现:
- SSE 流式响应:createAiChatCompletionStream AsyncGenerator + /api/ai/chat/stream SSE 端点 + useAiChatStream hook(AbortController 停止生成 + localStorage 持久化)
- Markdown 渲染:AiMarkdownRenderer(react-markdown + remark-gfm + 代码块/表格/列表 + hover 复制按钮)
- 全局 AI 助手:AiAssistantWidget 浮动按钮 + Sheet 侧抽屉 + usePathname 路由推断上下文(7 类场景系统提示)+ dashboard layout 全局注入 AiClientProvider
- 内容安全:content-safety.ts 多层过滤(输入/输出安全过滤 + 每日限制 student 50/teacher 200/parent 30/admin 500 + 学生苏格拉底模式),COPPA/FERPA K12 合规
- 多角色 AI 覆盖:家长端 AiChildSummary(学情摘要)+ 管理员端 AiUsageDashboard(使用监控)+ 学生端 AiStudyPath(个性化学习路径)
- i18n 修复:8 处错误键引用 + zh-CN/en ai.json 全面扩展
- 架构文档 004/005 同步更新
2026-06-23 01:34:37 +08:00
SpecialX
a60105455e
feat(exams,homework,parent): V3 审计深度修复 — 批量批改/考试分析/提交反馈/家长视图/移动端优化
...
V3-5: exam-actions.tsx 集成 useExamHomeworkFeatures hook,按角色控制菜单项可见性
V3-7: 批量批改 — 新增 batchAutoGradeSubmissions data-access + Server Action + HomeworkBatchGradingView 组件
V3-8: 考试分析仪表盘 — 新增 getExamAnalytics stats-service + ExamAnalyticsDashboard 组件 + /teacher/exams/[id]/analytics 路由
V3-9: 提交后即时反馈页 — 新增 HomeworkSubmissionResult 组件 + /student/learning/assignments/[id]/result 路由
V3-11: 家长考试详情 — 新增 ChildExamDetail 组件 + getStudentExamResults data-access + child-detail-panel exams Tab
V3-12: 移动端触控优化 — 题目导航与考试操作按钮 44px 最小触控目标
修复: instrumentation.ts 适配器补全 questionCount/averageScore/overdueCount 字段
修复: exam-homework-port.ts 类型导入对齐 ExamWithQuestionsForHomework
修复: trend-line-chart.tsx 数据类型允许 undefined(classAverage 可选场景)
同步更新 004/005 架构文档
2026-06-23 01:06:27 +08:00
SpecialX
21c5eba96c
feat(ai): 新增 AI 模块并集成至备课/错题集/试卷/改题四大业务场景
...
- 新增 src/modules/ai 独立模块,遵循三层架构(actions → services → shared/lib/ai)
- 通过 AiClientProvider + useAiClient 实现 React Context 依赖注入,业务组件零直接 import
- 6 个 Server Actions 均调用 requirePermission() 权限校验,返回 ActionState<T>
- withAiTracking 统一埋点,覆盖 chat/similar_question/grading_assist/lesson_content/question_variant/weakness_analysis
- 集成场景:作业批改 AiGradingAssist、错题集 AiErrorBookAnalysis、备课 AiLessonContentGenerator、试卷 AiQuestionVariantGenerator
- 全量 i18n(en/zh-CN ai.json),Error Boundary + Skeleton 边界处理
- 同步架构图 004/005,新增审计报告 ai-module-audit-report.md
2026-06-23 00:52:39 +08:00
SpecialX
ec87cd9efa
fix(textbooks): 规范核查修复 — 安全漏洞+功能缺失+i18n+类型安全
...
安全:createPrerequisiteAction 补充 prerequisiteKpId 归属校验;deletePrerequisiteAction 补充双知识点归属校验,防止跨教材越权。
功能:实现图谱添加/删除前置依赖(Dialog + Select 选择知识点 + 调用 Server Action + 自动刷新图谱),替换原 no-op 回调。
i18n:修复 8 处硬编码英文字符串(textbook-reader/chapter-sidebar-list/textbook-card/textbook-form-dialog/textbook-settings-dialog/create-chapter-dialog/teacher-textbook-reader),新增 saveFailed/createFailed/updateFailed/deleteFailed/questionCreatorDefaultContent 等 key。
类型安全:graph-prerequisite-edge.tsx 使用 GraphEdgeData 类型经 unknown 安全转换,替代裸 as 断言。
规范:analytics.tsx 移动 use client 指令到文件第一行;同步架构文档 005 JSON 类型定义(GraphNodeData/GraphEdgeData/MasteryLevel)。
验证:教材模块 lint 零错误、tsc 零错误、193 个单元测试全部通过。
2026-06-23 00:30:14 +08:00
SpecialX
58656da983
feat(textbooks): 知识图谱功能全面重构 — 前置依赖 + dagre 布局 + React Flow 可视化 + 师生双视角
...
将教材模块图谱从基本无用状态升级为完整知识图谱可视化系统。
数据层:新增 knowledgePointPrerequisites 表(复合主键+双外键 cascade);新增 data-access-graph.ts(server-only)知识点关联聚合、学生/班级掌握度查询;utils.ts 新增 hasCycleAfterAddingEdge(DFS 循环依赖检测)。
业务层:3 个新 Server Action(getKnowledgeGraphDataAction 三视图模式、createPrerequisiteAction 含循环检测、deletePrerequisiteAction);graph-layout.ts 重写为 dagre 分层有向图布局。
视图层:knowledge-graph.tsx 重写为 React Flow 主组件(全书视图+搜索高亮+关联节点高亮+章节着色);4 个新组件(graph-kp-node/graph-prerequisite-edge/graph-toolbar/graph-node-detail-panel);use-graph-data.ts 派生值模式避免 effect 中 setState。
架构:严格三层架构,客户端通过 Server Action 间接访问 server-only 数据层;权限校验+ i18n 全覆盖;架构文档 004/005 同步。
测试:utils.test.ts 新增 5 个循环检测测试,graph-layout.test.ts 重写 5 个 dagre 布局测试,全部 30 个教材模块单元测试通过。
附带提交 drizzle/0005 error-book 迁移文件以保持 journal 一致性。
2026-06-23 00:13:03 +08:00
SpecialX
15aa84b72c
refactor(school,classes): 完成 school/grade/class 审计全量改进项
...
P0-1/P0-2: 删除 grade-management 死模块,年级 CRUD 统一由 school 模块负责
P0-3: classes/actions.ts 从 974 行拆分为 6 个职责文件 + barrel re-export
P0-5: 13 个页面 i18n 全量接入(grades/departments/academic-year/classes/insights)
P1-1: 角色硬编码改为 hasAdminScope/hasTeacherScope/hasStudentScope 基于 dataScope.type
P1-3: 新增 SchoolErrorBoundary + SchoolListSkeleton/SchoolCardSkeleton,4 个页面包裹 Error Boundary
P1-4: classes/types.ts 跨领域类型添加归属决策注释
P1-5: schools-view.tsx 拆分为组合模式(SchoolFormDialog + SchoolDeleteDialog + SchoolListToolbar)
P1-6: 新增 getSchoolsForUser/getGradesForUser 权限感知查询函数
P2-1: 抽取 useSchoolData hook,对话框状态管理与 UI 分离
同步更新架构图文档 004/005
2026-06-22 18:54:01 +08:00
SpecialX
97e59b95a1
refactor(lesson-preparation): V2 审计深度修复 — Server Actions i18n + 错误码模式 + 类型断言清零 + a11y 深度修复 + Tracker 埋点接入
...
V2-1: 12 个 Server Action 通过 getTranslations 翻译错误消息;Service/DataAccess 层抛出错误码异常(PublishServiceError/LessonPlanDataError),Actions 层通过 PUBLISH_ERROR_KEY_MAP 翻译为 i18n 消息
V2-2: SYSTEM_TEMPLATES name/title 改为 i18n 键,createLessonPlan 接受 translateTitle 函数在服务端翻译后存储到 DB
V2-3: 8 处 as unknown as 断言替换为显式类型映射函数(mapRowToLessonPlan/mapRowToListItem/mapRowToTemplate/mapRowToVersion)+ 类型守卫(isLessonPlanStatus/isTemplateType/isTemplateScope)
V2-4: MiniMap nodeColor 复用 lib/node-summary.ts 的 getNodeColor
V2-5: a11y 深度修复 — lesson-plan-filters/exercise-block/inline-question-editor 的 select 添加 label htmlFor 关联;exercise-block 题目列表改为 ul/li;node-editor 画布添加 role=application + 键盘导航配置
V2-6: Tracker 埋点接入 — 新增 useLessonPlanTrackerSafe hook,在 create/save/publish/revert/duplicate/archive 6 处调用 tracker.track
同步更新架构图 004 和 005 文档
2026-06-22 18:45:35 +08:00
SpecialX
1fe30984b6
refactor(announcements,messaging,notifications): V1+V2 审计重构 — i18n 命名空间独立 + 通知标题 i18n 化 + 服务端过滤 + 编排下沉 + 表单错误展示 + 架构图同步
...
V1 改进(已完成):
- P0-4/P1-4/P1-5: 通知组件和 CRUD Action 从 messaging 迁移至 notifications 模块
- P1-5: 新增 getMessagesPageData / getAdminAnnouncementsPageData 编排函数
- P1-6: announcements schema 添加 superRefine 条件校验
- P1-7: 新增 useMessageSearch hook(防抖 + 请求竞态取消)+ 客户端分页 UI
- P1-9: deleteMessage 事务化
- P2-11: 全模块 trackEvent 埋点
- 全模块 i18n 接入 + Error Boundary + a11y 改进
V2 改进(本次完成):
- V2-P0-1: 通知 i18n 命名空间独立(notifications.json),useTranslations 从 "messages" 切换到 "notifications"
- V2-P0-2: 公告/消息通知标题 i18n 化,Server Action 中使用 getTranslations 生成通知标题
- V2-P1-1: AnnouncementList 纯服务端过滤,移除客户端 useState/useMemo
- V2-P1-2: MessageList 客户端过滤仅在初始数据时执行,搜索结果由服务端按 tab 过滤
- V2-P1-3: 消息详情页编排下沉,新增 getMessageDetailPageData 编排函数
- V2-P1-4: 表单服务端校验错误展示(fieldErrors + aria-invalid)
- V2-P2-1: 轮询间隔常量化(POLL_INTERVAL_MS)
- V2-P2-2: 架构图同步(004 + 005)
2026-06-22 18:43:12 +08:00
SpecialX
6d7838a210
refactor(exams,homework,proctoring): 审计重构 — 跨模块解耦 + 权限 + i18n + a11y + 单测 + 监控埋点
...
完成考试与作业模块深度审计的全部 10 项改进:
P0-3: 拆分 ai-pipeline.ts (927 行) 为 parse/request/structure/index 四个职责模块
P1-6: 抽取 QuestionRenderer 组件 (mode prop 驱动 take/preview/grade 三态)
P1-7: 抽取 question-content-utils 纯函数模块 (14 个纯函数 + applyAutoGrades 泛型)
P1-8: 拆分 homework data-access 为 data-access.ts + data-access-classes.ts
P2-9: 集成 useDebouncedAutoSave (防抖自动保存 + localStorage 离线缓存 + 状态指示器)
P2-12: a11y 修复 (难度色条 role=img + aria-label, 题目导航 aria-pressed + title)
P2-13: ExamHomeworkRoleConfig 配置驱动角色渲染 (6 角色 × 11 功能 + 并集合并)
6.1: ExamHomeworkServicePort 接口 + ServiceProvider 单例注册表
6.5: 63 个单测 (52 question-content-utils + 11 role-config)
6.7: trackExamEvent 监控埋点 (17 个新事件 + 便捷函数)
同步更新 005 架构数据文档与 v2 审计报告
2026-06-22 18:37:00 +08:00
SpecialX
682d385ee2
fix(dashboard): v3 审计修复 — 数据完整性、i18n、类型安全、死代码清理
...
P0 修复(严重):
- admin ContentRow 标签与值错配(stats.users→textbooks 等 6 处)
- admin/error.tsx 硬编码中文替换为 useTranslations
- UserGrowthChart 空数据时渲染 EmptyState(userGrowth/homeworkTrend 永远为空数组)
P1 修复(高):
- 新增 admin/dashboard 和 student/dashboard 的 loading.tsx + error.tsx
- 抽取 DashboardLoadingSkeleton 和 DashboardErrorFallback 共享组件,消除 5 套重复文件
- formatDate/formatLongDate 传入用户 locale(admin/teacher/student 共 6 个组件)
- 移除死代码:getCachedAdminDashboard、AvatarImage src={undefined}、TeacherStats isLoading prop
- filterTodaySchedule 改为泛型函数,消除 as 类型断言
- 辅助函数 getStatus/getDueUrgency 新增显式返回类型
- UserGrowthChart 新增 labelKey prop 区分用户增长/作业提交趋势标签
P2 修复(中):
- 4 个组件从客户端转为服务端组件(DashboardGreetingHeader、TeacherQuickActions、TeacherDashboardHeader、StudentDashboardHeader)
- Student dashboard 空状态新增 CTA(viewSchedule、viewAll)
- TeacherHomeworkCard 图标按钮新增 aria-label
- TeacherTodoCard 排序逻辑重写为可读的 if/return 模式
同步更新:
- docs/architecture/005_architecture_data.json 新增 DashboardLoadingSkeleton、DashboardErrorFallback 条目
- 新增 docs/architecture/audit/dashboard-audit-report-v3.md 审计报告
- dashboard.json 新增 6 个 i18n 键(textbooks/chapters/questions/exams/totalAssignments/totalSubmissions)
2026-06-22 18:36:46 +08:00
SpecialX
f62b8c0f86
refactor(attendance,elective): 审计第二轮 — 全量完成 P0/P1 改进项
...
P0 修复:
- 页面层 i18n 全量补齐(admin/teacher/parent/student × attendance/elective)
- types.ts 状态标签常量迁移至 constants.ts(i18n key + Badge variant)
- 修复 getTranslations 导入路径(next-intl → next-intl/server)
P1 改进:
- 解耦 parent 模块对 attendance 类型的直接依赖(本地 view-model 类型)
- 导出纯函数(computeStats/buildWarnings/buildLotteryRankCase 等)
- 统一空状态为 EmptyState 组件
- 清理死代码读 Action(attendance 5 个 + elective 3 个)
- 预留监控埋点接口(trackEvent 13 个新事件名)
- 补齐骨架屏 loading.tsx(8 个页面)
- AlertDialog 替换 window.confirm(student-selection-view)
- a11y 改进(aria-label/role/键盘导航)
修复:
- AttendanceStatus 从 constants.ts 重导出,消除 types/constants 双源混乱
- buildWarnings 的 Translator 类型改用 ReturnType<typeof useTranslations>
2026-06-22 17:33:29 +08:00
SpecialX
5f3a1a4662
refactor(grades,diagnostic): 完成成绩和学情诊断模块审计 P1+P2 改进项
...
P1-1: 抽取 stats-service.ts,将 8 个统计计算纯函数从 data-access 层分离
P1-5: 创建 WidgetBoundary 组件 + 补齐 teacher 路由 loading.tsx/error.tsx (14 文件)
P1-6: 同步架构图文档 004/005,新增 stats-service 与 widget-boundary 节点
P2-1: 补充 a11y ARIA 属性(5 图表 role=img + aria-label,2 表格 caption,3 列表 role=list,3 按钮 aria-label)
P2-3: 修复班级报告 studentId 字段语义错误(schema 改为可空 + 迁移 + 代码适配)
P2-4: 修复 grade_managed scope 返回空数据(改为子查询 classes 表按 gradeId 过滤)
P2-5: 新增 /parent/diagnostic/ 页面(多子女学情诊断聚合 + loading + error)
P2-6: 统一 SearchParams 工具(student/grades 和 management/grade/insights 改用 @/shared/lib/search-params)
2026-06-22 17:07:32 +08:00
SpecialX
e997abaf5e
refactor(dashboard): V2 审计重构 — i18n 补齐 + 共享抽象 + 单测 + a11y
...
V2 审计报告(docs/architecture/audit/dashboard-audit-report-v2.md)发现并修复:
- P0 i18n:10 个子组件硬编码字符串全部接入 next-intl(teacher-quick-actions /
teacher-classes-card / teacher-homework-card / teacher-schedule /
recent-submissions / teacher-grade-trends / student-grades-card /
student-today-schedule-card / student-upcoming-assignments-card /
admin-dashboard),新增 ~50 个翻译键
- P1 共享抽象:新增 DashboardGreetingHeader 组件,消除 teacher/student
头部 90% 重复代码,两个 Header 改为薄包装
- P2 单测:为 6 个纯函数添加 31 个单元测试
(tests/integration/dashboard/dashboard-utils.test.ts)
- P2 a11y:admin 表格 caption、teacher/student 视图语义化标签
(header / section aria-label / aside aria-label)
- 同步架构图 004/005
2026-06-22 17:01:00 +08:00
SpecialX
10c668f36a
feat(school,classes): 学校/年级/班级模块审计修复 — 权限校验 + i18n + 架构图同步
...
- 新增审计报告 docs/architecture/audit/school-grade-class-audit-report.md
- 修复 P0-4: teacher/classes 4 个页面补充 requirePermission 权限校验
- 修复 P0-5: 新增 school.json i18n 文件(zh-CN/en)并接入 schools-view 组件
- 同步架构图 004:补充 grade-management 死模块记录与 teacher/classes 权限修复说明
2026-06-22 16:44:02 +08:00
SpecialX
22d3f07fcf
feat(textbooks): 教材模块审计重构 — 跨模块解耦 + 权限 + i18n + 错误边界 + 纯函数抽取
...
P0 修复:
- 解耦跨模块 UI 依赖:knowledge-point-dialogs 不再直接 import questions,
改为 renderQuestionCreator render prop 由页面注入
- 接入 usePermission Hook 替换 canEdit 硬编码
- 全模块 i18n 改造:新增 en/zh-CN 翻译文件,替换所有硬编码文案
- Server Action 资源归属校验:新增 verifyChapterBelongsToTextbook/
verifyKnowledgePointBelongsToTextbook,在 reorder/update/delete/create 中校验
P1 改进:
- 补齐 Error Boundary:4 个 error.tsx + TextbookSectionErrorBoundary 区块包裹
- 抽取纯函数到 utils.ts/graph-layout.ts/constants.ts 并补单测(26 用例全通过)
- 消除重复组件:删除 knowledge-point-panel/create-knowledge-point-dialog
- 修复类型断言:chapter.children! → 守卫式访问
- 图谱 a11y:添加 role/aria-label/aria-pressed
- 统一删除确认:confirm() → AlertDialog
- 数据范围过滤:getTextbooksWithScope 支持学生端按年级过滤
P2 预留:
- TextbookAnalytics 埋点接口 + Provider + Hook
同步 005 架构数据 JSON:补充 getTextbooksWithScope/verify*/ChapterTreeNode 等
2026-06-22 16:25:59 +08:00
SpecialX
45ee1ae43c
refactor(grades,diagnostic): 成绩和学情诊断模块审计修复
...
P0-1: 10 个页面补充 requirePermission 权限校验
P0-2: diagnostic/data-access-reports.ts 移除直查 users 表,改用 getUserNamesByIds
P0-3: 新增 grade/grades/diagnostic 三组 i18n 翻译文件(zh-CN/en)
P0-4: 新增 /management/grade 重定向页面
P1-2: 抽取 toNumber/normalize/buildScopeClassFilter 到 lib/grade-utils.ts
P1-3: 为 12 个 Action 新增 Zod safeParse 校验(schema.ts +12 查询 schema)
P1-4: 修复 as 断言违规,改用类型守卫函数
P2-2: 移除 diagnostic 组件中 Tailwind 任意值
同步更新架构图文档 004 和 005
2026-06-22 16:23:34 +08:00
SpecialX
20691f53ce
feat(lesson-preparation): 备课模块审计重构 — 跨模块解耦 + i18n + 纯函数抽取 + 错误边界
...
P0-1 跨模块直查修复:publish-service 不再直查 examQuestions 表,新增 exams/data-access.addExamQuestions 接口,复用 classes/data-access.getStudentIdsByClassIds
P0-2 i18n 接入:新增 zh-CN/en 翻译文件,注册 lessonPreparation 命名空间,17 个组件改造为 useTranslations/getTranslations
P1 纯函数抽取:lib/document-migration.ts(类型守卫替代 as 断言)、lib/node-summary.ts(翻译函数注入)、lib/rf-mappers.ts
P1 错误边界+骨架屏:新增 LessonPlanErrorBoundary 和 4 个 Skeleton 组件
P1 Block 注册表:新增 config/block-registry.tsx(BlockRenderer 组件),node-edit-panel 重构为配置驱动渲染
P1 其他修复:exercise-block 改用 router.refresh(),node-editor/lesson-node 复用 lib/ 纯函数
架构图同步:更新 004 和 005 文档
Refs: docs/architecture/audit/lesson-preparation-audit-report.md
2026-06-22 16:17:58 +08:00
SpecialX
4833930834
feat(attendance,elective): 考勤与选修课模块审计重构 — P0 修复 + i18n + Error Boundary
...
审计报告:docs/architecture/audit/attendance-elective-audit-report.md
P0 修复:
- attendance: getAttendanceStats 统计失真(仅基于前 20 条记录)改为 SQL 聚合查询
- attendance: getClassStudentsForAttendance 跨模块直查 classEnrollments 改为调用 classes data-access
- attendance: update/delete Action 新增资源归属校验(assertRecordOwnership)
- elective: update/delete/openSelection/closeSelection/runLottery Action 新增资源归属校验(assertCourseOwnership)
i18n 接入:
- 新增 attendance/elective 命名空间(zh-CN + en)
- attendance-stats-cards 接入 useTranslations
- elective-course-list/form 接入 useTranslations
类型安全(P1):
- elective-course-form: 移除 as 断言,改用类型守卫 isSelectionMode
- elective-course-list: 移除 null as never 类型逃逸,改用泛型
Error Boundary:
- 新增 admin/teacher attendance error.tsx
- 新增 admin/student elective error.tsx
架构图同步:
- 004: 修正 attendance/elective/parent 章节的导出函数、文件清单、已知问题
- 005: 修正 actions 的 usedBy(标记无调用方的死代码)、新增 issues 字段、更新依赖矩阵
2026-06-22 16:17:00 +08:00