@endora-commerce/mod-catalog 0.100.0

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 (443) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +63 -0
  3. package/dist/admin/components/PackagingUnitsEditor.d.ts +12 -0
  4. package/dist/admin/components/PackagingUnitsEditor.d.ts.map +1 -0
  5. package/dist/admin/components/PackagingUnitsEditor.js +99 -0
  6. package/dist/admin/components/PackagingUnitsEditor.js.map +1 -0
  7. package/dist/admin/components/ProductAttributesTab.d.ts +13 -0
  8. package/dist/admin/components/ProductAttributesTab.d.ts.map +1 -0
  9. package/dist/admin/components/ProductAttributesTab.js +140 -0
  10. package/dist/admin/components/ProductAttributesTab.js.map +1 -0
  11. package/dist/admin/components/ProductInventoryTab.d.ts +14 -0
  12. package/dist/admin/components/ProductInventoryTab.d.ts.map +1 -0
  13. package/dist/admin/components/ProductInventoryTab.js +284 -0
  14. package/dist/admin/components/ProductInventoryTab.js.map +1 -0
  15. package/dist/admin/components/ProductScopeEditor.d.ts +94 -0
  16. package/dist/admin/components/ProductScopeEditor.d.ts.map +1 -0
  17. package/dist/admin/components/ProductScopeEditor.js +395 -0
  18. package/dist/admin/components/ProductScopeEditor.js.map +1 -0
  19. package/dist/admin/components/ProductsBulkEditDialog.d.ts +11 -0
  20. package/dist/admin/components/ProductsBulkEditDialog.d.ts.map +1 -0
  21. package/dist/admin/components/ProductsBulkEditDialog.js +304 -0
  22. package/dist/admin/components/ProductsBulkEditDialog.js.map +1 -0
  23. package/dist/admin/index.d.ts +45 -0
  24. package/dist/admin/index.d.ts.map +1 -0
  25. package/dist/admin/index.js +184 -0
  26. package/dist/admin/index.js.map +1 -0
  27. package/dist/admin/lib/resolve-product-selection.d.ts +21 -0
  28. package/dist/admin/lib/resolve-product-selection.d.ts.map +1 -0
  29. package/dist/admin/lib/resolve-product-selection.js +25 -0
  30. package/dist/admin/lib/resolve-product-selection.js.map +1 -0
  31. package/dist/admin/pages/AttachmentTypesPage.d.ts +18 -0
  32. package/dist/admin/pages/AttachmentTypesPage.d.ts.map +1 -0
  33. package/dist/admin/pages/AttachmentTypesPage.js +92 -0
  34. package/dist/admin/pages/AttachmentTypesPage.js.map +1 -0
  35. package/dist/admin/pages/AttributeSetsPage.d.ts +21 -0
  36. package/dist/admin/pages/AttributeSetsPage.d.ts.map +1 -0
  37. package/dist/admin/pages/AttributeSetsPage.js +158 -0
  38. package/dist/admin/pages/AttributeSetsPage.js.map +1 -0
  39. package/dist/admin/pages/AttributesManager.d.ts +9 -0
  40. package/dist/admin/pages/AttributesManager.d.ts.map +1 -0
  41. package/dist/admin/pages/AttributesManager.js +305 -0
  42. package/dist/admin/pages/AttributesManager.js.map +1 -0
  43. package/dist/admin/pages/BulkOperationDetailPage.d.ts +9 -0
  44. package/dist/admin/pages/BulkOperationDetailPage.d.ts.map +1 -0
  45. package/dist/admin/pages/BulkOperationDetailPage.js +187 -0
  46. package/dist/admin/pages/BulkOperationDetailPage.js.map +1 -0
  47. package/dist/admin/pages/BulkOperationsPage.d.ts +9 -0
  48. package/dist/admin/pages/BulkOperationsPage.d.ts.map +1 -0
  49. package/dist/admin/pages/BulkOperationsPage.js +98 -0
  50. package/dist/admin/pages/BulkOperationsPage.js.map +1 -0
  51. package/dist/admin/pages/CategoriesTree.d.ts +9 -0
  52. package/dist/admin/pages/CategoriesTree.d.ts.map +1 -0
  53. package/dist/admin/pages/CategoriesTree.js +176 -0
  54. package/dist/admin/pages/CategoriesTree.js.map +1 -0
  55. package/dist/admin/pages/ProductEditor.d.ts +13 -0
  56. package/dist/admin/pages/ProductEditor.d.ts.map +1 -0
  57. package/dist/admin/pages/ProductEditor.js +1050 -0
  58. package/dist/admin/pages/ProductEditor.js.map +1 -0
  59. package/dist/admin/pages/ProductsList.d.ts +9 -0
  60. package/dist/admin/pages/ProductsList.d.ts.map +1 -0
  61. package/dist/admin/pages/ProductsList.js +399 -0
  62. package/dist/admin/pages/ProductsList.js.map +1 -0
  63. package/dist/backend/commands/attribute-commands.d.ts +111 -0
  64. package/dist/backend/commands/attribute-commands.d.ts.map +1 -0
  65. package/dist/backend/commands/attribute-commands.js +482 -0
  66. package/dist/backend/commands/attribute-commands.js.map +1 -0
  67. package/dist/backend/demo/reset.d.ts +23 -0
  68. package/dist/backend/demo/reset.d.ts.map +1 -0
  69. package/dist/backend/demo/reset.js +41 -0
  70. package/dist/backend/demo/reset.js.map +1 -0
  71. package/dist/backend/demo/rows.d.ts +103 -0
  72. package/dist/backend/demo/rows.d.ts.map +1 -0
  73. package/dist/backend/demo/rows.js +162 -0
  74. package/dist/backend/demo/rows.js.map +1 -0
  75. package/dist/backend/demo/seed.d.ts +35 -0
  76. package/dist/backend/demo/seed.d.ts.map +1 -0
  77. package/dist/backend/demo/seed.js +177 -0
  78. package/dist/backend/demo/seed.js.map +1 -0
  79. package/dist/backend/entities/attachment-type.entity.d.ts +16 -0
  80. package/dist/backend/entities/attachment-type.entity.d.ts.map +1 -0
  81. package/dist/backend/entities/attachment-type.entity.js +57 -0
  82. package/dist/backend/entities/attachment-type.entity.js.map +1 -0
  83. package/dist/backend/entities/attribute-set-attribute.entity.d.ts +26 -0
  84. package/dist/backend/entities/attribute-set-attribute.entity.d.ts.map +1 -0
  85. package/dist/backend/entities/attribute-set-attribute.entity.js +55 -0
  86. package/dist/backend/entities/attribute-set-attribute.entity.js.map +1 -0
  87. package/dist/backend/entities/attribute-set.entity.d.ts +22 -0
  88. package/dist/backend/entities/attribute-set.entity.d.ts.map +1 -0
  89. package/dist/backend/entities/attribute-set.entity.js +67 -0
  90. package/dist/backend/entities/attribute-set.entity.js.map +1 -0
  91. package/dist/backend/entities/bulk-operation.entity.d.ts +78 -0
  92. package/dist/backend/entities/bulk-operation.entity.d.ts.map +1 -0
  93. package/dist/backend/entities/bulk-operation.entity.js +138 -0
  94. package/dist/backend/entities/bulk-operation.entity.js.map +1 -0
  95. package/dist/backend/entities/bundle-slot-option.entity.d.ts +23 -0
  96. package/dist/backend/entities/bundle-slot-option.entity.d.ts.map +1 -0
  97. package/dist/backend/entities/bundle-slot-option.entity.js +68 -0
  98. package/dist/backend/entities/bundle-slot-option.entity.js.map +1 -0
  99. package/dist/backend/entities/bundle-slot.entity.d.ts +25 -0
  100. package/dist/backend/entities/bundle-slot.entity.d.ts.map +1 -0
  101. package/dist/backend/entities/bundle-slot.entity.js +74 -0
  102. package/dist/backend/entities/bundle-slot.entity.js.map +1 -0
  103. package/dist/backend/entities/category.entity.d.ts +26 -0
  104. package/dist/backend/entities/category.entity.d.ts.map +1 -0
  105. package/dist/backend/entities/category.entity.js +119 -0
  106. package/dist/backend/entities/category.entity.js.map +1 -0
  107. package/dist/backend/entities/gallery-item-label.entity.d.ts +22 -0
  108. package/dist/backend/entities/gallery-item-label.entity.d.ts.map +1 -0
  109. package/dist/backend/entities/gallery-item-label.entity.js +50 -0
  110. package/dist/backend/entities/gallery-item-label.entity.js.map +1 -0
  111. package/dist/backend/entities/gallery-item.entity.d.ts +17 -0
  112. package/dist/backend/entities/gallery-item.entity.d.ts.map +1 -0
  113. package/dist/backend/entities/gallery-item.entity.js +58 -0
  114. package/dist/backend/entities/gallery-item.entity.js.map +1 -0
  115. package/dist/backend/entities/grouped-item.entity.d.ts +23 -0
  116. package/dist/backend/entities/grouped-item.entity.d.ts.map +1 -0
  117. package/dist/backend/entities/grouped-item.entity.js +68 -0
  118. package/dist/backend/entities/grouped-item.entity.js.map +1 -0
  119. package/dist/backend/entities/product-attachment.entity.d.ts +23 -0
  120. package/dist/backend/entities/product-attachment.entity.d.ts.map +1 -0
  121. package/dist/backend/entities/product-attachment.entity.js +77 -0
  122. package/dist/backend/entities/product-attachment.entity.js.map +1 -0
  123. package/dist/backend/entities/product-attribute.entity.d.ts +72 -0
  124. package/dist/backend/entities/product-attribute.entity.d.ts.map +1 -0
  125. package/dist/backend/entities/product-attribute.entity.js +161 -0
  126. package/dist/backend/entities/product-attribute.entity.js.map +1 -0
  127. package/dist/backend/entities/product-editor-preference.entity.d.ts +28 -0
  128. package/dist/backend/entities/product-editor-preference.entity.d.ts.map +1 -0
  129. package/dist/backend/entities/product-editor-preference.entity.js +63 -0
  130. package/dist/backend/entities/product-editor-preference.entity.js.map +1 -0
  131. package/dist/backend/entities/product-link.entity.d.ts +25 -0
  132. package/dist/backend/entities/product-link.entity.d.ts.map +1 -0
  133. package/dist/backend/entities/product-link.entity.js +70 -0
  134. package/dist/backend/entities/product-link.entity.js.map +1 -0
  135. package/dist/backend/entities/product-packaging-unit.entity.d.ts +26 -0
  136. package/dist/backend/entities/product-packaging-unit.entity.d.ts.map +1 -0
  137. package/dist/backend/entities/product-packaging-unit.entity.js +76 -0
  138. package/dist/backend/entities/product-packaging-unit.entity.js.map +1 -0
  139. package/dist/backend/entities/product-value-override.entity.d.ts +43 -0
  140. package/dist/backend/entities/product-value-override.entity.d.ts.map +1 -0
  141. package/dist/backend/entities/product-value-override.entity.js +90 -0
  142. package/dist/backend/entities/product-value-override.entity.js.map +1 -0
  143. package/dist/backend/entities/product-variant.entity.d.ts +18 -0
  144. package/dist/backend/entities/product-variant.entity.d.ts.map +1 -0
  145. package/dist/backend/entities/product-variant.entity.js +68 -0
  146. package/dist/backend/entities/product-variant.entity.js.map +1 -0
  147. package/dist/backend/entities/product.entity.d.ts +108 -0
  148. package/dist/backend/entities/product.entity.d.ts.map +1 -0
  149. package/dist/backend/entities/product.entity.js +230 -0
  150. package/dist/backend/entities/product.entity.js.map +1 -0
  151. package/dist/backend/index.d.ts +262 -0
  152. package/dist/backend/index.d.ts.map +1 -0
  153. package/dist/backend/index.js +642 -0
  154. package/dist/backend/index.js.map +1 -0
  155. package/dist/backend/plugin.d.ts +216 -0
  156. package/dist/backend/plugin.d.ts.map +1 -0
  157. package/dist/backend/plugin.js +223 -0
  158. package/dist/backend/plugin.js.map +1 -0
  159. package/dist/backend/prompt-tools.d.ts +47 -0
  160. package/dist/backend/prompt-tools.d.ts.map +1 -0
  161. package/dist/backend/prompt-tools.js +284 -0
  162. package/dist/backend/prompt-tools.js.map +1 -0
  163. package/dist/backend/routes.admin.d.ts +105 -0
  164. package/dist/backend/routes.admin.d.ts.map +1 -0
  165. package/dist/backend/routes.admin.js +1162 -0
  166. package/dist/backend/routes.admin.js.map +1 -0
  167. package/dist/backend/routes.api-key.d.ts +33 -0
  168. package/dist/backend/routes.api-key.d.ts.map +1 -0
  169. package/dist/backend/routes.api-key.js +43 -0
  170. package/dist/backend/routes.api-key.js.map +1 -0
  171. package/dist/backend/routes.external.d.ts +32 -0
  172. package/dist/backend/routes.external.d.ts.map +1 -0
  173. package/dist/backend/routes.external.js +115 -0
  174. package/dist/backend/routes.external.js.map +1 -0
  175. package/dist/backend/routes.public.d.ts +46 -0
  176. package/dist/backend/routes.public.d.ts.map +1 -0
  177. package/dist/backend/routes.public.js +318 -0
  178. package/dist/backend/routes.public.js.map +1 -0
  179. package/dist/backend/services/asset-references.d.ts +4 -0
  180. package/dist/backend/services/asset-references.d.ts.map +1 -0
  181. package/dist/backend/services/asset-references.js +104 -0
  182. package/dist/backend/services/asset-references.js.map +1 -0
  183. package/dist/backend/services/attachment.service.d.ts +45 -0
  184. package/dist/backend/services/attachment.service.d.ts.map +1 -0
  185. package/dist/backend/services/attachment.service.js +268 -0
  186. package/dist/backend/services/attachment.service.js.map +1 -0
  187. package/dist/backend/services/attribute-option-validator.d.ts +47 -0
  188. package/dist/backend/services/attribute-option-validator.d.ts.map +1 -0
  189. package/dist/backend/services/attribute-option-validator.js +69 -0
  190. package/dist/backend/services/attribute-option-validator.js.map +1 -0
  191. package/dist/backend/services/attribute-set-validations.d.ts +65 -0
  192. package/dist/backend/services/attribute-set-validations.d.ts.map +1 -0
  193. package/dist/backend/services/attribute-set-validations.js +89 -0
  194. package/dist/backend/services/attribute-set-validations.js.map +1 -0
  195. package/dist/backend/services/attribute-set.service.d.ts +50 -0
  196. package/dist/backend/services/attribute-set.service.d.ts.map +1 -0
  197. package/dist/backend/services/attribute-set.service.js +401 -0
  198. package/dist/backend/services/attribute-set.service.js.map +1 -0
  199. package/dist/backend/services/attribute-type-mapping.d.ts +66 -0
  200. package/dist/backend/services/attribute-type-mapping.d.ts.map +1 -0
  201. package/dist/backend/services/attribute-type-mapping.js +121 -0
  202. package/dist/backend/services/attribute-type-mapping.js.map +1 -0
  203. package/dist/backend/services/attribute-value-key.service.d.ts +48 -0
  204. package/dist/backend/services/attribute-value-key.service.d.ts.map +1 -0
  205. package/dist/backend/services/attribute-value-key.service.js +118 -0
  206. package/dist/backend/services/attribute-value-key.service.js.map +1 -0
  207. package/dist/backend/services/audit-references.d.ts +13 -0
  208. package/dist/backend/services/audit-references.d.ts.map +1 -0
  209. package/dist/backend/services/audit-references.js +51 -0
  210. package/dist/backend/services/audit-references.js.map +1 -0
  211. package/dist/backend/services/bulk-operation-queue.d.ts +26 -0
  212. package/dist/backend/services/bulk-operation-queue.d.ts.map +1 -0
  213. package/dist/backend/services/bulk-operation-queue.js +34 -0
  214. package/dist/backend/services/bulk-operation-queue.js.map +1 -0
  215. package/dist/backend/services/bulk-operation.service.d.ts +195 -0
  216. package/dist/backend/services/bulk-operation.service.d.ts.map +1 -0
  217. package/dist/backend/services/bulk-operation.service.js +510 -0
  218. package/dist/backend/services/bulk-operation.service.js.map +1 -0
  219. package/dist/backend/services/bundle.service.d.ts +87 -0
  220. package/dist/backend/services/bundle.service.d.ts.map +1 -0
  221. package/dist/backend/services/bundle.service.js +286 -0
  222. package/dist/backend/services/bundle.service.js.map +1 -0
  223. package/dist/backend/services/catalog-admin.service.d.ts +398 -0
  224. package/dist/backend/services/catalog-admin.service.d.ts.map +1 -0
  225. package/dist/backend/services/catalog-admin.service.js +1516 -0
  226. package/dist/backend/services/catalog-admin.service.js.map +1 -0
  227. package/dist/backend/services/catalog-attribute-read.service.d.ts +78 -0
  228. package/dist/backend/services/catalog-attribute-read.service.d.ts.map +1 -0
  229. package/dist/backend/services/catalog-attribute-read.service.js +216 -0
  230. package/dist/backend/services/catalog-attribute-read.service.js.map +1 -0
  231. package/dist/backend/services/catalog-bulk-import.service.d.ts +30 -0
  232. package/dist/backend/services/catalog-bulk-import.service.d.ts.map +1 -0
  233. package/dist/backend/services/catalog-bulk-import.service.js +136 -0
  234. package/dist/backend/services/catalog-bulk-import.service.js.map +1 -0
  235. package/dist/backend/services/catalog-bulk-update.service.d.ts +91 -0
  236. package/dist/backend/services/catalog-bulk-update.service.d.ts.map +1 -0
  237. package/dist/backend/services/catalog-bulk-update.service.js +330 -0
  238. package/dist/backend/services/catalog-bulk-update.service.js.map +1 -0
  239. package/dist/backend/services/catalog-category-read.service.d.ts +66 -0
  240. package/dist/backend/services/catalog-category-read.service.d.ts.map +1 -0
  241. package/dist/backend/services/catalog-category-read.service.js +248 -0
  242. package/dist/backend/services/catalog-category-read.service.js.map +1 -0
  243. package/dist/backend/services/catalog-org-price-decorator.d.ts +90 -0
  244. package/dist/backend/services/catalog-org-price-decorator.d.ts.map +1 -0
  245. package/dist/backend/services/catalog-org-price-decorator.js +184 -0
  246. package/dist/backend/services/catalog-org-price-decorator.js.map +1 -0
  247. package/dist/backend/services/catalog-product-filter.service.d.ts +82 -0
  248. package/dist/backend/services/catalog-product-filter.service.d.ts.map +1 -0
  249. package/dist/backend/services/catalog-product-filter.service.js +275 -0
  250. package/dist/backend/services/catalog-product-filter.service.js.map +1 -0
  251. package/dist/backend/services/catalog-product-read.service.d.ts +46 -0
  252. package/dist/backend/services/catalog-product-read.service.d.ts.map +1 -0
  253. package/dist/backend/services/catalog-product-read.service.js +197 -0
  254. package/dist/backend/services/catalog-product-read.service.js.map +1 -0
  255. package/dist/backend/services/catalog-query.service.d.ts +444 -0
  256. package/dist/backend/services/catalog-query.service.d.ts.map +1 -0
  257. package/dist/backend/services/catalog-query.service.js +1633 -0
  258. package/dist/backend/services/catalog-query.service.js.map +1 -0
  259. package/dist/backend/services/catalog-quick-search.service.d.ts +78 -0
  260. package/dist/backend/services/catalog-quick-search.service.d.ts.map +1 -0
  261. package/dist/backend/services/catalog-quick-search.service.js +159 -0
  262. package/dist/backend/services/catalog-quick-search.service.js.map +1 -0
  263. package/dist/backend/services/catalog-write-ports.d.ts +25 -0
  264. package/dist/backend/services/catalog-write-ports.d.ts.map +1 -0
  265. package/dist/backend/services/catalog-write-ports.js +63 -0
  266. package/dist/backend/services/catalog-write-ports.js.map +1 -0
  267. package/dist/backend/services/category-admin.service.d.ts +102 -0
  268. package/dist/backend/services/category-admin.service.d.ts.map +1 -0
  269. package/dist/backend/services/category-admin.service.js +271 -0
  270. package/dist/backend/services/category-admin.service.js.map +1 -0
  271. package/dist/backend/services/gallery.service.d.ts +85 -0
  272. package/dist/backend/services/gallery.service.d.ts.map +1 -0
  273. package/dist/backend/services/gallery.service.js +326 -0
  274. package/dist/backend/services/gallery.service.js.map +1 -0
  275. package/dist/backend/services/grouped.service.d.ts +39 -0
  276. package/dist/backend/services/grouped.service.d.ts.map +1 -0
  277. package/dist/backend/services/grouped.service.js +136 -0
  278. package/dist/backend/services/grouped.service.js.map +1 -0
  279. package/dist/backend/services/label-resolver.d.ts +16 -0
  280. package/dist/backend/services/label-resolver.d.ts.map +1 -0
  281. package/dist/backend/services/label-resolver.js +43 -0
  282. package/dist/backend/services/label-resolver.js.map +1 -0
  283. package/dist/backend/services/packaging-unit.service.d.ts +28 -0
  284. package/dist/backend/services/packaging-unit.service.d.ts.map +1 -0
  285. package/dist/backend/services/packaging-unit.service.js +197 -0
  286. package/dist/backend/services/packaging-unit.service.js.map +1 -0
  287. package/dist/backend/services/primary-asset-url.d.ts +4 -0
  288. package/dist/backend/services/primary-asset-url.d.ts.map +1 -0
  289. package/dist/backend/services/primary-asset-url.js +55 -0
  290. package/dist/backend/services/primary-asset-url.js.map +1 -0
  291. package/dist/backend/services/product-editor-preferences.service.d.ts +20 -0
  292. package/dist/backend/services/product-editor-preferences.service.d.ts.map +1 -0
  293. package/dist/backend/services/product-editor-preferences.service.js +44 -0
  294. package/dist/backend/services/product-editor-preferences.service.js.map +1 -0
  295. package/dist/backend/services/product-link.service.d.ts +169 -0
  296. package/dist/backend/services/product-link.service.d.ts.map +1 -0
  297. package/dist/backend/services/product-link.service.js +297 -0
  298. package/dist/backend/services/product-link.service.js.map +1 -0
  299. package/dist/backend/services/product-overrides.service.d.ts +77 -0
  300. package/dist/backend/services/product-overrides.service.d.ts.map +1 -0
  301. package/dist/backend/services/product-overrides.service.js +204 -0
  302. package/dist/backend/services/product-overrides.service.js.map +1 -0
  303. package/dist/backend/services/product-scope-context.service.d.ts +36 -0
  304. package/dist/backend/services/product-scope-context.service.d.ts.map +1 -0
  305. package/dist/backend/services/product-scope-context.service.js +106 -0
  306. package/dist/backend/services/product-scope-context.service.js.map +1 -0
  307. package/dist/backend/services/product-type-validations.d.ts +42 -0
  308. package/dist/backend/services/product-type-validations.d.ts.map +1 -0
  309. package/dist/backend/services/product-type-validations.js +55 -0
  310. package/dist/backend/services/product-type-validations.js.map +1 -0
  311. package/dist/backend/services/product-value-resolver.service.d.ts +59 -0
  312. package/dist/backend/services/product-value-resolver.service.d.ts.map +1 -0
  313. package/dist/backend/services/product-value-resolver.service.js +111 -0
  314. package/dist/backend/services/product-value-resolver.service.js.map +1 -0
  315. package/dist/backend/services/system-attribute-scopes.d.ts +18 -0
  316. package/dist/backend/services/system-attribute-scopes.d.ts.map +1 -0
  317. package/dist/backend/services/system-attribute-scopes.js +18 -0
  318. package/dist/backend/services/system-attribute-scopes.js.map +1 -0
  319. package/dist/backend/services/viewer-organization.d.ts +25 -0
  320. package/dist/backend/services/viewer-organization.d.ts.map +1 -0
  321. package/dist/backend/services/viewer-organization.js +31 -0
  322. package/dist/backend/services/viewer-organization.js.map +1 -0
  323. package/dist/manifest.d.ts +204 -0
  324. package/dist/manifest.d.ts.map +1 -0
  325. package/dist/manifest.js +686 -0
  326. package/dist/manifest.js.map +1 -0
  327. package/dist/migrations/20260429T064146_catalog_attribute_sets_init.d.ts +33 -0
  328. package/dist/migrations/20260429T064146_catalog_attribute_sets_init.d.ts.map +1 -0
  329. package/dist/migrations/20260429T064146_catalog_attribute_sets_init.js +118 -0
  330. package/dist/migrations/20260429T064146_catalog_attribute_sets_init.js.map +1 -0
  331. package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.d.ts +24 -0
  332. package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.d.ts.map +1 -0
  333. package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.js +31 -0
  334. package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.js.map +1 -0
  335. package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.d.ts +32 -0
  336. package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.d.ts.map +1 -0
  337. package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.js +58 -0
  338. package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.js.map +1 -0
  339. package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.d.ts +22 -0
  340. package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.d.ts.map +1 -0
  341. package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.js +66 -0
  342. package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.js.map +1 -0
  343. package/dist/migrations/20260429T112543_catalog_product_attachments.d.ts +18 -0
  344. package/dist/migrations/20260429T112543_catalog_product_attachments.d.ts.map +1 -0
  345. package/dist/migrations/20260429T112543_catalog_product_attachments.js +73 -0
  346. package/dist/migrations/20260429T112543_catalog_product_attachments.js.map +1 -0
  347. package/dist/migrations/20260429T123726_catalog_product_links.d.ts +21 -0
  348. package/dist/migrations/20260429T123726_catalog_product_links.d.ts.map +1 -0
  349. package/dist/migrations/20260429T123726_catalog_product_links.js +48 -0
  350. package/dist/migrations/20260429T123726_catalog_product_links.js.map +1 -0
  351. package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.d.ts +23 -0
  352. package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.d.ts.map +1 -0
  353. package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.js +94 -0
  354. package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.js.map +1 -0
  355. package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.d.ts +24 -0
  356. package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.d.ts.map +1 -0
  357. package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.js +31 -0
  358. package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.js.map +1 -0
  359. package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.d.ts +31 -0
  360. package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.d.ts.map +1 -0
  361. package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.js +133 -0
  362. package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.js.map +1 -0
  363. package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.d.ts +16 -0
  364. package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.d.ts.map +1 -0
  365. package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.js +23 -0
  366. package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.js.map +1 -0
  367. package/dist/migrations/20260526T124736_catalog_product_status_inactive.d.ts +10 -0
  368. package/dist/migrations/20260526T124736_catalog_product_status_inactive.d.ts.map +1 -0
  369. package/dist/migrations/20260526T124736_catalog_product_status_inactive.js +22 -0
  370. package/dist/migrations/20260526T124736_catalog_product_status_inactive.js.map +1 -0
  371. package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.d.ts +38 -0
  372. package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.d.ts.map +1 -0
  373. package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.js +98 -0
  374. package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.js.map +1 -0
  375. package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.d.ts +13 -0
  376. package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.d.ts.map +1 -0
  377. package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.js +17 -0
  378. package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.js.map +1 -0
  379. package/dist/migrations/20260611T140407_catalog_bulk_operations.d.ts +16 -0
  380. package/dist/migrations/20260611T140407_catalog_bulk_operations.d.ts.map +1 -0
  381. package/dist/migrations/20260611T140407_catalog_bulk_operations.js +42 -0
  382. package/dist/migrations/20260611T140407_catalog_bulk_operations.js.map +1 -0
  383. package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.d.ts +14 -0
  384. package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.d.ts.map +1 -0
  385. package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.js +18 -0
  386. package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.js.map +1 -0
  387. package/dist/migrations/20260611T140412_catalog_product_packaging_units.d.ts +11 -0
  388. package/dist/migrations/20260611T140412_catalog_product_packaging_units.d.ts.map +1 -0
  389. package/dist/migrations/20260611T140412_catalog_product_packaging_units.js +29 -0
  390. package/dist/migrations/20260611T140412_catalog_product_packaging_units.js.map +1 -0
  391. package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.d.ts +23 -0
  392. package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.d.ts.map +1 -0
  393. package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.js +35 -0
  394. package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.js.map +1 -0
  395. package/dist/migrations/20260718T200343_catalog_category_custom_field_values.d.ts +12 -0
  396. package/dist/migrations/20260718T200343_catalog_category_custom_field_values.d.ts.map +1 -0
  397. package/dist/migrations/20260718T200343_catalog_category_custom_field_values.js +16 -0
  398. package/dist/migrations/20260718T200343_catalog_category_custom_field_values.js.map +1 -0
  399. package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.d.ts +32 -0
  400. package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.d.ts.map +1 -0
  401. package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.js +286 -0
  402. package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.js.map +1 -0
  403. package/dist/migrations/20260804T152604_catalog_widen_product_sku.d.ts +36 -0
  404. package/dist/migrations/20260804T152604_catalog_widen_product_sku.d.ts.map +1 -0
  405. package/dist/migrations/20260804T152604_catalog_widen_product_sku.js +63 -0
  406. package/dist/migrations/20260804T152604_catalog_widen_product_sku.js.map +1 -0
  407. package/dist/migrations/20260804T160244_catalog_category_activation.d.ts +18 -0
  408. package/dist/migrations/20260804T160244_catalog_category_activation.d.ts.map +1 -0
  409. package/dist/migrations/20260804T160244_catalog_category_activation.js +22 -0
  410. package/dist/migrations/20260804T160244_catalog_category_activation.js.map +1 -0
  411. package/dist/migrations/20260912T094557_catalog_sales_channel_products.d.ts +27 -0
  412. package/dist/migrations/20260912T094557_catalog_sales_channel_products.d.ts.map +1 -0
  413. package/dist/migrations/20260912T094557_catalog_sales_channel_products.js +44 -0
  414. package/dist/migrations/20260912T094557_catalog_sales_channel_products.js.map +1 -0
  415. package/dist/migrations/20260912T094623_catalog_sales_channel_categories.d.ts +27 -0
  416. package/dist/migrations/20260912T094623_catalog_sales_channel_categories.d.ts.map +1 -0
  417. package/dist/migrations/20260912T094623_catalog_sales_channel_categories.js +44 -0
  418. package/dist/migrations/20260912T094623_catalog_sales_channel_categories.js.map +1 -0
  419. package/dist/migrations/20260925T125527_catalog_inventory_columns.d.ts +36 -0
  420. package/dist/migrations/20260925T125527_catalog_inventory_columns.d.ts.map +1 -0
  421. package/dist/migrations/20260925T125527_catalog_inventory_columns.js +87 -0
  422. package/dist/migrations/20260925T125527_catalog_inventory_columns.js.map +1 -0
  423. package/dist/migrations/index.d.ts +55 -0
  424. package/dist/migrations/index.d.ts.map +1 -0
  425. package/dist/migrations/index.js +80 -0
  426. package/dist/migrations/index.js.map +1 -0
  427. package/dist/ports/index.d.ts +96 -0
  428. package/dist/ports/index.d.ts.map +1 -0
  429. package/dist/ports/index.js +2 -0
  430. package/dist/ports/index.js.map +1 -0
  431. package/docs/catalog/attachments.md +69 -0
  432. package/docs/catalog/attribute-sets.md +63 -0
  433. package/docs/catalog/attributes.md +244 -0
  434. package/docs/catalog/composite-products.md +115 -0
  435. package/docs/catalog/gallery-and-labels.md +73 -0
  436. package/docs/catalog/packaging-units.md +67 -0
  437. package/docs/catalog/per-channel-per-language-overrides.md +234 -0
  438. package/docs/catalog/product-links.md +79 -0
  439. package/docs/catalog.md +207 -0
  440. package/i18n/en.json +649 -0
  441. package/i18n/pl.json +649 -0
  442. package/package.json +109 -0
  443. package/tailwind.css +14 -0
@@ -0,0 +1,297 @@
1
+ import { ERROR_CODES, listingPriceMoney, } from '@endora-commerce/contracts';
2
+ import { HttpError } from '@endora-commerce/platform/http';
3
+ import { Product } from '../entities/product.entity.js';
4
+ import { ProductLink } from '../entities/product-link.entity.js';
5
+ import { resolvePrimaryAssetUrls } from './primary-asset-url.js';
6
+ import { viewerOrganizationFor } from './viewer-organization.js';
7
+ function pickLang(blob, preferred) {
8
+ if (preferred && blob[preferred])
9
+ return blob[preferred];
10
+ const fallback = blob['en-US'] ?? blob['en'] ?? Object.values(blob)[0] ?? '';
11
+ return fallback;
12
+ }
13
+ export class ProductLinkService {
14
+ emFactory;
15
+ commandBus;
16
+ listingPrices;
17
+ assets;
18
+ channelMembership;
19
+ organizationDetails;
20
+ constructor(emFactory,
21
+ /** Feature 054 — audits product-link writes co-transactionally when provided. */
22
+ commandBus,
23
+ /**
24
+ * Issue #132 — the pricing engine, through the `pricingService` port. A
25
+ * related-product tile is a listing: it prices through the same chain as the
26
+ * catalogue grid, not off the catalogue's legacy default-price attribute.
27
+ */
28
+ listingPrices,
29
+ /**
30
+ * Feature 075 — `assets_library`'s read port. The two `join assets` clauses
31
+ * this service used to write are gone; the tile's image is resolved by the
32
+ * shared `resolvePrimaryAssetUrls` helper, which asks the owner for the
33
+ * asset row and keeps the bridge query on this module's own tables.
34
+ */
35
+ assets,
36
+ /**
37
+ * Issue #185 — the kernel's channel-membership accessor. The storefront
38
+ * link read below asked `sales_channel_products` in raw SQL, which crosses
39
+ * the boundary while naming no import specifier and is the read
40
+ * Constitution XII reserves to this service.
41
+ *
42
+ * Optional only in the signature, like the two above; a link read that
43
+ * reaches it unwired fails loudly rather than quietly answering the
44
+ * cross-channel set.
45
+ */
46
+ channelMembership,
47
+ /**
48
+ * `organizations`' read model — the customer group a group-targeted price
49
+ * list is selected by, which lives on the organisation row. Optional only
50
+ * in the signature, and never reached by an anonymous strip.
51
+ */
52
+ organizationDetails) {
53
+ this.emFactory = emFactory;
54
+ this.commandBus = commandBus;
55
+ this.listingPrices = listingPrices;
56
+ this.assets = assets;
57
+ this.channelMembership = channelMembership;
58
+ this.organizationDetails = organizationDetails;
59
+ }
60
+ #requireOrganizationDetails() {
61
+ if (!this.organizationDetails) {
62
+ throw new Error('ProductLinkService: the organization read port is not wired — a signed-in buyer cannot be priced.');
63
+ }
64
+ return this.organizationDetails;
65
+ }
66
+ #requireChannelMembership() {
67
+ if (!this.channelMembership) {
68
+ throw new Error('ProductLinkService: the channel-membership port is not wired — link tiles cannot be ' +
69
+ 'scoped to a channel without leaking the cross-channel set.');
70
+ }
71
+ return this.channelMembership;
72
+ }
73
+ #requireAssets() {
74
+ if (!this.assets) {
75
+ throw new Error('ProductLinkService: the asset read port is not wired — link tiles cannot show an image.');
76
+ }
77
+ return this.assets;
78
+ }
79
+ #requireListingPrices() {
80
+ if (!this.listingPrices) {
81
+ throw new Error('ProductLinkService: the pricing port is not wired — link tiles cannot be priced.');
82
+ }
83
+ return this.listingPrices;
84
+ }
85
+ /** Feature 054 — run a product-link write through the Command Bus. */
86
+ async #audited(action, objectId, write) {
87
+ if (this.commandBus) {
88
+ return this.commandBus.run({ action, objectType: 'product_link', objectId, run: ({ em }) => write(em) });
89
+ }
90
+ const em = this.emFactory();
91
+ const w = await write(em);
92
+ await em.flush();
93
+ return w.result;
94
+ }
95
+ async listForAdmin(sourceProductId, kind) {
96
+ const em = this.emFactory();
97
+ const where = { sourceProductId };
98
+ if (kind)
99
+ where['kind'] = kind;
100
+ const rows = await em.find(ProductLink, where, {
101
+ orderBy: { position: 'asc', id: 'asc' },
102
+ });
103
+ return rows.map((r) => ({
104
+ id: r.id,
105
+ sourceProductId: r.sourceProductId,
106
+ targetProductId: r.targetProductId,
107
+ kind: r.kind,
108
+ position: r.position,
109
+ }));
110
+ }
111
+ async bulkCreate(sourceProductId, inputs) {
112
+ const em = this.emFactory();
113
+ // 1) Source must exist and not be archived/deleted (404 PRODUCT_NOT_FOUND).
114
+ const source = await em.findOne(Product, { id: sourceProductId });
115
+ if (!source || source.deletedAt) {
116
+ throw new HttpError(404, ERROR_CODES.PRODUCT_NOT_FOUND, `Product "${sourceProductId}" not found.`);
117
+ }
118
+ // 2) Self-link rejected at API layer (400). The DB CHECK is the
119
+ // belt-and-braces backstop, but we want the typed error code first.
120
+ for (const input of inputs) {
121
+ if (input.targetProductId === sourceProductId) {
122
+ throw new HttpError(400, ERROR_CODES.SELF_LINK_NOT_ALLOWED, 'A product cannot link to itself.');
123
+ }
124
+ }
125
+ // 3) Targets must all exist (404 TARGET_PRODUCT_NOT_FOUND); single
126
+ // findIn keeps it to one query.
127
+ const targetIds = [...new Set(inputs.map((i) => i.targetProductId))];
128
+ const targets = await em.find(Product, { id: { $in: targetIds } });
129
+ const foundIds = new Set(targets.filter((t) => !t.deletedAt).map((t) => t.id));
130
+ for (const id of targetIds) {
131
+ if (!foundIds.has(id)) {
132
+ throw new HttpError(404, ERROR_CODES.TARGET_PRODUCT_NOT_FOUND, `Target product "${id}" not found.`);
133
+ }
134
+ }
135
+ // 4) Duplicate (source, target, kind) rejected up-front (409). The
136
+ // DB UNIQUE is the backstop; this lets us return the typed code
137
+ // without parsing PG error strings.
138
+ const existing = await em.find(ProductLink, {
139
+ sourceProductId,
140
+ targetProductId: { $in: targetIds },
141
+ });
142
+ const existingKey = new Set(existing.map((e) => `${e.targetProductId}|${e.kind}`));
143
+ for (const input of inputs) {
144
+ if (existingKey.has(`${input.targetProductId}|${input.kind}`)) {
145
+ throw new HttpError(409, ERROR_CODES.LINK_ALREADY_EXISTS, `Link source=${sourceProductId} target=${input.targetProductId} kind=${input.kind} already exists.`);
146
+ }
147
+ }
148
+ // 5) Default position: append to the end of the (source, kind) list.
149
+ const nextPositionByKind = new Map();
150
+ const tally = await em.find(ProductLink, { sourceProductId });
151
+ for (const row of tally) {
152
+ const cur = nextPositionByKind.get(row.kind) ?? -1;
153
+ if (row.position > cur)
154
+ nextPositionByKind.set(row.kind, row.position);
155
+ }
156
+ const created = await this.#audited('product_link.bulk_create', sourceProductId, async (cem) => {
157
+ const rows = [];
158
+ for (const input of inputs) {
159
+ const explicit = input.position;
160
+ const next = (nextPositionByKind.get(input.kind) ?? -1) + 1;
161
+ const position = explicit !== undefined ? explicit : next;
162
+ nextPositionByKind.set(input.kind, position);
163
+ rows.push(cem.create(ProductLink, {
164
+ sourceProductId,
165
+ targetProductId: input.targetProductId,
166
+ kind: input.kind,
167
+ position,
168
+ }));
169
+ }
170
+ await cem.flush();
171
+ return { result: rows, before: null, after: { sourceProductId, count: rows.length } };
172
+ });
173
+ return created.map((r) => ({
174
+ id: r.id,
175
+ sourceProductId: r.sourceProductId,
176
+ targetProductId: r.targetProductId,
177
+ kind: r.kind,
178
+ position: r.position,
179
+ }));
180
+ }
181
+ async removeLink(sourceProductId, linkId) {
182
+ await this.#audited('product_link.delete', linkId, async (em) => {
183
+ const link = await em.findOne(ProductLink, { id: linkId, sourceProductId });
184
+ if (!link) {
185
+ throw new HttpError(404, ERROR_CODES.PRODUCT_LINK_NOT_FOUND, `Link "${linkId}" not found on source ${sourceProductId}.`);
186
+ }
187
+ const before = { sourceProductId, targetProductId: link.targetProductId, kind: link.kind };
188
+ em.remove(link);
189
+ return { result: undefined, before, after: null };
190
+ });
191
+ }
192
+ /**
193
+ * Storefront read — drops links whose target product is not active or
194
+ * not visible in the requested sales channel; localizes name to the
195
+ * caller's preferred language.
196
+ */
197
+ async listForStorefront(sourceProductId, ctx, kind) {
198
+ const em = this.emFactory();
199
+ const where = { sourceProductId };
200
+ if (kind)
201
+ where['kind'] = kind;
202
+ const rows = await em.find(ProductLink, where, {
203
+ orderBy: { position: 'asc', id: 'asc' },
204
+ });
205
+ if (rows.length === 0)
206
+ return [];
207
+ const targetIds = rows.map((r) => r.targetProductId);
208
+ const targets = await em.find(Product, {
209
+ id: { $in: targetIds },
210
+ status: 'active',
211
+ });
212
+ const byId = new Map(targets.map((p) => [p.id, p]));
213
+ // Feature 053 (FR-006 / Principle XII) — sales-channel visibility. The
214
+ // channel is resolved once upstream (`getResolvedChannel()`) and handed in;
215
+ // the membership filter is ALWAYS applied, failing closed to an empty
216
+ // visible set rather than leaking the full cross-channel target set.
217
+ // Through the kernel's accessor since issue #185: this was a `select
218
+ // product_id from sales_channel_products` written here, which is the one
219
+ // read Principle XII names the membership service for.
220
+ const channel = ctx.resolvedChannel;
221
+ const visibleIds = targets.length > 0
222
+ ? new Set(await this.#requireChannelMembership().filterEntityIdsInChannel(channel.id, 'product', targets.map((t) => t.id)))
223
+ : // No targets → nothing is visible (fail closed).
224
+ new Set();
225
+ // Primary asset urls: the gallery thumb chain, with the legacy
226
+ // `product_assets` fallback. Shared with `CatalogQueryService` so the chain
227
+ // and the `assets_library` port call have one home.
228
+ const assetUrlByProductId = await resolvePrimaryAssetUrls(em, this.#requireAssets(), targetIds);
229
+ // Sales-channel public flag controls price visibility (R-18), read off the
230
+ // resolved channel handed in by the route. A channel that withholds prices
231
+ // is not asked for them (issue #132).
232
+ const visibleTargets = rows
233
+ .filter((link) => visibleIds.has(link.targetProductId))
234
+ .map((link) => byId.get(link.targetProductId))
235
+ .filter((target) => target !== undefined);
236
+ const viewerOrganization = ctx.audience.organizationId === null
237
+ ? null
238
+ : await viewerOrganizationFor(this.#requireOrganizationDetails(), ctx.audience);
239
+ const resolvedPrices = ctx.resolvedChannel.isPublic && visibleTargets.length > 0
240
+ ? await this.#requireListingPrices().resolveListingPrices({
241
+ products: visibleTargets,
242
+ context: {
243
+ salesChannel: {
244
+ id: ctx.resolvedChannel.id,
245
+ defaultCurrency: ctx.resolvedChannel.defaultCurrency,
246
+ },
247
+ organization: viewerOrganization,
248
+ },
249
+ })
250
+ : new Map();
251
+ const out = [];
252
+ for (const link of rows) {
253
+ if (!visibleIds.has(link.targetProductId))
254
+ continue;
255
+ const target = byId.get(link.targetProductId);
256
+ if (!target)
257
+ continue;
258
+ const name = pickLang(target.name, ctx.preferredLanguage);
259
+ const resolved = resolvedPrices.get(target.id);
260
+ const price = resolved === undefined ? null : listingPriceMoney(resolved);
261
+ out.push({
262
+ id: link.id,
263
+ kind: link.kind,
264
+ position: link.position,
265
+ product: {
266
+ id: target.id,
267
+ sku: target.sku,
268
+ slug: target.slug,
269
+ name,
270
+ primaryAssetUrl: assetUrlByProductId.get(target.id) ?? null,
271
+ price,
272
+ },
273
+ });
274
+ }
275
+ return out;
276
+ }
277
+ async reorderForKind(sourceProductId, kind, linkIds) {
278
+ await this.#audited('product_link.reorder', sourceProductId, async (em) => {
279
+ // Fetch all links of this (source, kind) so we can validate the input
280
+ // covers exactly that set.
281
+ const rows = await em.find(ProductLink, { sourceProductId, kind });
282
+ const byId = new Map(rows.map((r) => [r.id, r]));
283
+ for (const id of linkIds) {
284
+ if (!byId.has(id)) {
285
+ throw new HttpError(400, ERROR_CODES.VALIDATION_FAILED, `Link "${id}" is not part of (${sourceProductId}, ${kind}).`);
286
+ }
287
+ }
288
+ // Apply 0..N positions in array order.
289
+ for (let i = 0; i < linkIds.length; i++) {
290
+ const link = byId.get(linkIds[i]);
291
+ link.position = i;
292
+ }
293
+ return { result: undefined, before: null, after: { sourceProductId, kind, count: linkIds.length } };
294
+ });
295
+ }
296
+ }
297
+ //# sourceMappingURL=product-link.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-link.service.js","sourceRoot":"","sources":["../../../src/backend/services/product-link.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import type { EntityManager } from '@mikro-orm/postgresql';
2
+ import type { CommandBus } from '@endora-commerce/platform/commands';
3
+ import type { SalesChannelMembershipPort } from '@endora-commerce/platform/kernel';
4
+ import { ProductValueOverride } from '../entities/product-value-override.entity.js';
5
+ import type { CatalogAttributeReadService } from './catalog-attribute-read.service.js';
6
+ /**
7
+ * Feature 022 — channel-aware value-override CRUD.
8
+ *
9
+ * The bulk upsert+delete handler is the only mutator; it runs all
10
+ * operations in one MikroORM transaction so a single 422 rolls back
11
+ * every requested change (FR-030 atomicity).
12
+ *
13
+ * Validation rules (data-model.md §3.3 + §4):
14
+ * - `attribute_unknown` — key is neither a system attr nor a
15
+ * product_attributes.key row.
16
+ * - `attribute_not_channel_scoped` — caller wrote to a (channel, ...)
17
+ * slot for an attr that has
18
+ * channelScoped=false.
19
+ * - `attribute_missing_language` — caller wrote (channel, null) for
20
+ * an attr that has languageScoped=
21
+ * true (must address a specific
22
+ * language slot).
23
+ * - `channel_not_assigned_to_product` — channel is not in the
24
+ * product's membership set.
25
+ * - `language_not_in_channel` — language is not in the channel's
26
+ * SalesChannel.languages array.
27
+ * - `value_invalid` — value shape does not satisfy the
28
+ * attribute's valueType.
29
+ */
30
+ export type OverrideUpsertInput = {
31
+ attributeKey: string;
32
+ channelId: string;
33
+ languageCode: string | null;
34
+ value: {
35
+ v: unknown;
36
+ };
37
+ };
38
+ export type OverrideDeleteInput = {
39
+ attributeKey: string;
40
+ channelId: string;
41
+ languageCode: string | null;
42
+ };
43
+ export type ApplyOverridesInput = {
44
+ upserts: readonly OverrideUpsertInput[];
45
+ deletes: readonly OverrideDeleteInput[];
46
+ };
47
+ export type ApplyOverridesResult = {
48
+ productId: string;
49
+ applied: {
50
+ upserted: number;
51
+ deleted: number;
52
+ };
53
+ overrides: ProductValueOverride[];
54
+ };
55
+ export declare class ProductOverridesService {
56
+ #private;
57
+ private readonly emFactory;
58
+ private readonly salesChannelMembership;
59
+ /** Feature 054 — audits the override apply co-transactionally when provided. */
60
+ private readonly commandBus?;
61
+ /** Feature 061 — composed attribute read model (scope + value-type lookups). */
62
+ private readonly attributeRead?;
63
+ constructor(emFactory: () => EntityManager, salesChannelMembership: SalesChannelMembershipPort,
64
+ /** Feature 054 — audits the override apply co-transactionally when provided. */
65
+ commandBus?: CommandBus | undefined,
66
+ /** Feature 061 — composed attribute read model (scope + value-type lookups). */
67
+ attributeRead?: CatalogAttributeReadService | undefined);
68
+ listForProduct(productId: string): Promise<ProductValueOverride[]>;
69
+ /**
70
+ * Validate + apply a bulk write. All operations run in one
71
+ * transaction. The first validation failure aborts everything; the
72
+ * thrown HttpError carries the offending input's index in `issues`
73
+ * so callers can highlight the bad row.
74
+ */
75
+ applyBulk(productId: string, input: ApplyOverridesInput): Promise<ApplyOverridesResult>;
76
+ }
77
+ //# sourceMappingURL=product-overrides.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-overrides.service.d.ts","sourceRoot":"","sources":["../../../src/backend/services/product-overrides.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAGnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AAEpF,OAAO,KAAK,EACV,2BAA2B,EAE5B,MAAM,qCAAqC,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE;QAAE,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACxC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,SAAS,EAAE,oBAAoB,EAAE,CAAC;CACnC,CAAC;AAEF,qBAAa,uBAAuB;;IAEhC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,gFAAgF;IAChF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAC5B,gFAAgF;IAChF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;gBALd,SAAS,EAAE,MAAM,aAAa,EAC9B,sBAAsB,EAAE,0BAA0B;IACnE,gFAAgF;IAC/D,UAAU,CAAC,EAAE,UAAU,YAAA;IACxC,gFAAgF;IAC/D,aAAa,CAAC,EAAE,2BAA2B,YAAA;IAiCxD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAKxE;;;;;OAKG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CA+J9F"}
@@ -0,0 +1,204 @@
1
+ import { ERROR_CODES } from '@endora-commerce/contracts';
2
+ import { HttpError } from '@endora-commerce/platform/http';
3
+ import { SalesChannel } from '@endora-commerce/platform/kernel';
4
+ import { Product } from '../entities/product.entity.js';
5
+ import { ProductValueOverride } from '../entities/product-value-override.entity.js';
6
+ import { getAttributeScope, isSystemAttributeKey } from './system-attribute-scopes.js';
7
+ export class ProductOverridesService {
8
+ emFactory;
9
+ salesChannelMembership;
10
+ commandBus;
11
+ attributeRead;
12
+ constructor(emFactory, salesChannelMembership,
13
+ /** Feature 054 — audits the override apply co-transactionally when provided. */
14
+ commandBus,
15
+ /** Feature 061 — composed attribute read model (scope + value-type lookups). */
16
+ attributeRead) {
17
+ this.emFactory = emFactory;
18
+ this.salesChannelMembership = salesChannelMembership;
19
+ this.commandBus = commandBus;
20
+ this.attributeRead = attributeRead;
21
+ }
22
+ #requireAttributeRead() {
23
+ if (!this.attributeRead) {
24
+ throw new Error('ProductOverridesService: CatalogAttributeReadService is not wired — attribute reads are unavailable.');
25
+ }
26
+ return this.attributeRead;
27
+ }
28
+ /**
29
+ * Feature 054 — run the override mutations through the Command Bus (its
30
+ * transaction replaces the local `em.transactional`, and the audit is
31
+ * co-transactional). Bus-less path keeps the local transaction.
32
+ */
33
+ async #audited(action, objectId, write) {
34
+ if (this.commandBus) {
35
+ return this.commandBus.run({ action, objectType: 'product', objectId, run: ({ em }) => write(em) });
36
+ }
37
+ const em = this.emFactory();
38
+ return em.transactional(async (tem) => (await write(tem)).result);
39
+ }
40
+ async listForProduct(productId) {
41
+ const em = this.emFactory();
42
+ return em.find(ProductValueOverride, { productId });
43
+ }
44
+ /**
45
+ * Validate + apply a bulk write. All operations run in one
46
+ * transaction. The first validation failure aborts everything; the
47
+ * thrown HttpError carries the offending input's index in `issues`
48
+ * so callers can highlight the bad row.
49
+ */
50
+ async applyBulk(productId, input) {
51
+ const em = this.emFactory();
52
+ const product = await em.findOne(Product, { id: productId });
53
+ if (!product) {
54
+ throw new HttpError(404, ERROR_CODES.PRODUCT_NOT_FOUND, 'Product not found.');
55
+ }
56
+ // Collect referenced channels + attribute rows in one fetch each.
57
+ const channelIds = Array.from(new Set([
58
+ ...input.upserts.map((u) => u.channelId),
59
+ ...input.deletes.map((d) => d.channelId),
60
+ ]));
61
+ const channels = channelIds.length === 0
62
+ ? []
63
+ : await em.find(SalesChannel, { id: { $in: channelIds } });
64
+ const channelById = new Map(channels.map((c) => [c.id, c]));
65
+ const attrKeys = Array.from(new Set([
66
+ ...input.upserts.map((u) => u.attributeKey),
67
+ ...input.deletes.map((d) => d.attributeKey),
68
+ ])).filter((k) => !isSystemAttributeKey(k));
69
+ const wantedKeys = new Set(attrKeys);
70
+ const attrRows = attrKeys.length === 0
71
+ ? []
72
+ : (await this.#requireAttributeRead().listAll()).filter((v) => wantedKeys.has(v.key));
73
+ const attrByKey = new Map(attrRows.map((r) => [r.key, r]));
74
+ const assignedChannels = await this.salesChannelMembership.listChannelsForEntity('product', productId);
75
+ const assignedChannelIds = new Set(assignedChannels.map((c) => c.id));
76
+ // Run validation first; if anything throws, we abort before mutating.
77
+ const validateEntry = (kind, idx, e) => {
78
+ const pathPrefix = `${kind === 'upsert' ? 'upserts' : 'deletes'}[${idx}]`;
79
+ const attrRow = attrByKey.get(e.attributeKey);
80
+ if (!isSystemAttributeKey(e.attributeKey) && !attrRow) {
81
+ throw new HttpError(422, ERROR_CODES.VALIDATION_FAILED, 'attribute_unknown', [{ path: `${pathPrefix}.attributeKey`, issue: e.attributeKey }]);
82
+ }
83
+ const scope = getAttributeScope(e.attributeKey, attrRow ?? null);
84
+ if (!scope.channelScoped) {
85
+ throw new HttpError(422, ERROR_CODES.VALIDATION_FAILED, 'attribute_not_channel_scoped', [{ path: `${pathPrefix}.attributeKey`, issue: e.attributeKey }]);
86
+ }
87
+ if (scope.languageScoped && e.languageCode === null) {
88
+ throw new HttpError(422, ERROR_CODES.VALIDATION_FAILED, 'attribute_missing_language', [{ path: `${pathPrefix}.languageCode`, issue: 'null' }]);
89
+ }
90
+ if (!assignedChannelIds.has(e.channelId)) {
91
+ throw new HttpError(422, ERROR_CODES.VALIDATION_FAILED, 'channel_not_assigned_to_product', [{ path: `${pathPrefix}.channelId`, issue: e.channelId }]);
92
+ }
93
+ const channel = channelById.get(e.channelId);
94
+ if (e.languageCode !== null) {
95
+ if (!channel || !channel.languages.includes(e.languageCode)) {
96
+ throw new HttpError(422, ERROR_CODES.VALIDATION_FAILED, 'language_not_in_channel', [{ path: `${pathPrefix}.languageCode`, issue: e.languageCode }]);
97
+ }
98
+ }
99
+ if (kind === 'upsert') {
100
+ const u = e;
101
+ validateValueShape(u.value.v, attrRow?.valueType ?? 'string', `${pathPrefix}.value`);
102
+ }
103
+ };
104
+ input.upserts.forEach((u, i) => validateEntry('upsert', i, u));
105
+ input.deletes.forEach((d, i) => validateEntry('delete', i, d));
106
+ // Apply in one transaction (via the Command Bus — co-transactional audit).
107
+ const { upserted, deleted } = await this.#audited('product.overrides_apply', productId, async (tem) => {
108
+ let up = 0;
109
+ let del = 0;
110
+ for (const u of input.upserts) {
111
+ const where = {
112
+ productId,
113
+ attributeKey: u.attributeKey,
114
+ channelId: u.channelId,
115
+ languageCode: u.languageCode ?? null,
116
+ };
117
+ const existing = await tem.findOne(ProductValueOverride, where);
118
+ if (existing) {
119
+ existing.value = u.value;
120
+ // Touch flush; updatedAt hook handles the rest.
121
+ }
122
+ else {
123
+ tem.persist(tem.create(ProductValueOverride, {
124
+ productId,
125
+ attributeKey: u.attributeKey,
126
+ channelId: u.channelId,
127
+ languageCode: u.languageCode,
128
+ value: u.value,
129
+ }));
130
+ }
131
+ up += 1;
132
+ }
133
+ for (const d of input.deletes) {
134
+ const existing = await tem.findOne(ProductValueOverride, {
135
+ productId,
136
+ attributeKey: d.attributeKey,
137
+ channelId: d.channelId,
138
+ languageCode: d.languageCode ?? null,
139
+ });
140
+ if (existing) {
141
+ tem.remove(existing);
142
+ del += 1;
143
+ }
144
+ }
145
+ return {
146
+ result: { upserted: up, deleted: del },
147
+ before: null,
148
+ after: { productId, upserted: up, deleted: del },
149
+ };
150
+ });
151
+ const all = await em.find(ProductValueOverride, { productId });
152
+ return { productId, applied: { upserted, deleted }, overrides: all };
153
+ }
154
+ }
155
+ /**
156
+ * Minimal value-shape check. Allows null (clearing); otherwise enforces
157
+ * a primitive shape consistent with the attribute's valueType. Stricter
158
+ * validation (enum option membership, price decimals, date format) is
159
+ * deferred — the existing attribute-write path in catalog-admin.service
160
+ * does the strict pass when the value lands in the global baseline, and
161
+ * the override path can lean on that until a follow-up centralises the
162
+ * rule.
163
+ */
164
+ function validateValueShape(v, valueType, path) {
165
+ if (v === null || v === undefined)
166
+ return;
167
+ const fail = (issue) => {
168
+ throw new HttpError(422, ERROR_CODES.VALIDATION_FAILED, 'value_invalid', [
169
+ { path, issue },
170
+ ]);
171
+ };
172
+ switch (valueType) {
173
+ case 'string':
174
+ case 'enum':
175
+ case 'select':
176
+ if (typeof v !== 'string')
177
+ return fail(`expected string, got ${typeof v}`);
178
+ return;
179
+ case 'number':
180
+ case 'price':
181
+ if (typeof v !== 'number' || !Number.isFinite(v)) {
182
+ return fail(`expected finite number, got ${typeof v}`);
183
+ }
184
+ return;
185
+ case 'boolean':
186
+ if (typeof v !== 'boolean')
187
+ return fail(`expected boolean, got ${typeof v}`);
188
+ return;
189
+ case 'date':
190
+ if (typeof v !== 'string')
191
+ return fail(`expected ISO-date string, got ${typeof v}`);
192
+ return;
193
+ case 'multiselect':
194
+ if (!Array.isArray(v) || v.some((x) => typeof x !== 'string')) {
195
+ return fail('expected string[]');
196
+ }
197
+ return;
198
+ default:
199
+ // Unknown value types pass through; the legacy storage path will
200
+ // reject anything pathological.
201
+ return;
202
+ }
203
+ }
204
+ //# sourceMappingURL=product-overrides.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-overrides.service.js","sourceRoot":"","sources":["../../../src/backend/services/product-overrides.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAuDvF,MAAM,OAAO,uBAAuB;IAEf;IACA;IAEA;IAEA;IANnB,YACmB,SAA8B,EAC9B,sBAAkD;IACnE,gFAAgF;IAC/D,UAAuB;IACxC,gFAAgF;IAC/D,aAA2C;QAL3C,cAAS,GAAT,SAAS,CAAqB;QAC9B,2BAAsB,GAAtB,sBAAsB,CAA4B;QAElD,eAAU,GAAV,UAAU,CAAa;QAEvB,kBAAa,GAAb,aAAa,CAA8B;IAC3D,CAAC;IAEJ,qBAAqB;QACnB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,sGAAsG,CACvG,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CACZ,MAAc,EACd,QAAgB,EAChB,KAIE;QAEF,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACtG,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,SAAiB;QACpC,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IACtD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,SAAS,CAAC,SAAiB,EAAE,KAA0B;QAC3D,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAE5B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;QAChF,CAAC;QAED,kEAAkE;QAClE,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAC3B,IAAI,GAAG,CAAC;YACN,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YACxC,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;SACzC,CAAC,CACH,CAAC;QACF,MAAM,QAAQ,GACZ,UAAU,CAAC,MAAM,KAAK,CAAC;YACrB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAC/D,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAE5D,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CACzB,IAAI,GAAG,CAAC;YACN,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;YAC3C,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;SAC5C,CAAC,CACH,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAS,QAAQ,CAAC,CAAC;QAC7C,MAAM,QAAQ,GACZ,QAAQ,CAAC,MAAM,KAAK,CAAC;YACnB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1F,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3D,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,qBAAqB,CAC9E,SAAS,EACT,SAAS,CACV,CAAC;QACF,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEtE,sEAAsE;QACtE,MAAM,aAAa,GAAG,CACpB,IAAyB,EACzB,GAAW,EACX,CAA4C,EACtC,EAAE;YACR,MAAM,UAAU,GAAG,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,GAAG,CAAC;YAC1E,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;YAC9C,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACtD,MAAM,IAAI,SAAS,CACjB,GAAG,EACH,WAAW,CAAC,iBAAiB,EAC7B,mBAAmB,EACnB,CAAC,EAAE,IAAI,EAAE,GAAG,UAAU,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAChE,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,YAAY,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC;YACjE,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;gBACzB,MAAM,IAAI,SAAS,CACjB,GAAG,EACH,WAAW,CAAC,iBAAiB,EAC7B,8BAA8B,EAC9B,CAAC,EAAE,IAAI,EAAE,GAAG,UAAU,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAChE,CAAC;YACJ,CAAC;YACD,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;gBACpD,MAAM,IAAI,SAAS,CACjB,GAAG,EACH,WAAW,CAAC,iBAAiB,EAC7B,4BAA4B,EAC5B,CAAC,EAAE,IAAI,EAAE,GAAG,UAAU,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CACxD,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzC,MAAM,IAAI,SAAS,CACjB,GAAG,EACH,WAAW,CAAC,iBAAiB,EAC7B,iCAAiC,EACjC,CAAC,EAAE,IAAI,EAAE,GAAG,UAAU,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAC1D,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAC7C,IAAI,CAAC,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC;oBAC5D,MAAM,IAAI,SAAS,CACjB,GAAG,EACH,WAAW,CAAC,iBAAiB,EAC7B,yBAAyB,EACzB,CAAC,EAAE,IAAI,EAAE,GAAG,UAAU,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAChE,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,CAAwB,CAAC;gBACnC,kBAAkB,CAChB,CAAC,CAAC,KAAK,CAAC,CAAC,EACT,OAAO,EAAE,SAAS,IAAI,QAAQ,EAC9B,GAAG,UAAU,QAAQ,CACtB,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;QAEF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAE/D,2EAA2E;QAC3E,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAC/C,yBAAyB,EACzB,SAAS,EACT,KAAK,EAAE,GAAG,EAAE,EAAE;YACZ,IAAI,EAAE,GAAG,CAAC,CAAC;YACX,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG;oBACZ,SAAS;oBACT,YAAY,EAAE,CAAC,CAAC,YAAY;oBAC5B,SAAS,EAAE,CAAC,CAAC,SAAS;oBACtB,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,IAAI;iBAC5B,CAAC;gBACX,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;gBAChE,IAAI,QAAQ,EAAE,CAAC;oBACb,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;oBACzB,gDAAgD;gBAClD,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,OAAO,CACT,GAAG,CAAC,MAAM,CAAC,oBAAoB,EAAE;wBAC/B,SAAS;wBACT,YAAY,EAAE,CAAC,CAAC,YAAY;wBAC5B,SAAS,EAAE,CAAC,CAAC,SAAS;wBACtB,YAAY,EAAE,CAAC,CAAC,YAAY;wBAC5B,KAAK,EAAE,CAAC,CAAC,KAAK;qBACf,CAAC,CACH,CAAC;gBACJ,CAAC;gBACD,EAAE,IAAI,CAAC,CAAC;YACV,CAAC;YACD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC9B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE;oBACvD,SAAS;oBACT,YAAY,EAAE,CAAC,CAAC,YAAY;oBAC5B,SAAS,EAAE,CAAC,CAAC,SAAS;oBACtB,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,IAAI;iBACrC,CAAC,CAAC;gBACH,IAAI,QAAQ,EAAE,CAAC;oBACb,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACrB,GAAG,IAAI,CAAC,CAAC;gBACX,CAAC;YACH,CAAC;YACD,OAAO;gBACL,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE;gBACtC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE;aACjD,CAAC;QACJ,CAAC,CACF,CAAC;QAEF,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/D,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;IACvE,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,SAAS,kBAAkB,CAAC,CAAU,EAAE,SAAiB,EAAE,IAAY;IACrE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO;IAC1C,MAAM,IAAI,GAAG,CAAC,KAAa,EAAS,EAAE;QACpC,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,iBAAiB,EAAE,eAAe,EAAE;YACvE,EAAE,IAAI,EAAE,KAAK,EAAE;SAChB,CAAC,CAAC;IACL,CAAC,CAAC;IACF,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ;YACX,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC,wBAAwB,OAAO,CAAC,EAAE,CAAC,CAAC;YAC3E,OAAO;QACT,KAAK,QAAQ,CAAC;QACd,KAAK,OAAO;YACV,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjD,OAAO,IAAI,CAAC,+BAA+B,OAAO,CAAC,EAAE,CAAC,CAAC;YACzD,CAAC;YACD,OAAO;QACT,KAAK,SAAS;YACZ,IAAI,OAAO,CAAC,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC,yBAAyB,OAAO,CAAC,EAAE,CAAC,CAAC;YAC7E,OAAO;QACT,KAAK,MAAM;YACT,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC,iCAAiC,OAAO,CAAC,EAAE,CAAC,CAAC;YACpF,OAAO;QACT,KAAK,aAAa;YAChB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;gBAC9D,OAAO,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACnC,CAAC;YACD,OAAO;QACT;YACE,iEAAiE;YACjE,gCAAgC;YAChC,OAAO;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { EntityManager } from '@mikro-orm/postgresql';
2
+ import type { LanguageReadPort, ProductScopeContextResponse } from '@endora-commerce/contracts';
3
+ import type { SalesChannelMembershipPort } from '@endora-commerce/platform/kernel';
4
+ import { ProductEditorPreference } from '../entities/product-editor-preference.entity.js';
5
+ import type { ProductEditorPreferencesService } from './product-editor-preferences.service.js';
6
+ /**
7
+ * Feature 022 — assembles the response of
8
+ * `GET /admin/products/:id/scope-context`.
9
+ *
10
+ * Combines:
11
+ * - the product's assigned channels (via SalesChannelMembershipPort),
12
+ * each carrying its language list (`SalesChannel.languages` JSONB),
13
+ * - the union of those languages,
14
+ * - the platform's primary admin language (LanguageService.getDefault()),
15
+ * - the editor's remembered context (ProductEditorPreference).
16
+ *
17
+ * If the product has zero assigned channels, `languagesUnion` falls
18
+ * back to every active platform language so the editor can still
19
+ * translate the global baseline.
20
+ */
21
+ export declare class ProductScopeContextService {
22
+ private readonly emFactory;
23
+ private readonly salesChannelMembership;
24
+ private readonly languageService;
25
+ private readonly editorPreferences;
26
+ constructor(emFactory: () => EntityManager, salesChannelMembership: SalesChannelMembershipPort, languageService: LanguageReadPort, editorPreferences: ProductEditorPreferencesService);
27
+ getContext(productId: string, adminUserId: string): Promise<ProductScopeContextResponse>;
28
+ /**
29
+ * Validate that a remembered preference is still applicable for the
30
+ * given product. Used by the PUT editor-preference endpoint.
31
+ */
32
+ assertChannelAssignedToProduct(productId: string, channelId: string): Promise<void>;
33
+ /** Re-export for tests + consumers needing direct entity access. */
34
+ preferenceEntityClass(): typeof ProductEditorPreference;
35
+ }
36
+ //# sourceMappingURL=product-scope-context.service.d.ts.map