refactor(api): parsing out of runtime — pure-mirror sync, explicit organize, auto aggregate recompute
解析去运行时化(三层架构,plans/refactor/organize-script-refactor.md): - 同步 = 纯镜像:upsertOriginGood 不再写解析列、不再自动挂族;详情同步仍触发重算 - 整理 = 显式人工动作(OrganizeService):解析列回填 → 派生标签(人工接管永不 覆盖)→ auto-group 建族 → 全量重算;入口 CLI(pnpm --filter @inkreach/api organize)+ POST /product-families/organize + 后台「整理」按钮 - 重算 = 纯结构化聚合:不再按名称重派生标签(防上游改名倒灌,回归测试覆盖); 矩阵维度只认标签/CUSTOM 显式标签,未整理成员不进矩阵;工艺=不打印时 印花数量以单面占位(纯结构化规则);「恢复自动」走整理的单链接派生 - 派生默认补齐(脚本层假设):名称无单/双面且工艺非不打印 → 印花数量单面印花 - goods 服务建品/更新后仅镜像标签+重算(不派生);含商品名入库规范化 (normalizeGoodName,管理员输入边界质检) - organize.service.spec 由 tag-sync spec 迁移 + 防倒灌回归;sync/recompute/ public/families spec 全部适配;API 173/173,admin typecheck+22/22
This commit is contained in:
@@ -274,6 +274,44 @@ describe('GoodsService', () => {
|
||||
expect(after.total).toBe(before.total);
|
||||
});
|
||||
|
||||
describe('good name normalization', () => {
|
||||
it('create/update 时把结构完整的原始链接名规范化为 品名+型号', async () => {
|
||||
const created = await service.create({
|
||||
goodName: '德国(不包邮)230g水洗T恤-DETM002-双面印花',
|
||||
originGoodId: Number(originGoodIds[0]),
|
||||
countryId: Number(countryId),
|
||||
categoryId: Number(categoryId),
|
||||
});
|
||||
try {
|
||||
expect(created.goodName).toBe('230g水洗T恤 DETM002');
|
||||
const updated = await service.update(BigInt(created.id), {
|
||||
goodName: '加拿大(不包邮)180g纯棉T恤-CATM001-单面印花',
|
||||
});
|
||||
expect(updated.goodName).toBe('180g纯棉T恤 CATM001');
|
||||
} finally {
|
||||
await prisma.good.delete({ where: { id: BigInt(created.id) } });
|
||||
}
|
||||
});
|
||||
|
||||
it('非链接结构的名称原样保留(已解析名/自定义名)', async () => {
|
||||
const created = await service.create({
|
||||
goodName: '230g水洗T恤 DETM002',
|
||||
originGoodId: Number(originGoodIds[0]),
|
||||
countryId: Number(countryId),
|
||||
categoryId: Number(categoryId),
|
||||
});
|
||||
try {
|
||||
expect(created.goodName).toBe('230g水洗T恤 DETM002');
|
||||
const updated = await service.update(BigInt(created.id), {
|
||||
goodName: '自定义商品 ABC',
|
||||
});
|
||||
expect(updated.goodName).toBe('自定义商品 ABC');
|
||||
} finally {
|
||||
await prisma.good.delete({ where: { id: BigInt(created.id) } });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('merged origin goods', () => {
|
||||
it('creates a good with merged origin goods and reads them back', async () => {
|
||||
const created = await service.create({
|
||||
|
||||
+774
-754
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user