Files
atlas-seller-kit/docs/project/HANDOFF.md
T

14 KiB
Raw Blame History

Atlas Seller Kit 交接说明

更新:2026-09-02。此文是新 AI 对话、架构讨论与开发工作的首读入口。

1. 项目定位

这是一个全新的云端产品,不是 ozon-seller-kit 的本地版重构。目标用户可拥有多个门店,每个门店只能绑定一个平台;平台自身可支持多个市场、国家、语言和币种。因此语言、币种、类目和发布规则不能写死为 Ozon 或中文/俄文。

当前已完成 pnpm monorepo 初始化:包含 Web、NestJS API、BullMQ Worker、WXT 浏览器扩展、共享 API 契约、数据库包、本地基础设施 Compose 与依赖锁文件。API 仅实现健康检查;Web 已具备完整前端框架(布局、路由、主题)和登录/注册页面,业务页面均为占位;Worker 与扩展为可运行骨架。尚未实现业务模块、迁移执行器、数据库 schema、鉴权或实际部署。不要从旧项目复制 SQLite 模型、无鉴权 API、旧 /trial/:id 或商品编辑页组件。可选择性复用已经验证过的纯计价公式、采集扩展思路和 AI 任务经验,但必须先适配多租户和云端边界。

当前运行时基线: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/technology-and-deployment.md。

1.1 开发进度(2026-09-02)

今日完成三项工作,全部通过 typecheck、生产构建,并经浏览器或启动实测:

Web 前端框架(apps/web)

  • 参照 ozon-seller-kit/studio 搭建:紫色主题(colorPrimary #8b5cf6、圆角 8)、index.css CSS 变量、可折叠侧边栏 + 吸顶页头 + 移动端 Drawer 的 MainLayout、@ 路径别名、StrictMode 入口。
  • 主题显式 fontSize: 14;输入类控件默认高度 32→34(controlHeight)、小尺寸 24→26(controlHeightSM);body 字号同步 14px。
  • 依赖使用最新稳定版:React 19.2.8、antd 6.6.2,新增 @ant-design/icons 6.3.4;沿用仓库精确版本号约定。
  • 左侧菜单按 requirements/account-store-watermark.md 的导航约定:在线商品(默认首页)、采集箱、店铺管理、水印管理、定价工具,均为占位页;另有菜单外的商品 AI 编辑页 /products/:id。
  • 基础设施:services/api.ts(axios 封装 + 统一错误提取)、config/env.ts(VITE_ 变量)、统一占位组件 components/PagePlaceholder。
  • Web tsconfig 覆盖 base 的 module: Node16 为 ESNext + bundler(base 面向 NestJS;Node16 会要求相对导入带扩展名);TypeScript 7 已移除 baseUrl,paths 直接相对 tsconfig 解析为 "@/*": ["./src/*"]。

注册与登录页面(契约:api/auth.md)

  • /login、/register 两页共用 AuthLayout(品牌视觉与主布局一致)。注册字段:显示名称(选填 ≤80)、邮箱、密码、确认密码;登录失败统一 401 文案,注册重复邮箱 409 落到邮箱字段提示。
  • 会话基础:access token 仅内存持有(services/authToken.ts),不进入任何持久化存储;api.ts 拦截器自动附加 Bearer 头,401 时用 refresh cookie 换新 token 并重放一次(并发去重),刷新失败整页跳转 /login。
  • 实测发现并修复:antd v6 中空值会同时触发 required 与 type: 'email' 两条错误,已改为非空才校验格式的 emailFormatRule(utils/validators.ts)。
  • 浏览器实测通过:表单校验、页面互链、API 未启动时的错误提示路径。密码复杂度按契约不在前端硬编码,仅提示以服务端校验为准。
  • 留待 API 认证模块就绪后:接入真实 /api/auth/* 调用、主布局路由守卫、刷新页面后的会话恢复;auth 类型届时迁移至 @atlas/contracts。

Worker 与扩展骨架修复

  • Worker:ioredis 是 BullMQ 的可选 peer 依赖,pnpm 严格隔离下必须由应用显式声明,已新增 ioredis 6.0.0;main.ts 改为显式构造 IORedis 实例并设置 maxRetriesPerRequest: null(原生 ESM 运行必需,也是后续 BullMQ Worker 的硬性要求)。tsx dev 与 node dist/main.js 两种运行方式均验证可连接本地 Redis。
  • 扩展:WXT dev server 从默认的 3000–3010 漂移改为固定 8110(EXTENSION_PORT 可覆盖,strictPort 开启);.output/ 构建产物已加入 .gitignore 并移出 git 跟踪。端口约定同步更新至交接、部署与项目结构三份文档及 .env.example。

2. 已确认产品决策

主题 决策
商品模型 每个商品是一个 SPU,且始终至少有一条 SKU;单规格商品使用默认 SKU,多规格商品使用多条 SKU。
平台可售单元 一个 SKU 对应一个独立平台 offer;Ozon 首个平台中对应 /v3/product/import.items[] 的一项和独立 offer_id。
通用属性 标题、品牌、型号、主题标签、简介、条形码、采买地址、货源备注及未来商品级属性;类目和平台属性属于独立的平台发布配置。首期不做富内容。
SKU 属性 SKU 名称、图片、货号、采购价、售价、划线价、包装重量和尺寸、商品重量和尺寸、商品颜色、颜色名称等。首期不支持视频。
型号/货号 型号(model)是父商品通用字段;offer_id 是当前平台下的每个 SKU 字段。采集时两者可为空;首次上架前必须由用户填写,系统不从标题、规格或来源 SKU 自动生成。被成功导入的 offer_id 作为历史事实锁定。
规格 实物规格与包装物流规格严格分离;尺寸图只读取实物规格,计价/物流/发布只读取包装规格。
继承 可继承字段的 null 表示该字段没有覆盖父商品默认值,不表示 SKU 不存在、名称为空或商品为单规格。
尺寸图 必须逐 SKU 生成,任务保存 SKU ID 和实物规格快照。
定价 SKU 上点“定价”打开弹窗,以有效包装数据计算;用户确认后回填 SKU 销售价和划线价。
编辑体验 新商品 AI 编辑页取代旧商品编辑页;旧试算页不再追加多 SKU 功能。
采集插件 采集 Ozon、1688、淘宝、天猫详情页;未登录只显示登录入口,已登录显示“编辑上架 / 采集商品 / 进入 ERP”。采集箱为工作空间共用,采集记录不关联目标平台或门店;用户进入 ERP 编辑时,按页头当前平台(首期默认 Ozon)取得该平台发布配置并预选默认店铺。A/B 平台的上架状态独立。详情见 requirements/collector-browser-extension.md。
采集 SKU 只有来源给出稳定 SKU/组合证据时创建多个 SKU;不能把规格轴做笛卡尔积。没有专属 SKU 图时,真实 SKU 继承父商品默认图而不复制资产。
媒体 采集主图/详情图是商品候选池;来源明确给出 SKU、或可靠的规格轴值(如颜色)与图片关系时才自动绑定。其余素材由编辑页人工选择。
发布与在线商品 商品采集、编辑、定价、AI 媒体和首次导入至 Ozon 后台是核心闭环。正式发布使用官方 Seller API,按一 SKU 一 import item/offer 执行并轮询结果;首期不传库存或仓库,用户在 Ozon 后台设置库存。已导入 SKU 不可再次上架,未上架 SKU 仍可首次上架;SPU 在当前平台汇总为未上架/已部分上架/已上架。在线商品由异步 Ozon API 同步,按 Ozon 商品 SKU 展示,亦包含非 Atlas 发布商品。

3. Ozon 已核对结论

仓内旧项目的 docs/ozon-seller-api/04-product-import.md 记录:Ozon /v3/product/import 每个 item 都有独立 offer_id、价格、包装尺寸/重量和图片,尺寸/重量不能为零;单次最多 100 项。03-category-attributes.md 记录类目属性的 is_aspect=true 表示变体属性。

因此 Ozon 适配器应以“一 SKU 一 import item/offer”为最小稳定单位。现有资料没有可强制把多个 item 合并为一个 Ozon 前台变体组的 API 契约,不能依赖自动归并;这是未来 Ozon 联调阶段要在真实店铺或沙盒验证的能力。

4. 云端架构底线

  1. 使用 PostgreSQL;所有业务行必须受 workspace_id 或可安全追溯至工作空间的外键约束。
  2. 首期注册后静默创建一个个人工作空间,并只建立一个 owner 成员;不展示工作空间、成员、角色或店铺级权限管理。后续有团队协作需求时再扩展。
  3. 门店只能绑定一个平台,不能跨平台使用;市场/国家、默认语言、支持语言和支持币种属于平台能力配置,不属于门店。门店保留已确认的默认计价币种与加密凭据;上述信息均不得写进商品核心表。
  4. 本地素材使用 MinIO;共享测试和生产素材使用七牛 Kodo,不使用应用服务器本地目录作为持久存储。
  5. AI、生图、导出、采集转存和发布使用 Redis + BullMQ 队列/Worker,任务可重试、可恢复且携带工作空间与 SKU 上下文。关键可重试写操作使用持久化幂等记录;异步任务与业务事实在同一 PostgreSQL 事务写入 Transactional Outbox,再由 Dispatcher 投递队列。Redis/BullMQ 不作为业务事实唯一来源。
  6. 用户界面语言、采集源语言、商品编辑语言和发布目标语言相互独立;文案及属性值需要支持多语言版本。
  7. 一期实现插件中显式开启的 Ozon Seller 网页本地观察:在用户浏览器的已登录 Seller 标签页调用四个已记录内部接口,并仅上传净化结果;不得提取完整、保存或上传 Cookie,不得阻塞标准采集、不得替代官方 Seller API 发布或把未验证经营数据视为本店事实。加密保存 Cookie 仅作为未来二级实验能力预留。

建议的核心层级:

User → Workspace → Membership / Role
                  → Store → Platform connection / default currency
                           → Product (SPU) → ProductVariant (SKU)
                                             → attributes / media / pricing snapshots / tasks

5. 已冻结的第一阶段 API 契约

第一阶段 HTTP API 的接口范围已讨论完成,当前状态为设计冻结、业务接口尚未实现。仓库已有 NestJS API 启动骨架及 GET /health,它不构成任何已实现的业务契约。后续编码以 docs/api/ 为唯一 HTTP 契约来源;旧 product/api.md 仅作历史背景,不能作为实现依据。

  • 覆盖账户认证、平台/门店、水印与素材、定价、浏览器采集/采集箱、商品编辑/首次发布、在线商品读取与同步。
  • 所有接口遵循统一鉴权、工作空间隔离、页头平台上下文、金额字符串、错误格式、Idempotency-Key、If-Match 和异步 operation 约定。
  • 关键异步动作必须在同一事务写入业务记录、operations(如需用户可见进度)和 outbox_events;Dispatcher 至少一次投递 BullMQ,Worker 必须幂等。
  • DDL 已通过临时隔离 PostgreSQL 实例执行验证;API 契约已完成文档评审。这不表示 NestJS 模块、迁移执行器或 Worker 已实现。

仍需在对应模块开始编码前完成的 P1/P2 决策和数据模型补丁,集中记录在 reviews/implementation-readiness-open-items.md。

6. 下一步建议

项目初始化已完成;下一步进入实现准备,而不是继续扩大 API 范围:

  1. 以 001_foundation.sql、002_product-domain.sql 建立可重复执行的迁移执行器,并按数据库角色/RLS 约束验证本地环境。
  2. 在 API 建立配置校验、认证、工作空间上下文和事务包装器;任何工作空间查询前固定 SET LOCAL app.workspace_id。
  3. 建立 operations、幂等请求和 Outbox Dispatcher 的第一个集成测试闭环。
  4. 在开始商品编辑/在线同步模块前,关闭评审文档中的 P1 事项:同商品归属约束、未映射属性持久化、乐观锁 Repository 规则、平台能力 Schema;并确认在线商品归档策略和 Client ID 编辑边界。
  5. 优先实现账户、平台上下文、门店、素材上传的纵向最小闭环,再接入采集箱和商品编辑;浏览器扩展仅在采集 API 稳定后实现实际解析器。
  6. Web 侧:认证 API 就绪后把登录/注册接入真实 /api/auth/*,补主布局路由守卫与刷新后的会话恢复,auth 类型迁移至 @atlas/contracts。

7. 文档导航