docs(specs): reuse public endpoints and include admin frontend scope

This commit is contained in:
yeuimu
2026-08-28 12:04:35 +08:00
parent 14d77fbab2
commit 573549eb15
@@ -1,9 +1,10 @@
# 产品族(SPU)合并 — 后端设计 # 产品族(SPU)合并 — 后端设计
- 日期:2026-08-28(同日修订:价格允许人工覆盖、支持人工添加自定义商品入族) - 日期:2026-08-28(同日修订:价格允许人工覆盖、支持人工添加自定义商品入族;公开接口零新增全复用;admin 前端纳入本期
- 状态:已评审(讨论稿定稿,待实施计划) - 状态:已评审(讨论稿定稿,待实施计划)
- 分支:`feature/product-link-merge-yeuimu` - 分支:`feature/product-link-merge-yeuimu`
- 范围:后端(apps/api;前台展示层apps/adminapps/website仅列出依赖的接口契约 - 范围:后端(apps/api+ 后台管理前端apps/admin);官网(apps/website不在本期,
但公开接口保持 100% 兼容复用(见 §10.2)
## 1. 背景与问题 ## 1. 背景与问题
@@ -37,7 +38,7 @@ SDSInkPOD)上游会为同一个实体商品下发多条近似链接,名
- 不引入价格阶梯/折扣表(订单量定价已被明确否决);价格默认按链接推导透传, - 不引入价格阶梯/折扣表(订单量定价已被明确否决);价格默认按链接推导透传,
但**允许人工按格改价(覆盖表)**,并支持**人工添加自定义商品入族**(见 §5.5、§5.6、§8); 但**允许人工按格改价(覆盖表)**,并支持**人工添加自定义商品入族**(见 §5.5、§5.6、§8);
- 不改动同步任务的核心抓取逻辑与安全护栏; - 不改动同步任务的核心抓取逻辑与安全护栏;
-在本设计内实现 admin/website 的界面(仅约定接口契约) -改动 apps/website(官网)——公开接口零新增、原样复用,官网可无感灰度
## 3. 决策记录 ## 3. 决策记录
@@ -46,6 +47,8 @@ SDSInkPOD)上游会为同一个实体商品下发多条近似链接,名
| D1 | 合并落在哪一层 | **新增 SPU 产品族层**(介于 OriginGood 与 Good 之间),而非强化 Good 级合并或读取时动态聚合 | | D1 | 合并落在哪一层 | **新增 SPU 产品族层**(介于 OriginGood 与 Good 之间),而非强化 Good 级合并或读取时动态聚合 |
| D2 | 价格形态 | **默认按链接透传 + 人工覆盖**2026-08-28 修订):无阶梯折扣、无全手动明码矩阵;价格默认 = 成员链接变体的 SDS 原价,允许按格子人工改价(覆盖表),并允许人工添加自定义商品入族 | | D2 | 价格形态 | **默认按链接透传 + 人工覆盖**2026-08-28 修订):无阶梯折扣、无全手动明码矩阵;价格默认 = 成员链接变体的 SDS 原价,允许按格子人工改价(覆盖表),并允许人工添加自定义商品入族 |
| D3 | 买家选价粒度 | **五维全选**:详情页提供尺码/颜色/工艺(印花数量)/物流选择器,价格实时联动 | | D3 | 买家选价粒度 | **五维全选**:详情页提供尺码/颜色/工艺(印花数量)/物流选择器,价格实时联动 |
| D4 | 公开接口 | **零新增、全复用**:不新建任何公开端点,族数据以增量字段嵌入既有 `/public/*` 响应;`goodId=sdsGoodId` 与"任意成员命中同一族"语义不变 |
| D5 | 前端范围 | **admin 后台前端纳入本期**(原产品树按族分组、族管理、人工改价、自定义商品四块界面);官网不做 |
## 4. 架构 ## 4. 架构
@@ -259,6 +262,9 @@ model FamilyPriceOverride {
### 10.2 公开(无鉴权) ### 10.2 公开(无鉴权)
**复用原则(D4):不新增任何公开端点、不改变路径与参数语义**。族数据全部以增量字段
嵌入既有响应,官网现有代码继续工作;详情页消费 `family` 块属于纯增量升级。
`GET /public/goods/:goodId`goodId 仍为 sdsGoodId,主源或副源命中均可,语义不变)详情新增: `GET /public/goods/:goodId`goodId 仍为 sdsGoodId,主源或副源命中均可,语义不变)详情新增:
```jsonc ```jsonc
@@ -281,7 +287,45 @@ model FamilyPriceOverride {
- 不可用组合由矩阵行的**缺席**表达(前端禁用对应选项); - 不可用组合由矩阵行的**缺席**表达(前端禁用对应选项);
- 读路径切换加配置开关(如 `PUBLIC_DETAIL_FROM_FAMILY`)灰度,可秒回退。 - 读路径切换加配置开关(如 `PUBLIC_DETAIL_FROM_FAMILY`)灰度,可秒回退。
## 11. 迁移与灰度 ## 11. 后台管理前端(apps/adminD5
### 11.1 现状与入口
- 外层壳 `views/product-management/ProductManagementView.vue` 以标签页组织:
商品配置(`views/goods/GoodsView.vue`,约 2655 行)、数据同步(`views/sync/SyncView.vue`);
- 本期新增第三个标签页"**产品族**",并改造 GoodsView 的原产品树。
### 11.2 新增"产品族"标签页
新建 `views/product-family/` 目录,按职责拆组件(避免复刻 GoodsView 的巨型单文件):
- `FamilyList.vue`:族列表——关键词/分页/成员数、`stale` 红点、`autoManaged` 状态;
- `FamilyDetail.vue`:族详情——canonical 字段编辑(名称/主图/国家/分类/主链接/autoManaged)、
成员管理(SDS 链接增删、创建自定义成员)、手动重算;
- `AutoGroupDialog.vue`:自动建族——按 3 段规则展示候选分组预览,确认后应用;
- `PriceOverridePanel.vue`:人工改价矩阵——按 (工艺 × 物流) 切换页签,表格为尺码 × 颜色,
单元格显示有效价,人工格高亮并展示与推导价的差额,行内编辑即调
`PUT / DELETE price-overrides`
- 图片上传复用现有 `components/ImageUpload.vue`
### 11.3 GoodsView 改造
- 右侧原产品树分组依据从**前端名称截断**(`utils/origin-name.ts`,本期后退役)切换为
`GET /origin-goods/tree` 返回的真实族分组;
- 原"合并到 Good"交互改为"挂到族":勾选兄弟链接 → 加入既有族或新建族;
- Good 配置表单增加 `familyId`(选族替代选主源+副源),保留"主链接"概念用于跳转兜底。
### 11.4 API client
- 新增 `src/api/product-families.ts`(族 CRUD / auto-group / members / overrides / recompute);
- `src/api/origin-goods.ts``src/api/goods.ts` 随契约更新(familyId 字段)。
### 11.5 前端测试
关键交互(auto-group 预览、覆盖编辑、自定义成员创建、树分组切换)随仓库现有测试设施
补充组件/交互测试;全量现有测试保持通过。
## 12. 迁移与灰度
1. **建表加列**Prisma migrationproduct_families、OriginGood 四解析列 + familyId、Good.familyId); 1. **建表加列**Prisma migrationproduct_families、OriginGood 四解析列 + familyId、Good.familyId);
2. **解析回填**:脚本解析全部存量 `OriginGood.goodName` 填四列,输出不可解析清单; 2. **解析回填**:脚本解析全部存量 `OriginGood.goodName` 填四列,输出不可解析清单;
@@ -295,10 +339,10 @@ model FamilyPriceOverride {
7. **自定义商品与覆盖**:存量 `source=CUSTOM` 的 OriginGood 解析列保持为空,由管理员 7. **自定义商品与覆盖**:存量 `source=CUSTOM` 的 OriginGood 解析列保持为空,由管理员
按需补填并挂族;覆盖表初始为空,随运营逐步产生,无需数据迁移。 按需补填并挂族;覆盖表初始为空,随运营逐步产生,无需数据迁移。
分期建议:一期(族 + 解析 + 自动建族 + 后台树改造),二期(并集物化 + 公开详情切换 + Good.familyId), 分期建议:一期后端(族 + 解析 + 自动建族 + 树接口改造),二期 admin 前端(产品族页 + GoodsView 改造),
避免单次变更过大。 三期(并集物化 + 公开详情灰度切换 + Good.familyId),避免单次变更过大。
## 12. 测试要点 ## 13. 测试要点
- 解析器单元测试:golden 样本覆盖真实 552 条中的代表格式 + 畸形样本; - 解析器单元测试:golden 样本覆盖真实 552 条中的代表格式 + 畸形样本;
- 并集合并:同尺码冲突裁决、缺尺码补齐、包装规则合并、warning 记录; - 并集合并:同尺码冲突裁决、缺尺码补齐、包装规则合并、warning 记录;
@@ -311,7 +355,7 @@ model FamilyPriceOverride {
- 公开接口契约:开关两态下的响应形状、任何成员 sdsGoodId 均命中同一族; - 公开接口契约:开关两态下的响应形状、任何成员 sdsGoodId 均命中同一族;
- 全量现有测试保持通过(回归红线)。 - 全量现有测试保持通过(回归红线)。
## 13. 权限评估(按 AGENTS.md 要求) ## 14. 权限评估(按 AGENTS.md 要求)
新增后台操作需纳入现有权限体系(User/Role + JWT): 新增后台操作需纳入现有权限体系(User/Role + JWT):
@@ -321,7 +365,7 @@ model FamilyPriceOverride {
上线前需在 `docs/references/authority-matrix-ui.md` 同步权限矩阵。 上线前需在 `docs/references/authority-matrix-ui.md` 同步权限矩阵。
## 14. 默认值与待确认项 ## 15. 默认值与待确认项
以下规则已按默认值设计,实施前如需推翻请在此记录: 以下规则已按默认值设计,实施前如需推翻请在此记录: