Commit Graph

3 Commits

Author SHA1 Message Date
浅念 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
浅念 bb2d381308 fix(import): finish 域路径安全守卫;attachment ?p= 排除对齐;歧义/降级计数精化;permalink 形态覆盖
- isSafePath 扩至 finish 域②(分类页 public_base_path+slug)与域④(media_assets public_path)——WXR 原始 slug 与库表原样切片同携穿越向量,拒绝即 issue+不登记
- writeAttachmentRoute 与内容行同口径排除 ?p=/&page_id=(?attachment_id= 不在排除表,照常 query_key 建模),排除计数 routesExcludedQueries
- 多资产歧义消息改"命中 ≥2 行"(LIMIT 2 探针只知下界)
- 降级汇总去虚报:writeRoute 返回四态,downgraded 只计实际写入(created/updated)——重复 attachment 事件 no-op 不重复计数
- foldCollisionKey JSDoc 钉死:折叠仅 JS 侧计算落列,勿用 PG normalize 库侧重算(ICU 版本差异面)
- 测试补 permalink 形态 attachment 301(纯路径行 query_key NULL)+ 重复事件降级计数"1 条"断言 + 双 finish 域安全守卫拒绝用例(317 全绿)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-21 19:40:35 +08:00
浅念 9d2cc0a46d feat(import): 路由注册表生成
§6.1 处置全表落 route_registry(route 域唯一写入方):
- 内容 permalink → html(路径保真 + target_content_id 经 source_records 关联);
  首页 / 与主列表 /products/ /news/(CLI 参数注入)finish 期生成;
- category/product_cat → html(public_base_path 常量 + term slug);post_tag/
  product_tag → 301 对应主列表(terms×taxonomies 全表 finish 期生成);
- attachment 页一律 301 媒体文件(前置事实 10 降级一条汇总 issue;暂存事件、
  finish 反查 media_assets——依赖 media-writer 先落资产的时序契约);
  ?attachment_id= 查询形态走 query_key 单独建模(spec §5.6 查询路由不并 path);
- 上传媒体路径 → asset(media_assets 全表;target_file 为产物路径占位);
- ?p=/&page_id= 不插行(route_kind 六值无 excluded——查询路由 SP3),计数
  routesExcludedQueries + 逐条 issue 落 excluded_with_reason 报告语义;
- ADR-007 双键:/About 与 /about 并存 + collision_key 折叠预警不计失败;
  同 exact_key 异 owner 冲突保留先到 + issue 列后者;
- upsert 三分:miss INSERT / 同 owner 描述字段 diff UPDATE / 异 owner 冲突;
  幂等重跑零计数,--news-path 变化触发 tag 301 目标同行 UPDATE。

counts 独占五键(route 前缀):routesCreated/routesUpdated/routesRedirects/
routesCollisions/routesExcludedQueries。315 测试(+5);typecheck/lint 绿。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-21 19:15:21 +08:00