name: stock-invariant-deep description: | Углублённая проверка инварианта Stock.Quantity == Σ StockMovement по (product, store). Серия операций (Supply ×2, RetailSale ×2, Unpost, Re-post, ещё Supply) с проверкой после каждой. Плюс конкурентный POST двух чеков на один остаток — Serializable должен отбить один 409. preconditions: reset_db: true smoke_login_super_admin: true steps: - id: step01_bootstrap title: "Орг + admin + product (стартовый остаток 0)" - id: step02_supply_a_qty_20 title: "Supply A qty=20 → invariant stock=20, Σ movement=20" - id: step03_sale_a_qty_5 title: "RetailSale A qty=5 → invariant stock=15, Σ movement=15" - id: step04_supply_b_qty_10 title: "Supply B qty=10 → invariant stock=25, Σ movement=25" - id: step05_sale_b_qty_8 title: "RetailSale B qty=8 → invariant stock=17, Σ movement=17" - id: step06_unpost_sale_a title: "Unpost RetailSale A → invariant stock=22, Σ movement=22" - id: step07_repost_sale_a title: "Re-post RetailSale A → invariant stock=17, Σ movement=17" - id: step08_movement_count_correct title: "Всего StockMovement по продукту = 6 строк (2 supply + 2 sale + reverse sale + repost sale)" - id: step09_concurrent_sales_serialized title: "Два POST /post одновременно на один остаток — один 200, второй 409" - id: step10_final_invariant title: "Финальный invariant после всех операций сохраняется"