@open-mercato/core 0.9.1-develop.7473.1.de5b22888f → 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,703 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Plus, Trash2 } from "lucide-react";
5
+ import { Alert, AlertDescription, AlertTitle } from "@open-mercato/ui/primitives/alert";
6
+ import { Button } from "@open-mercato/ui/primitives/button";
7
+ import { IconButton } from "@open-mercato/ui/primitives/icon-button";
8
+ import { Input } from "@open-mercato/ui/primitives/input";
9
+ import { FormField } from "@open-mercato/ui/primitives/form-field";
10
+ import { SwitchField } from "@open-mercato/ui/primitives/switch-field";
11
+ import { TagInput } from "@open-mercato/ui/primitives/tag-input";
12
+ import {
13
+ Select,
14
+ SelectContent,
15
+ SelectItem,
16
+ SelectTrigger,
17
+ SelectValue
18
+ } from "@open-mercato/ui/primitives/select";
19
+ import { LoadingMessage, ErrorMessage } from "@open-mercato/ui/backend/detail";
20
+ import { flash } from "@open-mercato/ui/backend/FlashMessages";
21
+ import { useBackendChrome } from "@open-mercato/ui/backend/BackendChromeProvider";
22
+ import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
23
+ import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
24
+ import { hasFeature } from "@open-mercato/shared/security/features";
25
+ import { useOrganizationScopeDetail, useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
26
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
27
+ import { createLogger } from "@open-mercato/shared/lib/logger";
28
+ import { getTelemetryRuntime } from "@open-mercato/shared/lib/telemetry/runtime";
29
+ import { PriceChannelSelect, PricePriceKindSelect } from "./prices/PriceScopeSelectors.js";
30
+ const logger = createLogger("catalog").child({ component: "OmnibusSettings" });
31
+ const OMNIBUS_CONFIG_PATH = "/api/catalog/config/omnibus";
32
+ const MUTATION_CONTEXT_ID = "catalog-omnibus-settings";
33
+ const DEFAULT_LOOKBACK_DAYS = 30;
34
+ const MIN_LOOKBACK_DAYS = 1;
35
+ const MAX_LOOKBACK_DAYS = 365;
36
+ const COUNTRY_CODE_PATTERN = /^[A-Z]{2}$/;
37
+ class OmnibusSaveError extends Error {
38
+ constructor(status, body) {
39
+ super(`[internal] catalog omnibus config save failed with status ${status}`);
40
+ this.status = status;
41
+ this.body = body;
42
+ }
43
+ }
44
+ let rowSequence = 0;
45
+ function nextRowKey() {
46
+ rowSequence += 1;
47
+ return `omnibus-channel-${rowSequence}`;
48
+ }
49
+ function toFormState(config) {
50
+ const channels = Object.entries(config?.channels ?? {}).map(([channelId, channel]) => ({
51
+ key: nextRowKey(),
52
+ channelId,
53
+ presentedPriceKindId: channel.presentedPriceKindId ?? "",
54
+ countryCode: channel.countryCode ?? "",
55
+ lookbackDays: typeof channel.lookbackDays === "number" ? String(channel.lookbackDays) : "",
56
+ minimizationAxis: channel.minimizationAxis ?? "inherit"
57
+ }));
58
+ return {
59
+ enabled: config?.enabled === true,
60
+ lookbackDays: String(config?.lookbackDays ?? DEFAULT_LOOKBACK_DAYS),
61
+ enabledCountryCodes: Array.isArray(config?.enabledCountryCodes) ? [...config.enabledCountryCodes] : [],
62
+ noChannelMode: config?.noChannelMode ?? "best_effort",
63
+ minimizationAxis: config?.minimizationAxis ?? "gross",
64
+ defaultPresentedPriceKindId: config?.defaultPresentedPriceKindId ?? "",
65
+ channels
66
+ };
67
+ }
68
+ function parseLookbackDays(raw) {
69
+ const trimmed = raw.trim();
70
+ if (!/^\d+$/.test(trimmed)) return null;
71
+ const value = Number(trimmed);
72
+ if (!Number.isInteger(value) || value < MIN_LOOKBACK_DAYS || value > MAX_LOOKBACK_DAYS) return null;
73
+ return value;
74
+ }
75
+ function channelErrorKey(rowKey, field) {
76
+ return `channels.${rowKey}.${field}`;
77
+ }
78
+ function isRecord(value) {
79
+ return typeof value === "object" && value !== null && !Array.isArray(value);
80
+ }
81
+ function asStoredConfig(value) {
82
+ return isRecord(value) ? value : null;
83
+ }
84
+ function listStaleBackfillScopes(stored, form) {
85
+ const coverage = stored?.backfillCoverage ?? {};
86
+ const globalLookback = parseLookbackDays(form.lookbackDays);
87
+ if (globalLookback === null) return [];
88
+ const channelLookbacks = new Map(
89
+ form.channels.filter((row) => row.channelId).map((row) => [row.channelId, parseLookbackDays(row.lookbackDays) ?? globalLookback])
90
+ );
91
+ return Object.entries(coverage).filter(([scopeId, entry]) => {
92
+ const effective = scopeId ? channelLookbacks.get(scopeId) ?? globalLookback : globalLookback;
93
+ return entry.lookbackDays < effective;
94
+ }).map(([scopeId]) => scopeId).sort((left, right) => left < right ? -1 : left > right ? 1 : 0);
95
+ }
96
+ function OmnibusSettings() {
97
+ const t = useT();
98
+ const scopeVersion = useOrganizationScopeVersion();
99
+ const scopeTenantId = useOrganizationScopeDetail().tenantId;
100
+ const { payload: chromePayload, isReady: chromeReady } = useBackendChrome();
101
+ const grantedFeatures = chromePayload?.grantedFeatures;
102
+ const canManage = hasFeature(grantedFeatures, "catalog.settings.manage");
103
+ const canView = canManage || hasFeature(grantedFeatures, "catalog.settings.view");
104
+ const [stored, setStored] = React.useState(null);
105
+ const [form, setForm] = React.useState(() => toFormState(null));
106
+ const [loading, setLoading] = React.useState(true);
107
+ const [loadError, setLoadError] = React.useState(null);
108
+ const [saving, setSaving] = React.useState(false);
109
+ const [fieldErrors, setFieldErrors] = React.useState({});
110
+ const [formError, setFormError] = React.useState(null);
111
+ const [backfillChannels, setBackfillChannels] = React.useState(null);
112
+ const [backfillChannelNames, setBackfillChannelNames] = React.useState({});
113
+ const [reloadToken, setReloadToken] = React.useState(0);
114
+ const loadedSourceRef = React.useRef(null);
115
+ const { runMutation, retryLastMutation } = useGuardedMutation({
116
+ contextId: MUTATION_CONTEXT_ID,
117
+ blockedMessage: t("ui.forms.flash.saveBlocked", "Save blocked by validation")
118
+ });
119
+ const readOnly = !canManage || saving;
120
+ const errorMessages = React.useMemo(() => ({
121
+ omnibus_country_code_alpha2_required: t("catalog.omnibus.errors.countryCodeFormat", "Use a two-letter ISO country code."),
122
+ omnibus_country_code_eu_not_allowed: t("catalog.omnibus.errors.countryCodeEu", 'List individual member states instead of "EU".'),
123
+ omnibus_country_code_unknown: t("catalog.omnibus.errors.countryCodeUnknown", "Unknown country code."),
124
+ omnibus_presented_price_kind_required: t("catalog.omnibus.errors.presentedPriceKindRequired", "Select a default presented price kind, or configure a channel with its own price kind."),
125
+ omnibus_field_not_supported: t("catalog.omnibus.errors.fieldNotSupported", "This setting is not supported."),
126
+ omnibus_derogation_not_supported: t("catalog.omnibus.errors.fieldNotSupported", "This setting is not supported."),
127
+ omnibus_backfill_coverage_read_only: t("catalog.omnibus.errors.fieldNotSupported", "This setting is not supported.")
128
+ }), [t]);
129
+ const invalidValueMessage = t("catalog.omnibus.errors.invalidValue", "Invalid value.");
130
+ const lookbackRangeMessage = t("catalog.omnibus.errors.lookbackRange", "Enter a whole number of days between 1 and 365.");
131
+ const requiredMessage = t("catalog.omnibus.errors.required", "This field is required.");
132
+ const duplicateChannelMessage = t("catalog.omnibus.errors.duplicateChannel", "This channel is already configured.");
133
+ const saveErrorMessage = t("catalog.omnibus.errors.save", "Failed to save Omnibus settings.");
134
+ const staleBackfillScopes = React.useMemo(() => listStaleBackfillScopes(stored, form), [form, stored]);
135
+ const channelNameLookupKey = React.useMemo(
136
+ () => Array.from(new Set([...backfillChannels ?? [], ...staleBackfillScopes].filter((channelId) => channelId.length > 0))).sort((left, right) => left < right ? -1 : left > right ? 1 : 0).join(","),
137
+ [backfillChannels, staleBackfillScopes]
138
+ );
139
+ React.useEffect(() => {
140
+ const channelIds = channelNameLookupKey ? channelNameLookupKey.split(",") : [];
141
+ if (!channelIds.length) return;
142
+ let cancelled = false;
143
+ const query = new URLSearchParams({ ids: channelIds.join(","), pageSize: String(Math.min(channelIds.length, 100)) });
144
+ apiCall(`/api/sales/channels?${query.toString()}`).then((call) => {
145
+ if (cancelled || !call?.ok) return;
146
+ const items = Array.isArray(call.result?.items) ? call.result.items : [];
147
+ const names = {};
148
+ for (const item of items) {
149
+ if (typeof item.id === "string" && typeof item.name === "string" && item.name.length) names[item.id] = item.name;
150
+ }
151
+ setBackfillChannelNames((previous) => ({ ...previous, ...names }));
152
+ }).catch((err) => {
153
+ logger.warn("catalog.omnibus.settings.backfillChannelNames failed", { err });
154
+ getTelemetryRuntime()?.reportError(err, { module: "catalog", code: "catalog.omnibus_channel_names_load_failed" });
155
+ });
156
+ return () => {
157
+ cancelled = true;
158
+ };
159
+ }, [channelNameLookupKey]);
160
+ const loadErrorMessage = t("catalog.omnibus.errors.load", "Failed to load Omnibus settings.");
161
+ React.useEffect(() => {
162
+ if (!chromeReady || !canView) return;
163
+ let cancelled = false;
164
+ const previous = loadedSourceRef.current;
165
+ if (!previous) setLoading(true);
166
+ setLoadError(null);
167
+ apiCall(OMNIBUS_CONFIG_PATH).then((call) => {
168
+ if (cancelled) return;
169
+ if (!call.ok) {
170
+ loadedSourceRef.current = null;
171
+ setLoadError(loadErrorMessage);
172
+ return;
173
+ }
174
+ const config = asStoredConfig(call.result);
175
+ const configKey = JSON.stringify(config);
176
+ const keepsEdits = previous !== null && previous.configKey === configKey && (previous.tenantId === null || previous.tenantId === scopeTenantId);
177
+ loadedSourceRef.current = { tenantId: scopeTenantId, configKey };
178
+ setStored(config);
179
+ if (keepsEdits) return;
180
+ setForm(toFormState(config));
181
+ setFieldErrors({});
182
+ setFormError(null);
183
+ setBackfillChannels(null);
184
+ }).catch((err) => {
185
+ logger.error("catalog.omnibus.settings.load failed", { err });
186
+ getTelemetryRuntime()?.reportError(err, { module: "catalog", code: "catalog.omnibus_settings_load_failed" });
187
+ if (!cancelled) setLoadError(loadErrorMessage);
188
+ }).finally(() => {
189
+ if (!cancelled) setLoading(false);
190
+ });
191
+ return () => {
192
+ cancelled = true;
193
+ };
194
+ }, [canView, chromeReady, loadErrorMessage, reloadToken, scopeTenantId, scopeVersion]);
195
+ const translateServerError = React.useCallback(
196
+ (messages) => {
197
+ const first = Array.isArray(messages) ? messages.find((entry) => typeof entry === "string") : null;
198
+ if (typeof first !== "string") return invalidValueMessage;
199
+ return errorMessages[first] ?? invalidValueMessage;
200
+ },
201
+ [errorMessages, invalidValueMessage]
202
+ );
203
+ const mapServerFieldErrors = React.useCallback(
204
+ (raw) => {
205
+ const fields = {};
206
+ let unmatched = null;
207
+ for (const [path, messages] of Object.entries(raw)) {
208
+ const message = translateServerError(messages);
209
+ const segments = path.split(".");
210
+ const head = segments[0];
211
+ if (head === "channels" && segments.length >= 2) {
212
+ const row = form.channels.find((entry) => entry.channelId === segments[1]);
213
+ const field = segments[2] ?? "channelId";
214
+ if (row) {
215
+ fields[channelErrorKey(row.key, field)] = message;
216
+ continue;
217
+ }
218
+ } else if (head && head !== "_root" && head in form) {
219
+ fields[head] = fields[head] ?? message;
220
+ continue;
221
+ }
222
+ unmatched = unmatched ?? message;
223
+ }
224
+ return { fields, unmatched };
225
+ },
226
+ [form, translateServerError]
227
+ );
228
+ const buildPatch = React.useCallback(() => {
229
+ const errors = {};
230
+ const lookbackDays = parseLookbackDays(form.lookbackDays);
231
+ if (lookbackDays === null) errors.lookbackDays = lookbackRangeMessage;
232
+ const channels = {};
233
+ for (const row of form.channels) {
234
+ const channelId = row.channelId.trim();
235
+ if (!channelId) {
236
+ errors[channelErrorKey(row.key, "channelId")] = requiredMessage;
237
+ } else if (channels[channelId]) {
238
+ errors[channelErrorKey(row.key, "channelId")] = duplicateChannelMessage;
239
+ }
240
+ if (!row.presentedPriceKindId) errors[channelErrorKey(row.key, "presentedPriceKindId")] = requiredMessage;
241
+ const countryCode = row.countryCode.trim().toUpperCase();
242
+ if (countryCode && !COUNTRY_CODE_PATTERN.test(countryCode)) {
243
+ errors[channelErrorKey(row.key, "countryCode")] = errorMessages.omnibus_country_code_alpha2_required;
244
+ }
245
+ const channelLookback = row.lookbackDays.trim() ? parseLookbackDays(row.lookbackDays) : void 0;
246
+ if (channelLookback === null) errors[channelErrorKey(row.key, "lookbackDays")] = lookbackRangeMessage;
247
+ if (!channelId || channels[channelId]) continue;
248
+ channels[channelId] = {
249
+ presentedPriceKindId: row.presentedPriceKindId,
250
+ ...countryCode ? { countryCode } : {},
251
+ ...typeof channelLookback === "number" ? { lookbackDays: channelLookback } : {},
252
+ ...row.minimizationAxis !== "inherit" ? { minimizationAxis: row.minimizationAxis } : {}
253
+ };
254
+ }
255
+ if (Object.keys(errors).length > 0 || lookbackDays === null) return { patch: null, errors };
256
+ return {
257
+ patch: {
258
+ enabled: form.enabled,
259
+ lookbackDays,
260
+ enabledCountryCodes: form.enabledCountryCodes,
261
+ noChannelMode: form.noChannelMode,
262
+ minimizationAxis: form.minimizationAxis,
263
+ defaultPresentedPriceKindId: form.defaultPresentedPriceKindId || null,
264
+ channels
265
+ },
266
+ errors
267
+ };
268
+ }, [duplicateChannelMessage, errorMessages, form, lookbackRangeMessage, requiredMessage]);
269
+ const handleSubmit = React.useCallback(async () => {
270
+ if (!canManage || saving) return;
271
+ const { patch, errors } = buildPatch();
272
+ setFormError(null);
273
+ setBackfillChannels(null);
274
+ setFieldErrors(errors);
275
+ if (!patch) return;
276
+ setSaving(true);
277
+ try {
278
+ const saved = await runMutation({
279
+ operation: async () => {
280
+ const call = await apiCall(OMNIBUS_CONFIG_PATH, {
281
+ method: "PATCH",
282
+ headers: { "content-type": "application/json" },
283
+ body: JSON.stringify(patch)
284
+ });
285
+ if (!call.ok) {
286
+ throw new OmnibusSaveError(call.status, isRecord(call.result) ? call.result : null);
287
+ }
288
+ return asStoredConfig(call.result);
289
+ },
290
+ context: {
291
+ formId: MUTATION_CONTEXT_ID,
292
+ resourceKind: "catalog.settings",
293
+ resourceId: "omnibus",
294
+ retryLastMutation
295
+ },
296
+ mutationPayload: patch
297
+ });
298
+ loadedSourceRef.current = { tenantId: scopeTenantId, configKey: JSON.stringify(saved) };
299
+ setStored(saved);
300
+ setForm(toFormState(saved));
301
+ setFieldErrors({});
302
+ flash(t("catalog.omnibus.messages.saved", "Omnibus settings saved."), "success");
303
+ } catch (err) {
304
+ if (err instanceof OmnibusSaveError) {
305
+ const body = err.body;
306
+ if (err.status === 422 && body?.error === "backfill_required_before_enable") {
307
+ const channels = Array.isArray(body.channels) ? body.channels.filter((entry) => typeof entry === "string") : [];
308
+ setBackfillChannels(channels);
309
+ return;
310
+ }
311
+ const detailFieldErrors = body?.details?.fieldErrors;
312
+ const rawFieldErrors = isRecord(detailFieldErrors) ? detailFieldErrors : null;
313
+ if (err.status === 400 && rawFieldErrors) {
314
+ const mapped = mapServerFieldErrors(rawFieldErrors);
315
+ setFieldErrors(mapped.fields);
316
+ setFormError(mapped.unmatched ?? t("catalog.omnibus.errors.invalid", "Fix the highlighted fields and try again."));
317
+ return;
318
+ }
319
+ setFormError(saveErrorMessage);
320
+ return;
321
+ }
322
+ logger.error("catalog.omnibus.settings.save failed", { err });
323
+ getTelemetryRuntime()?.reportError(err, { module: "catalog", code: "catalog.omnibus_settings_save_failed" });
324
+ setFormError(err instanceof Error && !err.message.startsWith("[internal]") ? err.message : saveErrorMessage);
325
+ } finally {
326
+ setSaving(false);
327
+ }
328
+ }, [buildPatch, canManage, mapServerFieldErrors, retryLastMutation, runMutation, saveErrorMessage, saving, scopeTenantId, t]);
329
+ const handleCancel = React.useCallback(() => {
330
+ setForm(toFormState(stored));
331
+ setFieldErrors({});
332
+ setFormError(null);
333
+ setBackfillChannels(null);
334
+ }, [stored]);
335
+ const handleKeyDown = React.useCallback(
336
+ (event) => {
337
+ if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
338
+ event.preventDefault();
339
+ void handleSubmit();
340
+ return;
341
+ }
342
+ if (event.key === "Escape" && !event.defaultPrevented && canManage) {
343
+ event.preventDefault();
344
+ handleCancel();
345
+ }
346
+ },
347
+ [canManage, handleCancel, handleSubmit]
348
+ );
349
+ const updateForm = React.useCallback((patch) => {
350
+ setForm((prev) => ({ ...prev, ...patch }));
351
+ }, []);
352
+ const updateChannel = React.useCallback((rowKey, patch) => {
353
+ setForm((prev) => ({
354
+ ...prev,
355
+ channels: prev.channels.map((row) => row.key === rowKey ? { ...row, ...patch } : row)
356
+ }));
357
+ }, []);
358
+ const addChannel = React.useCallback(() => {
359
+ setForm((prev) => ({
360
+ ...prev,
361
+ channels: [
362
+ ...prev.channels,
363
+ { key: nextRowKey(), channelId: "", presentedPriceKindId: "", countryCode: "", lookbackDays: "", minimizationAxis: "inherit" }
364
+ ]
365
+ }));
366
+ }, []);
367
+ const removeChannel = React.useCallback((rowKey) => {
368
+ setForm((prev) => ({ ...prev, channels: prev.channels.filter((row) => row.key !== rowKey) }));
369
+ }, []);
370
+ const formatChannel = React.useCallback(
371
+ (channelId) => backfillChannelNames[channelId] ? `${backfillChannelNames[channelId]} (${channelId})` : channelId,
372
+ [backfillChannelNames]
373
+ );
374
+ const formatScope = React.useCallback(
375
+ (scopeId) => scopeId ? formatChannel(scopeId) : t("catalog.omnibus.settings.backfill.globalScope", "All channels (unscoped)"),
376
+ [formatChannel, t]
377
+ );
378
+ if (!chromeReady) {
379
+ return /* @__PURE__ */ jsx(LoadingMessage, { label: t("catalog.omnibus.settings.loading", "Loading Omnibus settings\u2026") });
380
+ }
381
+ if (!canView) return null;
382
+ const noChannelModeLabels = {
383
+ best_effort: t("catalog.omnibus.settings.noChannelMode.bestEffort", "Best effort (use global settings)"),
384
+ require_channel: t("catalog.omnibus.settings.noChannelMode.requireChannel", "Require a channel")
385
+ };
386
+ const axisLabels = {
387
+ gross: t("catalog.omnibus.settings.axis.gross", "Gross (B2C)"),
388
+ net: t("catalog.omnibus.settings.axis.net", "Net (B2B)")
389
+ };
390
+ return /* @__PURE__ */ jsxs("section", { className: "border bg-card text-card-foreground shadow-sm", "data-testid": "catalog-omnibus-settings", children: [
391
+ /* @__PURE__ */ jsxs("div", { className: "border-b px-6 py-4 space-y-1", children: [
392
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: t("catalog.omnibus.settings.title", "Omnibus price tracking") }),
393
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t(
394
+ "catalog.omnibus.settings.description",
395
+ "Show the lowest price from the lookback period next to announced price reductions (EU Directive 2019/2161)."
396
+ ) })
397
+ ] }),
398
+ /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: loading ? /* @__PURE__ */ jsx(LoadingMessage, { label: t("catalog.omnibus.settings.loading", "Loading Omnibus settings\u2026") }) : loadError ? /* @__PURE__ */ jsx(
399
+ ErrorMessage,
400
+ {
401
+ label: loadError,
402
+ action: /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setReloadToken((token) => token + 1), children: t("catalog.omnibus.settings.actions.retry", "Retry") })
403
+ }
404
+ ) : /* @__PURE__ */ jsxs(
405
+ "form",
406
+ {
407
+ className: "space-y-6",
408
+ noValidate: true,
409
+ onKeyDown: handleKeyDown,
410
+ onSubmit: (event) => {
411
+ event.preventDefault();
412
+ void handleSubmit();
413
+ },
414
+ children: [
415
+ !canManage ? /* @__PURE__ */ jsx(Alert, { status: "information", children: /* @__PURE__ */ jsx(AlertDescription, { children: t("catalog.omnibus.settings.readOnly", "You can view these settings but not change them.") }) }) : null,
416
+ backfillChannels ? /* @__PURE__ */ jsxs(Alert, { status: "error", "data-testid": "catalog-omnibus-backfill-required", children: [
417
+ /* @__PURE__ */ jsx(AlertTitle, { children: t("catalog.omnibus.settings.backfill.requiredTitle", "Backfill required before enabling") }),
418
+ /* @__PURE__ */ jsxs(AlertDescription, { children: [
419
+ /* @__PURE__ */ jsx("p", { children: t(
420
+ "catalog.omnibus.settings.backfill.requiredDescription",
421
+ 'Price history must be backfilled for every in-scope EU channel before Omnibus can be enabled. Run "mercato catalog omnibus:backfill --tenant <tenantId>" (add "--channel-id <channelId>" per channel), then save again.'
422
+ ) }),
423
+ backfillChannels.length > 0 ? /* @__PURE__ */ jsx("p", { className: "mt-1", children: t("catalog.omnibus.settings.backfill.channels", "Channels without backfill: {{channels}}", {
424
+ channels: backfillChannels.map(formatChannel).join(", ")
425
+ }) }) : null
426
+ ] })
427
+ ] }) : null,
428
+ staleBackfillScopes.length > 0 ? /* @__PURE__ */ jsxs(Alert, { status: "warning", "data-testid": "catalog-omnibus-backfill-stale", children: [
429
+ /* @__PURE__ */ jsx(AlertTitle, { children: t("catalog.omnibus.settings.backfill.staleTitle", "Lookback increased since the last backfill") }),
430
+ /* @__PURE__ */ jsx(AlertDescription, { children: t(
431
+ "catalog.omnibus.settings.backfill.staleDescription",
432
+ "Re-run the backfill so the longer window has baseline history: {{scopes}}",
433
+ { scopes: staleBackfillScopes.map(formatScope).join(", ") }
434
+ ) })
435
+ ] }) : null,
436
+ formError ? /* @__PURE__ */ jsx(ErrorMessage, { label: formError }) : null,
437
+ /* @__PURE__ */ jsx(
438
+ SwitchField,
439
+ {
440
+ label: t("catalog.omnibus.settings.enabled", "Enable Omnibus reference prices"),
441
+ description: t(
442
+ "catalog.omnibus.settings.enabledDescription",
443
+ "When enabled, products in EU channels expose the lowest price from the lookback window."
444
+ ),
445
+ checked: form.enabled,
446
+ disabled: readOnly,
447
+ onCheckedChange: (next) => updateForm({ enabled: next })
448
+ }
449
+ ),
450
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
451
+ /* @__PURE__ */ jsx(
452
+ FormField,
453
+ {
454
+ label: t("catalog.omnibus.settings.lookbackDays", "Lookback window (days)"),
455
+ description: t("catalog.omnibus.settings.lookbackDaysDescription", "Between 1 and 365 days. The directive requires at least 30."),
456
+ error: fieldErrors.lookbackDays,
457
+ required: true,
458
+ disabled: readOnly,
459
+ children: /* @__PURE__ */ jsx(
460
+ Input,
461
+ {
462
+ type: "number",
463
+ inputMode: "numeric",
464
+ min: MIN_LOOKBACK_DAYS,
465
+ max: MAX_LOOKBACK_DAYS,
466
+ value: form.lookbackDays,
467
+ onChange: (event) => updateForm({ lookbackDays: event.target.value }),
468
+ "data-testid": "catalog-omnibus-lookback"
469
+ }
470
+ )
471
+ }
472
+ ),
473
+ /* @__PURE__ */ jsx(
474
+ FormField,
475
+ {
476
+ label: t("catalog.omnibus.settings.enabledCountryCodes", "EU member states"),
477
+ description: t(
478
+ "catalog.omnibus.settings.enabledCountryCodesDescription",
479
+ "Two-letter ISO codes of the member states where Omnibus applies. Leave empty to disable it for every channel."
480
+ ),
481
+ error: fieldErrors.enabledCountryCodes,
482
+ disabled: readOnly,
483
+ children: /* @__PURE__ */ jsx(
484
+ TagInput,
485
+ {
486
+ value: form.enabledCountryCodes,
487
+ onChange: (next) => updateForm({ enabledCountryCodes: Array.from(new Set(next.map((code) => code.trim().toUpperCase()))) }),
488
+ validate: (tag) => {
489
+ const code = tag.trim().toUpperCase();
490
+ if (code === "EU") return errorMessages.omnibus_country_code_eu_not_allowed;
491
+ return COUNTRY_CODE_PATTERN.test(code) || errorMessages.omnibus_country_code_alpha2_required;
492
+ },
493
+ placeholder: t("catalog.omnibus.settings.enabledCountryCodesPlaceholder", "e.g. PL, DE"),
494
+ "aria-label": t("catalog.omnibus.settings.enabledCountryCodes", "EU member states"),
495
+ removeTagLabel: (tag) => t("catalog.omnibus.settings.removeCountry", "Remove {{code}}", { code: tag }),
496
+ disabled: readOnly
497
+ }
498
+ )
499
+ }
500
+ ),
501
+ /* @__PURE__ */ jsx(
502
+ FormField,
503
+ {
504
+ label: t("catalog.omnibus.settings.noChannelModeLabel", "Requests without a channel"),
505
+ error: fieldErrors.noChannelMode,
506
+ disabled: readOnly,
507
+ children: /* @__PURE__ */ jsxs(
508
+ Select,
509
+ {
510
+ value: form.noChannelMode,
511
+ onValueChange: (next) => updateForm({ noChannelMode: next }),
512
+ disabled: readOnly,
513
+ children: [
514
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { children: noChannelModeLabels[form.noChannelMode] }) }),
515
+ /* @__PURE__ */ jsx(SelectContent, { children: Object.keys(noChannelModeLabels).map((mode) => /* @__PURE__ */ jsx(SelectItem, { value: mode, children: noChannelModeLabels[mode] }, mode)) })
516
+ ]
517
+ }
518
+ )
519
+ }
520
+ ),
521
+ /* @__PURE__ */ jsx(
522
+ FormField,
523
+ {
524
+ label: t("catalog.omnibus.settings.minimizationAxis", "Compare prices by"),
525
+ error: fieldErrors.minimizationAxis,
526
+ disabled: readOnly,
527
+ children: /* @__PURE__ */ jsxs(
528
+ Select,
529
+ {
530
+ value: form.minimizationAxis,
531
+ onValueChange: (next) => updateForm({ minimizationAxis: next }),
532
+ disabled: readOnly,
533
+ children: [
534
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { children: axisLabels[form.minimizationAxis] }) }),
535
+ /* @__PURE__ */ jsx(SelectContent, { children: Object.keys(axisLabels).map((axis) => /* @__PURE__ */ jsx(SelectItem, { value: axis, children: axisLabels[axis] }, axis)) })
536
+ ]
537
+ }
538
+ )
539
+ }
540
+ ),
541
+ /* @__PURE__ */ jsx(
542
+ FormField,
543
+ {
544
+ label: t("catalog.omnibus.settings.defaultPresentedPriceKind", "Default presented price kind"),
545
+ description: t(
546
+ "catalog.omnibus.settings.defaultPresentedPriceKindDescription",
547
+ "The price kind shown to shoppers, used when a channel has no override. Required when Omnibus is enabled without channel overrides."
548
+ ),
549
+ error: fieldErrors.defaultPresentedPriceKindId,
550
+ disabled: readOnly,
551
+ className: "md:col-span-2",
552
+ children: /* @__PURE__ */ jsx(
553
+ PricePriceKindSelect,
554
+ {
555
+ value: form.defaultPresentedPriceKindId,
556
+ onChange: (next) => updateForm({ defaultPresentedPriceKindId: next }),
557
+ disabled: readOnly,
558
+ clearable: true
559
+ }
560
+ )
561
+ }
562
+ )
563
+ ] }),
564
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
565
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
566
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
567
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold", children: t("catalog.omnibus.settings.channels.title", "Channel overrides") }),
568
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t(
569
+ "catalog.omnibus.settings.channels.description",
570
+ "Map sales channels to a member state and override the presented price kind, lookback or comparison axis per channel."
571
+ ) })
572
+ ] }),
573
+ canManage ? /* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: addChannel, disabled: saving, children: [
574
+ /* @__PURE__ */ jsx(Plus, { className: "size-4", "aria-hidden": true }),
575
+ t("catalog.omnibus.settings.channels.add", "Add channel")
576
+ ] }) : null
577
+ ] }),
578
+ form.channels.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("catalog.omnibus.settings.channels.empty", "No channel overrides. Global settings apply to every channel.") }) : form.channels.map((row) => {
579
+ const rowError = (field) => fieldErrors[channelErrorKey(row.key, field)];
580
+ return /* @__PURE__ */ jsx("div", { className: "space-y-3 rounded-md border p-4", "data-testid": "catalog-omnibus-channel-row", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
581
+ /* @__PURE__ */ jsxs("div", { className: "grid flex-1 gap-4 md:grid-cols-2", children: [
582
+ /* @__PURE__ */ jsx(
583
+ FormField,
584
+ {
585
+ label: t("catalog.omnibus.settings.channels.channel", "Channel"),
586
+ error: rowError("channelId"),
587
+ disabled: readOnly,
588
+ children: /* @__PURE__ */ jsx(
589
+ PriceChannelSelect,
590
+ {
591
+ value: row.channelId,
592
+ onChange: (next) => updateChannel(row.key, { channelId: next }),
593
+ disabled: readOnly
594
+ }
595
+ )
596
+ }
597
+ ),
598
+ /* @__PURE__ */ jsx(
599
+ FormField,
600
+ {
601
+ label: t("catalog.omnibus.settings.channels.presentedPriceKind", "Presented price kind"),
602
+ error: rowError("presentedPriceKindId"),
603
+ disabled: readOnly,
604
+ children: /* @__PURE__ */ jsx(
605
+ PricePriceKindSelect,
606
+ {
607
+ value: row.presentedPriceKindId,
608
+ onChange: (next) => updateChannel(row.key, { presentedPriceKindId: next }),
609
+ disabled: readOnly
610
+ }
611
+ )
612
+ }
613
+ ),
614
+ /* @__PURE__ */ jsx(
615
+ FormField,
616
+ {
617
+ label: t("catalog.omnibus.settings.channels.countryCode", "Member state"),
618
+ description: t("catalog.omnibus.settings.channels.countryCodeDescription", "Leave empty for non-EU channels."),
619
+ error: rowError("countryCode"),
620
+ disabled: readOnly,
621
+ children: /* @__PURE__ */ jsx(
622
+ Input,
623
+ {
624
+ value: row.countryCode,
625
+ maxLength: 2,
626
+ onChange: (event) => updateChannel(row.key, { countryCode: event.target.value.toUpperCase() }),
627
+ placeholder: t("catalog.omnibus.settings.channels.countryCodePlaceholder", "e.g. PL")
628
+ }
629
+ )
630
+ }
631
+ ),
632
+ /* @__PURE__ */ jsx(
633
+ FormField,
634
+ {
635
+ label: t("catalog.omnibus.settings.channels.lookbackDays", "Lookback override (days)"),
636
+ description: t("catalog.omnibus.settings.channels.lookbackDaysDescription", "Leave empty to use the global window."),
637
+ error: rowError("lookbackDays"),
638
+ disabled: readOnly,
639
+ children: /* @__PURE__ */ jsx(
640
+ Input,
641
+ {
642
+ type: "number",
643
+ inputMode: "numeric",
644
+ min: MIN_LOOKBACK_DAYS,
645
+ max: MAX_LOOKBACK_DAYS,
646
+ value: row.lookbackDays,
647
+ onChange: (event) => updateChannel(row.key, { lookbackDays: event.target.value })
648
+ }
649
+ )
650
+ }
651
+ ),
652
+ /* @__PURE__ */ jsx(
653
+ FormField,
654
+ {
655
+ label: t("catalog.omnibus.settings.channels.minimizationAxis", "Compare prices by"),
656
+ error: rowError("minimizationAxis"),
657
+ disabled: readOnly,
658
+ children: /* @__PURE__ */ jsxs(
659
+ Select,
660
+ {
661
+ value: row.minimizationAxis,
662
+ onValueChange: (next) => updateChannel(row.key, { minimizationAxis: next }),
663
+ disabled: readOnly,
664
+ children: [
665
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { children: row.minimizationAxis === "inherit" ? t("catalog.omnibus.settings.channels.axisInherit", "Use global setting") : axisLabels[row.minimizationAxis] }) }),
666
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
667
+ /* @__PURE__ */ jsx(SelectItem, { value: "inherit", children: t("catalog.omnibus.settings.channels.axisInherit", "Use global setting") }),
668
+ Object.keys(axisLabels).map((axis) => /* @__PURE__ */ jsx(SelectItem, { value: axis, children: axisLabels[axis] }, axis))
669
+ ] })
670
+ ]
671
+ }
672
+ )
673
+ }
674
+ )
675
+ ] }),
676
+ canManage ? /* @__PURE__ */ jsx(
677
+ IconButton,
678
+ {
679
+ type: "button",
680
+ variant: "ghost",
681
+ size: "sm",
682
+ "aria-label": t("catalog.omnibus.settings.channels.remove", "Remove channel override"),
683
+ onClick: () => removeChannel(row.key),
684
+ disabled: saving,
685
+ children: /* @__PURE__ */ jsx(Trash2, { className: "size-4", "aria-hidden": true })
686
+ }
687
+ ) : null
688
+ ] }) }, row.key);
689
+ })
690
+ ] }),
691
+ canManage ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2", children: [
692
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: handleCancel, disabled: saving, children: t("catalog.omnibus.settings.actions.cancel", "Cancel") }),
693
+ /* @__PURE__ */ jsx(Button, { type: "submit", disabled: saving, "data-testid": "catalog-omnibus-save", children: saving ? t("catalog.omnibus.settings.actions.saving", "Saving\u2026") : t("catalog.omnibus.settings.actions.save", "Save") })
694
+ ] }) : null
695
+ ]
696
+ }
697
+ ) })
698
+ ] });
699
+ }
700
+ export {
701
+ OmnibusSettings
702
+ };
703
+ //# sourceMappingURL=OmnibusSettings.js.map