Files
junhong_cmp_fiber/openspec/changes/add-direct-exchange-flow/specs/exchange-order-model/spec.md
Break 27fba9160c
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 56s
提案
2026-06-04 09:39:20 +08:00

5.1 KiB
Raw Blame History

MODIFIED Requirements

Requirement: ExchangeOrder 换货单模型定义

系统 SHALL 定义 ExchangeOrder 模型并映射到 tb_exchange_order,用于承载客户端换货完整生命周期。

模型字段 MUST 至少包含:

  • 基础:idcreated_atupdated_atdeleted_atcreatorupdater
  • 单号:exchange_no
  • 流程:flow_type
  • 旧资产:old_asset_typeold_asset_idold_asset_identifier
  • 新资产:new_asset_typenew_asset_idnew_asset_identifier
  • 收货:recipient_namerecipient_phonerecipient_address
  • 物流:express_companyexpress_no
  • 迁移:migrate_datamigration_completedmigration_balance
  • 时间:shipped_atcompleted_at
  • 业务:exchange_reasonremarkstatus
  • 多租户:shop_id

flow_type MUST 使用字符串枚举,至少支持:

  • shipping:需要客户填写收货地址、后台发货、后台确认完成
  • direct:创建时直接完成,不经过客户填写地址和后台发货

flow_type MUST 在数据库层设置默认值 shipping,用于兼容历史记录与旧创建请求。

ExchangeOrder SHALL 嵌入 BaseModel 并实现 TableName() string,返回 tb_exchange_order

Scenario: 创建 shipping 换货单模型实例

  • WHEN 系统创建新的 shipping 换货单记录
  • THEN 记录 MUST 包含旧资产快照、流程类型 flow_type=shipping、收货信息占位、迁移状态字段和多租户字段

Scenario: 创建 direct 换货单模型实例

  • WHEN 系统创建新的 direct 换货单记录
  • THEN 记录 MUST 包含旧资产快照、新资产快照、流程类型 flow_type=direct
  • AND 记录在创建成功时即可具备 completed_at

Requirement: 换货状态常量定义

系统 MUST 使用 int 常量定义换货状态:

  • 1 待填写信息
  • 2 待发货
  • 3 已发货待确认
  • 4 已完成
  • 5 已取消

系统 MUST 使用独立的字符串常量定义换货流程类型:

  • shipping
  • direct

Scenario: 状态与流程常量一致性

  • WHEN Service、Store、Handler 读取或更新换货状态与流程类型
  • THEN 各层 MUST 使用统一常量值,禁止硬编码散落魔法数字和字符串

Requirement: 换货状态机流转规则

系统 SHALL 执行以下状态机:

  • shipping

    • 创建换货单后:status=1
    • 客户填写收货信息后:1 -> 2
    • 后台发货后:2 -> 3
    • 后台确认完成后:3 -> 4
    • 取消:仅允许 1/2 -> 5
  • direct

    • 创建换货单并完成后:status=4
    • 不经过 1/2/3
    • 不走客户端填写收货地址
    • 不走后台发货
    • 不进入取消状态机
    • 任一步失败时不保留半成品 direct 单据

系统 MUST 禁止非法流转(如 3 -> 54 -> 2direct 进入 2)。

Scenario: shipping 已发货不可取消

  • WHEN shipping 换货单状态为 3 且请求取消
  • THEN 系统 MUST 拒绝并返回状态流转非法错误

Scenario: direct 创建即完成

  • WHEN 后台以 flow_type=direct 创建换货单且所有校验通过
  • THEN 系统 MUST 直接创建 status=4 的换货单
  • AND MUST 写入 completed_at

Scenario: direct 失败不落半成品状态

  • WHEN 后台以 flow_type=direct 创建换货单但完成事务失败
  • THEN 系统 MUST 回滚创建
  • AND MUST NOT 产生 flow_type=direct AND status IN (1,2,3) 的换货单

Scenario: direct 不允许进入发货阶段

  • WHEN direct 换货单请求执行发货或填写收货地址
  • THEN 系统 MUST 拒绝并返回流程类型不支持该操作的错误

Requirement: 换货单号生成规则

系统 MUST 为每个换货单生成全局可追踪单号,格式为:EXC + 时间戳片段 + 随机数片段

生成规则 SHALL 满足:

  • 前缀固定为 EXC
  • 包含日期/时间信息用于人工排查
  • 包含随机片段降低并发冲突概率

Scenario: 生成换货单号

  • WHEN 后台发起换货并创建新单
  • THEN 系统 MUST 生成形如 EXC20260319XXXXXX 的单号并写入 exchange_no

Requirement: 换货关键业务时间字段语义

系统 SHALL 使用独立的业务时间字段表达发货完成和换货完成,而不是复用 updated_at

字段语义 MUST 满足:

  • shipped_at:仅在 shipping 流程发货成功后写入
  • completed_at:仅在换货完成成功后写入,shippingdirect 共用
  • direct 流程 MUST 保持 shipped_at 为空
  • 历史已完成单据若 completed_at 为空,查询与追溯层 MUST 回退使用 updated_at

Scenario: shipping 写入发货时间

  • WHEN shipping 换货单执行后台发货成功
  • THEN 系统 MUST 记录 shipped_at=当前时间

Scenario: direct 不写发货时间

  • WHEN direct 换货单创建并完成成功
  • THEN 系统 MUST 保持 shipped_at 为空
  • AND MUST 写入 completed_at=当前时间

Scenario: 历史单据完成时间兼容

  • WHEN 查询历史已完成换货单且 completed_at 为空
  • THEN 系统 MUST 在追溯展示中回退使用 updated_at 作为兼容完成时间