fix(product-family): auto-merge SKUs after manual tag edits; fix session cookie path
问题2(SKU 无法自动合并,GBIU017 案例)四处叠加根因修复: - 人工标签旧词「热转印」被封闭词表静默踢出合并矩阵 → CRAFT_TAG_ALIASES 别名归一为「烫画」(矩阵归因与 CUSTOM 标签同路径生效) - updateTags 缺任一定价维度组即整链掉出矩阵且人工接管后永不恢复 → 缺啥补啥(按链接名派生补齐,人工勾选值不动,响应带 filledDimensionTags) - autoGroup 只建新族从不并入已有族(产生 USIU005-2 类碎片)→ 并入已有 autoManaged 同款族优先,无匹配才新建;同款仅人工锁定族则跳过并报告 - 名称回退分组键含物流备注,包邮/不包邮永不同组 → 新增族语义键 familyNameKey(国家+品名+SKU),api/admin 两侧同构,合并默认勾选随之修复 附加: - updateTags 后未归族链接自动并入匹配族(attachToMatchingFamily,响应带 attachedFamilyId) - 整理新增碎片族合并 consolidateFragments:纯碎片族并入带商品族并删除 (保公开 goodId=族ID 稳定),带商品/覆盖价/人工锁定进人工复审报告 - admin:保存标签提示补齐明细,整理完成消息含并入/碎片合并/待人工数 问题1(后台频繁 Unauthorized 掉线): - refresh cookie path '/auth' 与代理前缀(/api、/v2-api)不匹配导致浏览器 永远带不上 refresh cookie → 两 cookie path 统一为 '/' - v2 构建基址带尾斜杠 + 手工拼接产生 /v2-api//auth/refresh 双斜杠 404 → request.ts 规范拼接 测试:api jest 187/187、admin vitest 22/22、双侧 tsc 0 错误; public.service 夹具改为自包含(不依赖共享库既有数据)。
This commit is contained in:
@@ -66,13 +66,15 @@
|
||||
**关键端点用法示例**(JWT):
|
||||
|
||||
```bash
|
||||
# 1. 自动成族:先预览
|
||||
# 1. 自动成族:先预览(action 标注 create=新建 / merge=并入已有族 / skip=同款仅人工锁定族)
|
||||
curl -X POST /product-families/auto-group -H "Authorization: Bearer $T" \
|
||||
-d '{"apply": false}'
|
||||
# → { applied: 0, groups: [{ groupKey: "cat:8240", familyName: "DG001 180G纯棉T恤(JSA002)", memberCount: 16, ... }] }
|
||||
# → { applied: 0, groups: [{ groupKey: "cat:8240", familyName: "DG001 180G纯棉T恤(JSA002)", memberCount: 16, action: "create", ... }] }
|
||||
|
||||
# 2. 应用(幂等,可重复执行)
|
||||
# 2. 应用(幂等,可重复执行)。已有同款 autoManaged 族时**并入**(不再新建 -2 碎片族);
|
||||
# 同款仅有人工锁定族(autoManaged=false)时跳过该组并计入 skipped。
|
||||
curl -X POST /product-families/auto-group -H "Authorization: Bearer $T" -d '{"apply": true}'
|
||||
# → { applied: 新建族数, merged: 并入链接数, skipped: ["cat:..."], groups: [...] }
|
||||
|
||||
# 3. 族详情:成员 + 并集尺码表/包装 + 五维价格矩阵
|
||||
curl /product-families/12 -H "Authorization: Bearer $T"
|
||||
@@ -95,7 +97,10 @@ curl -X POST /product-families/12/members/custom -H "Authorization: Bearer $T" \
|
||||
|
||||
1. **同步 = 纯镜像**:SDS 给什么存什么(名称原文/图/价/分类 ID),不解析、不归族、不写解析列;
|
||||
2. **整理 = 显式人工动作**(所有解析/派生集中于此,可审查可重跑):回填解析列 → 派生链接标签
|
||||
(未人工接管的 SDS 链接按名称刷新;人工接管永不覆盖)→ 自动建族 → 全量重算。入口二选一:
|
||||
(未人工接管的 SDS 链接按名称刷新;人工接管永不覆盖)→ 自动建族(**并入已有同款族优先,
|
||||
无匹配才新建**)→ 碎片族合并(同分类多族时,纯碎片族并入带商品的族并删除,带商品/覆盖价/
|
||||
人工锁定的进人工复审报告)→ 全量重算。返回含 `familiesMerged / fragmentsConsolidated /
|
||||
fragmentsManualReview`。入口二选一:
|
||||
|
||||
```bash
|
||||
pnpm --filter @inkreach/api organize # CLI
|
||||
@@ -110,6 +115,17 @@ curl -X POST /product-families/organize -H "$AUTH" # 后台「整理
|
||||
单面印花;不打印/光板 无印花面不补(矩阵中印花数量以单面占位,纯结构化规则)。
|
||||
「恢复自动」(链接标签重置)本身是显式人工动作,同样走整理服务的单链接派生。
|
||||
|
||||
**人工标签缺啥补啥 + 旧词别名**(2026-09-02 起):
|
||||
|
||||
- `PUT /origin-goods/:id/tags` 保存人工标签时,三个定价维度组(印花数量/工艺/物流)缺哪组
|
||||
就按链接名称自动补哪组(并入人工集合一起存为 manual 行,人工勾选值永不被动),响应带
|
||||
`filledDimensionTags`;未归族链接随后自动并入匹配族(同 SDS 分类优先,回退族语义名称键),
|
||||
响应带 `attachedFamilyId`。
|
||||
- 工艺旧词「热转印」按别名归一为「烫画」进价格矩阵(`CRAFT_TAG_ALIASES`),标签字典本身不动。
|
||||
历史背景:曾有 16 条人工链接因勾了旧词「热转印」被封闭词表静默踢出合并矩阵。
|
||||
- 名称回退分组键为**族语义键** `familyNameKey`(第 1 段剥离物流备注、保留 国家+品名+SKU):
|
||||
包邮/不包邮、单面/双面印花是矩阵维度,不再拆族;不同国家/不同款号仍不同族。
|
||||
|
||||
**公开读路径(四期族化契约,默认开启)**:`PUBLIC_DETAIL_FROM_FAMILY=false` 可应急回退旧行为。
|
||||
公开端点**以款(族)为一等公民**:
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ apps/api/
|
||||
│ ├── tag-groups/ # 标签分组 CRUD(受 JWT 保护,含批量排序)
|
||||
│ ├── positions/ # 坑位 CRUD(受 JWT 保护)
|
||||
│ ├── origin-goods/ # SDS 原始商品快照(只读分页 + 配置状态树 + 链接级标签人工接管)
|
||||
│ ├── product-families/ # 产品族(SPU 层):CRUD / auto-group / 成员管理 / 自定义成员 / 价格覆盖 / 重算 / 按链接名称派生标签(auto-tag-rules)
|
||||
│ ├── product-families/ # 产品族(SPU 层):CRUD / auto-group(并入已有族优先,familyNameKey 族语义键)/ attachToMatchingFamily(单链接自动归族)/ consolidateFragments(碎片族合并)/ 成员管理 / 自定义成员 / 价格覆盖 / 重算 / 按链接名称派生标签(auto-tag-rules,含 热转印→烫画 别名)
|
||||
│ ├── goods/ # 商品 CRUD + 批量优先级 + 批量创建
|
||||
│ ├── sync/ # SDS 同步:分类 / 商品 / 同步日志
|
||||
│ ├── public/ # 公开 API:分类树 / 国家 / 商品分页 / 商品详情
|
||||
@@ -123,8 +123,8 @@ apps/api/
|
||||
| `/origin-goods/tree` `GET` | 配置状态树(叶子含 `familyId/familyName/familyCode/familyStale`) | JWT |
|
||||
| `/origin-goods/:id/tags` `GET/PUT/DELETE` | 链接级标签:查(含 manual 标记)/ 人工接管全量替换 / 恢复按名称自动派生;写入后镜像到名下商品 | JWT |
|
||||
| `/product-families` `GET/POST` | 产品族分页列表(`keyword` 匹配名称/编码)/ 建族(可直挂成员) | JWT |
|
||||
| `/product-families/organize` `POST` | 整理原产品库(显式人工动作):回填解析列 → 派生标签(人工接管不动)→ 自动建族 → 全量重算;CLI 等价 `pnpm --filter @inkreach/api organize` | JWT |
|
||||
| `/product-families/auto-group` `POST` | 自动成族:按 SDS 分类(产品模型)聚合无族链接;`{apply:false}` 仅预览,`{apply:true}` 落库并逐族重算(幂等) | JWT |
|
||||
| `/product-families/organize` `POST` | 整理原产品库(显式人工动作):回填解析列 → 派生标签(人工接管不动)→ 自动建族(并入已有同款族优先)→ 碎片族合并 → 全量重算;返回 `familiesMerged/fragmentsConsolidated/fragmentsManualReview`;CLI 等价 `pnpm --filter @inkreach/api organize` | JWT |
|
||||
| `/product-families/auto-group` `POST` | 自动成族:按 SDS 分类(产品模型)聚合无族链接,无分类回退族语义名称键(`familyNameKey`,物流/工艺不分族);已有同款 autoManaged 族则**并入**(不建 -2 碎片族),同款仅人工锁定族则跳过;`{apply:false}` 预览含 `action: create/merge/skip`,`{apply:true}` 落库并重算(幂等) | JWT |
|
||||
| `/product-families/:id` `GET/PATCH` | 族详情(成员+覆盖)/ 编辑 canonical 字段、`autoManaged`、主链接 | JWT |
|
||||
| `/product-families/:id/recompute` `POST` | 手动重算并集与价格矩阵 | JWT |
|
||||
| `/product-families/:id/members` `POST` | 成员增删 `{addOriginGoodIds, removeOriginGoodIds}`;移除主链接后 primary 落到剩余成员 | JWT |
|
||||
|
||||
Reference in New Issue
Block a user