feat(M09-D3): 完成商品寄存与安全取出闭环

This commit is contained in:
Codex
2026-08-11 07:39:46 +08:00
parent 1a3ea7bdf0
commit 60264cbd11
28 changed files with 2735 additions and 72 deletions
@@ -0,0 +1,32 @@
# 2026-08-11 M09-D3 商品寄存与安全取出
## 工程结果
- 工程状态:当前工作树已完成,待以 `feat(M09-D3): 完成商品寄存与安全取出闭环` 中文标题提交并取得 SHA。
- 寄存来源限定为本人已完成商品订单或具备 `goods.storage.manage` 且拥有门店范围的员工手工创建;订单来源最多创建一张寄存单,手工来源必须绑定同租户有效顾客和当前门店有效上架 SKU。
- 状态机覆盖 `STORED``PARTIALLY_RETRIEVED``RETRIEVED``EXPIRED``CANCELLED`。每次取出锁定寄存单与明细、校验剩余数量和版本,逐项扣减后写不可变事件项流水。
- 领取凭证原文只在创建、主动轮换或部分取出后的响应中返回;数据库仅保存 SHA-256。部分取出自动产生下一版凭证,旧凭证立即失效;全量取出、取消和过期会消费凭证。
- 顾客只能查询和操作本人的寄存;管理端同时校验租户、`goods.storage.read/manage` 和授权门店范围。创建重放不会再次返回原始凭证,动作重放不会泄露轮换后的凭证。
- 寄存、取出、凭证轮换、取消和过期均在同一事务写审计与 `PRODUCT_STORAGE` outbox;死锁和锁等待超时进行最多 3 次完整事务重试。
## 数据库结果
`2026081109_m09d3_product_storage` 新增 4 张表:
1. `qipai_product_storage_records`
2. `qipai_product_storage_items`
3. `qipai_product_storage_events`
4. `qipai_product_storage_event_items`
迁移同时为商品订单项补充租户/门店/订单/主键复合唯一键,以支持寄存明细来源复合外键。寄存来源订单、客户端请求、事件请求、事件版本和订单项来源均有唯一约束;4 个触发器拒绝修改或删除寄存事件和逐项数量流水。
## 验证证据
- `node scripts/check-m09-d3-product-storage.mjs`PASS。
- 后端 `npm run build` 与全量 `npm test`:PASS;新增服务测试覆盖凭证摘要、取出状态转换和输入边界,路由测试覆盖顾客归属、管理权限与门店范围。
- WSL 原生临时副本 + MySQL 8.4.10:完成 `up → verify → down → up → verify`217 条 up、159 条 verify、199 条 downM09-D1 interrupted up/down 重试会按依赖先撤销 D3/D2并完整恢复。
- 真实 MySQL 业务用例覆盖订单寄存、手工寄存、创建幂等与指纹冲突、同源重复拒绝、跨租户/跨寄存人拒绝、超量拒绝、部分取出与旧凭证失效、并发全量取出单赢家、员工领取、主动轮换、取消、过期、outbox、审计和不可变触发器。
## 阶段结论
`M09-D3=DONE`。唯一执行游标进入 `M09-D4`,下一阶段在顾客小程序和运营后台接入商品目录、订单、库存与寄存/取出工作台。