初审日期:2026-09-19
复核及修复日期:2026-09-19
审核范围:当前 git 未提交改动,并结合当时的集成设计归档进行权限、FileRequest、生命周期和存储约束复核。当前文档入口见 README.md。 关联台账:data-download-open-issues.md
原报告 11 条结论中:CR-02、CR-05、CR-06、CR-08 是实际问题;CR-04、CR-07、CR-10、CR-11 是低风险一致性或完整性问题;CR-01、CR-03、CR-09 不成立或没有足够证据。
本轮已经修复确认成立且适合在当前范围内处理的问题,并补充修复复核时发现的任务计数错误。CR-08 的 HTTP 下载内存放大已经解决,但 ZIP 构建、Renderer 首次生成和上游二进制读取仍属于 DD-010,不能标记为整体解决。
| ID | 原严重度 | 复核结论 | 当前状态 | 处理结果 |
|---|---|---|---|---|
| CR-01 | 高 | 不成立 | rejected | 当前没有同 key 嵌套加锁;binary 与 rendered 分支互斥。不可重入只属于未来维护约束。 |
| CR-02 | 高 | 成立 | resolved | 上游请求改用独立、自动续租的 FileRequest lease;content 锁仅覆盖提交阶段;等待者通过 Asynq 延迟重试。 |
| CR-03 | 高 | 证据不足 | rejected | 短数组补 nil 与旧 PowerFlow 导出语义一致;新增测试固定该兼容行为。 |
| CR-04 | 中 | 低风险类型不一致 | resolved | run_status 改用 *int32,超出 PostgreSQL integer 范围时显式报错。 |
| CR-05 | 中 | 成立 | resolved | item 写入改为 (taskId,itemKey) upsert 并回填已有 _id;稳定队列 TaskID 冲突视为已调度。 |
| CR-06 | 中 | 成立 | resolved | 清理时统一使用 ExpiresAt + 30天。 |
| CR-07 | 中 | 字段未维护属实,影响被夸大 | resolved | Recount 统计空 TaskDocument,前端任务进度显示空文档数。 |
| CR-08 | 中 | 成立 | partially resolved | Package、二进制文档、缓存 RenderArtifact 已流式响应;生成和打包阶段的内存问题继续由 DD-010 跟踪。 |
| CR-09 | 中 | 不成立 | rejected | 设计明确允许其他登录用户查看、预览和下载;所有 /api 路由已有统一认证。 |
| CR-10 | 低 | 防御性建议 | resolved | 删除弱类型 mapToBSON,改用显式 bson.M。 |
| CR-11 | 低 | 文档建议 | resolved | 在 PowerFlow 持久化模型中明确本地 wall-clock 与 UTC instant 的语义。 |
data-download:request:{DocumentID} 请求租约,RequestID 使用唯一 lease token。AwaitRequestID,按 15、30、60 秒退避重新入队;等待期间 item 保持 pending,不占用 worker。这解决了 CR-02,并落实了设计文档 3.2、8.2、9.1、9.2 的主要行为。普通 content/Renderer 锁的完整 fencing/CAS 仍由 DD-001、DD-007 跟踪。
InsertDataDownloadItems 已由 InsertMany 改为无序 BulkWrite upsert。重复规划会取得已存在 item 的 _id,不会因唯一索引冲突失败;重复提交稳定 Asynq TaskID 时也不会把 item 错误标记为失败。该修复同时覆盖 plan handler 和 site_validation 重规划路径。
除原报告指出的 Empty 未写入外,复核还发现两个遗漏:
succeeded/failed 值不会归零;skipped 视为成功,但 Recount 未计入 succeeded。当前 Recount 会先清零计数、将 success + skipped 汇总为 succeeded,并从 TaskDocument 统计空文档数。
SendStream。清理时间+30天,而是固定使用 ExpiresAt+30天。ZIP 仍完整构建在内存中,Renderer 首次生成仍产生完整 []byte,因此 DD-010 保持 open。
BuildDataDownloadPackage 的 binary 分支自行取得 content 锁,structured 分支则直接进入 ReadRenderedDataDownloadDocument;两者不会在同一调用路径对同一 key 二次加锁。原报告描述的是假设未来修改后的风险,不是当前缺陷。
旧 PowerFlow 导出和前端转换均以时间轴为基准,并允许较短的并行数组以空值补齐。当前实现拒绝长于时间轴的数组、保留短数组中的“缺测值”语义,没有证据证明应强制全部等长。新增单元测试防止未来把兼容行为误改为报错。
设计文档 12.7 明确规定:其他用户可以查看任务和文件、预览、下载及批量下载,但不能修改、取消、重试或删除。归档读取属于文件查看/下载,且 /api 已由统一认证中间件保护,因此不能增加 owner/admin 限制。
原报告建议把 REPO-006 更正为 GetAlarmSnapshotData,该建议不正确。
REPO-006 描述的是旧测试 service/test/getSnapTest/getAlarmSnapshotTest.go 仍调用不存在的 jobs.GetAlarmSnapshot;DataDownload 新代码调用存在的 jobs.GetAlarmSnapshotData。两项事实同时成立,问题台账无需更正。
go test ./services ./controllers ./repositories/mongo ./repositories/pgsql ./repositories/minio ./task/queue/dataDownloadQueue ./cache/redisx ./database:通过。run_status 被拒绝。pnpm type-check:通过。pnpm exec eslint src/service/dataDownload src/views/data-download:通过。git diff --check:通过。go test ./...:仍被 REPO-001~007 的既有源码问题阻断;DataDownload 相关包未出现新增失败。