解析去运行时化(三层架构,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
36 lines
1.6 KiB
TypeScript
36 lines
1.6 KiB
TypeScript
/**
|
|
* 整理脚本(幂等 / 显式人工触发)——解析去运行时化后的唯一解析入口:
|
|
* 1. 回填结构化解析列(只补 NULL,不覆盖存量);
|
|
* 2. 派生链接标签(未人工接管的 SDS 链接按名称刷新,人工接管不动)+ 商品镜像;
|
|
* 3. 自动建族(auto-group);
|
|
* 4. 全量族重算(并集尺码表/包装 + 五维价格矩阵)。
|
|
*
|
|
* 运行:pnpm --filter @inkreach/api organize
|
|
* 后台等价入口:POST /product-families/organize(「整理」按钮)。
|
|
*/
|
|
import { PrismaService } from '../src/prisma/prisma.service';
|
|
import { FamilyRecomputeService } from '../src/product-families/family-recompute.service';
|
|
import { ProductFamiliesService } from '../src/product-families/product-families.service';
|
|
import { OrganizeService } from '../src/product-families/organize.service';
|
|
|
|
async function main() {
|
|
const prisma = new PrismaService();
|
|
await prisma.onModuleInit();
|
|
const recompute = new FamilyRecomputeService(prisma);
|
|
const families = new ProductFamiliesService(prisma, recompute);
|
|
const organize = new OrganizeService(prisma, recompute, families);
|
|
|
|
const result = await organize.organize();
|
|
console.log(
|
|
`[organize] labels parsed=${result.labelsParsed} (unparsable=${result.labelsUnparsable}) | ` +
|
|
`tags links=${result.linksUpdated} goods=${result.goodsUpdated} | ` +
|
|
`families created=${result.familiesCreated} recomputed=${result.familiesRecomputed}`,
|
|
);
|
|
await prisma.onModuleDestroy();
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|