feat(edit): 商品编辑页开发

This commit is contained in:
R524809
2026-09-10 17:45:46 +08:00
parent 130a005231
commit 946af649dd
22 changed files with 7034 additions and 518 deletions
+70 -1
View File
@@ -1,6 +1,6 @@
# Atlas Seller Kit 交接说明
> 更新:2026-09-07。此文是新 AI 对话、架构讨论与开发工作的首读入口。开始开发前,必须先阅读并遵守 [`development-collaboration-contract.md`](./development-collaboration-contract.md)。
> 更新:2026-09-10。此文是新 AI 对话、架构讨论与开发工作的首读入口。开始开发前,必须先阅读并遵守 [`development-collaboration-contract.md`](./development-collaboration-contract.md)。
## 1. 项目定位
@@ -10,6 +10,16 @@
当前运行时基线:Node 24.20.0、pnpm 11.25.0、PostgreSQL 18.6、Redis 7.4.11、MinIO `RELEASE.2025-09-07T16-13-09Z`;Web 默认端口为 `8100`,API 默认端口为 `8200`,扩展 dev server 默认端口为 `8110`(仅本地开发用),Worker 无 HTTP 端口。完整目录、依赖边界与版本表见 [`architecture/project-structure.md`](../architecture/project-structure.md) 和 [`architecture/technology-and-deployment.md`](../architecture/technology-and-deployment.md)。
## 0. 交接结论(先看这里)
当前已经完成的是“采集 → 采集箱 → 商品编辑草稿”的主要数据闭环,以及 M3.0–M3.4 商品领域基础、编辑器核心、AI 来源素材字段级合并、动态属性和缓存同步基础。数据库迁移、工作空间隔离、同商品归属外键、幂等键和 product/profile 双乐观锁已经落地。
当前没有完成的是“可直接用于发布”的闭环:候选素材选择/物化、定价确认、AI 任务与候选结果、Ozon 首次发布、在线商品同步仍未开发。真实站点回归也尚未由本项目完成;用户已确认此前提出的首次回归项基本满足采集箱和商品编辑需求,但仍建议在最终发布前保留一轮样本验收。
当前最高优先级是类目行为改造:旧代码仍允许用户手动同步 Ozon 类目,最新决定要求改为应用启动后同步一次并写入数据库,编辑器使用树形 Cascader 直接读取缓存;Ozon 采集到的类目还需要按层级路径自动回填,且不能覆盖用户已经保存的类目。该项目前处于代码改造中,未完成端到端验收,详见 [1.27](#127-当前进行中2026-09-10类目树交互改造尚未验收)。
接手前请注意:工作区存在未提交的 M3 商品编辑、M3.4/M3.5 缓存、前端样式和迁移改动。不要用 `git reset --hard` 或批量清理未跟踪文件;先阅读 `git status --short`,按文件和迁移编号判断归属。当前中间代码的共享 contracts 类型需先构建,再执行 Web/API/Worker 检查。
### 1.1 开发进度(2026-09-02)
今日完成三项工作,全部通过 typecheck、生产构建,并经浏览器或启动实测:
@@ -176,6 +186,54 @@
- Web 的采集箱“编辑上架”和手动创建现会创建编辑上下文后进入 `/products/{id}/editor`。正式页可编辑产品基础资料、当前平台文案及 SKU/货号,遇到版本冲突会重新加载最新快照。
- 此批刻意不展示未具备平台 schema 或发布校验的数据:类目/属性切换与未映射属性恢复、规格继承、候选媒体物化/选图、定价确认、AI 和首次 Ozon 导入仍待后续纵向任务。
### 1.21 开发进度(2026-09-10):复采与编辑草稿 P0 修复
- 重复采集不再删除 `product_variants`。未进入编辑器前,SKU 仍可作为最新来源快照投影更新;一旦任一 `product_platform_profile` 存在,复采只更新来源证据/规范化载荷/候选素材,并按稳定 `source_variant_key` 复用既有 SKU ID,不覆盖 Atlas 草稿字段或已建平台 listing。
- 复采新发现的来源 SKU 会为该商品全部现有平台 profile 建立独立 `not_listed` listing;来源不再返回的 SKU 不会被自动删除或恢复。这样既保留用户编辑和发布审计,也不会以级联删除绕开 SKU 与 profile 的同商品归属约束。
- 扩展集成测试已覆盖“进入编辑、保存人工 SKU 字段与 offer 后再次采集”的场景,并确认原映射保留、新 SKU 可编辑。完整 API 集成测试通过。
### 1.22 开发进度(2026-09-10):M3.2 商品编辑核心
- 编辑快照与 `PUT /api/products/{id}/editor-draft` 已覆盖父商品实物/包装规格、SKU 覆盖规格、有效继承规格、规格轴值、每个 SKU 当前平台状态、以及该平台全部活动且凭据有效的目标店铺候选。
- 切换目标店铺仍通过同一原子草稿保存:仅 `not_listed` / `failed` 等未导入 listing 改为新店铺;`imported` SKU 永远保留其首次导入的店铺映射。规格确认状态为 `confirmed` 时服务端要求相应四项尺寸/重量完整,数值必须大于零。
- Web 编辑页新增父/子规格编辑、规格轴值、复制 SKU、已导入 SKU 删除影响提示、目标店铺选择、上架状态摘要,以及路由离页与浏览器关闭前的未保存修改确认。类目/动态属性、素材选择、定价、AI 与首次发布仍未开始。
- 商品编辑集成测试覆盖规格保存/继承、复制 SKU、店铺切换与已导入 SKU 映射保留;Web production build 通过。
### 1.23 开发进度(2026-09-10):M3.3 编辑器数据闭环
- 新增迁移 `019_product_editor_ai_source_material.sql`,在商品聚合中持久化结构化 `ai_source_material`。未保存时由当前规范化采集载荷初始化;保存后作为用户整理稿保留,后续复采不覆盖。原始 `normalized_payload` / `raw_evidence` 不被编辑器修改。
- `GET /api/products/{id}/editor` 直接返回 `collection_item_id`、`source_material` 和服务端组装的 `ai_input`,Web 不再扫描采集箱前 100 条记录寻找来源。`ai_input` 同时包含父商品默认实物/包装规格,以及每个 SKU 合并继承后的有效规格和规格轴。
- `PUT /api/products/{id}/editor-draft` 将 AI 来源素材与商品、平台文案、SKU 和规格原子保存,并继续使用 product/profile 双 revision 与幂等键。右侧来源标题和描述的修改现可持久化;未来 AI 动作必须先保存草稿,再从服务端读模型创建任务。
- 商品编辑集成测试覆盖来源载荷初始化、用户素材保存、原始证据不变、复采不覆盖整理稿,以及父/SKU 有效规格进入 AI 输入。
### 1.24 开发进度(2026-09-10):M3.3.1 来源素材字段级合并
- 新增迁移 `020_product_ai_source_overrides.sql`:将 M3.3 的整份 `ai_source_material` 草稿演进为 `ai_source_material_overrides` 与 `ai_source_material_base_revision`。服务端以最新规范化采集数据为底稿,只叠加用户明确编辑过的顶层字段。
- 编辑快照新增 `source_material_state`:同时返回最新来源、覆盖字段、复采后发生分歧的字段与基线版本。右侧“采集的商品信息”展示合并后的有效值;未编辑字段随复采自动更新,已编辑字段保留,并支持逐项恢复或全部采用最新。
- 保存请求新增 `ai_source_overridden_fields`。来源版本必须与服务端当前版本一致;保存过程中发生复采返回 `409 SOURCE_SNAPSHOT_CHANGED`,防止旧页面覆盖新证据。原始 `normalized_payload` / `raw_evidence` 仍保持只读。
- AI 输入继续由服务端组装:来源部分读取字段级合并后的有效素材;规格部分读取用户在左侧保存的父商品规格、SKU 覆盖值及其继承后的有效值。
### 1.25 开发进度(2026-09-10):M3.4 类目与动态属性
- 新增迁移 `021_product_category_attribute_schema.sql`,建立平台级的类目属性 schema 与字典值缓存表。缓存记录属性值类型、必填、多值上限、字典标识及 `is_aspect`;它们不是工作空间草稿,商品属性只能引用当前平台/类目的有效 schema。
- 新增编辑器接口:类目候选、类目属性 schema 与属性字典值。类目 schema/字典接口支持传入未保存的 `category_id` 预览,因此用户选择新类目后不必先保存一次才能填写字段。
- 编辑器草稿可原子保存 `platform_product_category_id`、类目来源与商品/SKU 属性;服务端派生 `platform_type_id`,复核类型、值数量、字典值与 SKU 归属。类目变更或 schema 下线的旧属性会转入 `product_unmapped_attributes`,不会默默丢失或进入新的发布 payload。
- Web 编辑页已提供类目选择、商品/SKU 维度动态字段、字典选择、未映射属性告警;上架店铺/主题标签保持标准 40px 控件高度,父商品包装重量与三项包装尺寸宽度分别为 150px / 120px。
### 1.26 开发进度(2026-09-10):M3.5 Ozon 类目与属性缓存同步
- 已实现类目树、类目属性 schema、字典值缓存的数据表、Worker 同步逻辑、Transactional Outbox 和读 API;缓存属于平台级元数据,不属于某个商品草稿。浏览器、operation 响应与 outbox 事件都不含 API Key。
- 当前旧实现仍把“同步 Ozon 类目”暴露为商品编辑页操作;这已被最新产品决策否定,不能作为完成状态使用。属性 schema 仍是按类目读取/按需同步的现状,后续需单独确认是否也改为启动预热。
- 字典不会全量拉取:字段先读取已有缓存;用户输入至少两个字符且本地无匹配时,现有实现可显式发起 Ozon `/attribute/values/search`,Worker 仅 upsert 返回的命中项。同步失败应保留旧缓存和可读错误状态。
### 1.27 当前进行中(2026-09-10):类目树交互改造,尚未验收
- 最新产品要求:应用启动后为 Ozon 执行一次类目树同步并持久化到 `platform_product_categories`;商品编辑页不再出现“同步/刷新类目”按钮,打开“产品类目”时直接从数据库读取并展示树形层级。
- 当前代码已开始把类目候选扩展为 `parent_id`、`is_active` 并将前端控件改为 Cascader,但仍需完成启动同步触发、旧手动同步入口清理、树形数据与表单值的最终对接,以及真实页面回归。不要把这部分当作 M3.5 已完成。
- Ozon 采集器现在保存 BreadcrumbList/可见面包屑的名称与 URL 证据,但 `common.categories` 尚未保存可直接关联缓存节点的稳定 Ozon 类目 ID。需要在编辑上下文创建/读取时按规范化层级路径匹配缓存树,并且只在 profile 尚无用户选择时回填 `platform_product_category_id`,来源标记为 `source_capture`;用户手工选择或已保存类目不能被复采覆盖。
- 类目树同步应使用一个已验证的 Ozon 店铺凭据作为平台共享缓存来源,任务去重、失败重试和并发启动保护必须明确;不能为每个商品或每次打开编辑器重复请求 Ozon。类目缓存为空时页面应显示“缓存准备中/暂无可用类目”,而不是让用户发起同步。
- 当前中间代码的 TypeScript 检查需要先构建共享 contracts,再检查 Web/API/Worker;已验证命令为:`tsc -p packages/contracts/tsconfig.json`、随后分别执行各应用 `tsc --noEmit`。启动同步与类目自动回填尚未有集成测试。
## 2. 已确认产品决策
| 主题 | 决策 |
@@ -236,6 +294,17 @@ User → Workspace → Membership / Role
下一步建议按以下顺序推进:
> 注意:下面的历史清单仍保留用于追溯;当前执行优先级以 [`1.27 当前进行中`](#127-当前进行中2026-09-10类目树交互改造尚未验收) 和本段补充为准。先完成类目启动同步、树形选择与 Ozon 来源类目自动回填,再进入真实采集回归和后续发布能力。
当前执行顺序:
1. 实现 Worker 启动时一次性、幂等预热 Ozon 类目树;移除编辑器手动同步 UI;Cascader 直接读取数据库树。
2. 在创建/读取商品编辑上下文时,用来源面包屑层级与缓存 `path` 精确匹配 Ozon 类目;仅在 profile 没有用户已选类目时回填,并标记 `source_capture`。
3. 为启动同步、空缓存、重复启动、失败重试、树形选择和自动回填补 API/Worker 集成测试;重新执行 contracts、API、Worker、Web typecheck、Web build 与真实 8100 页面回归。
4. 完成动态属性 schema/字典缓存、候选媒体、定价、AI 任务、首次发布和在线商品同步的剩余纵向闭环。
### 历史计划(仅供追溯)
1. 在真实 Ozon 多 SKU 页面加载已构建扩展,确认 MAIN world bridge 未被页面策略阻断、三 SKU 都写入采集测试页、SKU 级画廊关系正确,并在新版规范化载荷确认完整特征与描述;再以任一兄弟 SKU 页面重采集,确认服务端覆盖同一记录。
2. 用允许保存的单 SKU、单规格轴和颜色×尺码页面样本,在 1688、淘宝、天猫逐项验证采集结果;页面状态未暴露组合数据时补站点适配器,但绝不以规格轴猜测 SKU。之后独立实施 Seller 网页四接口本地观察实验,默认关闭、仅保存净化结果且不影响标准采集。
3. 将当前 `/collection-test/{collectionItemId}` 只读检查面替换为正式商品编辑入口:按页头平台创建发布配置、预选同平台默认门店,并接入 SKU/媒体/类目编辑。