@open-mercato/core 0.6.7-develop.6661.1.0043ed1d03 → 0.6.7-develop.6670.1.4efa7961c6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/inventory_balance/index.js +21 -0
  3. package/dist/generated/entities/inventory_balance/index.js.map +7 -0
  4. package/dist/generated/entities/inventory_lot/index.js +19 -0
  5. package/dist/generated/entities/inventory_lot/index.js.map +7 -0
  6. package/dist/generated/entities/inventory_movement/index.js +35 -0
  7. package/dist/generated/entities/inventory_movement/index.js.map +7 -0
  8. package/dist/generated/entities/inventory_reservation/index.js +23 -0
  9. package/dist/generated/entities/inventory_reservation/index.js.map +7 -0
  10. package/dist/generated/entities/product_inventory_profile/index.js +21 -0
  11. package/dist/generated/entities/product_inventory_profile/index.js.map +7 -0
  12. package/dist/generated/entities/sales_order_warehouse_assignment/index.js +11 -0
  13. package/dist/generated/entities/sales_order_warehouse_assignment/index.js.map +7 -0
  14. package/dist/generated/entities/warehouse/index.js +25 -0
  15. package/dist/generated/entities/warehouse/index.js.map +7 -0
  16. package/dist/generated/entities/warehouse_location/index.js +21 -0
  17. package/dist/generated/entities/warehouse_location/index.js.map +7 -0
  18. package/dist/generated/entities/warehouse_zone/index.js +11 -0
  19. package/dist/generated/entities/warehouse_zone/index.js.map +7 -0
  20. package/dist/generated/entities.ids.generated.js +12 -0
  21. package/dist/generated/entities.ids.generated.js.map +2 -2
  22. package/dist/generated/entity-fields-registry.js +98 -0
  23. package/dist/generated/entity-fields-registry.js.map +2 -2
  24. package/dist/modules/auth/backend/roles/page.js +12 -4
  25. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  26. package/dist/modules/auth/lib/backendChrome.js +1 -0
  27. package/dist/modules/auth/lib/backendChrome.js.map +2 -2
  28. package/dist/modules/auth/services/rbacService.js +16 -17
  29. package/dist/modules/auth/services/rbacService.js.map +2 -2
  30. package/dist/modules/catalog/api/products/route.js +3 -0
  31. package/dist/modules/catalog/api/products/route.js.map +2 -2
  32. package/dist/modules/catalog/api/variants/route.js +3 -0
  33. package/dist/modules/catalog/api/variants/route.js.map +2 -2
  34. package/dist/modules/customer_accounts/migrations/Migration20260724120000_customer_accounts.js +56 -0
  35. package/dist/modules/customer_accounts/migrations/Migration20260724120000_customer_accounts.js.map +7 -0
  36. package/dist/modules/directory/api/organizations/route.js +1 -1
  37. package/dist/modules/directory/api/organizations/route.js.map +1 -1
  38. package/dist/modules/entities/api/definitions.js +2 -0
  39. package/dist/modules/entities/api/definitions.js.map +2 -2
  40. package/dist/modules/entities/lib/helpers.js +1 -0
  41. package/dist/modules/entities/lib/helpers.js.map +2 -2
  42. package/dist/modules/query_index/lib/engine.js +6 -6
  43. package/dist/modules/query_index/lib/engine.js.map +2 -2
  44. package/dist/modules/sales/api/documents/factory.js +1 -0
  45. package/dist/modules/sales/api/documents/factory.js.map +2 -2
  46. package/dist/modules/sales/api/quotes/accept/route.js +7 -2
  47. package/dist/modules/sales/api/quotes/accept/route.js.map +2 -2
  48. package/dist/modules/sales/api/quotes/public/[token]/route.js +2 -1
  49. package/dist/modules/sales/api/quotes/public/[token]/route.js.map +2 -2
  50. package/dist/modules/sales/commands/documents.js +53 -0
  51. package/dist/modules/sales/commands/documents.js.map +2 -2
  52. package/dist/modules/sales/components/documents/ItemsSection.js +51 -2
  53. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  54. package/dist/modules/sales/events.js +2 -0
  55. package/dist/modules/sales/events.js.map +2 -2
  56. package/dist/modules/sales/lib/publicQuoteTenantScope.js +24 -0
  57. package/dist/modules/sales/lib/publicQuoteTenantScope.js.map +7 -0
  58. package/dist/modules/sales/widgets/injection/order-items-context.js +11 -0
  59. package/dist/modules/sales/widgets/injection/order-items-context.js.map +7 -0
  60. package/dist/modules/wms/acl.js +18 -0
  61. package/dist/modules/wms/acl.js.map +7 -0
  62. package/dist/modules/wms/analytics.js +11 -0
  63. package/dist/modules/wms/analytics.js.map +7 -0
  64. package/dist/modules/wms/api/dashboard/operational/route.js +80 -0
  65. package/dist/modules/wms/api/dashboard/operational/route.js.map +7 -0
  66. package/dist/modules/wms/api/interceptors.js +90 -0
  67. package/dist/modules/wms/api/interceptors.js.map +7 -0
  68. package/dist/modules/wms/api/inventory/adjust/route.js +51 -0
  69. package/dist/modules/wms/api/inventory/adjust/route.js.map +7 -0
  70. package/dist/modules/wms/api/inventory/allocate/route.js +51 -0
  71. package/dist/modules/wms/api/inventory/allocate/route.js.map +7 -0
  72. package/dist/modules/wms/api/inventory/balances/route.js +172 -0
  73. package/dist/modules/wms/api/inventory/balances/route.js.map +7 -0
  74. package/dist/modules/wms/api/inventory/cycle-count/route.js +52 -0
  75. package/dist/modules/wms/api/inventory/cycle-count/route.js.map +7 -0
  76. package/dist/modules/wms/api/inventory/helpers.js +113 -0
  77. package/dist/modules/wms/api/inventory/helpers.js.map +7 -0
  78. package/dist/modules/wms/api/inventory/import/apply/route.js +46 -0
  79. package/dist/modules/wms/api/inventory/import/apply/route.js.map +7 -0
  80. package/dist/modules/wms/api/inventory/import/helpers.js +195 -0
  81. package/dist/modules/wms/api/inventory/import/helpers.js.map +7 -0
  82. package/dist/modules/wms/api/inventory/import/template/route.js +32 -0
  83. package/dist/modules/wms/api/inventory/import/template/route.js.map +7 -0
  84. package/dist/modules/wms/api/inventory/import/validate/route.js +54 -0
  85. package/dist/modules/wms/api/inventory/import/validate/route.js.map +7 -0
  86. package/dist/modules/wms/api/inventory/move/route.js +51 -0
  87. package/dist/modules/wms/api/inventory/move/route.js.map +7 -0
  88. package/dist/modules/wms/api/inventory/movements/route.js +164 -0
  89. package/dist/modules/wms/api/inventory/movements/route.js.map +7 -0
  90. package/dist/modules/wms/api/inventory/receive/route.js +50 -0
  91. package/dist/modules/wms/api/inventory/receive/route.js.map +7 -0
  92. package/dist/modules/wms/api/inventory/release/route.js +44 -0
  93. package/dist/modules/wms/api/inventory/release/route.js.map +7 -0
  94. package/dist/modules/wms/api/inventory/reservations/route.js +128 -0
  95. package/dist/modules/wms/api/inventory/reservations/route.js.map +7 -0
  96. package/dist/modules/wms/api/inventory/reserve/route.js +59 -0
  97. package/dist/modules/wms/api/inventory/reserve/route.js.map +7 -0
  98. package/dist/modules/wms/api/inventory-profiles/route.js +178 -0
  99. package/dist/modules/wms/api/inventory-profiles/route.js.map +7 -0
  100. package/dist/modules/wms/api/listEnrichers.js +181 -0
  101. package/dist/modules/wms/api/listEnrichers.js.map +7 -0
  102. package/dist/modules/wms/api/listSearch.js +77 -0
  103. package/dist/modules/wms/api/listSearch.js.map +7 -0
  104. package/dist/modules/wms/api/locations/route.js +172 -0
  105. package/dist/modules/wms/api/locations/route.js.map +7 -0
  106. package/dist/modules/wms/api/lots/route.js +204 -0
  107. package/dist/modules/wms/api/lots/route.js.map +7 -0
  108. package/dist/modules/wms/api/openapi.js +27 -0
  109. package/dist/modules/wms/api/openapi.js.map +7 -0
  110. package/dist/modules/wms/api/sales-orders/[salesOrderId]/re-run-reservation/route.js +54 -0
  111. package/dist/modules/wms/api/sales-orders/[salesOrderId]/re-run-reservation/route.js.map +7 -0
  112. package/dist/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.js +279 -0
  113. package/dist/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.js.map +7 -0
  114. package/dist/modules/wms/api/sales-orders/assign-warehouse/route.js +56 -0
  115. package/dist/modules/wms/api/sales-orders/assign-warehouse/route.js.map +7 -0
  116. package/dist/modules/wms/api/sales-orders/unassign-warehouse/route.js +43 -0
  117. package/dist/modules/wms/api/sales-orders/unassign-warehouse/route.js.map +7 -0
  118. package/dist/modules/wms/api/warehouses/route.js +181 -0
  119. package/dist/modules/wms/api/warehouses/route.js.map +7 -0
  120. package/dist/modules/wms/api/zones/route.js +159 -0
  121. package/dist/modules/wms/api/zones/route.js.map +7 -0
  122. package/dist/modules/wms/backend/config/wms/page.js +9 -0
  123. package/dist/modules/wms/backend/config/wms/page.js.map +7 -0
  124. package/dist/modules/wms/backend/config/wms/page.meta.js +18 -0
  125. package/dist/modules/wms/backend/config/wms/page.meta.js.map +7 -0
  126. package/dist/modules/wms/backend/page.js +9 -0
  127. package/dist/modules/wms/backend/page.js.map +7 -0
  128. package/dist/modules/wms/backend/page.meta.js +16 -0
  129. package/dist/modules/wms/backend/page.meta.js.map +7 -0
  130. package/dist/modules/wms/backend/wms/inventory/page.js +9 -0
  131. package/dist/modules/wms/backend/wms/inventory/page.js.map +7 -0
  132. package/dist/modules/wms/backend/wms/inventory/page.meta.js +18 -0
  133. package/dist/modules/wms/backend/wms/inventory/page.meta.js.map +7 -0
  134. package/dist/modules/wms/backend/wms/location/[id]/page.js +9 -0
  135. package/dist/modules/wms/backend/wms/location/[id]/page.js.map +7 -0
  136. package/dist/modules/wms/backend/wms/location/[id]/page.meta.js +18 -0
  137. package/dist/modules/wms/backend/wms/location/[id]/page.meta.js.map +7 -0
  138. package/dist/modules/wms/backend/wms/locations/page.js +10 -0
  139. package/dist/modules/wms/backend/wms/locations/page.js.map +7 -0
  140. package/dist/modules/wms/backend/wms/locations/page.meta.js +18 -0
  141. package/dist/modules/wms/backend/wms/locations/page.meta.js.map +7 -0
  142. package/dist/modules/wms/backend/wms/lot/[id]/page.js +9 -0
  143. package/dist/modules/wms/backend/wms/lot/[id]/page.js.map +7 -0
  144. package/dist/modules/wms/backend/wms/lot/[id]/page.meta.js +18 -0
  145. package/dist/modules/wms/backend/wms/lot/[id]/page.meta.js.map +7 -0
  146. package/dist/modules/wms/backend/wms/lots/page.js +9 -0
  147. package/dist/modules/wms/backend/wms/lots/page.js.map +7 -0
  148. package/dist/modules/wms/backend/wms/lots/page.meta.js +18 -0
  149. package/dist/modules/wms/backend/wms/lots/page.meta.js.map +7 -0
  150. package/dist/modules/wms/backend/wms/movements/page.js +22 -0
  151. package/dist/modules/wms/backend/wms/movements/page.js.map +7 -0
  152. package/dist/modules/wms/backend/wms/movements/page.meta.js +18 -0
  153. package/dist/modules/wms/backend/wms/movements/page.meta.js.map +7 -0
  154. package/dist/modules/wms/backend/wms/reservations/page.js +23 -0
  155. package/dist/modules/wms/backend/wms/reservations/page.js.map +7 -0
  156. package/dist/modules/wms/backend/wms/reservations/page.meta.js +18 -0
  157. package/dist/modules/wms/backend/wms/reservations/page.meta.js.map +7 -0
  158. package/dist/modules/wms/backend/wms/sku/[id]/page.js +9 -0
  159. package/dist/modules/wms/backend/wms/sku/[id]/page.js.map +7 -0
  160. package/dist/modules/wms/backend/wms/sku/[id]/page.meta.js +18 -0
  161. package/dist/modules/wms/backend/wms/sku/[id]/page.meta.js.map +7 -0
  162. package/dist/modules/wms/backend/wms/warehouses/page.js +10 -0
  163. package/dist/modules/wms/backend/wms/warehouses/page.js.map +7 -0
  164. package/dist/modules/wms/backend/wms/warehouses/page.meta.js +18 -0
  165. package/dist/modules/wms/backend/wms/warehouses/page.meta.js.map +7 -0
  166. package/dist/modules/wms/backend/wms/zones/page.js +10 -0
  167. package/dist/modules/wms/backend/wms/zones/page.js.map +7 -0
  168. package/dist/modules/wms/backend/wms/zones/page.meta.js +18 -0
  169. package/dist/modules/wms/backend/wms/zones/page.meta.js.map +7 -0
  170. package/dist/modules/wms/ce.js +80 -0
  171. package/dist/modules/wms/ce.js.map +7 -0
  172. package/dist/modules/wms/cli.js +83 -0
  173. package/dist/modules/wms/cli.js.map +7 -0
  174. package/dist/modules/wms/commands/configuration.js +1519 -0
  175. package/dist/modules/wms/commands/configuration.js.map +7 -0
  176. package/dist/modules/wms/commands/index.js +4 -0
  177. package/dist/modules/wms/commands/index.js.map +7 -0
  178. package/dist/modules/wms/commands/inventory-actions.js +1539 -0
  179. package/dist/modules/wms/commands/inventory-actions.js.map +7 -0
  180. package/dist/modules/wms/commands/sales-order-assignment.js +277 -0
  181. package/dist/modules/wms/commands/sales-order-assignment.js.map +7 -0
  182. package/dist/modules/wms/commands/shared.js +82 -0
  183. package/dist/modules/wms/commands/shared.js.map +7 -0
  184. package/dist/modules/wms/components/backend/AdjustInventoryDialog.js +755 -0
  185. package/dist/modules/wms/components/backend/AdjustInventoryDialog.js.map +7 -0
  186. package/dist/modules/wms/components/backend/ChangeLotStatusDialog.js +269 -0
  187. package/dist/modules/wms/components/backend/ChangeLotStatusDialog.js.map +7 -0
  188. package/dist/modules/wms/components/backend/CycleCountWizardDialog.js +1783 -0
  189. package/dist/modules/wms/components/backend/CycleCountWizardDialog.js.map +7 -0
  190. package/dist/modules/wms/components/backend/ImportInventoryDialog.js +766 -0
  191. package/dist/modules/wms/components/backend/ImportInventoryDialog.js.map +7 -0
  192. package/dist/modules/wms/components/backend/InventoryOperationsSection.js +119 -0
  193. package/dist/modules/wms/components/backend/InventoryOperationsSection.js.map +7 -0
  194. package/dist/modules/wms/components/backend/LocationEditDialog.js +140 -0
  195. package/dist/modules/wms/components/backend/LocationEditDialog.js.map +7 -0
  196. package/dist/modules/wms/components/backend/MoveInventoryDialog.js +791 -0
  197. package/dist/modules/wms/components/backend/MoveInventoryDialog.js.map +7 -0
  198. package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js +656 -0
  199. package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js.map +7 -0
  200. package/dist/modules/wms/components/backend/ReleaseReservationDialog.js +344 -0
  201. package/dist/modules/wms/components/backend/ReleaseReservationDialog.js.map +7 -0
  202. package/dist/modules/wms/components/backend/ReserveInventoryDialog.js +475 -0
  203. package/dist/modules/wms/components/backend/ReserveInventoryDialog.js.map +7 -0
  204. package/dist/modules/wms/components/backend/WmsConfigurationPage.js +1112 -0
  205. package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +7 -0
  206. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +908 -0
  207. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +7 -0
  208. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +1015 -0
  209. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +7 -0
  210. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +1049 -0
  211. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +7 -0
  212. package/dist/modules/wms/components/backend/WmsLotsListPage.js +297 -0
  213. package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +7 -0
  214. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +757 -0
  215. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +7 -0
  216. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +975 -0
  217. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +7 -0
  218. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +710 -0
  219. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +7 -0
  220. package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js +79 -0
  221. package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js.map +7 -0
  222. package/dist/modules/wms/components/backend/useWmsInventoryScopeFromSearchParams.js +24 -0
  223. package/dist/modules/wms/components/backend/useWmsInventoryScopeFromSearchParams.js.map +7 -0
  224. package/dist/modules/wms/components/backend/wmsLookupLoaders.js +55 -0
  225. package/dist/modules/wms/components/backend/wmsLookupLoaders.js.map +7 -0
  226. package/dist/modules/wms/data/enrichers.js +501 -0
  227. package/dist/modules/wms/data/enrichers.js.map +7 -0
  228. package/dist/modules/wms/data/entities.js +467 -0
  229. package/dist/modules/wms/data/entities.js.map +7 -0
  230. package/dist/modules/wms/data/validators.js +399 -0
  231. package/dist/modules/wms/data/validators.js.map +7 -0
  232. package/dist/modules/wms/di.js +27 -0
  233. package/dist/modules/wms/di.js.map +7 -0
  234. package/dist/modules/wms/events.js +42 -0
  235. package/dist/modules/wms/events.js.map +7 -0
  236. package/dist/modules/wms/index.js +17 -0
  237. package/dist/modules/wms/index.js.map +7 -0
  238. package/dist/modules/wms/lib/catalogInventoryProfileIntent.js +54 -0
  239. package/dist/modules/wms/lib/catalogInventoryProfileIntent.js.map +7 -0
  240. package/dist/modules/wms/lib/catalogInventoryProfileSync.js +144 -0
  241. package/dist/modules/wms/lib/catalogInventoryProfileSync.js.map +7 -0
  242. package/dist/modules/wms/lib/expiry.js +29 -0
  243. package/dist/modules/wms/lib/expiry.js.map +7 -0
  244. package/dist/modules/wms/lib/flashMutationError.js +51 -0
  245. package/dist/modules/wms/lib/flashMutationError.js.map +7 -0
  246. package/dist/modules/wms/lib/inventoryDisplayUi.js +188 -0
  247. package/dist/modules/wms/lib/inventoryDisplayUi.js.map +7 -0
  248. package/dist/modules/wms/lib/inventoryIdempotency.js +37 -0
  249. package/dist/modules/wms/lib/inventoryIdempotency.js.map +7 -0
  250. package/dist/modules/wms/lib/inventoryImportCsv.js +173 -0
  251. package/dist/modules/wms/lib/inventoryImportCsv.js.map +7 -0
  252. package/dist/modules/wms/lib/inventoryImportService.js +468 -0
  253. package/dist/modules/wms/lib/inventoryImportService.js.map +7 -0
  254. package/dist/modules/wms/lib/inventoryMutationUi.js +25 -0
  255. package/dist/modules/wms/lib/inventoryMutationUi.js.map +7 -0
  256. package/dist/modules/wms/lib/inventoryPolicy.js +61 -0
  257. package/dist/modules/wms/lib/inventoryPolicy.js.map +7 -0
  258. package/dist/modules/wms/lib/inventoryReconciliation.js +193 -0
  259. package/dist/modules/wms/lib/inventoryReconciliation.js.map +7 -0
  260. package/dist/modules/wms/lib/inventoryTrackingValidation.js +13 -0
  261. package/dist/modules/wms/lib/inventoryTrackingValidation.js.map +7 -0
  262. package/dist/modules/wms/lib/loadOperationalDashboard.js +580 -0
  263. package/dist/modules/wms/lib/loadOperationalDashboard.js.map +7 -0
  264. package/dist/modules/wms/lib/lowStockBalanceFilter.js +49 -0
  265. package/dist/modules/wms/lib/lowStockBalanceFilter.js.map +7 -0
  266. package/dist/modules/wms/lib/primaryWarehousePolicy.js +32 -0
  267. package/dist/modules/wms/lib/primaryWarehousePolicy.js.map +7 -0
  268. package/dist/modules/wms/lib/roleFeatures.js +30 -0
  269. package/dist/modules/wms/lib/roleFeatures.js.map +7 -0
  270. package/dist/modules/wms/lib/salesOrderInventoryAutomation.js +291 -0
  271. package/dist/modules/wms/lib/salesOrderInventoryAutomation.js.map +7 -0
  272. package/dist/modules/wms/lib/salesOrderWarehouseAssignment.js +54 -0
  273. package/dist/modules/wms/lib/salesOrderWarehouseAssignment.js.map +7 -0
  274. package/dist/modules/wms/lib/wmsIntegrationToggles.js +71 -0
  275. package/dist/modules/wms/lib/wmsIntegrationToggles.js.map +7 -0
  276. package/dist/modules/wms/migrations/Migration20260428110546.js +78 -0
  277. package/dist/modules/wms/migrations/Migration20260428110546.js.map +7 -0
  278. package/dist/modules/wms/migrations/Migration20260527120000.js +15 -0
  279. package/dist/modules/wms/migrations/Migration20260527120000.js.map +7 -0
  280. package/dist/modules/wms/migrations/Migration20260527140000.js +37 -0
  281. package/dist/modules/wms/migrations/Migration20260527140000.js.map +7 -0
  282. package/dist/modules/wms/migrations/Migration20260613120000.js +23 -0
  283. package/dist/modules/wms/migrations/Migration20260613120000.js.map +7 -0
  284. package/dist/modules/wms/migrations/Migration20260616090000.js +13 -0
  285. package/dist/modules/wms/migrations/Migration20260616090000.js.map +7 -0
  286. package/dist/modules/wms/migrations/Migration20260707180000.js +15 -0
  287. package/dist/modules/wms/migrations/Migration20260707180000.js.map +7 -0
  288. package/dist/modules/wms/notifications.client.js +18 -0
  289. package/dist/modules/wms/notifications.client.js.map +7 -0
  290. package/dist/modules/wms/notifications.js +53 -0
  291. package/dist/modules/wms/notifications.js.map +7 -0
  292. package/dist/modules/wms/search.js +196 -0
  293. package/dist/modules/wms/search.js.map +7 -0
  294. package/dist/modules/wms/setup.js +30 -0
  295. package/dist/modules/wms/setup.js.map +7 -0
  296. package/dist/modules/wms/subscribers/low-stock-notification.js +40 -0
  297. package/dist/modules/wms/subscribers/low-stock-notification.js.map +7 -0
  298. package/dist/modules/wms/subscribers/reservation-shortfall-notification.js +69 -0
  299. package/dist/modules/wms/subscribers/reservation-shortfall-notification.js.map +7 -0
  300. package/dist/modules/wms/subscribers/sales-order-cancelled-release.js +14 -0
  301. package/dist/modules/wms/subscribers/sales-order-cancelled-release.js.map +7 -0
  302. package/dist/modules/wms/subscribers/sales-order-confirmed-reserve.js +14 -0
  303. package/dist/modules/wms/subscribers/sales-order-confirmed-reserve.js.map +7 -0
  304. package/dist/modules/wms/translations.js +10 -0
  305. package/dist/modules/wms/translations.js.map +7 -0
  306. package/dist/modules/wms/vector.js +9 -0
  307. package/dist/modules/wms/vector.js.map +7 -0
  308. package/dist/modules/wms/widgets/injection/catalog-inventory-profile/widget.js +200 -0
  309. package/dist/modules/wms/widgets/injection/catalog-inventory-profile/widget.js.map +7 -0
  310. package/dist/modules/wms/widgets/injection/order-items-stock-column/widget.js +104 -0
  311. package/dist/modules/wms/widgets/injection/order-items-stock-column/widget.js.map +7 -0
  312. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js +389 -0
  313. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js.map +7 -0
  314. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.js +16 -0
  315. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.js.map +7 -0
  316. package/dist/modules/wms/widgets/injection-table.js +36 -0
  317. package/dist/modules/wms/widgets/injection-table.js.map +7 -0
  318. package/dist/modules/wms/widgets/notifications/WmsLowStockRenderer.js +150 -0
  319. package/dist/modules/wms/widgets/notifications/WmsLowStockRenderer.js.map +7 -0
  320. package/dist/modules/wms/widgets/notifications/WmsReservationShortfallRenderer.js +186 -0
  321. package/dist/modules/wms/widgets/notifications/WmsReservationShortfallRenderer.js.map +7 -0
  322. package/dist/modules/wms/widgets/notifications/index.js +7 -0
  323. package/dist/modules/wms/widgets/notifications/index.js.map +7 -0
  324. package/generated/entities/inventory_balance/index.ts +9 -0
  325. package/generated/entities/inventory_lot/index.ts +8 -0
  326. package/generated/entities/inventory_movement/index.ts +16 -0
  327. package/generated/entities/inventory_reservation/index.ts +10 -0
  328. package/generated/entities/product_inventory_profile/index.ts +9 -0
  329. package/generated/entities/sales_order_warehouse_assignment/index.ts +4 -0
  330. package/generated/entities/warehouse/index.ts +11 -0
  331. package/generated/entities/warehouse_location/index.ts +9 -0
  332. package/generated/entities/warehouse_zone/index.ts +4 -0
  333. package/generated/entities.ids.generated.ts +12 -0
  334. package/generated/entity-fields-registry.ts +98 -0
  335. package/package.json +7 -7
  336. package/src/modules/auth/backend/roles/page.tsx +13 -4
  337. package/src/modules/auth/i18n/de.json +2 -0
  338. package/src/modules/auth/i18n/en.json +2 -0
  339. package/src/modules/auth/i18n/es.json +2 -0
  340. package/src/modules/auth/i18n/pl.json +2 -0
  341. package/src/modules/auth/lib/backendChrome.tsx +1 -0
  342. package/src/modules/auth/services/rbacService.ts +25 -21
  343. package/src/modules/catalog/api/products/route.ts +3 -0
  344. package/src/modules/catalog/api/variants/route.ts +3 -0
  345. package/src/modules/customer_accounts/migrations/Migration20260724120000_customer_accounts.ts +96 -0
  346. package/src/modules/directory/api/organizations/route.ts +1 -1
  347. package/src/modules/entities/api/definitions.ts +2 -0
  348. package/src/modules/entities/lib/helpers.ts +1 -0
  349. package/src/modules/query_index/lib/engine.ts +18 -6
  350. package/src/modules/sales/api/documents/factory.ts +1 -0
  351. package/src/modules/sales/api/quotes/accept/route.ts +9 -2
  352. package/src/modules/sales/api/quotes/public/[token]/route.ts +2 -1
  353. package/src/modules/sales/commands/documents.ts +71 -0
  354. package/src/modules/sales/components/documents/ItemsSection.tsx +58 -0
  355. package/src/modules/sales/events.ts +2 -0
  356. package/src/modules/sales/lib/publicQuoteTenantScope.ts +49 -0
  357. package/src/modules/sales/widgets/injection/order-items-context.ts +15 -0
  358. package/src/modules/wms/acl.ts +14 -0
  359. package/src/modules/wms/analytics.ts +9 -0
  360. package/src/modules/wms/api/dashboard/operational/route.ts +83 -0
  361. package/src/modules/wms/api/interceptors.ts +108 -0
  362. package/src/modules/wms/api/inventory/adjust/route.ts +50 -0
  363. package/src/modules/wms/api/inventory/allocate/route.ts +50 -0
  364. package/src/modules/wms/api/inventory/balances/route.ts +178 -0
  365. package/src/modules/wms/api/inventory/cycle-count/route.ts +51 -0
  366. package/src/modules/wms/api/inventory/helpers.ts +128 -0
  367. package/src/modules/wms/api/inventory/import/apply/route.ts +47 -0
  368. package/src/modules/wms/api/inventory/import/helpers.ts +223 -0
  369. package/src/modules/wms/api/inventory/import/template/route.ts +31 -0
  370. package/src/modules/wms/api/inventory/import/validate/route.ts +56 -0
  371. package/src/modules/wms/api/inventory/move/route.ts +50 -0
  372. package/src/modules/wms/api/inventory/movements/route.ts +164 -0
  373. package/src/modules/wms/api/inventory/receive/route.ts +49 -0
  374. package/src/modules/wms/api/inventory/release/route.ts +43 -0
  375. package/src/modules/wms/api/inventory/reservations/route.ts +128 -0
  376. package/src/modules/wms/api/inventory/reserve/route.ts +59 -0
  377. package/src/modules/wms/api/inventory-profiles/route.ts +177 -0
  378. package/src/modules/wms/api/listEnrichers.ts +312 -0
  379. package/src/modules/wms/api/listSearch.ts +121 -0
  380. package/src/modules/wms/api/locations/route.ts +171 -0
  381. package/src/modules/wms/api/lots/route.ts +205 -0
  382. package/src/modules/wms/api/openapi.ts +28 -0
  383. package/src/modules/wms/api/sales-orders/[salesOrderId]/re-run-reservation/route.ts +58 -0
  384. package/src/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.ts +306 -0
  385. package/src/modules/wms/api/sales-orders/assign-warehouse/route.ts +57 -0
  386. package/src/modules/wms/api/sales-orders/unassign-warehouse/route.ts +43 -0
  387. package/src/modules/wms/api/warehouses/route.ts +181 -0
  388. package/src/modules/wms/api/zones/route.ts +158 -0
  389. package/src/modules/wms/backend/config/wms/page.meta.ts +14 -0
  390. package/src/modules/wms/backend/config/wms/page.tsx +5 -0
  391. package/src/modules/wms/backend/page.meta.ts +12 -0
  392. package/src/modules/wms/backend/page.tsx +5 -0
  393. package/src/modules/wms/backend/wms/inventory/page.meta.ts +14 -0
  394. package/src/modules/wms/backend/wms/inventory/page.tsx +5 -0
  395. package/src/modules/wms/backend/wms/location/[id]/page.meta.ts +14 -0
  396. package/src/modules/wms/backend/wms/location/[id]/page.tsx +5 -0
  397. package/src/modules/wms/backend/wms/locations/page.meta.ts +14 -0
  398. package/src/modules/wms/backend/wms/locations/page.tsx +12 -0
  399. package/src/modules/wms/backend/wms/lot/[id]/page.meta.ts +14 -0
  400. package/src/modules/wms/backend/wms/lot/[id]/page.tsx +5 -0
  401. package/src/modules/wms/backend/wms/lots/page.meta.ts +14 -0
  402. package/src/modules/wms/backend/wms/lots/page.tsx +5 -0
  403. package/src/modules/wms/backend/wms/movements/page.meta.ts +14 -0
  404. package/src/modules/wms/backend/wms/movements/page.tsx +23 -0
  405. package/src/modules/wms/backend/wms/reservations/page.meta.ts +14 -0
  406. package/src/modules/wms/backend/wms/reservations/page.tsx +24 -0
  407. package/src/modules/wms/backend/wms/sku/[id]/page.meta.ts +14 -0
  408. package/src/modules/wms/backend/wms/sku/[id]/page.tsx +5 -0
  409. package/src/modules/wms/backend/wms/warehouses/page.meta.ts +14 -0
  410. package/src/modules/wms/backend/wms/warehouses/page.tsx +12 -0
  411. package/src/modules/wms/backend/wms/zones/page.meta.ts +14 -0
  412. package/src/modules/wms/backend/wms/zones/page.tsx +12 -0
  413. package/src/modules/wms/ce.ts +76 -0
  414. package/src/modules/wms/cli.ts +96 -0
  415. package/src/modules/wms/commands/configuration.ts +1844 -0
  416. package/src/modules/wms/commands/index.ts +3 -0
  417. package/src/modules/wms/commands/inventory-actions.ts +1866 -0
  418. package/src/modules/wms/commands/sales-order-assignment.ts +346 -0
  419. package/src/modules/wms/commands/shared.ts +90 -0
  420. package/src/modules/wms/components/backend/AdjustInventoryDialog.tsx +820 -0
  421. package/src/modules/wms/components/backend/ChangeLotStatusDialog.tsx +312 -0
  422. package/src/modules/wms/components/backend/CycleCountWizardDialog.tsx +2007 -0
  423. package/src/modules/wms/components/backend/ImportInventoryDialog.tsx +1018 -0
  424. package/src/modules/wms/components/backend/InventoryOperationsSection.tsx +159 -0
  425. package/src/modules/wms/components/backend/LocationEditDialog.tsx +185 -0
  426. package/src/modules/wms/components/backend/MoveInventoryDialog.tsx +907 -0
  427. package/src/modules/wms/components/backend/ReceiveInventoryDialog.tsx +695 -0
  428. package/src/modules/wms/components/backend/ReleaseReservationDialog.tsx +424 -0
  429. package/src/modules/wms/components/backend/ReserveInventoryDialog.tsx +511 -0
  430. package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +1340 -0
  431. package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +1132 -0
  432. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +1310 -0
  433. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +1355 -0
  434. package/src/modules/wms/components/backend/WmsLotsListPage.tsx +359 -0
  435. package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +958 -0
  436. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +1245 -0
  437. package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +960 -0
  438. package/src/modules/wms/components/backend/useWmsInventoryMutationAccess.ts +89 -0
  439. package/src/modules/wms/components/backend/useWmsInventoryScopeFromSearchParams.ts +32 -0
  440. package/src/modules/wms/components/backend/wmsLookupLoaders.ts +78 -0
  441. package/src/modules/wms/data/enrichers.ts +718 -0
  442. package/src/modules/wms/data/entities.ts +436 -0
  443. package/src/modules/wms/data/validators.ts +463 -0
  444. package/src/modules/wms/di.ts +25 -0
  445. package/src/modules/wms/events.ts +41 -0
  446. package/src/modules/wms/i18n/de.json +1051 -0
  447. package/src/modules/wms/i18n/en.json +1051 -0
  448. package/src/modules/wms/i18n/es.json +1051 -0
  449. package/src/modules/wms/i18n/pl.json +1051 -0
  450. package/src/modules/wms/index.ts +15 -0
  451. package/src/modules/wms/lib/catalogInventoryProfileIntent.ts +65 -0
  452. package/src/modules/wms/lib/catalogInventoryProfileSync.ts +199 -0
  453. package/src/modules/wms/lib/expiry.ts +30 -0
  454. package/src/modules/wms/lib/flashMutationError.ts +74 -0
  455. package/src/modules/wms/lib/inventoryDisplayUi.ts +249 -0
  456. package/src/modules/wms/lib/inventoryIdempotency.ts +54 -0
  457. package/src/modules/wms/lib/inventoryImportCsv.ts +212 -0
  458. package/src/modules/wms/lib/inventoryImportService.ts +629 -0
  459. package/src/modules/wms/lib/inventoryMutationUi.ts +21 -0
  460. package/src/modules/wms/lib/inventoryPolicy.ts +111 -0
  461. package/src/modules/wms/lib/inventoryReconciliation.ts +263 -0
  462. package/src/modules/wms/lib/inventoryTrackingValidation.ts +23 -0
  463. package/src/modules/wms/lib/loadOperationalDashboard.ts +776 -0
  464. package/src/modules/wms/lib/lowStockBalanceFilter.ts +74 -0
  465. package/src/modules/wms/lib/primaryWarehousePolicy.ts +46 -0
  466. package/src/modules/wms/lib/roleFeatures.ts +32 -0
  467. package/src/modules/wms/lib/salesOrderInventoryAutomation.ts +390 -0
  468. package/src/modules/wms/lib/salesOrderWarehouseAssignment.ts +78 -0
  469. package/src/modules/wms/lib/wmsIntegrationToggles.ts +81 -0
  470. package/src/modules/wms/migrations/.snapshot-open-mercato.json +2880 -0
  471. package/src/modules/wms/migrations/Migration20260428110546.ts +91 -0
  472. package/src/modules/wms/migrations/Migration20260527120000.ts +15 -0
  473. package/src/modules/wms/migrations/Migration20260527140000.ts +35 -0
  474. package/src/modules/wms/migrations/Migration20260613120000.ts +21 -0
  475. package/src/modules/wms/migrations/Migration20260616090000.ts +11 -0
  476. package/src/modules/wms/migrations/Migration20260707180000.ts +13 -0
  477. package/src/modules/wms/notifications.client.ts +18 -0
  478. package/src/modules/wms/notifications.ts +51 -0
  479. package/src/modules/wms/search.ts +230 -0
  480. package/src/modules/wms/setup.ts +29 -0
  481. package/src/modules/wms/subscribers/low-stock-notification.ts +54 -0
  482. package/src/modules/wms/subscribers/reservation-shortfall-notification.ts +98 -0
  483. package/src/modules/wms/subscribers/sales-order-cancelled-release.ts +21 -0
  484. package/src/modules/wms/subscribers/sales-order-confirmed-reserve.ts +21 -0
  485. package/src/modules/wms/translations.ts +6 -0
  486. package/src/modules/wms/vector.ts +7 -0
  487. package/src/modules/wms/widgets/injection/catalog-inventory-profile/widget.ts +238 -0
  488. package/src/modules/wms/widgets/injection/order-items-stock-column/widget.tsx +153 -0
  489. package/src/modules/wms/widgets/injection/sales-order-stock-context/widget.client.tsx +476 -0
  490. package/src/modules/wms/widgets/injection/sales-order-stock-context/widget.ts +15 -0
  491. package/src/modules/wms/widgets/injection-table.ts +34 -0
  492. package/src/modules/wms/widgets/notifications/WmsLowStockRenderer.tsx +153 -0
  493. package/src/modules/wms/widgets/notifications/WmsReservationShortfallRenderer.tsx +194 -0
  494. package/src/modules/wms/widgets/notifications/index.ts +2 -0
@@ -23,6 +23,7 @@ import {
23
23
  import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
24
24
  import { resolveNotificationService } from "../../notifications/lib/notificationService";
25
25
  import { buildFeatureNotificationFromType } from "../../notifications/lib/notificationBuilder";
26
+ import { emitSalesEvent } from "../events";
26
27
  import { setRecordCustomFields } from "@open-mercato/core/modules/entities/lib/helpers";
27
28
  import { loadCustomFieldValues } from "@open-mercato/shared/lib/crud/custom-fields";
28
29
  import { normalizeCustomFieldValues } from "@open-mercato/shared/lib/custom-fields/normalize";
@@ -858,6 +859,70 @@ function normalizeStatusValue(raw: unknown): string | null {
858
859
  return trimmed.length ? trimmed : null;
859
860
  }
860
861
 
862
+ function isConfirmedOrderStatus(status: string | null): boolean {
863
+ return status === "confirmed";
864
+ }
865
+
866
+ function isCancelledOrderStatus(status: string | null): boolean {
867
+ return status === "canceled" || status === "cancelled";
868
+ }
869
+
870
+ async function emitOrderLifecycleEvent(input: {
871
+ eventId: "sales.order.confirmed" | "sales.order.cancelled";
872
+ order: SalesOrder;
873
+ previousStatus: string | null;
874
+ }): Promise<void> {
875
+ await emitSalesEvent(input.eventId, {
876
+ id: input.order.id,
877
+ orderId: input.order.id,
878
+ orderNumber: input.order.orderNumber,
879
+ previousStatus: input.previousStatus,
880
+ status: normalizeStatusValue(input.order.status),
881
+ tenantId: input.order.tenantId,
882
+ organizationId: input.order.organizationId,
883
+ });
884
+ }
885
+
886
+ function emitOrderLifecycleEventsForTransition(input: {
887
+ order: SalesOrder;
888
+ previousStatus: string | null;
889
+ }): void {
890
+ const nextStatus = normalizeStatusValue(input.order.status);
891
+ if (input.previousStatus === nextStatus) return;
892
+
893
+ if (isConfirmedOrderStatus(nextStatus)) {
894
+ void emitOrderLifecycleEvent({
895
+ eventId: "sales.order.confirmed",
896
+ order: input.order,
897
+ previousStatus: input.previousStatus,
898
+ }).catch((err) => {
899
+ // Surface as warning so downstream automations (e.g. WMS reservation
900
+ // subscriber) failing to register/persist their own follow-up state is
901
+ // observable in logs instead of being silently dropped. The order
902
+ // status transition itself is already committed at this point.
903
+ logger.warn("order lifecycle event emit failed", {
904
+ eventId: "sales.order.confirmed",
905
+ orderId: input.order.id,
906
+ err,
907
+ });
908
+ });
909
+ }
910
+
911
+ if (isCancelledOrderStatus(nextStatus)) {
912
+ void emitOrderLifecycleEvent({
913
+ eventId: "sales.order.cancelled",
914
+ order: input.order,
915
+ previousStatus: input.previousStatus,
916
+ }).catch((err) => {
917
+ logger.warn("order lifecycle event emit failed", {
918
+ eventId: "sales.order.cancelled",
919
+ orderId: input.order.id,
920
+ err,
921
+ });
922
+ });
923
+ }
924
+ }
925
+
861
926
  function resolveNoteAuthorFromAuth(auth: AuthContext | null): string | null {
862
927
  if (!auth || auth.isApiKey) return null;
863
928
  const sub = typeof auth.sub === "string" ? auth.sub.trim() : "";
@@ -5359,6 +5424,7 @@ const updateOrderCommand: CommandHandler<
5359
5424
  ],
5360
5425
  { transaction: true },
5361
5426
  );
5427
+ emitOrderLifecycleEventsForTransition({ order, previousStatus });
5362
5428
  if (statusChangeNote) {
5363
5429
  const dataEngine = ctx.container.resolve("dataEngine");
5364
5430
  await emitCrudSideEffects({
@@ -5800,6 +5866,11 @@ const createOrderCommand: CommandHandler<
5800
5866
  "created",
5801
5867
  );
5802
5868
 
5869
+ emitOrderLifecycleEventsForTransition({
5870
+ order,
5871
+ previousStatus: null,
5872
+ });
5873
+
5803
5874
  return { orderId: order.id };
5804
5875
  },
5805
5876
  captureAfter: async (_input, result, ctx) => {
@@ -27,6 +27,9 @@ import type { SectionAction } from "@open-mercato/ui/backend/detail";
27
27
  import { extractCustomFieldValues } from "./customFieldHelpers";
28
28
  import { canonicalizeUnitCode } from "@open-mercato/shared/lib/units/unitCodes";
29
29
  import type { SalesLineUomSnapshot } from "../../lib/types";
30
+ import { useInjectionDataWidgets } from "@open-mercato/ui/backend/injection/useInjectionDataWidgets";
31
+ import type { InjectionColumnDefinition } from "@open-mercato/shared/modules/widgets/injection";
32
+ import { OrderItemsInjectionContext } from "../../widgets/injection/order-items-context";
30
33
  import { createLogger } from '@open-mercato/shared/lib/logger'
31
34
 
32
35
  const logger = createLogger('sales')
@@ -110,6 +113,19 @@ function getUomFields(item: Record<string, unknown>) {
110
113
  };
111
114
  }
112
115
 
116
+ function resolveInjectedColumnValue(
117
+ row: Record<string, unknown>,
118
+ accessorKey: string,
119
+ ): unknown {
120
+ const segments = accessorKey.split(".").filter(Boolean);
121
+ let current: unknown = row;
122
+ for (const segment of segments) {
123
+ if (!current || typeof current !== "object") return undefined;
124
+ current = (current as Record<string, unknown>)[segment];
125
+ }
126
+ return current;
127
+ }
128
+
113
129
  type SalesDocumentItemsSectionProps = {
114
130
  documentId: string;
115
131
  kind: "order" | "quote";
@@ -148,6 +164,22 @@ export function SalesDocumentItemsSection({
148
164
  new Map(),
149
165
  );
150
166
 
167
+ const { widgets: allColumnWidgets } = useInjectionDataWidgets(
168
+ "data-table:sales.order.items:columns",
169
+ );
170
+ const columnWidgets = kind === "order" ? allColumnWidgets : [];
171
+ const injectedColumns = React.useMemo<InjectionColumnDefinition[]>(() => {
172
+ const cols: InjectionColumnDefinition[] = [];
173
+ for (const widget of columnWidgets) {
174
+ if (!("columns" in widget)) continue;
175
+ for (const def of (widget as { columns?: InjectionColumnDefinition[] })
176
+ .columns ?? []) {
177
+ cols.push(def);
178
+ }
179
+ }
180
+ return cols;
181
+ }, [columnWidgets]);
182
+
151
183
  const resourcePath = React.useMemo(
152
184
  () => (kind === "order" ? "sales/order-lines" : "sales/quote-lines"),
153
185
  [kind],
@@ -575,6 +607,7 @@ export function SalesDocumentItemsSection({
575
607
  };
576
608
 
577
609
  return (
610
+ <OrderItemsInjectionContext.Provider value={{ documentId, kind }}>
578
611
  <div className="space-y-4">
579
612
  {loading ? (
580
613
  <LoadingMessage
@@ -615,6 +648,14 @@ export function SalesDocumentItemsSection({
615
648
  <th className="px-3 py-2 font-medium">
616
649
  {t("sales.documents.items.table.total", "Total")}
617
650
  </th>
651
+ {injectedColumns.map((col) => (
652
+ <th
653
+ key={col.id}
654
+ className="px-3 py-2 font-medium whitespace-nowrap"
655
+ >
656
+ {col.headerKey ? t(col.headerKey, col.header) : col.header}
657
+ </th>
658
+ ))}
618
659
  <th className="px-3 py-2 font-medium sr-only">
619
660
  {t("sales.documents.items.table.actions", "Actions")}
620
661
  </th>
@@ -770,6 +811,22 @@ export function SalesDocumentItemsSection({
770
811
  </span>
771
812
  </div>
772
813
  </td>
814
+ {injectedColumns.map((col) => {
815
+ const colValue = resolveInjectedColumnValue(
816
+ item as unknown as Record<string, unknown>,
817
+ col.accessorKey,
818
+ );
819
+ const Cell = col.cell;
820
+ return (
821
+ <td
822
+ key={col.id}
823
+ className="px-3 py-3"
824
+ onClick={(e) => e.stopPropagation()}
825
+ >
826
+ {Cell ? <Cell getValue={() => colValue} /> : null}
827
+ </td>
828
+ );
829
+ })}
773
830
  <td className="px-3 py-3">
774
831
  <div className="flex items-center gap-2 justify-end">
775
832
  <Button
@@ -829,5 +886,6 @@ export function SalesDocumentItemsSection({
829
886
  />
830
887
  {ConfirmDialogElement}
831
888
  </div>
889
+ </OrderItemsInjectionContext.Provider>
832
890
  );
833
891
  }
@@ -10,6 +10,8 @@ const events = [
10
10
  { id: 'sales.order.created', label: 'Sales Order Created', entity: 'order', category: 'crud' },
11
11
  { id: 'sales.order.updated', label: 'Sales Order Updated', entity: 'order', category: 'crud' },
12
12
  { id: 'sales.order.deleted', label: 'Sales Order Deleted', entity: 'order', category: 'crud' },
13
+ { id: 'sales.order.confirmed', label: 'Sales Order Confirmed', entity: 'order', category: 'lifecycle' },
14
+ { id: 'sales.order.cancelled', label: 'Sales Order Cancelled', entity: 'order', category: 'lifecycle' },
13
15
 
14
16
  // Quotes
15
17
  { id: 'sales.quote.created', label: 'Quote Created', entity: 'quote', category: 'crud' },
@@ -0,0 +1,49 @@
1
+ import type { AuthContext } from '@open-mercato/shared/lib/auth/server'
2
+
3
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
4
+
5
+ function normalizeTenantValue(value: unknown): string | null {
6
+ if (typeof value !== 'string') return null
7
+ const trimmed = value.trim()
8
+ if (!UUID_RE.test(trimmed)) return null
9
+ return trimmed.toLowerCase()
10
+ }
11
+
12
+ /**
13
+ * The tenant a signed-in actor's reads and writes are scoped to, or null when none can be
14
+ * resolved (including anonymous requests).
15
+ *
16
+ * `applySuperAdminScope` rewrites `auth.tenantId` from the `om_selected_tenant` cookie and
17
+ * preserves the actor's own tenant under `actorTenantId`. An explicit selection is an intentional
18
+ * scope and wins; an empty cookie ("all tenants") sets `auth.tenantId` to null on an otherwise
19
+ * fully authenticated session, so the actor's own tenant is the fallback. `auth.tenantId` alone
20
+ * cannot decide the scope, which is what defeated the public quote guard in #4309.
21
+ *
22
+ * A value that is not a well-formed UUID is treated as unresolvable rather than passed through to
23
+ * a `uuid` column filter, since the cookie is attacker-controllable by the actor themselves.
24
+ */
25
+ export function resolveEffectiveTenantId(auth: AuthContext): string | null {
26
+ if (!auth) return null
27
+ const selectedTenantId = normalizeTenantValue(auth.tenantId)
28
+ if (selectedTenantId !== null) return selectedTenantId
29
+ return normalizeTenantValue((auth as { actorTenantId?: unknown }).actorTenantId)
30
+ }
31
+
32
+ /**
33
+ * True when the request carries a session belonging to a tenant other than the document's.
34
+ *
35
+ * An authenticated session whose tenant cannot be resolved counts as foreign — treating
36
+ * "tenant unknown" as "allow" is the #4309 bug. Two cases are deliberately NOT foreign:
37
+ *
38
+ * - Anonymous requests. The public quote link is meant to work without a session, and denying
39
+ * here would break the endpoint's entire purpose.
40
+ * - API keys with no tenant. `ApiKey.tenantId` is nullable, so a global key legitimately resolves
41
+ * to no tenant. Denying it would reject a more-privileged caller than the anonymous one that
42
+ * the same link already serves.
43
+ */
44
+ export function isForeignTenantActor(auth: AuthContext, documentTenantId: unknown): boolean {
45
+ if (!auth) return false
46
+ const effectiveTenantId = resolveEffectiveTenantId(auth)
47
+ if (effectiveTenantId === null) return auth.isApiKey !== true
48
+ return effectiveTenantId !== normalizeTenantValue(documentTenantId)
49
+ }
@@ -0,0 +1,15 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+
5
+ export type OrderItemsInjectionContextValue = {
6
+ documentId: string
7
+ kind: 'order' | 'quote'
8
+ }
9
+
10
+ export const OrderItemsInjectionContext =
11
+ React.createContext<OrderItemsInjectionContextValue | null>(null)
12
+
13
+ export function useOrderItemsInjectionContext(): OrderItemsInjectionContextValue | null {
14
+ return React.useContext(OrderItemsInjectionContext)
15
+ }
@@ -0,0 +1,14 @@
1
+ export const features = [
2
+ { id: 'wms.view', title: 'View WMS data', module: 'wms' },
3
+ { id: 'wms.manage_warehouses', title: 'Manage warehouses', module: 'wms' },
4
+ { id: 'wms.manage_zones', title: 'Manage warehouse zones', module: 'wms' },
5
+ { id: 'wms.manage_locations', title: 'Manage warehouse locations', module: 'wms' },
6
+ { id: 'wms.manage_inventory', title: 'Manage inventory profiles and stock state', module: 'wms' },
7
+ { id: 'wms.manage_reservations', title: 'Manage inventory reservations', module: 'wms' },
8
+ { id: 'wms.adjust_inventory', title: 'Adjust and move inventory', module: 'wms' },
9
+ { id: 'wms.receive_inventory', title: 'Receive inbound inventory', module: 'wms' },
10
+ { id: 'wms.cycle_count', title: 'Run cycle counts', module: 'wms' },
11
+ { id: 'wms.import', title: 'Import inventory from CSV', module: 'wms' },
12
+ ]
13
+
14
+ export default features
@@ -0,0 +1,9 @@
1
+ import type { AnalyticsModuleConfig } from '@open-mercato/shared/modules/analytics'
2
+
3
+ export const analyticsConfig: AnalyticsModuleConfig = {
4
+ entities: [],
5
+ }
6
+
7
+ export const config = analyticsConfig
8
+
9
+ export default analyticsConfig
@@ -0,0 +1,83 @@
1
+ import { NextResponse } from 'next/server'
2
+ import { z } from 'zod'
3
+ import type { EntityManager } from '@mikro-orm/postgresql'
4
+ import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
5
+ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
6
+ import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
7
+ import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
8
+ import { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'
9
+ import { createLogger } from '@open-mercato/shared/lib/logger'
10
+ import {
11
+ operationalDashboardQuerySchema,
12
+ operationalDashboardResponseSchema,
13
+ } from '../../../data/validators'
14
+ import {
15
+ loadOperationalDashboard,
16
+ OperationalDashboardWarehouseNotFoundError,
17
+ } from '../../../lib/loadOperationalDashboard'
18
+
19
+ const logger = createLogger('wms')
20
+
21
+ export const metadata = {
22
+ GET: { requireAuth: true, requireFeatures: ['wms.view'] },
23
+ }
24
+
25
+ export async function GET(request: Request) {
26
+ try {
27
+ const url = new URL(request.url)
28
+ const parsedQuery = operationalDashboardQuerySchema.parse(Object.fromEntries(url.searchParams.entries()))
29
+ const container = await createRequestContainer()
30
+ const auth = await getAuthFromRequest(request)
31
+ if (!auth?.tenantId) {
32
+ throw new CrudHttpError(401, { error: 'Unauthorized' })
33
+ }
34
+ const organizationScope = await resolveOrganizationScopeForRequest({
35
+ container,
36
+ auth,
37
+ request,
38
+ })
39
+ const organizationId = organizationScope?.selectedId ?? auth.orgId ?? null
40
+ if (!organizationId) {
41
+ throw new CrudHttpError(401, { error: 'Unauthorized' })
42
+ }
43
+
44
+ const em = (container.resolve('em') as EntityManager).fork()
45
+ const payload = await loadOperationalDashboard(em, {
46
+ organizationId,
47
+ tenantId: auth.tenantId,
48
+ warehouseId: parsedQuery.warehouseId ?? null,
49
+ })
50
+
51
+ return NextResponse.json(operationalDashboardResponseSchema.parse(payload))
52
+ } catch (error) {
53
+ if (error instanceof OperationalDashboardWarehouseNotFoundError) {
54
+ return NextResponse.json({ error: 'Warehouse not found' }, { status: 404 })
55
+ }
56
+ if (error instanceof CrudHttpError) {
57
+ return NextResponse.json(error.body, { status: error.status })
58
+ }
59
+ if (error instanceof z.ZodError) {
60
+ return NextResponse.json({ error: 'Validation failed', details: error.issues }, { status: 400 })
61
+ }
62
+ logger.error('GET operational dashboard failed', { err: error })
63
+ return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
64
+ }
65
+ }
66
+
67
+ export const openApi: OpenApiRouteDoc = {
68
+ tag: 'WMS',
69
+ summary: 'Operational dashboard',
70
+ description:
71
+ 'Aggregated KPIs, expiry watch lot rows (`expiryLots`), monthly movement trends, and recent activity for the WMS operational dashboard.',
72
+ methods: {
73
+ GET: {
74
+ summary: 'Load operational dashboard data',
75
+ query: operationalDashboardQuerySchema,
76
+ responses: [
77
+ { status: 200, description: 'Dashboard payload', schema: operationalDashboardResponseSchema },
78
+ { status: 401, description: 'Unauthorized' },
79
+ { status: 404, description: 'Warehouse not found' },
80
+ ],
81
+ },
82
+ },
83
+ }
@@ -0,0 +1,108 @@
1
+ import type { ApiInterceptor } from '@open-mercato/shared/lib/crud/api-interceptor'
2
+ import {
3
+ decodeCatalogInventoryProfileIntent,
4
+ WMS_CATALOG_PROFILE_HEADER,
5
+ } from '../lib/catalogInventoryProfileIntent'
6
+ import {
7
+ syncCatalogInventoryProfile,
8
+ } from '../lib/catalogInventoryProfileSync'
9
+
10
+ function resolveRecordId(
11
+ requestBody: Record<string, unknown> | undefined,
12
+ responseBody: Record<string, unknown> | undefined,
13
+ ): string | null {
14
+ const responseId = responseBody?.id
15
+ if (typeof responseId === 'string' && responseId.trim().length > 0) {
16
+ return responseId
17
+ }
18
+
19
+ const requestId = requestBody?.id
20
+ if (typeof requestId === 'string' && requestId.trim().length > 0) {
21
+ return requestId
22
+ }
23
+
24
+ return null
25
+ }
26
+
27
+ export const interceptors: ApiInterceptor[] = [
28
+ {
29
+ id: 'wms.catalog-products.inventory-profile-sync',
30
+ targetRoute: 'catalog/products',
31
+ methods: ['POST', 'PUT'],
32
+ priority: 120,
33
+ async before(request) {
34
+ const rawHeader = request.headers[WMS_CATALOG_PROFILE_HEADER]
35
+ if (!rawHeader) return { ok: true }
36
+
37
+ const intent = decodeCatalogInventoryProfileIntent(rawHeader)
38
+ return {
39
+ ok: true,
40
+ metadata: { intent, target: 'product' },
41
+ }
42
+ },
43
+ async after(request, response, context) {
44
+ if (response.statusCode >= 400) return {}
45
+
46
+ const metadata = context.metadata as
47
+ | { intent?: ReturnType<typeof decodeCatalogInventoryProfileIntent>; target?: 'product' | 'variant' }
48
+ | undefined
49
+ if (!metadata?.intent) return {}
50
+
51
+ const recordId = resolveRecordId(request.body, response.body)
52
+ if (!recordId) return {}
53
+
54
+ await syncCatalogInventoryProfile({
55
+ intent: metadata.intent,
56
+ target: 'product',
57
+ recordId,
58
+ organizationId: context.organizationId,
59
+ tenantId: context.tenantId,
60
+ userId: context.userId,
61
+ container: context.container,
62
+ })
63
+
64
+ return {}
65
+ },
66
+ },
67
+ {
68
+ id: 'wms.catalog-variants.inventory-profile-sync',
69
+ targetRoute: 'catalog/variants',
70
+ methods: ['POST', 'PUT'],
71
+ priority: 120,
72
+ async before(request) {
73
+ const rawHeader = request.headers[WMS_CATALOG_PROFILE_HEADER]
74
+ if (!rawHeader) return { ok: true }
75
+
76
+ const intent = decodeCatalogInventoryProfileIntent(rawHeader)
77
+ return {
78
+ ok: true,
79
+ metadata: { intent, target: 'variant' },
80
+ }
81
+ },
82
+ async after(request, response, context) {
83
+ if (response.statusCode >= 400) return {}
84
+
85
+ const metadata = context.metadata as
86
+ | { intent?: ReturnType<typeof decodeCatalogInventoryProfileIntent>; target?: 'product' | 'variant' }
87
+ | undefined
88
+ if (!metadata?.intent) return {}
89
+
90
+ const recordId = resolveRecordId(request.body, response.body)
91
+ if (!recordId) return {}
92
+
93
+ await syncCatalogInventoryProfile({
94
+ intent: metadata.intent,
95
+ target: 'variant',
96
+ recordId,
97
+ organizationId: context.organizationId,
98
+ tenantId: context.tenantId,
99
+ userId: context.userId,
100
+ container: context.container,
101
+ })
102
+
103
+ return {}
104
+ },
105
+ },
106
+ ]
107
+
108
+ export default interceptors
@@ -0,0 +1,50 @@
1
+ import { z } from 'zod'
2
+ import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
3
+ import { inventoryAdjustSchema } from '../../../data/validators'
4
+ import { executeWmsCustomPostRoute } from '../helpers'
5
+
6
+ export const metadata = {
7
+ POST: { requireAuth: true, requireFeatures: ['wms.adjust_inventory'] },
8
+ }
9
+
10
+ export async function POST(request: Request) {
11
+ return executeWmsCustomPostRoute({
12
+ request,
13
+ routePath: 'wms/inventory/adjust',
14
+ inputSchema: inventoryAdjustSchema,
15
+ commandId: 'wms.inventory.adjust',
16
+ describeResource: (input) => ({
17
+ resourceKind: 'wms.inventory',
18
+ resourceId: `${input.warehouseId}:${input.locationId}:${input.catalogVariantId}`,
19
+ }),
20
+ mapSuccess: (result: { movementId: string }) => ({
21
+ ok: true,
22
+ movementId: result.movementId,
23
+ }),
24
+ })
25
+ }
26
+
27
+ const successSchema = z.object({
28
+ ok: z.literal(true),
29
+ movementId: z.string().uuid(),
30
+ })
31
+ const errorSchema = z.object({ error: z.string() })
32
+
33
+ export const openApi: OpenApiRouteDoc = {
34
+ tag: 'WMS',
35
+ summary: 'Adjust inventory',
36
+ methods: {
37
+ POST: {
38
+ summary: 'Adjust inventory',
39
+ description: 'Applies a manual inventory adjustment and appends a movement ledger row.',
40
+ requestBody: { contentType: 'application/json', schema: inventoryAdjustSchema },
41
+ responses: [{ status: 200, description: 'Inventory adjusted', schema: successSchema }],
42
+ errors: [
43
+ { status: 400, description: 'Validation failed', schema: errorSchema },
44
+ { status: 401, description: 'Unauthorized', schema: errorSchema },
45
+ { status: 409, description: 'Insufficient stock', schema: errorSchema },
46
+ { status: 422, description: 'Invalid location', schema: errorSchema },
47
+ ],
48
+ },
49
+ },
50
+ }
@@ -0,0 +1,50 @@
1
+ import { z } from 'zod'
2
+ import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
3
+ import { inventoryReservationAllocateSchema } from '../../../data/validators'
4
+ import { executeWmsCustomPostRoute } from '../helpers'
5
+
6
+ export const metadata = {
7
+ POST: { requireAuth: true, requireFeatures: ['wms.manage_reservations'] },
8
+ }
9
+
10
+ export async function POST(request: Request) {
11
+ return executeWmsCustomPostRoute({
12
+ request,
13
+ routePath: 'wms/inventory/allocate',
14
+ inputSchema: inventoryReservationAllocateSchema,
15
+ commandId: 'wms.inventory.allocate',
16
+ describeResource: (input) => ({
17
+ resourceKind: 'wms.inventoryReservation',
18
+ resourceId: input.reservationId,
19
+ }),
20
+ mapSuccess: (result: { allocationState: 'allocated' }) => ({
21
+ ok: true,
22
+ allocationState: result.allocationState,
23
+ }),
24
+ })
25
+ }
26
+
27
+ const successSchema = z.object({
28
+ ok: z.literal(true),
29
+ allocationState: z.literal('allocated'),
30
+ })
31
+ const errorSchema = z.object({ error: z.string() })
32
+
33
+ export const openApi: OpenApiRouteDoc = {
34
+ tag: 'WMS',
35
+ summary: 'Allocate reservation',
36
+ methods: {
37
+ POST: {
38
+ summary: 'Allocate reservation',
39
+ description: 'Converts a reservation from reserved quantity into allocated quantity on the selected stock buckets.',
40
+ requestBody: { contentType: 'application/json', schema: inventoryReservationAllocateSchema },
41
+ responses: [{ status: 200, description: 'Reservation allocated', schema: successSchema }],
42
+ errors: [
43
+ { status: 400, description: 'Validation failed', schema: errorSchema },
44
+ { status: 401, description: 'Unauthorized', schema: errorSchema },
45
+ { status: 404, description: 'Reservation not found', schema: errorSchema },
46
+ { status: 409, description: 'Invalid reservation state', schema: errorSchema },
47
+ ],
48
+ },
49
+ },
50
+ }