Skip to content

Latest commit

 

History

History
201 lines (144 loc) · 14.7 KB

File metadata and controls

201 lines (144 loc) · 14.7 KB

Progress Log

2026-07-25 - Task: 重构文件上传逻辑(修「点开始分析一直转圈」)

What was done

  • 定位线上故障根因:单序列页点「开始分析」时会先逐个串行上传文件,该循环无超时、无进度、无错误暴露,任一请求挂住就永久转圈,/api/analyze 根本没发出(服务器端两个会话只落地部分文件、且没有任何分析日志,可佐证)。
  • 重写 uploadFiles:客户端先按后端同样的 base_i.ext 约定给重名文件去重(消除并发下后端 file.exists 去重的竞态)、首个文件串行上传以建立会话、其余按并发 4 上传、按下标回填保证返回顺序与入参一致、单请求 60 秒超时后中止并返回带文件名的可读错误(并提示改用 ZIP 一次性上传)。
  • 修正失败判定:plumber 把 success 序列化成 [false],而数组本身是真值,旧代码会把后端失败当成功继续往下走;改为解包后再判断。
  • 单序列页与多序列页在上传阶段显示「上传 i/N…」,不再只有一个没有说明的转圈。
  • 「已上传 N 个文件」改为「已选择 N 个文件」——该文案是本地选中数,此前会让人误以为文件已经传上去了,是这次误判为「转发故障」的一环。

Testing

  • 新增 frontend/src/lib/__tests__/upload.test.ts(8 例):并发乱序完成仍保序、首请求不带会话头且其余复用、同名去重、进度回调递增到 total、请求卡住按超时中止并报出文件名、success:[false] 判为失败、中途失败短路不再发起后续请求、空列表返回错误。
  • npx vitest run:16 个测试文件 / 51 例全部通过。
  • npx tsc --noEmit 通过;npm run build 通过。
  • 浏览器实测(本地 dev server + stub 上传响应):按钮依次显示「上传 0/9…→上传 1/9…→上传 5/9…」;请求发起时序为 0ms / 982ms×4 / 1982ms×4,确认首个串行、其余并发 4;首请求无 x-session-id、其余均带后端返回的会话 id。
  • 未验证:60 秒默认超时没有在真实慢网络上跑过(单测用 20ms 覆盖同一分支)。
  • 顺带发现未修:frontend/src/app/multi/page.tsx:140 有一处既有 eslint react-hooks/set-state-in-effect 报错,与本轮改动无关(stash 后复现),未处理。

Notes

Changed files:

  • frontend/src/lib/api.ts: 重写 uploadFiles(去重 / 建会话 / 并发 / 保序 / 超时 / 进度回调 / 失败判定),analyzeBatch 增加可选上传进度回调参数。
  • frontend/src/app/page.tsx: 上传阶段按钮显示「上传 i/N…」。
  • frontend/src/app/multi/page.tsx: 同上。
  • frontend/src/components/FileUploader.tsx: 「已上传」文案改为「已选择」。
  • frontend/src/lib/__tests__/upload.test.ts: 新增,上传逻辑单测。

Rollback:

  • 本轮改动尚未提交,回滚点为当前 HEAD c5dac80git checkout -- frontend/src/lib/api.ts frontend/src/app/page.tsx frontend/src/app/multi/page.tsx frontend/src/components/FileUploader.tsx && rm frontend/src/lib/__tests__/upload.test.ts

2026-07-25 - Task: 上传改为本地打包 ZIP 单请求 + 后端请求级日志 + 部署

承接上一条:上一条的「逐文件并发上传」方案已被本条取代(同一轮工作内的方案升级,保留上一条记录不改写)。 选型依据:实测 ab1 压缩率 52.6%(209 个文件 45MB→24MB),且 30MB 单请求经公网域名 200 OK / 5.7s, 中间层没有 body 上限,所以"打成一个包传"这条路可行且收益更大。

What was done

  • 前端上传改为:本地按去重后的文件名打包成一个 ZIP(fflate,level 6),单请求 POST 到已有的 /api/upload/zip。几十次往返压成一次,慢网络下不再"断一次就整批卡死"。
  • 上传改用 XHR 而非 fetch,拿到真实的字节级上传进度;按钮依次显示「打包 i/N…」→「上传 xx%…」(封顶 99%,留给服务端解压)。
  • 超时判据从"单请求总时长"改为"传输停滞":60 秒内没有任何字节发出才中止并报「上传停滞」。慢但仍在传的连接不会被误杀,而线上那种传到一半彻底不动的情况会被立刻暴露。
  • 返回的文件名以本地清单为准(入参顺序),不用服务端 list.files 的字典序;并校验服务端解压清单与上传清单一致,不一致直接报错,避免错位的文件名流进指派表。
  • 后端 start_api.R 的 postroute hook 增加请求级访问日志:[api] METHOD PATH?QUERY status=xxx NNms session=xxx。此前任何一层都没有请求日志,故障只能靠 /tmp 里的文件数倒推。

Testing

  • frontend/src/lib/__tests__/upload.test.ts 重写为 13 例:单请求且打到 /api/upload/zip、请求体是真 ZIP 且条目名正确、服务端返回字典序时仍按入参顺序返回、同名去重、打包/上传两段进度、停滞中止、success:[false] 判失败、解压清单不一致报错、非 JSON 响应报可读错误、空列表报错,外加 uploadStageLabel 三例。
  • npx vitest run:16 文件 / 56 例全过npx tsc --noEmit 通过;npm run build 通过。
  • Rscript -e 'parse("start_api.R")' 语法通过。
  • 浏览器真实回归(本地 dev → 生产 /api/upload/zip):4 个故意非字典序命名的文件上传成功,服务端 session 目录落地 a-/b-/m-/z-sample.ab1 四个原名文件(无 _i 改名),确认"以本地清单为准"的映射成立;随后分析按预期返回「所有文件分析失败」(测试文件是假字节),错误横幅正常显示、转圈正常结束。测试会话已从服务器删除。
  • 进度文案实测序列:打包 4/4… → 上传 16% → 33% → 50% → 66% → 83% → 99% → 结束
  • 未验证:60 秒停滞阈值未在真实劣化网络上跑过(单测用 30ms 覆盖同一分支)。

Notes

Changed files:

  • frontend/src/lib/api.ts: uploadFiles 改为打包 ZIP + XHR 单请求上传,新增 postZipUploadUploadProgressuploadStageLabel
  • frontend/src/app/page.tsx / frontend/src/app/multi/page.tsx: 按钮显示打包/上传两段进度。
  • frontend/src/components/FileUploader.tsx: 「已上传」文案改「已选择」。
  • frontend/src/lib/__tests__/upload.test.ts: 重写单测。
  • frontend/package.json / package-lock.json: 新增依赖 fflate 0.8.3。
  • start_api.R: postroute 增加请求级访问日志(未声明 value 形参,不影响响应体)。

Rollback:

  • 回滚点 c5dac80(本次改动之前的 main)。git revert <merge/commit> 后服务器 git pull + cd frontend && npm run build + sudo systemctl restart editr-frontend.service editr-api.service

2026-07-31 - Task: 编辑质量指标与指标说明页设计

What was done

  • 核对现有 Non_Target_Edit_Rate_at_Top_Position 的真实计算口径,确认其表示“总非参考碱基比例”,包含预期编辑碱基信号。
  • 确定向后兼容方案:保留旧字段,新增目标位点与最高编辑位点的非预期替换率和编辑产物纯度,并新增目标位点总非参考碱基比例。
  • 完成 /metrics 指标说明页的页面结构、字段范围、兼容策略、测试要求与 Sanger 数据解释边界设计。

Testing

  • 对照 R/analysis.RR/data_processing.Rserver.R、前端类型与顶栏结构完成只读一致性检查。
  • 使用仓库内置 AB1 样本核验四碱基比例之和、总非参考比例、非预期替换率和编辑产物纯度公式。
  • 设计文档自检:无 TBD/TODO 占位;新增字段、空值规则、兼容路径和验收标准一致。

Notes

Changed files:

  • docs/superpowers/specs/2026-07-31-edit-metrics-reference-design.md: 新增编辑质量指标与指标说明页书面设计。
  • progress.md: 追加本轮设计与核验记录。

Rollback:

  • 删除 docs/superpowers/specs/2026-07-31-edit-metrics-reference-design.md,并回退 progress.md 末尾本条记录。

2026-07-31 - Task: 编辑质量指标与指标说明页实施计划

What was done

  • 将已批准的编辑质量指标设计拆解为后端公式、前端说明页、文档、全量验证和生产部署五个可独立验证的实施任务。
  • 明确测试驱动顺序、五个新增字段的接口名称、旧字段兼容要求以及部署后的 API/页面/公式冒烟检查。

Testing

  • 对照书面设计逐项检查计划覆盖:公式、空值规则、旧 Shiny 路径、API/Excel/归档、前端类型、/metrics、导航、文档、完整测试及部署均有对应步骤。
  • 检查计划中的字段名称在前后任务间一致,无占位步骤。

Notes

Changed files:

  • docs/superpowers/plans/2026-07-31-edit-metrics-reference.md: 新增完整实施与部署计划。
  • progress.md: 追加本轮实施计划记录。

Rollback:

  • 删除 docs/superpowers/plans/2026-07-31-edit-metrics-reference.md,并回退 progress.md 末尾本条记录。

2026-07-31 - Task: 新增编辑质量指标与指标说明页

What was done

  • 保留历史字段 Non_Target_Edit_Rate_at_Top_Position 及其现有口径,明确它表示最高编辑位点的“总非参考碱基比例”,包含预期编辑信号。
  • 新增目标位点的总非参考比例、非预期替换率、编辑产物纯度,以及最高编辑位点的非预期替换率和编辑产物纯度,共 5 个 summary 字段;所需碱基比例缺失或分母不合法时返回空值。
  • 新增前端 /metrics 页面与顶栏入口,集中展示核心术语、summary/raw 字段、计算公式、C→T 示例和 Sanger 数据解释边界。
  • 新增稳定指标契约文档,并在 README 增加入口说明。
  • 修复新增导航入口后在窄屏被挤成竖排的问题;小屏保持导航单行、隐藏版本号,指标表格继续独立横向滚动。

Testing

  • Rscript run_tests.R:20/20 通过,包含新增 tests/test_edit_quality_metrics.R
  • cd frontend && npm test:17 个测试文件 / 60 例全部通过。
  • cd frontend && npx tsc --noEmit:通过。
  • cd frontend && npm run build:通过,/metrics 作为静态页面生成。
  • cd frontend && npx eslint src/app/metrics/page.tsx src/components/ui/TopBar.tsx src/lib/metric-definitions.ts src/lib/__tests__/metric-definitions.test.ts:通过。
  • 浏览器实测桌面与 390×844 窄屏:字段、公式和示例完整显示;页面无整体横向溢出,表格容器可横向滚动;四个导航项保持单行;控制台无 warning/error。
  • 完整 npm run lint 仍有 4 个既有错误和 1 个既有警告,均位于本轮未修改文件,未扩大范围处理。

Notes

Changed files:

  • R/data_processing.R: 计算并输出 5 个新增编辑质量 summary 字段。
  • server.R / ui.R: 旧 Shiny 结果表同步展示新增字段。
  • tests/test_edit_quality_metrics.R: 覆盖目标位点、最高编辑位点、零分母和缺失输入。
  • frontend/src/lib/types.ts: 补充新增 summary 字段类型。
  • frontend/src/lib/metric-definitions.ts: 集中维护指标名称、公式、语义和注意事项。
  • frontend/src/app/metrics/page.tsx: 新增指标说明页。
  • frontend/src/components/ui/TopBar.tsx: 增加指标说明入口并修复窄屏导航。
  • frontend/src/lib/__tests__/metric-definitions.test.ts: 校验字段文档、导航入口和窄屏样式约束。
  • docs/metrics.md: 新增稳定指标计算契约。
  • README.md: 增加指标说明页与契约文档入口。

Rollback:

  • 在合并后的主分支执行 git revert aa2f238..HEAD,重新构建并重启前后端服务;本轮未修改数据库结构或历史数据。

2026-07-31 - Task: 部署编辑质量指标与指标说明页

What was done

  • 将生产服务器 frontend/package-lock.json 的既有未提交改动保存到可恢复的 stash@{0},说明为 codex-predeploy-package-lock-2026-07-31,未覆盖服务器现场。
  • 生产仓库从 e2e6a26 快进到 28f31cb,按 systemd 使用的 Node 20.20.2 环境重新安装依赖并完成 Next.js 生产构建。
  • 首次 npm ci 因 npm audit 网络连接进入 CLOSE-WAIT 且日志停止增长而中止;改用 npm ci --no-audit --no-fund 后按 lockfile 安装成功。
  • 重启 editr-api.serviceeditr-frontend.service,并确认两项服务持续为 active

Testing

  • GET http://127.0.0.1:8001/api/health:返回 status=okversion=2.0.0db_ready=true
  • GET http://127.0.0.1:3000/metrics:页面包含 Edit_Product_Purity_at_Target_Position
  • 生产服务器执行 /home/wang/.local/envs/editr2/bin/Rscript tests/test_edit_quality_metrics.R:通过。
  • 浏览器访问生产 /metrics:顶栏入口、符号约定、摘要字段和计算示例正常渲染,控制台无 warning/error。
  • 生产仓库 HEAD 为 28f31cb0cf560a6c8e27d8b6e22cf8c2b6f4228a,部署后工作区干净。

Notes

Changed files:

  • progress.md: 追加生产部署、验证和服务器 stash 记录。

Rollback:

  • 在主分支回退 e2e6a26..28f31cb 的功能提交并推送,生产服务器拉取后重新执行前端构建与两项服务重启;服务器原锁文件改动仍可从 stash@{0} 恢复。

2026-07-31 - Task: 恢复生产 ZIP 上传代理与归档记录页面

What was done

  • 用户反馈 ZIP 上传返回 HTTP 500、记录页面为空后,立即停止进一步重启和数据操作,先只读核对 API/前端日志、SQLite 与归档目录。
  • 确认持久化数据未丢失:SQLite 中仍有 15 条归档记录,归档目录约 157MB,最近记录时间仍为 2026-07-29。
  • 定位直接故障为生产前端运行目录缺少 node_modules/next,Next.js 代理请求时报 Cannot find module 'next/dist/compiled/http-proxy';因此 ZIP 上传和归档列表等经 /api/* rewrite 的请求统一返回 500。
  • 停止前端服务后重新执行完整依赖安装,显式确认 next/dist/compiled/http-proxy 可解析,再完成生产构建并启动前端服务;R API 与数据库、归档目录均未改动。

Testing

  • 经前端代理请求 GET /api/health:返回 status=okdb_ready=true
  • 经前端代理请求 GET /api/archive/list:返回成功且共 15 条记录。
  • 经前端代理实际上传仅含测试文件的微型 ZIP:POST /api/upload/zip 返回 200、成功解压 smoke.ab1;测试会话随后清理。
  • 浏览器打开生产 /report:15 条归档记录重新正常显示,包含 2026-07-29 最新记录。
  • editr-api.serviceeditr-frontend.service 均为 active
  • 修复后日志未再出现 Cannot find module 'next/dist/compiled/http-proxy'

Notes

Changed files:

  • progress.md: 追加生产代理故障、数据核验和恢复记录。

Rollback:

  • 本轮未修改代码、数据库或归档文件;若需回退依赖恢复动作,仅停止前端服务并按当前 package-lock.json 重新安装即可。