浅念
|
77687e2330
|
fix(import): 失败报告部分冲刷;列表路径校验(建行前);JSDoc 求和措辞;reason 归档
Task 6 质量评审四项修复:
- 失败报告部分冲刷(Fix 1):orchestratedPipeline 分派/finish 包 try/catch——
中途抛错时把可安全取得的部分产出冲入 ctx.report 后重抛:term/content 的
finish 是纯返回(已算成复用、未算成就地补算 trySyncFinish,自身抛错放弃
该部分不掩盖原错)、已收集的 adapter 问题/清洗统计、进度计数
eventsDispatched(orchestrator 键,仅失败路径出现——成功路径不占 18 键面)。
media/route finish 依赖库与先序产物,失败路径不调用(其键缺席如实反映)。
- 列表路径校验(Fix 3):ImportErrorCode 增 INVALID_LIST_PATH;解析期防线
移至阶段 2.5(建 job 行前——建行/置 running 后再抛会留悬挂行);复用
route-writer 导出的 isSafePath;normalizeListPath 自带安全拒绝(写入器
自调用位双覆盖)。CLI 无需新码(既有 ImportError 通道按 code 呈现)。
- JSDoc 求和措辞(Fix 2):content-writer/media-writer 的 counts 键契约
注记由"返回值覆盖同名键 CLOBBER"改为"同名键求和(Task 6 钉死——防覆盖
安全网)",与 ImportPipelineOutcome.counts 契约对齐。
- reason 归档(Fix 4):分派循环对 unsupported/error 事件把 reason/issue
推入 adapter 问题组(此前被静默丢弃)。
测试:import-full 增 2 例(手构流 3 事件后爆炸 → failed + eventsDispatched=3
+ 部分 content/term 计数 + unsupported/error reason 双归档;--products-path
/../x/ 等 → INVALID_LIST_PATH 零 job 行)。全量 325 通过;typecheck/lint 干净。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 20:34:43 +08:00 |
|
浅念
|
8003de336b
|
feat(import): 全链编排与导入报告
Task 6(Plan 3):四家写入器汇流为默认编排管道。
- import.service:注入 events/pipeline 缺席时走真实事件流(runWxrAdapter
惰性 async generator,mapConfig.locale=site.default_locale 前置事实 8);
分派严格串行 content→term→media→route(禁 Promise.all);finish 硬序
term(sync)→content(sync)→media(await)→route(await);counts 由 ⊕ 覆盖
改为逐 key 求和聚合;新增 stale 回收(同站点 queued/running >24h 一条
SQL 置 stale);报告新增 paths/productsPath+newsPath、issueGroups 六组、
sanitize 清洗统计(事件流 changedRows/byDiffType 聚合)、adapterTiming。
- content-writer:NULL-entry 收编(快照行在而 content_entry 空,五列先验
三分支:无先验新建挂接/同 checksum 挂接 skipped/异 checksum 挂接新版本)。
- route-writer:attachment 降级汇总按去重 sourceId 计(重跑仍必现);
normalizeListPath 导出;writeAttachmentRoute 返回 written/resolved/blocked。
- 四家写入器 identity 收敛共享基类型 WriterContext =
Pick<ImportJobContext,'db'|'siteId'|'connectionId'>(type-only import,
无运行时环依赖)。
- CLI import 增 --products-path/--news-path(前置事实 9,缺省 /products/
/news/)记入 job 报告。
- 测试:tests/integration/import-full.test.ts 6 例(全链 zh-CN 接线证明
+published 全 NULL/报告四域计数+sanitize+分组/幂等重跑零写语义/
无 media 快照域缺失不失败/NULL-entry 收编/stale 回收/REPORT_WRITE_FAILED
遗留补测);import-job 契约测试钉死 counts 求和(100⊕3=103)。
全量 323 通过;typecheck/lint 干净。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 20:08:06 +08:00 |
|
浅念
|
7e6ce91001
|
fix(import): 媒体工厂守卫与加固——manifest 形态/侧车门控/冲突约束名/窗口边界与冲突测试
评审加固五项:
- manifest 形态守卫:bundle 在场而 metadata.manifest 非数组 → throw(与
storageRoot 守卫同风格),不与"bundle 合法缺席=空清单"共用静默空 coercion
- 侧车门控:空清单下级②不可达,跳过侧车加载——破损侧车副本不因无用输入
让整 job 失败
- public_path 冲突 catch 按约束名精确认领(postgres.js 的 constraint_name,
drizzle 包一层在 cause)——未来加第三唯一索引不误标,其余 23505 原样上抛
- 集成用例:不同 source_url 同旧 uploads 路径 → 后到不覆盖、issue 报告、
只留一行(mediaRegistered=1)
- 单测边界对拍:'<svg' 恰好收在 1024 字节窗口内(起点 1020)检出;起点
1021 被截断为 '<sv' → null
310 测试(308+2);typecheck/lint 三绿。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 18:56:16 +08:00 |
|
浅念
|
ed081ec477
|
feat(import): 媒体登记与安全校验
Plan 3 Task 4:media-writer(attachment 行三级对拍 + 内容行引用提取双事件消费)
+ magic-bytes 手写签名表(零新增依赖)。
- 三级对拍(前置事实 7):①uploads 相对路径清单精确命中 ②侧车 source_url→
file_path→清单实体(精确 miss 按文件名候选,多候选歧义不自动选全列 issue)
③missing 只进报告不插行(sha256 NOT NULL 库层防线)
- 魔数校验:命中实体读存储副本头部实际字节——SVG 检出 status=quarantined 不进
产物语义(引用不建 usage);未知签名 unsupported;扩展名声明 MIME 与检测不符
→ issue(按检测登记)
- usage 两阶段时序(WXR 文档序 items 先于 attachment):内容行提取引用 + 修订
锚点(依赖 content-writer 先处理同事件——Task 6 编排顺序契约),finish 统一
对 media_assets 反查(id→source_id / URL→source_url→public_path),顺序无关
- 悬空引用计数 mediaDanglingRefs 不静默(mini 203/204 钉死)
- counts 六键 media 前缀独占(勿复用 'skipped' 的键契约注记)
- 幂等:(site,source_url) 定向 onConflictDoNothing + usage 复合主键——重跑零增行
308 测试(296+6 单测+6 集成);typecheck/lint 三绿。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 18:38:10 +08:00 |
|