@open-mercato/core 0.9.1-develop.7474.1.51db10479d → 0.9.1-develop.7475.1.28ca93ed97

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 (597) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/catalog_price_history_entry/index.js +53 -0
  3. package/dist/generated/entities/catalog_price_history_entry/index.js.map +7 -0
  4. package/dist/generated/entities/customer_group_terms/index.js +2 -0
  5. package/dist/generated/entities/customer_group_terms/index.js.map +2 -2
  6. package/dist/generated/entities/ecommerce_store/index.js +33 -0
  7. package/dist/generated/entities/ecommerce_store/index.js.map +7 -0
  8. package/dist/generated/entities/ecommerce_store_channel_binding/index.js +29 -0
  9. package/dist/generated/entities/ecommerce_store_channel_binding/index.js.map +7 -0
  10. package/dist/generated/entities/ecommerce_store_domain_binding/index.js +23 -0
  11. package/dist/generated/entities/ecommerce_store_domain_binding/index.js.map +7 -0
  12. package/dist/generated/entities.ids.generated.js +8 -1
  13. package/dist/generated/entities.ids.generated.js.map +2 -2
  14. package/dist/generated/entity-fields-registry.js +72 -0
  15. package/dist/generated/entity-fields-registry.js.map +2 -2
  16. package/dist/helpers/integration/customerGroupsFixtures.js.map +2 -2
  17. package/dist/modules/catalog/acl.js +8 -1
  18. package/dist/modules/catalog/acl.js.map +2 -2
  19. package/dist/modules/catalog/api/config/omnibus/route.js +184 -0
  20. package/dist/modules/catalog/api/config/omnibus/route.js.map +7 -0
  21. package/dist/modules/catalog/api/prices/history/route.js +131 -0
  22. package/dist/modules/catalog/api/prices/history/route.js.map +7 -0
  23. package/dist/modules/catalog/api/prices/omnibus-preview/route.js +184 -0
  24. package/dist/modules/catalog/api/prices/omnibus-preview/route.js.map +7 -0
  25. package/dist/modules/catalog/api/products/route.js +54 -245
  26. package/dist/modules/catalog/api/products/route.js.map +3 -3
  27. package/dist/modules/catalog/api/tags/route.js +6 -0
  28. package/dist/modules/catalog/api/tags/route.js.map +2 -2
  29. package/dist/modules/catalog/backend/config/catalog/page.js +3 -1
  30. package/dist/modules/catalog/backend/config/catalog/page.js.map +2 -2
  31. package/dist/modules/catalog/cli.js +80 -2
  32. package/dist/modules/catalog/cli.js.map +2 -2
  33. package/dist/modules/catalog/commands/categories.js +51 -2
  34. package/dist/modules/catalog/commands/categories.js.map +2 -2
  35. package/dist/modules/catalog/commands/prices.js +43 -1
  36. package/dist/modules/catalog/commands/prices.js.map +2 -2
  37. package/dist/modules/catalog/commands/products.js +71 -0
  38. package/dist/modules/catalog/commands/products.js.map +2 -2
  39. package/dist/modules/catalog/commands/variants.js +7 -0
  40. package/dist/modules/catalog/commands/variants.js.map +2 -2
  41. package/dist/modules/catalog/components/OmnibusSettings.js +703 -0
  42. package/dist/modules/catalog/components/OmnibusSettings.js.map +7 -0
  43. package/dist/modules/catalog/components/PriceEditorOmnibusRow.js +152 -0
  44. package/dist/modules/catalog/components/PriceEditorOmnibusRow.js.map +7 -0
  45. package/dist/modules/catalog/components/lookupSources.js +31 -0
  46. package/dist/modules/catalog/components/lookupSources.js.map +7 -0
  47. package/dist/modules/catalog/components/prices/PriceScopeSelectors.js +8 -2
  48. package/dist/modules/catalog/components/prices/PriceScopeSelectors.js.map +2 -2
  49. package/dist/modules/catalog/components/products/VariantBuilder.js +11 -1
  50. package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
  51. package/dist/modules/catalog/data/entities.js +122 -1
  52. package/dist/modules/catalog/data/entities.js.map +2 -2
  53. package/dist/modules/catalog/data/validators.js +78 -0
  54. package/dist/modules/catalog/data/validators.js.map +2 -2
  55. package/dist/modules/catalog/di.js +18 -0
  56. package/dist/modules/catalog/di.js.map +2 -2
  57. package/dist/modules/catalog/lib/omnibus.js +285 -0
  58. package/dist/modules/catalog/lib/omnibus.js.map +7 -0
  59. package/dist/modules/catalog/lib/omnibusBackfill.js +146 -0
  60. package/dist/modules/catalog/lib/omnibusBackfill.js.map +7 -0
  61. package/dist/modules/catalog/lib/omnibusCache.js +89 -0
  62. package/dist/modules/catalog/lib/omnibusCache.js.map +7 -0
  63. package/dist/modules/catalog/lib/omnibusConfig.js +64 -0
  64. package/dist/modules/catalog/lib/omnibusConfig.js.map +7 -0
  65. package/dist/modules/catalog/lib/omnibusHistoryQueries.js +191 -0
  66. package/dist/modules/catalog/lib/omnibusHistoryQueries.js.map +7 -0
  67. package/dist/modules/catalog/lib/omnibusPresentedEntry.js +73 -0
  68. package/dist/modules/catalog/lib/omnibusPresentedEntry.js.map +7 -0
  69. package/dist/modules/catalog/lib/omnibusProductListEnrichment.js +94 -0
  70. package/dist/modules/catalog/lib/omnibusProductListEnrichment.js.map +7 -0
  71. package/dist/modules/catalog/lib/omnibusTypes.js +115 -0
  72. package/dist/modules/catalog/lib/omnibusTypes.js.map +7 -0
  73. package/dist/modules/catalog/lib/optionSchemaTranslations.js +55 -0
  74. package/dist/modules/catalog/lib/optionSchemaTranslations.js.map +7 -0
  75. package/dist/modules/catalog/lib/priceHistoryQuery.js +103 -0
  76. package/dist/modules/catalog/lib/priceHistoryQuery.js.map +7 -0
  77. package/dist/modules/catalog/lib/pricing.js +26 -2
  78. package/dist/modules/catalog/lib/pricing.js.map +2 -2
  79. package/dist/modules/catalog/lib/productFilters.js +273 -0
  80. package/dist/modules/catalog/lib/productFilters.js.map +7 -0
  81. package/dist/modules/catalog/lib/productScopeKeys.js +105 -0
  82. package/dist/modules/catalog/lib/productScopeKeys.js.map +7 -0
  83. package/dist/modules/catalog/lib/productScopeReindex.js +73 -0
  84. package/dist/modules/catalog/lib/productScopeReindex.js.map +7 -0
  85. package/dist/modules/catalog/migrations/Migration20261005105352_catalog.js +39 -0
  86. package/dist/modules/catalog/migrations/Migration20261005105352_catalog.js.map +7 -0
  87. package/dist/modules/catalog/migrations/Migration20261005150824_catalog.js +39 -0
  88. package/dist/modules/catalog/migrations/Migration20261005150824_catalog.js.map +7 -0
  89. package/dist/modules/catalog/services/catalogOmnibusService.js +480 -0
  90. package/dist/modules/catalog/services/catalogOmnibusService.js.map +7 -0
  91. package/dist/modules/catalog/setup.js +3 -1
  92. package/dist/modules/catalog/setup.js.map +2 -2
  93. package/dist/modules/catalog/subscribers/product-scope-keys-category-deleted.js +16 -0
  94. package/dist/modules/catalog/subscribers/product-scope-keys-category-deleted.js.map +7 -0
  95. package/dist/modules/catalog/subscribers/product-scope-keys-category-updated.js +17 -0
  96. package/dist/modules/catalog/subscribers/product-scope-keys-category-updated.js.map +7 -0
  97. package/dist/modules/catalog/translations.js +10 -0
  98. package/dist/modules/catalog/translations.js.map +2 -2
  99. package/dist/modules/configs/lib/upgrade-actions.js +28 -0
  100. package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
  101. package/dist/modules/customer_groups/api/customer-groups/[id]/terms/route.js +5 -0
  102. package/dist/modules/customer_groups/api/customer-groups/[id]/terms/route.js.map +2 -2
  103. package/dist/modules/customer_groups/components/CustomerGroupTermsSection.js +111 -3
  104. package/dist/modules/customer_groups/components/CustomerGroupTermsSection.js.map +2 -2
  105. package/dist/modules/customer_groups/components/customerGroupAssortmentScope.js +43 -0
  106. package/dist/modules/customer_groups/components/customerGroupAssortmentScope.js.map +7 -0
  107. package/dist/modules/customer_groups/data/entities.js +3 -0
  108. package/dist/modules/customer_groups/data/entities.js.map +2 -2
  109. package/dist/modules/customer_groups/data/validators.js +9 -0
  110. package/dist/modules/customer_groups/data/validators.js.map +2 -2
  111. package/dist/modules/customer_groups/migrations/Migration20261005110250_customer_groups.js +17 -0
  112. package/dist/modules/customer_groups/migrations/Migration20261005110250_customer_groups.js.map +7 -0
  113. package/dist/modules/customer_groups/services/customerGroupsService.js +62 -15
  114. package/dist/modules/customer_groups/services/customerGroupsService.js.map +2 -2
  115. package/dist/modules/ecommerce/acl.js +13 -0
  116. package/dist/modules/ecommerce/acl.js.map +7 -0
  117. package/dist/modules/ecommerce/api/domain-mappings/route.js +72 -0
  118. package/dist/modules/ecommerce/api/domain-mappings/route.js.map +7 -0
  119. package/dist/modules/ecommerce/api/openapi.js +27 -0
  120. package/dist/modules/ecommerce/api/openapi.js.map +7 -0
  121. package/dist/modules/ecommerce/api/store-channel-bindings/[id]/assortment-count/route.js +109 -0
  122. package/dist/modules/ecommerce/api/store-channel-bindings/[id]/assortment-count/route.js.map +7 -0
  123. package/dist/modules/ecommerce/api/store-channel-bindings/crud.js +265 -0
  124. package/dist/modules/ecommerce/api/store-channel-bindings/crud.js.map +7 -0
  125. package/dist/modules/ecommerce/api/store-channel-bindings/route.js +67 -0
  126. package/dist/modules/ecommerce/api/store-channel-bindings/route.js.map +7 -0
  127. package/dist/modules/ecommerce/api/store-domain-bindings/crud.js +296 -0
  128. package/dist/modules/ecommerce/api/store-domain-bindings/crud.js.map +7 -0
  129. package/dist/modules/ecommerce/api/store-domain-bindings/route.js +73 -0
  130. package/dist/modules/ecommerce/api/store-domain-bindings/route.js.map +7 -0
  131. package/dist/modules/ecommerce/api/storefront/categories/[slug]/route.js +87 -0
  132. package/dist/modules/ecommerce/api/storefront/categories/[slug]/route.js.map +7 -0
  133. package/dist/modules/ecommerce/api/storefront/categories/openapiSchemas.js +50 -0
  134. package/dist/modules/ecommerce/api/storefront/categories/openapiSchemas.js.map +7 -0
  135. package/dist/modules/ecommerce/api/storefront/categories/route.js +75 -0
  136. package/dist/modules/ecommerce/api/storefront/categories/route.js.map +7 -0
  137. package/dist/modules/ecommerce/api/storefront/context/route.js +163 -0
  138. package/dist/modules/ecommerce/api/storefront/context/route.js.map +7 -0
  139. package/dist/modules/ecommerce/api/storefront/products/[idOrHandle]/route.js +87 -0
  140. package/dist/modules/ecommerce/api/storefront/products/[idOrHandle]/route.js.map +7 -0
  141. package/dist/modules/ecommerce/api/storefront/products/openapiSchemas.js +177 -0
  142. package/dist/modules/ecommerce/api/storefront/products/openapiSchemas.js.map +7 -0
  143. package/dist/modules/ecommerce/api/storefront/products/route.js +78 -0
  144. package/dist/modules/ecommerce/api/storefront/products/route.js.map +7 -0
  145. package/dist/modules/ecommerce/api/storefront/search/suggest/openapiSchemas.js +25 -0
  146. package/dist/modules/ecommerce/api/storefront/search/suggest/openapiSchemas.js.map +7 -0
  147. package/dist/modules/ecommerce/api/storefront/search/suggest/route.js +75 -0
  148. package/dist/modules/ecommerce/api/storefront/search/suggest/route.js.map +7 -0
  149. package/dist/modules/ecommerce/api/storefront/storefrontRouteSupport.js +58 -0
  150. package/dist/modules/ecommerce/api/storefront/storefrontRouteSupport.js.map +7 -0
  151. package/dist/modules/ecommerce/api/stores/[id]/branding/route.js +183 -0
  152. package/dist/modules/ecommerce/api/stores/[id]/branding/route.js.map +7 -0
  153. package/dist/modules/ecommerce/api/stores/[id]/preview-branding/route.js +92 -0
  154. package/dist/modules/ecommerce/api/stores/[id]/preview-branding/route.js.map +7 -0
  155. package/dist/modules/ecommerce/api/stores/crud.js +401 -0
  156. package/dist/modules/ecommerce/api/stores/crud.js.map +7 -0
  157. package/dist/modules/ecommerce/api/stores/route.js +64 -0
  158. package/dist/modules/ecommerce/api/stores/route.js.map +7 -0
  159. package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.js +9 -0
  160. package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.js.map +7 -0
  161. package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.meta.js +16 -0
  162. package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.meta.js.map +7 -0
  163. package/dist/modules/ecommerce/backend/config/ecommerce/page.js +9 -0
  164. package/dist/modules/ecommerce/backend/config/ecommerce/page.js.map +7 -0
  165. package/dist/modules/ecommerce/backend/config/ecommerce/page.meta.js +16 -0
  166. package/dist/modules/ecommerce/backend/config/ecommerce/page.meta.js.map +7 -0
  167. package/dist/modules/ecommerce/commands/stores.js +110 -0
  168. package/dist/modules/ecommerce/commands/stores.js.map +7 -0
  169. package/dist/modules/ecommerce/components/ChannelAssortmentCount.js +90 -0
  170. package/dist/modules/ecommerce/components/ChannelAssortmentCount.js.map +7 -0
  171. package/dist/modules/ecommerce/components/ChannelBindingFormSections.js +33 -0
  172. package/dist/modules/ecommerce/components/ChannelBindingFormSections.js.map +7 -0
  173. package/dist/modules/ecommerce/components/ChannelLookupPicker.js +11 -0
  174. package/dist/modules/ecommerce/components/ChannelLookupPicker.js.map +7 -0
  175. package/dist/modules/ecommerce/components/DomainStatusWarning.js +24 -0
  176. package/dist/modules/ecommerce/components/DomainStatusWarning.js.map +7 -0
  177. package/dist/modules/ecommerce/components/StoreAvailabilityDefaultsSection.js +190 -0
  178. package/dist/modules/ecommerce/components/StoreAvailabilityDefaultsSection.js.map +7 -0
  179. package/dist/modules/ecommerce/components/StoreBrandingControls.js +67 -0
  180. package/dist/modules/ecommerce/components/StoreBrandingControls.js.map +7 -0
  181. package/dist/modules/ecommerce/components/StoreBrandingPreview.js +69 -0
  182. package/dist/modules/ecommerce/components/StoreBrandingPreview.js.map +7 -0
  183. package/dist/modules/ecommerce/components/StoreBrandingTab.js +218 -0
  184. package/dist/modules/ecommerce/components/StoreBrandingTab.js.map +7 -0
  185. package/dist/modules/ecommerce/components/StoreChannelBindingDialog.js +270 -0
  186. package/dist/modules/ecommerce/components/StoreChannelBindingDialog.js.map +7 -0
  187. package/dist/modules/ecommerce/components/StoreChannelsTab.js +313 -0
  188. package/dist/modules/ecommerce/components/StoreChannelsTab.js.map +7 -0
  189. package/dist/modules/ecommerce/components/StoreCreateDialog.js +164 -0
  190. package/dist/modules/ecommerce/components/StoreCreateDialog.js.map +7 -0
  191. package/dist/modules/ecommerce/components/StoreDomainBindingDialog.js +162 -0
  192. package/dist/modules/ecommerce/components/StoreDomainBindingDialog.js.map +7 -0
  193. package/dist/modules/ecommerce/components/StoreDomainsTab.js +357 -0
  194. package/dist/modules/ecommerce/components/StoreDomainsTab.js.map +7 -0
  195. package/dist/modules/ecommerce/components/StoreEditPage.js +155 -0
  196. package/dist/modules/ecommerce/components/StoreEditPage.js.map +7 -0
  197. package/dist/modules/ecommerce/components/StoreGeneralTab.js +167 -0
  198. package/dist/modules/ecommerce/components/StoreGeneralTab.js.map +7 -0
  199. package/dist/modules/ecommerce/components/StoreListPage.js +290 -0
  200. package/dist/modules/ecommerce/components/StoreListPage.js.map +7 -0
  201. package/dist/modules/ecommerce/components/StoreSeoTab.js +132 -0
  202. package/dist/modules/ecommerce/components/StoreSeoTab.js.map +7 -0
  203. package/dist/modules/ecommerce/components/StoreStatusBadge.js +20 -0
  204. package/dist/modules/ecommerce/components/StoreStatusBadge.js.map +7 -0
  205. package/dist/modules/ecommerce/components/channelLookups.js +28 -0
  206. package/dist/modules/ecommerce/components/channelLookups.js.map +7 -0
  207. package/dist/modules/ecommerce/components/storeAdmin.js +41 -0
  208. package/dist/modules/ecommerce/components/storeAdmin.js.map +7 -0
  209. package/dist/modules/ecommerce/components/storeBrandingForm.js +197 -0
  210. package/dist/modules/ecommerce/components/storeBrandingForm.js.map +7 -0
  211. package/dist/modules/ecommerce/components/storeChannels.js +140 -0
  212. package/dist/modules/ecommerce/components/storeChannels.js.map +7 -0
  213. package/dist/modules/ecommerce/components/storeDomains.js +167 -0
  214. package/dist/modules/ecommerce/components/storeDomains.js.map +7 -0
  215. package/dist/modules/ecommerce/components/storeEditTabs.js +62 -0
  216. package/dist/modules/ecommerce/components/storeEditTabs.js.map +7 -0
  217. package/dist/modules/ecommerce/components/storeGeneral.js +95 -0
  218. package/dist/modules/ecommerce/components/storeGeneral.js.map +7 -0
  219. package/dist/modules/ecommerce/components/storeSeo.js +69 -0
  220. package/dist/modules/ecommerce/components/storeSeo.js.map +7 -0
  221. package/dist/modules/ecommerce/components/useChannelAssortmentCount.js +45 -0
  222. package/dist/modules/ecommerce/components/useChannelAssortmentCount.js.map +7 -0
  223. package/dist/modules/ecommerce/components/useStoreAccess.js +28 -0
  224. package/dist/modules/ecommerce/components/useStoreAccess.js.map +7 -0
  225. package/dist/modules/ecommerce/data/enrichers.js +157 -0
  226. package/dist/modules/ecommerce/data/enrichers.js.map +7 -0
  227. package/dist/modules/ecommerce/data/entities.js +197 -0
  228. package/dist/modules/ecommerce/data/entities.js.map +7 -0
  229. package/dist/modules/ecommerce/data/validators.js +406 -0
  230. package/dist/modules/ecommerce/data/validators.js.map +7 -0
  231. package/dist/modules/ecommerce/di.js +11 -0
  232. package/dist/modules/ecommerce/di.js.map +7 -0
  233. package/dist/modules/ecommerce/events.js +27 -0
  234. package/dist/modules/ecommerce/events.js.map +7 -0
  235. package/dist/modules/ecommerce/index.js +16 -0
  236. package/dist/modules/ecommerce/index.js.map +7 -0
  237. package/dist/modules/ecommerce/lib/assortmentCount.js +112 -0
  238. package/dist/modules/ecommerce/lib/assortmentCount.js.map +7 -0
  239. package/dist/modules/ecommerce/lib/brandingStyles.js +184 -0
  240. package/dist/modules/ecommerce/lib/brandingStyles.js.map +7 -0
  241. package/dist/modules/ecommerce/lib/buyerContext.js +284 -0
  242. package/dist/modules/ecommerce/lib/buyerContext.js.map +7 -0
  243. package/dist/modules/ecommerce/lib/cacheInvalidation.js +186 -0
  244. package/dist/modules/ecommerce/lib/cacheInvalidation.js.map +7 -0
  245. package/dist/modules/ecommerce/lib/cacheKeys.js +236 -0
  246. package/dist/modules/ecommerce/lib/cacheKeys.js.map +7 -0
  247. package/dist/modules/ecommerce/lib/createConflictRecheck.js +29 -0
  248. package/dist/modules/ecommerce/lib/createConflictRecheck.js.map +7 -0
  249. package/dist/modules/ecommerce/lib/crudEvents.js +94 -0
  250. package/dist/modules/ecommerce/lib/crudEvents.js.map +7 -0
  251. package/dist/modules/ecommerce/lib/crudSupport.js +64 -0
  252. package/dist/modules/ecommerce/lib/crudSupport.js.map +7 -0
  253. package/dist/modules/ecommerce/lib/domainBindingRebind.js +99 -0
  254. package/dist/modules/ecommerce/lib/domainBindingRebind.js.map +7 -0
  255. package/dist/modules/ecommerce/lib/domainMappingSummaries.js +39 -0
  256. package/dist/modules/ecommerce/lib/domainMappingSummaries.js.map +7 -0
  257. package/dist/modules/ecommerce/lib/exclusiveFlag.js +57 -0
  258. package/dist/modules/ecommerce/lib/exclusiveFlag.js.map +7 -0
  259. package/dist/modules/ecommerce/lib/references.js +70 -0
  260. package/dist/modules/ecommerce/lib/references.js.map +7 -0
  261. package/dist/modules/ecommerce/lib/seedDraftStore.js +99 -0
  262. package/dist/modules/ecommerce/lib/seedDraftStore.js.map +7 -0
  263. package/dist/modules/ecommerce/lib/storeBindingCascade.js +109 -0
  264. package/dist/modules/ecommerce/lib/storeBindingCascade.js.map +7 -0
  265. package/dist/modules/ecommerce/lib/storeBranding.js +40 -0
  266. package/dist/modules/ecommerce/lib/storeBranding.js.map +7 -0
  267. package/dist/modules/ecommerce/lib/storeBrandingRoute.js +76 -0
  268. package/dist/modules/ecommerce/lib/storeBrandingRoute.js.map +7 -0
  269. package/dist/modules/ecommerce/lib/storeContext.js +393 -0
  270. package/dist/modules/ecommerce/lib/storeContext.js.map +7 -0
  271. package/dist/modules/ecommerce/lib/storeContextService.js +43 -0
  272. package/dist/modules/ecommerce/lib/storeContextService.js.map +7 -0
  273. package/dist/modules/ecommerce/lib/storeLocale.js +60 -0
  274. package/dist/modules/ecommerce/lib/storeLocale.js.map +7 -0
  275. package/dist/modules/ecommerce/lib/storeNotifications.js +41 -0
  276. package/dist/modules/ecommerce/lib/storeNotifications.js.map +7 -0
  277. package/dist/modules/ecommerce/lib/storefrontCatalogSupport.js +248 -0
  278. package/dist/modules/ecommerce/lib/storefrontCatalogSupport.js.map +7 -0
  279. package/dist/modules/ecommerce/lib/storefrontCategories.js +241 -0
  280. package/dist/modules/ecommerce/lib/storefrontCategories.js.map +7 -0
  281. package/dist/modules/ecommerce/lib/storefrontCategoryCache.js +71 -0
  282. package/dist/modules/ecommerce/lib/storefrontCategoryCache.js.map +7 -0
  283. package/dist/modules/ecommerce/lib/storefrontDetail.js +447 -0
  284. package/dist/modules/ecommerce/lib/storefrontDetail.js.map +7 -0
  285. package/dist/modules/ecommerce/lib/storefrontFacets.js +441 -0
  286. package/dist/modules/ecommerce/lib/storefrontFacets.js.map +7 -0
  287. package/dist/modules/ecommerce/lib/storefrontOptionFilter.js +15 -0
  288. package/dist/modules/ecommerce/lib/storefrontOptionFilter.js.map +7 -0
  289. package/dist/modules/ecommerce/lib/storefrontPricing.js +393 -0
  290. package/dist/modules/ecommerce/lib/storefrontPricing.js.map +7 -0
  291. package/dist/modules/ecommerce/lib/storefrontProductCache.js +90 -0
  292. package/dist/modules/ecommerce/lib/storefrontProductCache.js.map +7 -0
  293. package/dist/modules/ecommerce/lib/storefrontProductScope.js +107 -0
  294. package/dist/modules/ecommerce/lib/storefrontProductScope.js.map +7 -0
  295. package/dist/modules/ecommerce/lib/storefrontProducts.js +670 -0
  296. package/dist/modules/ecommerce/lib/storefrontProducts.js.map +7 -0
  297. package/dist/modules/ecommerce/lib/storefrontQuery.js +156 -0
  298. package/dist/modules/ecommerce/lib/storefrontQuery.js.map +7 -0
  299. package/dist/modules/ecommerce/lib/storefrontRateLimit.js +99 -0
  300. package/dist/modules/ecommerce/lib/storefrontRateLimit.js.map +7 -0
  301. package/dist/modules/ecommerce/lib/storefrontSearch.js +303 -0
  302. package/dist/modules/ecommerce/lib/storefrontSearch.js.map +7 -0
  303. package/dist/modules/ecommerce/lib/storefrontSearchCache.js +35 -0
  304. package/dist/modules/ecommerce/lib/storefrontSearchCache.js.map +7 -0
  305. package/dist/modules/ecommerce/lib/subscriberSupport.js +33 -0
  306. package/dist/modules/ecommerce/lib/subscriberSupport.js.map +7 -0
  307. package/dist/modules/ecommerce/lib/types.js +1 -0
  308. package/dist/modules/ecommerce/lib/types.js.map +7 -0
  309. package/dist/modules/ecommerce/migrations/Migration20261005113233_ecommerce.js +32 -0
  310. package/dist/modules/ecommerce/migrations/Migration20261005113233_ecommerce.js.map +7 -0
  311. package/dist/modules/ecommerce/migrations/Migration20261006112733_ecommerce.js +17 -0
  312. package/dist/modules/ecommerce/migrations/Migration20261006112733_ecommerce.js.map +7 -0
  313. package/dist/modules/ecommerce/notifications.client.js +47 -0
  314. package/dist/modules/ecommerce/notifications.client.js.map +7 -0
  315. package/dist/modules/ecommerce/notifications.js +48 -0
  316. package/dist/modules/ecommerce/notifications.js.map +7 -0
  317. package/dist/modules/ecommerce/search.js +83 -0
  318. package/dist/modules/ecommerce/search.js.map +7 -0
  319. package/dist/modules/ecommerce/setup.js +17 -0
  320. package/dist/modules/ecommerce/setup.js.map +7 -0
  321. package/dist/modules/ecommerce/subscribers/assortment-empty-notifications.js +14 -0
  322. package/dist/modules/ecommerce/subscribers/assortment-empty-notifications.js.map +7 -0
  323. package/dist/modules/ecommerce/subscribers/availability-policy-cache-invalidation.js +14 -0
  324. package/dist/modules/ecommerce/subscribers/availability-policy-cache-invalidation.js.map +7 -0
  325. package/dist/modules/ecommerce/subscribers/catalog-category-cache-invalidation.js +14 -0
  326. package/dist/modules/ecommerce/subscribers/catalog-category-cache-invalidation.js.map +7 -0
  327. package/dist/modules/ecommerce/subscribers/catalog-price-cache-invalidation.js +14 -0
  328. package/dist/modules/ecommerce/subscribers/catalog-price-cache-invalidation.js.map +7 -0
  329. package/dist/modules/ecommerce/subscribers/catalog-product-cache-invalidation.js +14 -0
  330. package/dist/modules/ecommerce/subscribers/catalog-product-cache-invalidation.js.map +7 -0
  331. package/dist/modules/ecommerce/subscribers/catalog-variant-cache-invalidation.js +14 -0
  332. package/dist/modules/ecommerce/subscribers/catalog-variant-cache-invalidation.js.map +7 -0
  333. package/dist/modules/ecommerce/subscribers/customer-group-cache-invalidation.js +14 -0
  334. package/dist/modules/ecommerce/subscribers/customer-group-cache-invalidation.js.map +7 -0
  335. package/dist/modules/ecommerce/subscribers/customer-group-membership-cache-invalidation.js +14 -0
  336. package/dist/modules/ecommerce/subscribers/customer-group-membership-cache-invalidation.js.map +7 -0
  337. package/dist/modules/ecommerce/subscribers/customer-group-terms-cache-invalidation.js +14 -0
  338. package/dist/modules/ecommerce/subscribers/customer-group-terms-cache-invalidation.js.map +7 -0
  339. package/dist/modules/ecommerce/subscribers/customer-user-deleted-cache-invalidation.js +14 -0
  340. package/dist/modules/ecommerce/subscribers/customer-user-deleted-cache-invalidation.js.map +7 -0
  341. package/dist/modules/ecommerce/subscribers/customer-user-updated-cache-invalidation.js +14 -0
  342. package/dist/modules/ecommerce/subscribers/customer-user-updated-cache-invalidation.js.map +7 -0
  343. package/dist/modules/ecommerce/subscribers/domain-binding-rebind.js +16 -0
  344. package/dist/modules/ecommerce/subscribers/domain-binding-rebind.js.map +7 -0
  345. package/dist/modules/ecommerce/subscribers/domain-mapping-cache-invalidation.js +14 -0
  346. package/dist/modules/ecommerce/subscribers/domain-mapping-cache-invalidation.js.map +7 -0
  347. package/dist/modules/ecommerce/subscribers/store-cache-invalidation.js +14 -0
  348. package/dist/modules/ecommerce/subscribers/store-cache-invalidation.js.map +7 -0
  349. package/dist/modules/ecommerce/subscribers/store-channel-binding-cache-invalidation.js +14 -0
  350. package/dist/modules/ecommerce/subscribers/store-channel-binding-cache-invalidation.js.map +7 -0
  351. package/dist/modules/ecommerce/subscribers/store-domain-binding-cache-invalidation.js +14 -0
  352. package/dist/modules/ecommerce/subscribers/store-domain-binding-cache-invalidation.js.map +7 -0
  353. package/dist/modules/ecommerce/subscribers/store-notifications.js +14 -0
  354. package/dist/modules/ecommerce/subscribers/store-notifications.js.map +7 -0
  355. package/dist/modules/query_index/lib/batch.js +23 -9
  356. package/dist/modules/query_index/lib/batch.js.map +2 -2
  357. package/dist/modules/query_index/lib/doc-enrichers.js +212 -0
  358. package/dist/modules/query_index/lib/doc-enrichers.js.map +7 -0
  359. package/dist/modules/query_index/lib/document.js +2 -0
  360. package/dist/modules/query_index/lib/document.js.map +2 -2
  361. package/dist/modules/query_index/lib/engine.js +68 -1
  362. package/dist/modules/query_index/lib/engine.js.map +2 -2
  363. package/dist/modules/query_index/lib/indexer.js +7 -0
  364. package/dist/modules/query_index/lib/indexer.js.map +2 -2
  365. package/dist/modules/query_index/lib/search-tokens.js +2 -0
  366. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  367. package/dist/modules/query_index/migrations/Migration20261005201500_query_index.js +17 -0
  368. package/dist/modules/query_index/migrations/Migration20261005201500_query_index.js.map +7 -0
  369. package/dist/modules/translations/components/TranslationManager.js +3 -3
  370. package/dist/modules/translations/components/TranslationManager.js.map +2 -2
  371. package/dist/modules/translations/data/validators.js +1 -1
  372. package/dist/modules/translations/data/validators.js.map +1 -1
  373. package/dist/modules/translations/lib/batch.js +21 -1
  374. package/dist/modules/translations/lib/batch.js.map +2 -2
  375. package/dist/modules/translations/lib/helpers.js +3 -0
  376. package/dist/modules/translations/lib/helpers.js.map +2 -2
  377. package/dist/modules/translations/lib/resolve-field-list.js +14 -2
  378. package/dist/modules/translations/lib/resolve-field-list.js.map +2 -2
  379. package/generated/entities/catalog_price_history_entry/index.ts +25 -0
  380. package/generated/entities/customer_group_terms/index.ts +1 -0
  381. package/generated/entities/ecommerce_store/index.ts +15 -0
  382. package/generated/entities/ecommerce_store_channel_binding/index.ts +13 -0
  383. package/generated/entities/ecommerce_store_domain_binding/index.ts +10 -0
  384. package/generated/entities.ids.generated.ts +8 -1
  385. package/generated/entity-fields-registry.ts +72 -0
  386. package/package.json +7 -7
  387. package/src/helpers/integration/customerGroupsFixtures.ts +2 -0
  388. package/src/modules/auth/i18n/de.json +8 -0
  389. package/src/modules/auth/i18n/en.json +8 -0
  390. package/src/modules/auth/i18n/es.json +8 -0
  391. package/src/modules/auth/i18n/ko.json +8 -0
  392. package/src/modules/auth/i18n/pl.json +8 -0
  393. package/src/modules/catalog/AGENTS.md +5 -2
  394. package/src/modules/catalog/acl.ts +7 -0
  395. package/src/modules/catalog/api/config/omnibus/route.ts +204 -0
  396. package/src/modules/catalog/api/prices/history/route.ts +139 -0
  397. package/src/modules/catalog/api/prices/omnibus-preview/route.ts +202 -0
  398. package/src/modules/catalog/api/products/route.ts +53 -308
  399. package/src/modules/catalog/api/tags/route.ts +6 -0
  400. package/src/modules/catalog/backend/config/catalog/page.tsx +2 -0
  401. package/src/modules/catalog/cli.ts +84 -1
  402. package/src/modules/catalog/commands/categories.ts +54 -2
  403. package/src/modules/catalog/commands/prices.ts +43 -1
  404. package/src/modules/catalog/commands/products.ts +84 -1
  405. package/src/modules/catalog/commands/variants.ts +7 -0
  406. package/src/modules/catalog/components/OmnibusSettings.tsx +832 -0
  407. package/src/modules/catalog/components/PriceEditorOmnibusRow.tsx +219 -0
  408. package/src/modules/catalog/components/lookupSources.ts +29 -0
  409. package/src/modules/catalog/components/prices/PriceScopeSelectors.tsx +9 -0
  410. package/src/modules/catalog/components/products/VariantBuilder.tsx +9 -0
  411. package/src/modules/catalog/data/entities.ts +123 -1
  412. package/src/modules/catalog/data/validators.ts +118 -0
  413. package/src/modules/catalog/di.ts +23 -0
  414. package/src/modules/catalog/i18n/de.json +77 -0
  415. package/src/modules/catalog/i18n/en.json +77 -0
  416. package/src/modules/catalog/i18n/es.json +77 -0
  417. package/src/modules/catalog/i18n/ko.json +77 -0
  418. package/src/modules/catalog/i18n/pl.json +77 -0
  419. package/src/modules/catalog/lib/omnibus.ts +406 -0
  420. package/src/modules/catalog/lib/omnibusBackfill.ts +198 -0
  421. package/src/modules/catalog/lib/omnibusCache.ts +111 -0
  422. package/src/modules/catalog/lib/omnibusConfig.ts +73 -0
  423. package/src/modules/catalog/lib/omnibusHistoryQueries.ts +248 -0
  424. package/src/modules/catalog/lib/omnibusPresentedEntry.ts +76 -0
  425. package/src/modules/catalog/lib/omnibusProductListEnrichment.ts +125 -0
  426. package/src/modules/catalog/lib/omnibusTypes.ts +202 -0
  427. package/src/modules/catalog/lib/optionSchemaTranslations.ts +55 -0
  428. package/src/modules/catalog/lib/priceHistoryQuery.ts +155 -0
  429. package/src/modules/catalog/lib/pricing.ts +42 -4
  430. package/src/modules/catalog/lib/productFilters.ts +349 -0
  431. package/src/modules/catalog/lib/productScopeKeys.ts +162 -0
  432. package/src/modules/catalog/lib/productScopeReindex.ts +139 -0
  433. package/src/modules/catalog/migrations/.snapshot-open-mercato.json +572 -0
  434. package/src/modules/catalog/migrations/Migration20261005105352_catalog.ts +39 -0
  435. package/src/modules/catalog/migrations/Migration20261005150824_catalog.ts +39 -0
  436. package/src/modules/catalog/services/catalogOmnibusService.ts +642 -0
  437. package/src/modules/catalog/setup.ts +2 -0
  438. package/src/modules/catalog/subscribers/product-scope-keys-category-deleted.ts +18 -0
  439. package/src/modules/catalog/subscribers/product-scope-keys-category-updated.ts +19 -0
  440. package/src/modules/catalog/translations.ts +12 -0
  441. package/src/modules/configs/i18n/de.json +5 -1
  442. package/src/modules/configs/i18n/en.json +5 -1
  443. package/src/modules/configs/i18n/es.json +5 -1
  444. package/src/modules/configs/i18n/ko.json +5 -1
  445. package/src/modules/configs/i18n/pl.json +5 -1
  446. package/src/modules/configs/lib/upgrade-actions.ts +35 -0
  447. package/src/modules/customer_groups/api/customer-groups/[id]/terms/route.ts +7 -0
  448. package/src/modules/customer_groups/components/CustomerGroupTermsSection.tsx +124 -2
  449. package/src/modules/customer_groups/components/customerGroupAssortmentScope.ts +46 -0
  450. package/src/modules/customer_groups/data/entities.ts +4 -0
  451. package/src/modules/customer_groups/data/validators.ts +14 -0
  452. package/src/modules/customer_groups/i18n/de.json +12 -0
  453. package/src/modules/customer_groups/i18n/en.json +12 -0
  454. package/src/modules/customer_groups/i18n/es.json +12 -0
  455. package/src/modules/customer_groups/i18n/ko.json +12 -0
  456. package/src/modules/customer_groups/i18n/pl.json +12 -0
  457. package/src/modules/customer_groups/migrations/.snapshot-open-mercato.json +17 -0
  458. package/src/modules/customer_groups/migrations/Migration20261005110250_customer_groups.ts +15 -0
  459. package/src/modules/customer_groups/services/customerGroupsService.ts +74 -23
  460. package/src/modules/ecommerce/acl.ts +9 -0
  461. package/src/modules/ecommerce/api/domain-mappings/route.ts +76 -0
  462. package/src/modules/ecommerce/api/openapi.ts +28 -0
  463. package/src/modules/ecommerce/api/store-channel-bindings/[id]/assortment-count/route.ts +141 -0
  464. package/src/modules/ecommerce/api/store-channel-bindings/crud.ts +283 -0
  465. package/src/modules/ecommerce/api/store-channel-bindings/route.ts +67 -0
  466. package/src/modules/ecommerce/api/store-domain-bindings/crud.ts +324 -0
  467. package/src/modules/ecommerce/api/store-domain-bindings/route.ts +73 -0
  468. package/src/modules/ecommerce/api/storefront/categories/[slug]/route.ts +94 -0
  469. package/src/modules/ecommerce/api/storefront/categories/openapiSchemas.ts +63 -0
  470. package/src/modules/ecommerce/api/storefront/categories/route.ts +78 -0
  471. package/src/modules/ecommerce/api/storefront/context/route.ts +203 -0
  472. package/src/modules/ecommerce/api/storefront/products/[idOrHandle]/route.ts +94 -0
  473. package/src/modules/ecommerce/api/storefront/products/openapiSchemas.ts +193 -0
  474. package/src/modules/ecommerce/api/storefront/products/route.ts +81 -0
  475. package/src/modules/ecommerce/api/storefront/search/suggest/openapiSchemas.ts +25 -0
  476. package/src/modules/ecommerce/api/storefront/search/suggest/route.ts +78 -0
  477. package/src/modules/ecommerce/api/storefront/storefrontRouteSupport.ts +68 -0
  478. package/src/modules/ecommerce/api/stores/[id]/branding/route.ts +205 -0
  479. package/src/modules/ecommerce/api/stores/[id]/preview-branding/route.ts +99 -0
  480. package/src/modules/ecommerce/api/stores/crud.ts +457 -0
  481. package/src/modules/ecommerce/api/stores/route.ts +66 -0
  482. package/src/modules/ecommerce/backend/config/ecommerce/[id]/page.meta.ts +12 -0
  483. package/src/modules/ecommerce/backend/config/ecommerce/[id]/page.tsx +5 -0
  484. package/src/modules/ecommerce/backend/config/ecommerce/page.meta.ts +12 -0
  485. package/src/modules/ecommerce/backend/config/ecommerce/page.tsx +5 -0
  486. package/src/modules/ecommerce/commands/stores.ts +154 -0
  487. package/src/modules/ecommerce/components/ChannelAssortmentCount.tsx +138 -0
  488. package/src/modules/ecommerce/components/ChannelBindingFormSections.tsx +40 -0
  489. package/src/modules/ecommerce/components/ChannelLookupPicker.tsx +5 -0
  490. package/src/modules/ecommerce/components/DomainStatusWarning.tsx +32 -0
  491. package/src/modules/ecommerce/components/StoreAvailabilityDefaultsSection.tsx +219 -0
  492. package/src/modules/ecommerce/components/StoreBrandingControls.tsx +73 -0
  493. package/src/modules/ecommerce/components/StoreBrandingPreview.tsx +77 -0
  494. package/src/modules/ecommerce/components/StoreBrandingTab.tsx +242 -0
  495. package/src/modules/ecommerce/components/StoreChannelBindingDialog.tsx +306 -0
  496. package/src/modules/ecommerce/components/StoreChannelsTab.tsx +375 -0
  497. package/src/modules/ecommerce/components/StoreCreateDialog.tsx +204 -0
  498. package/src/modules/ecommerce/components/StoreDomainBindingDialog.tsx +198 -0
  499. package/src/modules/ecommerce/components/StoreDomainsTab.tsx +426 -0
  500. package/src/modules/ecommerce/components/StoreEditPage.tsx +193 -0
  501. package/src/modules/ecommerce/components/StoreGeneralTab.tsx +189 -0
  502. package/src/modules/ecommerce/components/StoreListPage.tsx +326 -0
  503. package/src/modules/ecommerce/components/StoreSeoTab.tsx +152 -0
  504. package/src/modules/ecommerce/components/StoreStatusBadge.tsx +22 -0
  505. package/src/modules/ecommerce/components/channelLookups.ts +24 -0
  506. package/src/modules/ecommerce/components/storeAdmin.ts +56 -0
  507. package/src/modules/ecommerce/components/storeBrandingForm.ts +230 -0
  508. package/src/modules/ecommerce/components/storeChannels.ts +210 -0
  509. package/src/modules/ecommerce/components/storeDomains.ts +221 -0
  510. package/src/modules/ecommerce/components/storeEditTabs.tsx +76 -0
  511. package/src/modules/ecommerce/components/storeGeneral.ts +155 -0
  512. package/src/modules/ecommerce/components/storeSeo.ts +78 -0
  513. package/src/modules/ecommerce/components/useChannelAssortmentCount.ts +67 -0
  514. package/src/modules/ecommerce/components/useStoreAccess.ts +36 -0
  515. package/src/modules/ecommerce/data/enrichers.ts +213 -0
  516. package/src/modules/ecommerce/data/entities.ts +168 -0
  517. package/src/modules/ecommerce/data/validators.ts +587 -0
  518. package/src/modules/ecommerce/di.ts +9 -0
  519. package/src/modules/ecommerce/events.ts +27 -0
  520. package/src/modules/ecommerce/i18n/de.json +341 -0
  521. package/src/modules/ecommerce/i18n/en.json +341 -0
  522. package/src/modules/ecommerce/i18n/es.json +341 -0
  523. package/src/modules/ecommerce/i18n/ko.json +341 -0
  524. package/src/modules/ecommerce/i18n/pl.json +341 -0
  525. package/src/modules/ecommerce/index.ts +14 -0
  526. package/src/modules/ecommerce/lib/assortmentCount.ts +175 -0
  527. package/src/modules/ecommerce/lib/brandingStyles.ts +215 -0
  528. package/src/modules/ecommerce/lib/buyerContext.ts +401 -0
  529. package/src/modules/ecommerce/lib/cacheInvalidation.ts +302 -0
  530. package/src/modules/ecommerce/lib/cacheKeys.ts +340 -0
  531. package/src/modules/ecommerce/lib/createConflictRecheck.ts +31 -0
  532. package/src/modules/ecommerce/lib/crudEvents.ts +128 -0
  533. package/src/modules/ecommerce/lib/crudSupport.ts +85 -0
  534. package/src/modules/ecommerce/lib/domainBindingRebind.ts +138 -0
  535. package/src/modules/ecommerce/lib/domainMappingSummaries.ts +71 -0
  536. package/src/modules/ecommerce/lib/exclusiveFlag.ts +90 -0
  537. package/src/modules/ecommerce/lib/references.ts +93 -0
  538. package/src/modules/ecommerce/lib/seedDraftStore.ts +125 -0
  539. package/src/modules/ecommerce/lib/storeBindingCascade.ts +138 -0
  540. package/src/modules/ecommerce/lib/storeBranding.ts +48 -0
  541. package/src/modules/ecommerce/lib/storeBrandingRoute.ts +91 -0
  542. package/src/modules/ecommerce/lib/storeContext.ts +669 -0
  543. package/src/modules/ecommerce/lib/storeContextService.ts +71 -0
  544. package/src/modules/ecommerce/lib/storeLocale.ts +88 -0
  545. package/src/modules/ecommerce/lib/storeNotifications.ts +55 -0
  546. package/src/modules/ecommerce/lib/storefrontCatalogSupport.ts +427 -0
  547. package/src/modules/ecommerce/lib/storefrontCategories.ts +419 -0
  548. package/src/modules/ecommerce/lib/storefrontCategoryCache.ts +113 -0
  549. package/src/modules/ecommerce/lib/storefrontDetail.ts +654 -0
  550. package/src/modules/ecommerce/lib/storefrontFacets.ts +697 -0
  551. package/src/modules/ecommerce/lib/storefrontOptionFilter.ts +44 -0
  552. package/src/modules/ecommerce/lib/storefrontPricing.ts +583 -0
  553. package/src/modules/ecommerce/lib/storefrontProductCache.ts +126 -0
  554. package/src/modules/ecommerce/lib/storefrontProductScope.ts +181 -0
  555. package/src/modules/ecommerce/lib/storefrontProducts.ts +963 -0
  556. package/src/modules/ecommerce/lib/storefrontQuery.ts +215 -0
  557. package/src/modules/ecommerce/lib/storefrontRateLimit.ts +126 -0
  558. package/src/modules/ecommerce/lib/storefrontSearch.ts +454 -0
  559. package/src/modules/ecommerce/lib/storefrontSearchCache.ts +49 -0
  560. package/src/modules/ecommerce/lib/subscriberSupport.ts +41 -0
  561. package/src/modules/ecommerce/lib/types.ts +69 -0
  562. package/src/modules/ecommerce/migrations/.snapshot-open-mercato.json +829 -0
  563. package/src/modules/ecommerce/migrations/Migration20261005113233_ecommerce.ts +32 -0
  564. package/src/modules/ecommerce/migrations/Migration20261006112733_ecommerce.ts +15 -0
  565. package/src/modules/ecommerce/notifications.client.ts +46 -0
  566. package/src/modules/ecommerce/notifications.ts +46 -0
  567. package/src/modules/ecommerce/search.ts +93 -0
  568. package/src/modules/ecommerce/setup.ts +15 -0
  569. package/src/modules/ecommerce/subscribers/assortment-empty-notifications.ts +12 -0
  570. package/src/modules/ecommerce/subscribers/availability-policy-cache-invalidation.ts +12 -0
  571. package/src/modules/ecommerce/subscribers/catalog-category-cache-invalidation.ts +12 -0
  572. package/src/modules/ecommerce/subscribers/catalog-price-cache-invalidation.ts +12 -0
  573. package/src/modules/ecommerce/subscribers/catalog-product-cache-invalidation.ts +12 -0
  574. package/src/modules/ecommerce/subscribers/catalog-variant-cache-invalidation.ts +12 -0
  575. package/src/modules/ecommerce/subscribers/customer-group-cache-invalidation.ts +12 -0
  576. package/src/modules/ecommerce/subscribers/customer-group-membership-cache-invalidation.ts +12 -0
  577. package/src/modules/ecommerce/subscribers/customer-group-terms-cache-invalidation.ts +12 -0
  578. package/src/modules/ecommerce/subscribers/customer-user-deleted-cache-invalidation.ts +12 -0
  579. package/src/modules/ecommerce/subscribers/customer-user-updated-cache-invalidation.ts +12 -0
  580. package/src/modules/ecommerce/subscribers/domain-binding-rebind.ts +14 -0
  581. package/src/modules/ecommerce/subscribers/domain-mapping-cache-invalidation.ts +12 -0
  582. package/src/modules/ecommerce/subscribers/store-cache-invalidation.ts +12 -0
  583. package/src/modules/ecommerce/subscribers/store-channel-binding-cache-invalidation.ts +12 -0
  584. package/src/modules/ecommerce/subscribers/store-domain-binding-cache-invalidation.ts +12 -0
  585. package/src/modules/ecommerce/subscribers/store-notifications.ts +12 -0
  586. package/src/modules/query_index/lib/batch.ts +25 -9
  587. package/src/modules/query_index/lib/doc-enrichers.ts +306 -0
  588. package/src/modules/query_index/lib/document.ts +2 -0
  589. package/src/modules/query_index/lib/engine.ts +58 -1
  590. package/src/modules/query_index/lib/indexer.ts +8 -0
  591. package/src/modules/query_index/lib/search-tokens.ts +2 -0
  592. package/src/modules/query_index/migrations/Migration20261005201500_query_index.ts +42 -0
  593. package/src/modules/translations/components/TranslationManager.tsx +3 -3
  594. package/src/modules/translations/data/validators.ts +1 -1
  595. package/src/modules/translations/lib/batch.ts +47 -0
  596. package/src/modules/translations/lib/helpers.ts +4 -0
  597. package/src/modules/translations/lib/resolve-field-list.ts +16 -2
@@ -0,0 +1,202 @@
1
+ import { z } from 'zod'
2
+
3
+ export const PRICE_HISTORY_CHANGE_TYPES = ['create', 'update', 'delete', 'undo'] as const
4
+
5
+ export const priceHistoryChangeTypeSchema = z.enum(PRICE_HISTORY_CHANGE_TYPES)
6
+
7
+ export type PriceHistoryChangeType = z.infer<typeof priceHistoryChangeTypeSchema>
8
+
9
+ export const PRICE_HISTORY_SOURCES = ['api', 'system'] as const
10
+
11
+ export const priceHistorySourceSchema = z.enum(PRICE_HISTORY_SOURCES)
12
+
13
+ export type PriceHistorySource = z.infer<typeof priceHistorySourceSchema>
14
+
15
+ const numericString = z.string().regex(/^-?\d+(\.\d+)?$/)
16
+
17
+ export const priceHistoryEntrySchema = z.object({
18
+ tenantId: z.string().uuid(),
19
+ organizationId: z.string().uuid(),
20
+ priceId: z.string().uuid(),
21
+ productId: z.string().uuid(),
22
+ variantId: z.string().uuid().nullable(),
23
+ offerId: z.string().uuid().nullable(),
24
+ channelId: z.string().uuid().nullable(),
25
+ priceKindId: z.string().uuid(),
26
+ priceKindCode: z.string().min(1),
27
+ currencyCode: z.string().length(3),
28
+ unitPriceNet: numericString.nullable(),
29
+ unitPriceGross: numericString.nullable(),
30
+ taxRate: numericString.nullable(),
31
+ taxAmount: numericString.nullable(),
32
+ minQuantity: z.number().int().nullable(),
33
+ maxQuantity: z.number().int().nullable(),
34
+ startsAt: z.date().nullable(),
35
+ endsAt: z.date().nullable(),
36
+ recordedAt: z.date(),
37
+ changeType: priceHistoryChangeTypeSchema,
38
+ source: priceHistorySourceSchema,
39
+ isAnnounced: z.boolean().nullable(),
40
+ idempotencyKey: z.string().min(1).nullable(),
41
+ metadata: z.record(z.string(), z.unknown()).nullable(),
42
+ })
43
+
44
+ export type PriceHistoryEntryInput = z.infer<typeof priceHistoryEntrySchema>
45
+
46
+ export const OMNIBUS_CONFIG_MODULE_ID = 'catalog'
47
+
48
+ export const OMNIBUS_CONFIG_NAME = 'omnibus'
49
+
50
+ export const OMNIBUS_DEFAULT_LOOKBACK_DAYS = 30
51
+
52
+ export const OMNIBUS_NO_CHANNEL_MODES = ['best_effort', 'require_channel'] as const
53
+
54
+ export const omnibusNoChannelModeSchema = z.enum(OMNIBUS_NO_CHANNEL_MODES)
55
+
56
+ export type OmnibusNoChannelMode = z.infer<typeof omnibusNoChannelModeSchema>
57
+
58
+ export const OMNIBUS_MINIMIZATION_AXES = ['gross', 'net'] as const
59
+
60
+ export const omnibusMinimizationAxisSchema = z.enum(OMNIBUS_MINIMIZATION_AXES)
61
+
62
+ export type OmnibusMinimizationAxis = z.infer<typeof omnibusMinimizationAxisSchema>
63
+
64
+ export const OMNIBUS_APPLICABILITY_REASONS = [
65
+ 'no_history',
66
+ 'not_in_eu_market',
67
+ 'missing_channel_context',
68
+ 'insufficient_history',
69
+ 'announced_promotion',
70
+ 'not_announced',
71
+ 'progressive_reduction_frozen',
72
+ 'perishable_exempt',
73
+ 'perishable_last_price',
74
+ 'new_arrival_reduced_window',
75
+ ] as const
76
+
77
+ export const omnibusApplicabilityReasonSchema = z.enum(OMNIBUS_APPLICABILITY_REASONS)
78
+
79
+ export type OmnibusApplicabilityReason = z.infer<typeof omnibusApplicabilityReasonSchema>
80
+
81
+ export const omnibusCountryCodeSchema = z
82
+ .string()
83
+ .regex(/^[A-Z]{2}$/)
84
+ .refine((value) => value !== 'EU')
85
+
86
+ export const omnibusLookbackDaysSchema = z.number().int().min(1).max(365)
87
+
88
+ export const omnibusChannelConfigSchema = z.object({
89
+ presentedPriceKindId: z.string().uuid(),
90
+ countryCode: omnibusCountryCodeSchema.optional(),
91
+ lookbackDays: omnibusLookbackDaysSchema.optional(),
92
+ minimizationAxis: omnibusMinimizationAxisSchema.optional(),
93
+ })
94
+
95
+ export type OmnibusChannelConfig = z.infer<typeof omnibusChannelConfigSchema>
96
+
97
+ export const omnibusBackfillCoverageSchema = z.object({
98
+ completedAt: z.string().datetime({ offset: true }),
99
+ lookbackDays: omnibusLookbackDaysSchema,
100
+ })
101
+
102
+ export const omnibusConfigSchema = z.object({
103
+ enabled: z.boolean().default(false),
104
+ enabledCountryCodes: z.array(omnibusCountryCodeSchema).default([]),
105
+ noChannelMode: omnibusNoChannelModeSchema.default('best_effort'),
106
+ lookbackDays: omnibusLookbackDaysSchema.default(OMNIBUS_DEFAULT_LOOKBACK_DAYS),
107
+ minimizationAxis: omnibusMinimizationAxisSchema.default('gross'),
108
+ defaultPresentedPriceKindId: z.string().uuid().optional(),
109
+ backfillCoverage: z.record(z.string(), omnibusBackfillCoverageSchema).default({}),
110
+ channels: z.record(z.string().uuid(), omnibusChannelConfigSchema).default({}),
111
+ })
112
+
113
+ export type OmnibusConfig = z.infer<typeof omnibusConfigSchema>
114
+
115
+ export type OmnibusResolutionContext = {
116
+ tenantId: string
117
+ organizationId: string
118
+ productId?: string | null
119
+ variantId?: string | null
120
+ offerId?: string | null
121
+ channelId?: string | null
122
+ priceKindId?: string | null
123
+ currencyCode: string
124
+ isStorefront?: boolean
125
+ now?: Date
126
+ }
127
+
128
+ export type OmnibusPresentedEntry = {
129
+ priceId: string
130
+ changeType: PriceHistoryChangeType
131
+ recordedAt: Date | string
132
+ startsAt?: Date | string | null
133
+ offerId?: string | null
134
+ isAnnounced?: boolean | null
135
+ }
136
+
137
+ export type OmnibusResolutionRequest = {
138
+ context: OmnibusResolutionContext
139
+ presentedEntry?: OmnibusPresentedEntry | null
140
+ priceKindIsPromotion?: boolean
141
+ }
142
+
143
+ /** Undo of this command removes the price, so its history row is a tombstone, not a price observation. */
144
+ export const OMNIBUS_PRICE_REMOVING_UNDO_COMMAND = 'catalog.prices.create'
145
+
146
+ export type OmnibusHistoryRow = {
147
+ id: string
148
+ priceId: string
149
+ changeType: PriceHistoryChangeType
150
+ recordedAt: string
151
+ unitPriceNet: string | null
152
+ unitPriceGross: string | null
153
+ undoneCommand?: string | null
154
+ }
155
+
156
+ export type OmnibusLowestPriceResult = {
157
+ reason: OmnibusApplicabilityReason | null
158
+ presentedPriceKindId: string | null
159
+ lowestRow: OmnibusHistoryRow | null
160
+ previousRow: OmnibusHistoryRow | null
161
+ insufficientHistory: boolean
162
+ promotionAnchorAt: string | null
163
+ coverageStartAt: string | null
164
+ windowStart: string | null
165
+ windowEnd: string | null
166
+ lookbackDays: number
167
+ minimizationAxis: OmnibusMinimizationAxis
168
+ }
169
+
170
+ export type OmnibusBlock = {
171
+ presentedPriceKindId: string | null
172
+ lookbackDays: number
173
+ minimizationAxis: OmnibusMinimizationAxis
174
+ promotionAnchorAt: string | null
175
+ windowStart: string | null
176
+ windowEnd: string | null
177
+ coverageStartAt: string | null
178
+ lowestPriceNet: string | null
179
+ lowestPriceGross: string | null
180
+ previousPriceNet: string | null
181
+ previousPriceGross: string | null
182
+ currencyCode: string
183
+ applicable: boolean
184
+ applicabilityReason: OmnibusApplicabilityReason
185
+ }
186
+
187
+ export const omnibusBlockSchema = z.object({
188
+ presentedPriceKindId: z.string().uuid().nullable(),
189
+ lookbackDays: z.number().int(),
190
+ minimizationAxis: omnibusMinimizationAxisSchema,
191
+ promotionAnchorAt: z.string().nullable(),
192
+ windowStart: z.string().nullable(),
193
+ windowEnd: z.string().nullable(),
194
+ coverageStartAt: z.string().nullable(),
195
+ lowestPriceNet: z.string().nullable(),
196
+ lowestPriceGross: z.string().nullable(),
197
+ previousPriceNet: z.string().nullable(),
198
+ previousPriceGross: z.string().nullable(),
199
+ currencyCode: z.string(),
200
+ applicable: z.boolean(),
201
+ applicabilityReason: omnibusApplicabilityReasonSchema,
202
+ }) satisfies z.ZodType<OmnibusBlock>
@@ -0,0 +1,55 @@
1
+ import type { TranslatableFieldExpansion } from '@open-mercato/shared/lib/localization/translatable-fields'
2
+
3
+ export const OPTION_SCHEMA_TEMPLATE_ENTITY_TYPE = 'catalog:catalog_option_schema_template'
4
+
5
+ export function optionLabelTranslationField(optionCode: string): string {
6
+ return `options.${optionCode}.label`
7
+ }
8
+
9
+ export function optionChoiceLabelTranslationField(optionCode: string, choiceCode: string): string {
10
+ return `options.${optionCode}.choices.${choiceCode}.label`
11
+ }
12
+
13
+ function isRecord(value: unknown): value is Record<string, unknown> {
14
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
15
+ }
16
+
17
+ function nonEmptyText(value: unknown): string | null {
18
+ return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null
19
+ }
20
+
21
+ export function expandOptionSchemaTranslationFields(record: Record<string, unknown>): TranslatableFieldExpansion[] {
22
+ const schema = isRecord(record.schema) ? record.schema : null
23
+ const options = schema && Array.isArray(schema.options) ? schema.options : []
24
+ const expansions: TranslatableFieldExpansion[] = []
25
+ const seen = new Set<string>()
26
+ const push = (expansion: TranslatableFieldExpansion) => {
27
+ if (seen.has(expansion.key)) return
28
+ seen.add(expansion.key)
29
+ expansions.push(expansion)
30
+ }
31
+ for (const option of options) {
32
+ if (!isRecord(option)) continue
33
+ const optionCode = nonEmptyText(option.code)
34
+ if (!optionCode) continue
35
+ const optionLabel = nonEmptyText(option.label) ?? optionCode
36
+ push({
37
+ key: optionLabelTranslationField(optionCode),
38
+ label: optionLabel,
39
+ baseValue: nonEmptyText(option.label) ?? '',
40
+ })
41
+ const choices = Array.isArray(option.choices) ? option.choices : []
42
+ for (const choice of choices) {
43
+ if (!isRecord(choice)) continue
44
+ const choiceCode = nonEmptyText(choice.code)
45
+ if (!choiceCode) continue
46
+ const choiceLabel = nonEmptyText(choice.label)
47
+ push({
48
+ key: optionChoiceLabelTranslationField(optionCode, choiceCode),
49
+ label: `${optionLabel} › ${choiceLabel ?? choiceCode}`,
50
+ baseValue: choiceLabel ?? '',
51
+ })
52
+ }
53
+ }
54
+ return expansions
55
+ }
@@ -0,0 +1,155 @@
1
+ import { z } from 'zod'
2
+ import type { FilterQuery } from '@mikro-orm/postgresql'
3
+ import type { CatalogPriceHistoryEntry } from '../data/entities'
4
+ import type { PriceHistoryQuery } from '../data/validators'
5
+ import type { PriceHistoryChangeType, PriceHistorySource } from './omnibusTypes'
6
+
7
+ export type PriceHistoryCursor = {
8
+ recordedAt: string
9
+ id: string
10
+ }
11
+
12
+ const cursorSchema = z.object({
13
+ recordedAt: z.string().datetime({ offset: true }),
14
+ id: z.string().uuid(),
15
+ })
16
+
17
+ export function encodePriceHistoryCursor(cursor: PriceHistoryCursor): string {
18
+ return Buffer.from(JSON.stringify(cursor), 'utf8').toString('base64')
19
+ }
20
+
21
+ export function decodePriceHistoryCursor(value: string | null | undefined): PriceHistoryCursor | null {
22
+ if (typeof value !== 'string' || value.trim().length === 0) return null
23
+ try {
24
+ const decoded = Buffer.from(value.trim(), 'base64').toString('utf8')
25
+ const parsed = cursorSchema.safeParse(JSON.parse(decoded))
26
+ if (!parsed.success) return null
27
+ return { recordedAt: new Date(parsed.data.recordedAt).toISOString(), id: parsed.data.id }
28
+ } catch {
29
+ return null
30
+ }
31
+ }
32
+
33
+ export type PriceHistoryScope = {
34
+ tenantId: string
35
+ organizationIds: string[] | null
36
+ }
37
+
38
+ export type PriceHistoryOrganizationScopeInput = {
39
+ selectedId: string | null
40
+ filterIds: string[] | null
41
+ allowedIds: string[] | null
42
+ }
43
+
44
+ export function resolvePriceHistoryOrganizationIds(
45
+ scope: PriceHistoryOrganizationScopeInput,
46
+ authOrganizationId: string | null | undefined,
47
+ ): string[] | null {
48
+ if (scope.selectedId) return [scope.selectedId]
49
+ if (Array.isArray(scope.filterIds) && scope.filterIds.length > 0) return Array.from(new Set(scope.filterIds))
50
+ if (scope.filterIds === null && scope.allowedIds === null) return null
51
+ return authOrganizationId ? [authOrganizationId] : []
52
+ }
53
+
54
+ export function buildPriceHistoryWhere(
55
+ scope: PriceHistoryScope,
56
+ query: PriceHistoryQuery,
57
+ ): FilterQuery<CatalogPriceHistoryEntry> {
58
+ const where: Record<string, unknown> = { tenantId: scope.tenantId }
59
+ if (scope.organizationIds) where.organizationId = { $in: scope.organizationIds }
60
+ if (query.productId) where.productId = query.productId
61
+ if (query.variantId) where.variantId = query.variantId
62
+ if (query.priceKindId) where.priceKindId = query.priceKindId
63
+ if (query.channelId) where.channelId = query.channelId
64
+ if (query.currencyCode) where.currencyCode = query.currencyCode
65
+ const recordedAt: Record<string, Date> = {}
66
+ if (query.from) recordedAt.$gte = new Date(query.from)
67
+ if (query.to) recordedAt.$lte = new Date(query.to)
68
+ if (Object.keys(recordedAt).length > 0) where.recordedAt = recordedAt
69
+ return where as FilterQuery<CatalogPriceHistoryEntry>
70
+ }
71
+
72
+ export function applyPriceHistoryCursor(
73
+ where: FilterQuery<CatalogPriceHistoryEntry>,
74
+ cursor: PriceHistoryCursor | null,
75
+ ): FilterQuery<CatalogPriceHistoryEntry> {
76
+ if (!cursor) return where
77
+ const recordedAt = new Date(cursor.recordedAt)
78
+ return {
79
+ $and: [
80
+ where,
81
+ {
82
+ $or: [
83
+ { recordedAt: { $lt: recordedAt } },
84
+ { recordedAt, id: { $lt: cursor.id } },
85
+ ],
86
+ },
87
+ ],
88
+ } as FilterQuery<CatalogPriceHistoryEntry>
89
+ }
90
+
91
+ export function formatFixedDecimal4(value: string | number | null | undefined): string | null {
92
+ if (value === null || value === undefined) return null
93
+ const raw = typeof value === 'number' ? value.toFixed(4) : value.trim()
94
+ const match = /^(-?)(\d+)(?:\.(\d*))?$/.exec(raw)
95
+ if (!match) return raw
96
+ const [, sign, whole, fraction = ''] = match
97
+ const normalizedFraction = fraction.length >= 4 ? fraction.slice(0, 4) : fraction.padEnd(4, '0')
98
+ return `${sign}${whole}.${normalizedFraction}`
99
+ }
100
+
101
+ function toIsoOrNull(value: Date | string | null | undefined): string | null {
102
+ if (!value) return null
103
+ const date = value instanceof Date ? value : new Date(value)
104
+ return Number.isNaN(date.getTime()) ? null : date.toISOString()
105
+ }
106
+
107
+ export type PriceHistoryItem = {
108
+ id: string
109
+ priceId: string
110
+ productId: string
111
+ variantId: string | null
112
+ offerId: string | null
113
+ channelId: string | null
114
+ priceKindId: string
115
+ priceKindCode: string
116
+ currencyCode: string
117
+ unitPriceNet: string | null
118
+ unitPriceGross: string | null
119
+ taxRate: string | null
120
+ taxAmount: string | null
121
+ minQuantity: number | null
122
+ maxQuantity: number | null
123
+ startsAt: string | null
124
+ endsAt: string | null
125
+ recordedAt: string
126
+ changeType: PriceHistoryChangeType
127
+ source: PriceHistorySource
128
+ isAnnounced: boolean
129
+ }
130
+
131
+ export function serializePriceHistoryEntry(entry: CatalogPriceHistoryEntry): PriceHistoryItem {
132
+ return {
133
+ id: entry.id,
134
+ priceId: entry.priceId,
135
+ productId: entry.productId,
136
+ variantId: entry.variantId ?? null,
137
+ offerId: entry.offerId ?? null,
138
+ channelId: entry.channelId ?? null,
139
+ priceKindId: entry.priceKindId,
140
+ priceKindCode: entry.priceKindCode,
141
+ currencyCode: entry.currencyCode,
142
+ unitPriceNet: formatFixedDecimal4(entry.unitPriceNet),
143
+ unitPriceGross: formatFixedDecimal4(entry.unitPriceGross),
144
+ taxRate: formatFixedDecimal4(entry.taxRate),
145
+ taxAmount: formatFixedDecimal4(entry.taxAmount),
146
+ minQuantity: entry.minQuantity ?? null,
147
+ maxQuantity: entry.maxQuantity ?? null,
148
+ startsAt: toIsoOrNull(entry.startsAt),
149
+ endsAt: toIsoOrNull(entry.endsAt),
150
+ recordedAt: toIsoOrNull(entry.recordedAt) ?? new Date(0).toISOString(),
151
+ changeType: entry.changeType,
152
+ source: entry.source,
153
+ isAnnounced: entry.isAnnounced === true,
154
+ }
155
+ }
@@ -20,6 +20,15 @@ export type PricingContext = {
20
20
  customerGroupIds?: string[]
21
21
  /** When set, only rows in this currency match. Omitted (the default): no currency filtering, unchanged legacy behavior. */
22
22
  currencyCode?: string | null
23
+ /**
24
+ * When set, only rows of this price kind (by `CatalogPriceKind` id) match, plus rows of any promotional
25
+ * kind (`CatalogPriceKind.isPromotion === true`) as an overlay (pricing-engine amendment D2a). Promotion
26
+ * status is read from a populated `priceKind`; a row carrying only a kind id string is admitted solely when
27
+ * that id equals this one. Unset or `null`: kind is not filtered, unchanged legacy behavior.
28
+ */
29
+ priceKindId?: string | null
30
+ /** The buyer's customer entities, person first, then company. A row's `customerId` matches when it appears in this list. Falls back to `customerId` (above) when omitted. */
31
+ customerIds?: string[]
23
32
  quantity: number
24
33
  date: Date
25
34
  }
@@ -47,6 +56,23 @@ export function resolvePriceChannelId(row: PriceRow): string | null {
47
56
  return row.channelId ?? row.offer.channelId ?? null
48
57
  }
49
58
 
59
+ export function resolvePriceKindId(row: PriceRow): string | null {
60
+ if (!row.priceKind) return null
61
+ return typeof row.priceKind === 'string' ? row.priceKind : row.priceKind.id ?? null
62
+ }
63
+
64
+ function resolveContextCustomerIds(ctx: PricingContext): string[] {
65
+ return ctx.customerIds ?? (ctx.customerId ? [ctx.customerId] : [])
66
+ }
67
+
68
+ function isPromotionalPriceKindRow(row: PriceRow): boolean {
69
+ return Boolean(row.priceKind && typeof row.priceKind !== 'string' && row.priceKind.isPromotion === true)
70
+ }
71
+
72
+ function matchesPriceKind(row: PriceRow, priceKindId: string): boolean {
73
+ return resolvePriceKindId(row) === priceKindId || isPromotionalPriceKindRow(row)
74
+ }
75
+
50
76
  export function resolvePriceKindCode(row: PriceRow): string {
51
77
  if (row.priceKind) {
52
78
  if (typeof row.priceKind === 'string') return row.priceKind
@@ -68,12 +94,13 @@ function matchesContext(row: PriceRow, ctx: PricingContext): boolean {
68
94
  }
69
95
  if (row.userId && ctx.userId !== row.userId) return false
70
96
  if (row.userGroupId && ctx.userGroupId !== row.userGroupId) return false
71
- if (row.customerId && ctx.customerId !== row.customerId) return false
97
+ if (row.customerId && !resolveContextCustomerIds(ctx).includes(row.customerId)) return false
72
98
  if (row.customerGroupId) {
73
99
  const candidateGroupIds = ctx.customerGroupIds ?? (ctx.customerGroupId ? [ctx.customerGroupId] : [])
74
100
  if (!candidateGroupIds.includes(row.customerGroupId)) return false
75
101
  }
76
102
  if (ctx.currencyCode && row.currencyCode !== ctx.currencyCode) return false
103
+ if (ctx.priceKindId && !matchesPriceKind(row, ctx.priceKindId)) return false
77
104
  if (ctx.offerId && resolvePriceOfferId(row) && resolvePriceOfferId(row) !== ctx.offerId) return false
78
105
  return true
79
106
  }
@@ -86,7 +113,8 @@ function matchesContext(row: PriceRow, ctx: PricingContext): boolean {
86
113
  * `.ai/specs/2026-08-21-pricing-engine.md` § Row narrowing).
87
114
  *
88
115
  * Covers only the dimensions that are plain column comparisons: customer,
89
- * customer-group, user, user-group, channel, currency. Quantity bounds,
116
+ * customer-group, user, user-group, channel, currency, price kind (the resolved
117
+ * kind or any promotional kind, via a `priceKind.isPromotion` relation clause). Quantity bounds,
90
118
  * validity windows, and offer-derived channel resolution stay in
91
119
  * `matchesContext` — they are cheap over an already-narrowed set and are not
92
120
  * expressible as one column predicate (offer's own `channelId` lives on a
@@ -101,10 +129,11 @@ function matchesContext(row: PriceRow, ctx: PricingContext): boolean {
101
129
  */
102
130
  export function buildPriceRowFilter(ctx: PricingContext): FilterQuery<CatalogProductPrice> {
103
131
  const customerGroupIds = ctx.customerGroupIds ?? (ctx.customerGroupId ? [ctx.customerGroupId] : [])
132
+ const customerIds = resolveContextCustomerIds(ctx)
104
133
 
105
134
  const clauses: FilterQuery<CatalogProductPrice>[] = [
106
- ctx.customerId
107
- ? { $or: [{ customerId: null }, { customerId: ctx.customerId }] }
135
+ customerIds.length
136
+ ? { $or: [{ customerId: null }, { customerId: { $in: customerIds } }] }
108
137
  : { customerId: null },
109
138
  customerGroupIds.length
110
139
  ? { $or: [{ customerGroupId: null }, { customerGroupId: { $in: customerGroupIds } }] }
@@ -124,6 +153,10 @@ export function buildPriceRowFilter(ctx: PricingContext): FilterQuery<CatalogPro
124
153
  clauses.push({ currencyCode: ctx.currencyCode })
125
154
  }
126
155
 
156
+ if (ctx.priceKindId) {
157
+ clauses.push({ $or: [{ priceKind: ctx.priceKindId }, { priceKind: { isPromotion: true } }] })
158
+ }
159
+
127
160
  return { $and: clauses } as FilterQuery<CatalogProductPrice>
128
161
  }
129
162
 
@@ -148,9 +181,14 @@ function scorePrice(row: PriceRow): number {
148
181
  export function selectBestPrice(rows: PriceRow[], ctx: PricingContext): PriceRow | null {
149
182
  const candidates = rows.filter((row) => matchesContext(row, ctx))
150
183
  if (!candidates.length) return null
184
+ const customerIds = resolveContextCustomerIds(ctx)
185
+ const customerRank = (row: PriceRow): number => (row.customerId ? customerIds.indexOf(row.customerId) : -1)
151
186
  candidates.sort((a, b) => {
152
187
  const scoreDiff = scorePrice(b) - scorePrice(a)
153
188
  if (scoreDiff !== 0) return scoreDiff
189
+ const rankA = customerRank(a)
190
+ const rankB = customerRank(b)
191
+ if (rankA >= 0 && rankB >= 0 && rankA !== rankB) return rankA - rankB
154
192
  const startA = a.startsAt ? a.startsAt.getTime() : 0
155
193
  const startB = b.startsAt ? b.startsAt.getTime() : 0
156
194
  if (startA !== startB) return startB - startA