fix: improve import, evidence indexing and material-scoped grading
Preserve document revisions and evidence, harden indexing and export behavior, add explicit material selection and direct-folder import, validate model JSON schemas with safe error messages, and retain student selection while loading scoring data.
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
# 资料选择与评分批次改进
|
||||
|
||||
日期:2026-10-13。
|
||||
|
||||
原页面只能选择课程版本与评分规则,创建批次时包含该课程版本下全部项目,列表没有显示学生身份。多份资料共用规则 v1 时,用户无法确定正在评哪一份。导入完成后也缺少查找已导入文件和进入评分页面的入口。
|
||||
|
||||
## 当前行为
|
||||
|
||||
- 创建区域顺序为课程、课程版本、评分规则、选择资料、创建批次。资料按学生项目分组,可选一份资料包或多份,不选择时不能创建。
|
||||
- 选择后显示具体文件名、材料类型、所属学生和解析状态。最终报告与三份阶段报告、汇报材料仍按原有类型评价,不把单份最终报告冒充完整五类材料。
|
||||
- 创建接口新增可选 `project_ids`,显式选择必须非空,拒绝重复、不存在和跨课程版本的项目。选定名单写入既有批次快照字段,无需迁移。
|
||||
- 未传 `project_ids` 的旧接口调用保留原有全部项目行为。网页始终显式传入用户选择的名单。
|
||||
- 批次列表显示姓名、学号、项目数量、实际课程/规则版本及已处理项数。历史批次范围保持不变,不自动加入后来导入的项目。
|
||||
- 评分详情只提供该批次中的学生项目,切换时清除旧结果,取消过期请求的显示,避免把不同资料的结果混在一起。
|
||||
- 导入成功后提供“查看已导入资料”和“去评分”。去评分链接带上导入时的课程版本与项目名单,仍由用户选择评分规则并创建批次。
|
||||
- 导航中的“学生资料”用于查看已导入的个人材料。
|
||||
|
||||
## 验证与部署
|
||||
|
||||
- 后端批次选择与既有可靠性回归:55 passed,使用项目隔离 SQLite 验证业务状态;不是完整 PostgreSQL 测试套件验收。
|
||||
- 浏览器测试:9 passed,覆盖单独选择、课程切换重置、批次范围、具体文件显示、导入后转入评分和既有会话行为。这组测试使用受控接口响应,不产生实际导入或模型费用。
|
||||
- TypeScript 与 Vite 构建通过。
|
||||
- 本机 Docker 实例 `wisegrade-preview` 的 API 与网页重新构建并健康启动,数据库、Redis 和 worker 保留。
|
||||
- 真实后端浏览器检查通过:规则后同一行显示选择资料;所选模拟资料显示5个PDF文件;旧批次名单保持;单项目批次排除后来导入的学生;切换学生后不再显示之前的结果。没有接口模拟、页面异常或写入请求。
|
||||
- 本次没有创建真实新批次、重跑评分、修改教师分数、清理原数据或推送源码。
|
||||
|
||||
真实浏览器记录位于工作区隔离测试目录 `docker-preview/batch-selection-live.json`。页面截图与工具日志保留在同一目录,个人数据不纳入仓库。
|
||||
@@ -1,5 +1,7 @@
|
||||
# WiseGrade(智评)项目指南
|
||||
|
||||
当前源码的索引版本为 5、证据政策为 2,最新迁移为 `0009`。解析与评分改进见 [第一轮优化说明](OPTIMIZATION_2026-10-12.md),历史文档修订与失败恢复见 [第二轮优化说明](OPTIMIZATION_2026-10-13.md),实际 PDF 流程发现的目录权限问题及最新升级边界见 [PDF 实流程说明](PDF_TEST_2026-10-13.md)。旧部署记录不表示本轮改动已在正式环境应用。
|
||||
|
||||
本指南统一维护部署、教师使用、技术设计和开发说明;项目简介和快速启动见 [README](../README.md)。整理日期:2026-09-30;会话实现说明沿用 2026-09-27 的记录。
|
||||
|
||||
部署与会话章节描述已有实现;“业务规则与技术设计”保留原始设计基线,其中标为初稿、建议或验收目标的内容不代表已全部实现。当前实现与验证边界见 [交接记录](../HANDOFF.md),具体接口以代码和运行中的 `/docs` 为准。开发任务提示词集中在 [prompts](prompts/README.md),不作为功能完成证明。
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# 2026-10-14 目录扫描与模型故障修复
|
||||
|
||||
## 原因与修复
|
||||
|
||||
- 直接扫描 `test/示例` 原来返回 `projects: []`,因为扫描器只遍历子文件夹。现在支持所选目录直接存放资料,并继续支持下一级学生资料目录;空目录不再生成空项目。
|
||||
- 未按“学号_姓名_选题”命名的资料目录原来只返回 `detected_identity`,确认表仍为空。现在用无冲突的封面信息预填空字段;不同封面信息冲突会提示人工确认,不覆盖目录名中已有的信息。
|
||||
- 旧批次 5 的模拟样例有 14 个 `ConnectError`。本次容器内使用已保存配置访问模型列表接口返回 HTTP 200;相同配置的批次 6 后续完成全部 22 项评分。旧连接故障目前未重现,不能据此断言历史故障具体来自 DNS、代理或服务商。
|
||||
- 批次 6 的事实抽取仍报 `ValidationError`。原调用仅要求严格 JSON,没有传递事实/一致性结果所需的字段类型。现在所有 JSON 调用明确包含对应 Pydantic JSON Schema,不放宽评分、引文或证据来源校验。
|
||||
- 网络、超时、HTTP 认证/限流/服务异常提供可操作的提示,仍不输出响应正文、凭据、请求 URL 或原始异常文本。评分页面直接显示每项错误和批次重试入口说明;空扫描显示提示并禁用确认导入。
|
||||
- 最后实际浏览器复查还复现了多项目批次链接加载时丢失学生选择的问题:批次列表先返回、项目列表未返回时,页面误以为所选学生不在批次中。评分页现在等两个列表都加载完才判断项目范围;新增延迟项目列表的回归测试,修复前失败,修复后通过。
|
||||
- 示例 PPT 有 4 页文字层不足 30 字,触发 OCR;此前缺少离线模型导致整个 PPT 解析失败。依照 [PaddleOCR 检测文档](https://www.paddleocr.ai/main/en/version3.x/module_usage/text_detection.html)和[识别文档](https://www.paddleocr.ai/main/en/version3.x/module_usage/text_recognition.html),在本项目 `models/ocr/detection` 与 `models/ocr/recognition` 安装 PP-OCRv5 mobile 推理模型(约 21.75 MB),使用容器已有 PaddleOCR 3.7.0 / PaddlePaddle 3.3.1,未改变系统 Python 或驱动。下载链接和本地 SHA256 记录在运行证据 `ocr-setup/manifest.json`。真实首页 OCR 返回非空文字。
|
||||
|
||||
## 验证
|
||||
|
||||
- 新的导入和模型错误测试在修复前 8 项失败,修复后连同优化和批次测试共 63 项通过。
|
||||
- 网页 Playwright 最终测试 12 项通过,TypeScript/Vite 构建通过。
|
||||
- 实际 Docker 网页(无接口模拟)验证直接扫描 `test/示例`、预填身份、展示 5 份 PDF、显示 14 项历史连接错误以及新项目资料详情,无页面异常。
|
||||
- 使用真实扫描结果确认导入“李傲琦 / 1023009006 / 基于ROS2 系统的自瞄移动机器人”,项目 ID 6,初始索引任务 7–11;补齐 OCR 模型后保留失败任务 7,并生成重试任务 12。原 PDF 和历史批次保留。
|
||||
- 新镜像部署 API、网页和 worker;worker 在批次 6 原任务结束且无活动任务后更新。重试批次 6 仅补做事实抽取/一致性检查,已有 22 项评分跳过模型调用。
|
||||
- 批次 6 真实重试结束为 `completed`,22/22 个评分项为 `scored`,事实结果不再含 `error`。93.55 为明确标注模拟数据的测试样例分数,不是李傲琦或胡旭阳的实际成绩。
|
||||
- 最终项目 6 的 5/5 份资料为 `ready`、解析错误为空,5 个知识库文档均可检索;任务 8、9、10、11、12 全部完成。任务 7 保留首次缺 OCR 模型的历史失败,不影响重试后的资料状态。验收脚本验证了 PPT 首页 OCR 与可见标题一致、原 5 份 PDF 哈希完全一致及批次 6 的完整成功状态。
|
||||
|
||||
## 材料范围提醒
|
||||
|
||||
`test/示例/汇报PPT.pdf` 首页实际显示“课程导学/自动化专业综合实践”。应在评分前确认它是否属于学生汇报稿,而不是课程说明。本次只导入和索引该示例资料包,未创建或启动它的新评分批次。
|
||||
|
||||
运行证据保存在工作区 `.wisegrade-testing/docker-preview/`,包括 `import-model-live.json`、`import-test-sample-2026-10-14.json`、浏览器截图和构建/部署日志。实际入库与批次重试的最终状态见该目录 `import-model-final-2026-10-14.json`。
|
||||
@@ -0,0 +1,46 @@
|
||||
# 2026-10-12 解析与评分可靠性优化
|
||||
|
||||
后续记录:第二轮新增迁移 `0008`,同源重建改为创建独立文档修订,保留旧页面和片段;最新验证及升级说明见 [2026-10-13 优化说明](OPTIMIZATION_2026-10-13.md)。本文件保留第一轮的结果和验证范围。
|
||||
|
||||
本轮基于 `29c95ce` 的失败用例修复源码。用户提供的 PDF、处理资产和详细日志保留在仓库外的隔离测试目录,不提交到 Git。未连接或修改正式业务环境。
|
||||
|
||||
## 行为变化
|
||||
|
||||
- 摘要标题可位于页首报告标题之后;摘要与目录不参与内容评分。
|
||||
- 切块按实际小节拆分并沿用跨页章节路径,避免同页所有内容被标为最后一个小节。混合页正文块具有独立来源类型,评分和引用不再用整页目录标签覆盖它。
|
||||
- PDF 解析补充限定区域的三线表识别,保留原页文字、图像、边框位置及推断告警。推断列边界仍可能切分表头或跨列文本,教师应核对原页,不能把检测到表格等同于全部单元格准确。
|
||||
- 封面标签支持中文字符之间的空白。无法识别材料类型时仍要求教师确认。
|
||||
- 原始未解析字符保持不变,页面记录质量告警,包含异常字符的正文片段被标为 `unknown` 并排除出自动内容检索;引文校验也拒绝未解析字符。项目材料详情显示文字和表格解析提醒。没有猜测符号或用低分替代质量问题。
|
||||
- 规则接口支持对象式证据目标,校验目标标识、用途和页面权限,目标标识随规则持久保存。旧字符串形式继续可读。
|
||||
- 内容正分必须有合法内容引文,未知目标被拒绝。同一片段可关联多个目标;选取候选时先保留目标覆盖,再填充剩余预算。
|
||||
- 文档范围、文档就绪状态、索引版本和旧片段过滤在候选上限之前执行;指定课程公共文档也使用正确范围。ASCII 关键词按完整词匹配,重复词不额外增加关键词分。
|
||||
- 评分项返回 `null` 时记录原始不足原因;最后一个评分项复核后重新计算批次状态。教师在模型请求期间完成的复核优先保留,PDF 和 Excel 保留合法 `0` 分。
|
||||
- 索引与评分共用 `submissions.py`,从评分模块移出解析与文件锁。索引重建修复错误导入,复用已保存解析结果并覆盖已保存的课程页面;还有待处理文档时不会标为完成。
|
||||
- 文件内容变化时旧文档被标为 `superseded`,保留历史页面和引用。新解析图像使用文件内容哈希目录,避免覆盖旧引用图像。已退休索引不参与检索和待重建统计。
|
||||
- 会话引用优先使用精确片段链接,普通页号不会关联另一份文档的同页。会话显示来源类型、结构用途及历史引用标签。
|
||||
- 结果查询合并逐评分项的证据查询并预取来源页面;会话界面按需加载。修复构建依赖 `source-map-js` 已知告警,依赖锁文件只更新该包至 1.2.2。
|
||||
|
||||
## 索引与升级
|
||||
|
||||
迁移 `0007` 仅对新文档的索引版本默认值设为 `4`;现有文档不会被自动宣称已重建。当前分类器版本为 `4`,证据政策版本为 `2`。
|
||||
|
||||
升级前应备份数据库及处理资产,在专用 PostgreSQL/pgvector 环境演练迁移和重建,等待旧评分/索引任务排空后再更新服务。旧政策批次的结果和复核保持可读;带旧政策快照的批次不继续按新政策重试,应创建新批次。
|
||||
|
||||
迁移后,通过 `/api/knowledge/stale/{course_version_id}` 查看待重建文档,再调用 `/api/knowledge/reindex/{course_version_id}` 并跟踪任务结果。源文件变化或缺少规范页面时会明确报告剩余项。重建优先复用缓存,旧缓存不会自动补出新的三线表结构;本轮三线表改进在新解析材料上验证。
|
||||
|
||||
本轮没有执行正式迁移、重建或部署。SQLite 新库升级、默认值降级及再次升级的测试不等于 PostgreSQL 数据恢复演练;`0007` 降级也不会恢复旧切块内容。
|
||||
|
||||
## 验证范围
|
||||
|
||||
新增 `backend/tests/test_optimization.py` 覆盖解析政策、规则接口至批次快照、混合页检索至证据校验、文档范围/版本过滤、复核状态、零分导出、历史引用保留、缓存重建、迁移默认值及文件锁。数据库测试使用隔离 SQLite、确定性嵌入和模型替身,明确不代替 PostgreSQL/pgvector 或真实模型验证。
|
||||
|
||||
另实际执行本机可运行的原有测试、前端 TypeScript/生产构建和 Chromium 浏览器测试。用户提供的 17 页 PDF 完整解析、渲染并核对:摘要分类、封面字段、小节标签、三张结果表及原页定位已复验;19 个原始异常字符仍保留并受到质量政策约束。没有生成真实模型成绩。
|
||||
|
||||
详细命令、数量、构建大小、失败修复过程和 PDF 前后对比见本地隔离测试目录中的最新优化报告。真实 PostgreSQL、Redis/RQ 故障恢复、真实 BGE-M3/OCR/评分模型、LibreOffice 与实际 PDF 导出仍需在目标容器环境验证。前端仍有主包体积警告,按需加载改善入口拆分,不代表默认会话页总下载量或响应时间已经下降。
|
||||
|
||||
## 本地验证记录(2026-10-13 核对)
|
||||
|
||||
- 后端:35 项新增回归用例与 19 项可在本机执行的原有用例合计 `53 passed, 1 skipped`;跳过项需要 LibreOffice。原有完整数据库套件没有执行,Windows 符号链接权限相关用例未纳入本轮通过数量。
|
||||
- 真实 PDF:重新运行当前源码解析与检查,`18 passed`。相比基线,摘要从正文中分离,封面字段可提取,表格从 1 张增至 4 张(封面表加 3 张结果表),切块从 41 个变为 56 个。源文件 SHA256 与 17 张渲染页图保持一致。异常字符检查验收的是保留、告警和排除受损证据,不能解读为 19 个异常字符已修复。
|
||||
- 前端:TypeScript 和生产构建通过;使用模拟接口的 Chromium 测试 `3 passed`,手机截图在禁用动画后核对。依赖审计本轮记录为 0 项漏洞。
|
||||
- 两台已配置远端的 SSH 连接在建立阶段被关闭,没有新增远端数据库、模型或部署验证。源码修改仍为本地未提交状态;详细日志和含个人信息的测试材料在仓库外保存。
|
||||
@@ -0,0 +1,31 @@
|
||||
# 2026-10-13 历史引用保护与索引失败恢复
|
||||
|
||||
后续记录:本日实际 PDF 入库与检索发现并修复无点线目录条目的权限问题。最新索引版本为 5,迁移为 `0009`;见 [PDF 实流程说明](PDF_TEST_2026-10-13.md)。本文件保留第二轮的结果和验证范围。
|
||||
|
||||
同一文件重建索引时,原实现会删除旧片段并覆盖规范页面,历史会话中的片段 ID 可能失效;将文件恢复为过去的内容时还会复用并改写旧文档。第二轮将重建、材料类别变化和恢复旧内容都处理为新文档修订,历史来源仅标记为 superseded,保留原页、片段与成绩引用。无需重建的当前索引仍直接复用。
|
||||
|
||||
## 行为与性能变化
|
||||
|
||||
- 新迁移 `0008` 增加 `knowledge_documents.revision`,替换原有同源唯一约束,允许同一文件哈希保留多份历史修订。现有记录以修订 1 保留,页面与片段 ID 不变。重建结果包含原 document_id 与 replacement_document_id,便于审计。修订号用于区分同源索引,不替代源文件 SHA256 或索引算法版本。
|
||||
- 公共资料重建与课程入库使用同一个课程文件锁,取得锁后重新读取文档状态。重叠任务不会再次重建已被替代的旧快照。本机双线程测试覆盖这一情形,不能代替跨主机或 PostgreSQL 任务并发验收。
|
||||
- 索引任务在数据库写入失败后先回滚,再重新读取任务并保存失败状态及已得到的结果。课程资料逐份入库也在失败后回滚,后续资料与结构化课程资料仍能继续处理。
|
||||
- 成绩结果和历史会话在读取时根据文档退休状态显示历史引用标记。保存的成绩引文、消息内容、引用 URL 和 JSON 不改写。会话按文档集合批量查询退休状态,成绩沿用已有批量预取。
|
||||
- 知识库列表批量统计片段数;26 份文档的回归场景从 27 次查询降至 2 次。当前版本但状态失败的文档也明确需要重建;已退休文档不作为待重建项。
|
||||
|
||||
## 验证记录
|
||||
|
||||
本轮新增 9 项回归,优化回归累计 44 项;与上轮选择的 19 项本机可执行原有用例合计 `62 passed, 1 skipped`。LibreOffice 用例继续跳过,Windows 符号链接权限用例不纳入通过数量。完整 PostgreSQL 测试套件没有运行。
|
||||
|
||||
新增检查覆盖:原页面和片段保留、恢复旧哈希及材料类别变化、数据库事务失败的任务状态、课程部分写入失败、成绩和会话的历史标签、已有记录的迁移与有损降级拦截、失败重建后重试、双任务公共资料重建、知识库列表查询数量及失败索引提示。原有数据库套件的重建用例已调整为新语义,仍需在专用 PostgreSQL 环境执行。
|
||||
|
||||
用户提供的真实 17 页 PDF 重新解析后的 `18 passed`,原件 SHA256 与 17 张渲染页图保持一致。保留此前的 19 个异常字符告警与受损证据过滤,没有生成真实模型成绩。
|
||||
|
||||
迁移测试包含新库完整升级、无历史修订时降级及再升级,也包含手工构造的 0007 同源唯一约束和已有文档/页面,再升级至 0008。创建同源修订后尝试降级会在结构修改前停止,两份文档和原页面均保留。这些测试使用 SQLite,未执行生产 PostgreSQL 迁移。
|
||||
|
||||
## 升级与验证边界
|
||||
|
||||
当前索引算法版本仍为 4,证据政策仍为 2,Alembic 最新迁移为 0008。更新服务前,应备份数据库和处理资产、排空旧任务,并在独立 PostgreSQL/pgvector 数据库演练 `alembic upgrade head`。不要将未升级的数据库直接交给包含 revision 字段的新服务。
|
||||
|
||||
0008 降级在存在同源历史修订时主动拒绝,不能通过删除历史来源绕过;需要完整回退时恢复升级前数据库及相匹配的处理资产备份。仅修改索引默认值或降级算法版本不会恢复此前已被删除的历史片段;本轮只能保护仍然存在及以后生成的来源。
|
||||
|
||||
保留历史修订会增加存储量,本轮不自动清理。真实 PostgreSQL/pgvector、Redis/RQ 重试与跨主机锁、真实嵌入和评分模型、实际 PDF 导出仍待目标环境验收。源代码修改仍为本地未提交状态,没有正式迁移、部署或推送。个人 PDF 和详细日志位于仓库外 `.wisegrade-testing/round2`,不提交到 Git。
|
||||
@@ -0,0 +1,26 @@
|
||||
# 2026-10-13 实际 PDF 入库、检索与引用验证
|
||||
|
||||
本轮使用用户提供的 17 页工程报告,执行实际扫描 API、诊断类型确认、索引 worker、规范页面接口、关键词检索、引用定位、重复导入、缓存重建及未评分结果导出。材料、原文、个人信息、页图和详细日志均位于仓库外隔离目录,不上传到 Git。
|
||||
|
||||
## 实测发现与修复
|
||||
|
||||
此前 18 项 PDF 检查关注页级分类、封面、表格、小节及证据定位,未检查目录页的每个片段。扩展测试发现:纯目录页的四条一级标题没有点线,标题至页码之间留有大量空格;程序把它们标为正文,并错误地将页面判为混合页。这些条目不仅能进入纯关键词召回,也能被确定性评分校验接受为内容正分的引文。测试没有调用模型或将测试分数写成真实成绩。
|
||||
|
||||
修复仅在已识别的目录上下文中识别对齐页码的无点线条目,进入实际正文后关闭这一识别,避免把普通数字内容作为目录。增加 4 项匿名回归,涵盖两空格、大量空格、Tab 对齐,以及目录和真实正文同页的边界。分类器和索引算法版本同步升至 5;旧索引需要重建。
|
||||
|
||||
一处实流程测试最初要求清洗后的片段逐字出现在保留版式换行的整页文本中。已按现有引文契约改为验证可定位的原文连续片段,保留空白归一化规则;该测试断言修正与目录权限修复分别记录。
|
||||
|
||||
## 结果
|
||||
|
||||
- 实际材料专项:`38 passed`,包括 18 项解析与证据检查,以及 20 项实际数据的导入、索引、检索与接口检查。
|
||||
- 后端回归:`66 passed, 1 skipped`。优化回归累计 48 项,另运行 19 项可在本机执行的原有用例;LibreOffice 项跳过,符号链接权限用例不纳入通过数量。
|
||||
- 原件及全部 17 张页图哈希与基线一致。封面、摘要、目录和 14 页正文均识别;保留封面表及三张结果表。纯目录页不再包含内容片段,切块数由错误混合分类时的 56 个变为 48 个。
|
||||
- 三个检索样例分别定位到报告中的主控方案、实验数据及异常恢复记录。数据库为带真实外键的隔离 SQLite,使用固定测试向量;这些检查不能证明 BGE-M3 的语义检索质量。
|
||||
- 19 个异常字符仍保留并告警,受损片段不进入内容检索;三线表列边界仍为推断结果,需要核对原页。
|
||||
- 未执行真实模型评分,结果和 Excel 中未生成的分数保持空白,状态明确为未完成。材料类型 final_report 和课程 1 仅用于诊断,不是经过教师确认的真实课程映射。
|
||||
|
||||
## 升级边界
|
||||
|
||||
最新迁移 `0009` 仅将新文档索引默认值改为 5,不会自动重写现有索引。更新前备份数据库与处理资产、排空旧任务,在专用 PostgreSQL/pgvector 数据库演练 `alembic upgrade head`,再通过现有 stale/reindex 接口重建。重建继续创建新文档修订,保留历史页图和片段 ID。
|
||||
|
||||
证据政策版本仍为 2。真实 PostgreSQL/pgvector、Redis/RQ、BGE-M3、OCR 和真实评分模型尚未验收;本轮未执行正式迁移、部署、提交或推送。
|
||||
Reference in New Issue
Block a user