diff --git a/docs/task/194-蝦皮规格回填PDD.md b/docs/task/194-蝦皮规格回填PDD.md new file mode 100644 index 0000000..e82734e --- /dev/null +++ b/docs/task/194-蝦皮规格回填PDD.md @@ -0,0 +1,59 @@ +# 194 Admin:将指定蝦皮店铺正式规格补入关联 PDD 空规格 + +- 类型:需求 +- 父级大工单:#14 +- 所属 MVP / 版本:#15 +- 状态:已完成 +- 日期:2026-08-12 +- Gitea 工单: + +## 背景与目标 + +#193 确认 `qwg8fkb044` 店铺大量商品已经关联 PDD,但 PDD 尚无规格。用户确认允许用蝦皮正式颜色、尺码创建规格骨架,同时不得猜测价格和库存,也不得覆盖已有或异常的 PDD 规格。 + +## 最终方案 + +增加默认 dry-run 的独立命令 `backfill-shop-pdd-specs`。它只处理店铺名精确匹配、PDD 关联有效、蝦皮存在正式规格且 PDD 规格为空的商品;只有传入 `--apply` 才写库。 + +规格骨架保留颜色、尺码组合,价格字段为 `null`,库存使用 `availability_status=unknown`,不写 `available=true/false`,并用 `spec_source=shopee_backfill` 标记来源。已有规格、非法 JSON、软删除、无正式规格及多对一规格歧义均跳过。 + +写入前在本机临时目录保存原值备份;正式更新在单个事务中进行,并用原始 `skus_json` 作乐观锁,目标被并发修改时整批回滚。商品和规格拆成两次查询,避免把较大的 PDD JSON 随每个蝦皮 SKU 重复传输。 + +实际执行结果:1917 件蝦皮商品去重后对应 1738 件 PDD,全部完成规格骨架回填。155 件没有正式蝦皮规格、3 件已有 PDD 规格,均保持不变。回填后复查候选为 0。 + +## 改了哪些 + +- `admin/cmd/backfill-shop-pdd-specs/main.go`:增加 dry-run、显式 apply、本机备份和汇总输出。 +- `admin/repository/spec_compare.go`:优化只读查询,并增加带原值乐观锁的参数化更新。 +- `admin/repository/spec_compare_test.go`:验证原值变化时不会覆盖。 +- `admin/service/spec_backfill.go`:增加候选判定、规格骨架、歧义跳过、事务应用和回填复核。 +- `admin/service/spec_backfill_test.go`:覆盖未知价格库存、已有数据保护、多对一歧义、骨架识别和事务回滚。 + +## 验收结果 + +| 验收标准 | 结果 | +|---|---| +| 默认 dry-run,只有显式 `--apply` 才写库 | 通过 | +| 仅处理精确店铺、有效关联、正式规格存在且 PDD 规格为空的商品 | 通过 | +| 颜色尺码已写入,价格为 `null`,库存保持未知 | 通过 | +| 已有、异常、软删除、无正式规格和多对一歧义数据不覆盖 | 通过 | +| 单事务写入并使用原值乐观锁 | 通过 | +| apply 后复核 1738 件 PDD 已回填且候选为 0 | 通过 | + +## 测试 + +- 执行的命令:`$env:GOTOOLCHAIN="go1.23.0"; go vet ./...; go build ./...; go test ./... -count=1` +- 结果:全部通过。 +- 执行的命令:`go run ./cmd/backfill-shop-pdd-specs --shop qwg8fkb044` +- 结果:apply 前候选 1738 件 PDD;apply 后候选 0,已回填 1738 件。 +- 执行的命令:`go run ./cmd/backfill-shop-pdd-specs --shop qwg8fkb044 --apply` +- 结果:事务提交成功,本机回退备份生成成功。 +- **没验证到的部分**:没有把回填骨架当作 PDD 实时价格或库存使用;这些字段按需求保持未知,后续仍需真实采集才能补齐。 + +## 遗留问题 + +155 件蝦皮正式规格不可用、3 件已有 PDD 规格与蝦皮规格不一致,本工单按确认范围保留待人工补充,没有自动覆盖。 + +## 相关提交 + +- `8f7fb09` 回填店铺关联 PDD 空规格