feat(M09-D2): 完成商品订单与库存占用生命周期

This commit is contained in:
Codex
2026-08-11 07:04:23 +08:00
parent 93af128002
commit 1a3ea7bdf0
30 changed files with 3773 additions and 91 deletions
@@ -2,7 +2,7 @@
## 工程结果
- 工程状态:当前工作树已完成,待`feat(M09-D1): 完成商品目录与库存流水底座` 中文标题提交并取得 SHA
- 工程状态:已由 `93af128002c27ea548e9ed7d0c9af7b8f264002a` `feat(M09-D1): 完成商品目录与库存流水底座` 中文标题提交并推送
- 新增分类、商品、SKU、门店上架、门店销售设置、每周最多 8 段且支持跨日的营业时段;分类/商品/SKU 支持软删除后的代码或条码复用,写操作统一使用 `expectedVersion` 乐观锁。
- 新增 `TRACKED` / `UNLIMITED` 库存策略、可用/锁定/损耗三类数量,以及入库、调整、盘点、损耗、批量锁定、释放和扣减服务;批量操作同事务完成,任何一个 SKU 失败均整体回滚。
- 库存请求以租户、门店和大小写敏感 requestId 建立全局幂等记录;请求指纹不一致明确拒绝,锁定归属按业务类型和业务号核对,重复释放、跨订单释放和超额扣减不会改动库存。
@@ -33,7 +33,7 @@
- 管理端 `npm run build``npm test`PASS。
- WSL 原生临时副本 + MySQL 8.4.10:完成 `up → verify → down → up → verify`179 条 up、141 条 verify、171 条 down;双连接迁移锁、interrupted up/down DDL 原地重跑、增量 marker/checksum、触发器生产前置和 cleanup probe 均 PASS。
- 真实 MySQL 业务用例覆盖门店唯一性、跨日时段、商品/SKU 版本冲突、并发锁定单赢家、重复 requestId 重放与冲突、批量原子回滚、锁定/释放/扣减、损耗/盘点、负库存拒绝、流水对账与不可变触发器。
- Windows 汇总门禁在全部 M09-D1 与 V5.7 文件显式暂存后执行最终复跑;不得将提交前的未跟踪完整性提示记为功能失败。
- Windows 汇总门禁在全部 M09-D1 与 V5.7 文件显式暂存后最终复跑通过;提交前的未跟踪完整性提示未被记作功能失败。
## 阶段结论
@@ -0,0 +1,37 @@
# 2026-08-11 M09-D2 商品订单与库存生命周期
## 工程结果
- 工程状态:当前工作树已完成,待以 `feat(M09-D2): 完成商品订单与库存占用生命周期` 中文标题提交并取得 SHA。
- 新增独立的商品订单、订单项快照、订单事件、支付、退款、支付回调和退款事件领域;商品订单不复用房间订单或支付单状态,订单项固化商品/SKU 名称、规格、单价、数量、小计和备注。
- 顾客创建订单时由服务端读取有效门店上架、售价、销售开关和跨日营业时段并复算金额;`DELIVERY` 必须绑定本人当前有效房间订单,`SELF_SERVICE` 明确禁止伪造房间绑定。
- 下单按稳定订单业务号批量锁定库存;支付成功回调在同一事务扣减并推进 `PAID`,取消和待支付超时释放,退款按履约状态选择 `RESTOCK``NO_RESTOCK`。重复请求、重复回调和指纹冲突分别重放或明确拒绝。
- 支付回调统一事务边界对 MySQL 死锁和锁等待超时最多重试 3 次;真实并发回调验证只有一个扣减副作用,另一请求按已落库 callback 幂等返回。
- 顾客 API 支持创建、本人列表/详情、取消;管理 API 同时提供后台和管理员小程序前缀,支持门店列表/详情、接单、配送、自助待取、完成、取消和退款。服务端重复校验 `goods.order.read/manage`、租户和授权门店范围。
- 测试支付与退款适配器只在显式非生产开关开启时注册;生产支付/退款回调通过领域服务输入对接后续真实微信适配器,禁止暴露测试完成接口。
## 数据库结果
`2026081108_m09d2_product_order_payment_inventory` 新增 7 张表:
1. `qipai_product_orders`
2. `qipai_product_order_items`
3. `qipai_product_order_events`
4. `qipai_product_payments`
5. `qipai_product_refunds`
6. `qipai_product_payment_callbacks`
7. `qipai_product_refund_events`
订单项、订单事件和退款事件均由数据库双触发器拒绝 UPDATE/DELETE;订单/支付/退款业务号、客户端请求、有效单据、回调和事件版本使用唯一键防重。复合外键保持租户、门店、订单、支付、退款和库存请求归属一致。
## 验证证据
- `node scripts/check-m09-d2-product-orders.mjs`:PASS,静态门禁确认迁移、路由、服务、RBAC、回归入口及 Windows/WSL 门禁均已接线。
- 后端 `npm run build`、后端全量 `npm test`:PASS;新增服务与路由测试覆盖服务端快照、状态转换、本人边界、门店范围和测试适配器生产隔离。
- WSL 原生临时副本 + MySQL 8.4.10:完成 `up → verify → down → up → verify`201 条 up、150 条 verify、187 条 downM09-D1 interrupted up/down 重试会先按依赖撤销 D2,恢复后 D2 权限和表完整重建。
- 真实 MySQL 业务用例覆盖下单重放/指纹冲突、无效房间配送拒绝、并发支付单次扣减、配送和自助状态机、已完成订单退款不返库、未履约订单退款返库、待支付取消释放、超时批量回收、跨门店拒绝及不可变事件触发器。
- Windows 汇总门禁在全部 M09-D2 与伴随文档显式暂存后执行最终复跑;提交前唯一失败为完整性门禁按设计拒绝未跟踪的新交付文件,不是功能失败。
## 阶段结论
`M09-D2=DONE`。唯一执行游标进入 `M09-D3`,下一阶段建立寄存单、分次取出、哈希领取凭证、并发防超领和通知 outbox。