@open-mercato/core 0.6.6-develop.6465.1.019f0fb26f → 0.6.6-develop.6471.1.9ab5bdd79a

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 (1213) hide show
  1. package/dist/bootstrap.js +13 -11
  2. package/dist/bootstrap.js.map +2 -2
  3. package/dist/helpers/integration/queue-runner.js +4 -2
  4. package/dist/helpers/integration/queue-runner.js.map +2 -2
  5. package/dist/modules/api_keys/services/apiKeyService.js +5 -3
  6. package/dist/modules/api_keys/services/apiKeyService.js.map +2 -2
  7. package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js +4 -2
  8. package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js.map +2 -2
  9. package/dist/modules/attachments/api/library/[id]/route.js +3 -1
  10. package/dist/modules/attachments/api/library/[id]/route.js.map +2 -2
  11. package/dist/modules/attachments/api/route.js +8 -6
  12. package/dist/modules/attachments/api/route.js.map +2 -2
  13. package/dist/modules/attachments/components/AttachmentPartitionSettings.js +5 -3
  14. package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
  15. package/dist/modules/attachments/lib/assignmentDetails.js +3 -1
  16. package/dist/modules/attachments/lib/assignmentDetails.js.map +2 -2
  17. package/dist/modules/attachments/lib/drivers/driverFactory.js +3 -1
  18. package/dist/modules/attachments/lib/drivers/driverFactory.js.map +2 -2
  19. package/dist/modules/attachments/lib/ocrQueue.js +10 -11
  20. package/dist/modules/attachments/lib/ocrQueue.js.map +2 -2
  21. package/dist/modules/attachments/lib/ocrService.js +6 -4
  22. package/dist/modules/attachments/lib/ocrService.js.map +2 -2
  23. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js +3 -1
  24. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js.map +2 -2
  25. package/dist/modules/audit_logs/api/audit-logs/actions/undo/route.js +3 -1
  26. package/dist/modules/audit_logs/api/audit-logs/actions/undo/route.js.map +2 -2
  27. package/dist/modules/audit_logs/backend/audit-logs/page.js +3 -1
  28. package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
  29. package/dist/modules/audit_logs/components/AuditLogsActions.js +4 -2
  30. package/dist/modules/audit_logs/components/AuditLogsActions.js.map +2 -2
  31. package/dist/modules/audit_logs/services/accessLogService.js +4 -2
  32. package/dist/modules/audit_logs/services/accessLogService.js.map +2 -2
  33. package/dist/modules/audit_logs/services/actionLogService.js +7 -5
  34. package/dist/modules/audit_logs/services/actionLogService.js.map +3 -3
  35. package/dist/modules/auth/api/profile/route.js +4 -2
  36. package/dist/modules/auth/api/profile/route.js.map +2 -2
  37. package/dist/modules/auth/api/reset/confirm.js +3 -1
  38. package/dist/modules/auth/api/reset/confirm.js.map +2 -2
  39. package/dist/modules/auth/api/reset.js +4 -2
  40. package/dist/modules/auth/api/reset.js.map +2 -2
  41. package/dist/modules/auth/api/roles/route.js +3 -1
  42. package/dist/modules/auth/api/roles/route.js.map +2 -2
  43. package/dist/modules/auth/api/sidebar/variants/route.js +3 -1
  44. package/dist/modules/auth/api/sidebar/variants/route.js.map +2 -2
  45. package/dist/modules/auth/api/users/resend-invite/route.js +4 -2
  46. package/dist/modules/auth/api/users/resend-invite/route.js.map +2 -2
  47. package/dist/modules/auth/api/users/route.js +3 -1
  48. package/dist/modules/auth/api/users/route.js.map +2 -2
  49. package/dist/modules/auth/backend/auth/profile/page.js +3 -1
  50. package/dist/modules/auth/backend/auth/profile/page.js.map +2 -2
  51. package/dist/modules/auth/backend/profile/change-password/page.js +3 -1
  52. package/dist/modules/auth/backend/profile/change-password/page.js.map +2 -2
  53. package/dist/modules/auth/backend/users/[id]/edit/page.js +5 -3
  54. package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
  55. package/dist/modules/auth/backend/users/create/page.js +4 -2
  56. package/dist/modules/auth/backend/users/create/page.js.map +2 -2
  57. package/dist/modules/auth/cli.js +10 -0
  58. package/dist/modules/auth/cli.js.map +2 -2
  59. package/dist/modules/auth/commands/users.js +4 -2
  60. package/dist/modules/auth/commands/users.js.map +2 -2
  61. package/dist/modules/auth/lib/consentIntegrity.js +3 -3
  62. package/dist/modules/auth/lib/consentIntegrity.js.map +2 -2
  63. package/dist/modules/auth/lib/setup-app.js +9 -10
  64. package/dist/modules/auth/lib/setup-app.js.map +2 -2
  65. package/dist/modules/auth/lib/tenantAccess.js +3 -1
  66. package/dist/modules/auth/lib/tenantAccess.js.map +2 -2
  67. package/dist/modules/auth/lib/tokenHash.js +3 -3
  68. package/dist/modules/auth/lib/tokenHash.js.map +2 -2
  69. package/dist/modules/business_rules/api/rules/route.js +4 -2
  70. package/dist/modules/business_rules/api/rules/route.js.map +2 -2
  71. package/dist/modules/business_rules/lib/expression-evaluator.js +7 -5
  72. package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
  73. package/dist/modules/business_rules/lib/rule-engine.js +5 -3
  74. package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
  75. package/dist/modules/business_rules/lib/rule-evaluator.js +11 -12
  76. package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
  77. package/dist/modules/business_rules/subscribers/crud-rule-trigger.js +3 -1
  78. package/dist/modules/business_rules/subscribers/crud-rule-trigger.js.map +2 -2
  79. package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js +3 -1
  80. package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js.map +2 -2
  81. package/dist/modules/catalog/ai-agents-context.js +4 -5
  82. package/dist/modules/catalog/ai-agents-context.js.map +2 -2
  83. package/dist/modules/catalog/ai-tools/_shared.js +3 -1
  84. package/dist/modules/catalog/ai-tools/_shared.js.map +2 -2
  85. package/dist/modules/catalog/ai-tools/authoring-pack.js +3 -1
  86. package/dist/modules/catalog/ai-tools/authoring-pack.js.map +2 -2
  87. package/dist/modules/catalog/ai-tools/merchandising-pack.js +3 -1
  88. package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
  89. package/dist/modules/catalog/api/dictionaries/[key]/route.js +3 -1
  90. package/dist/modules/catalog/api/dictionaries/[key]/route.js.map +2 -2
  91. package/dist/modules/catalog/api/prices/route.js +3 -1
  92. package/dist/modules/catalog/api/prices/route.js.map +2 -2
  93. package/dist/modules/catalog/api/products/route.js +5 -3
  94. package/dist/modules/catalog/api/products/route.js.map +2 -2
  95. package/dist/modules/catalog/api/settings/route.js +4 -2
  96. package/dist/modules/catalog/api/settings/route.js.map +2 -2
  97. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +14 -12
  98. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  99. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +8 -6
  100. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
  101. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js +5 -3
  102. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js.map +2 -2
  103. package/dist/modules/catalog/backend/catalog/products/create/page.js +5 -6
  104. package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
  105. package/dist/modules/catalog/backend/catalog/products/optionSchemaClient.js +3 -1
  106. package/dist/modules/catalog/backend/catalog/products/optionSchemaClient.js.map +2 -2
  107. package/dist/modules/catalog/components/PriceKindSettings.js +5 -3
  108. package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
  109. package/dist/modules/catalog/components/UnitPriceDisplaySettings.js +4 -2
  110. package/dist/modules/catalog/components/UnitPriceDisplaySettings.js.map +2 -2
  111. package/dist/modules/catalog/inbox-actions.js +4 -2
  112. package/dist/modules/catalog/inbox-actions.js.map +2 -2
  113. package/dist/modules/catalog/seed/examples.js +4 -5
  114. package/dist/modules/catalog/seed/examples.js.map +2 -2
  115. package/dist/modules/catalog/subscribers/low-stock-notification.js +3 -1
  116. package/dist/modules/catalog/subscribers/low-stock-notification.js.map +2 -2
  117. package/dist/modules/catalog/widgets/injection/product-seo/state.js +3 -1
  118. package/dist/modules/catalog/widgets/injection/product-seo/state.js.map +2 -2
  119. package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js +12 -11
  120. package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js.map +2 -2
  121. package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js +3 -1
  122. package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js.map +2 -2
  123. package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js +3 -1
  124. package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js.map +2 -2
  125. package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js +5 -3
  126. package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js.map +2 -2
  127. package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js +6 -6
  128. package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js.map +2 -2
  129. package/dist/modules/communication_channels/commands/connect-credential-channel.js +4 -6
  130. package/dist/modules/communication_channels/commands/connect-credential-channel.js.map +2 -2
  131. package/dist/modules/communication_channels/commands/delete-channel.js +3 -3
  132. package/dist/modules/communication_channels/commands/delete-channel.js.map +2 -2
  133. package/dist/modules/communication_channels/commands/deliver-outbound-message.js +4 -5
  134. package/dist/modules/communication_channels/commands/deliver-outbound-message.js.map +2 -2
  135. package/dist/modules/communication_channels/commands/disconnect-channel.js +3 -3
  136. package/dist/modules/communication_channels/commands/disconnect-channel.js.map +2 -2
  137. package/dist/modules/communication_channels/commands/ingest-inbound-message.js +5 -12
  138. package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +2 -2
  139. package/dist/modules/communication_channels/commands/push-unregister.js +3 -3
  140. package/dist/modules/communication_channels/commands/push-unregister.js.map +2 -2
  141. package/dist/modules/communication_channels/commands/reassign-conversation.js +5 -3
  142. package/dist/modules/communication_channels/commands/reassign-conversation.js.map +2 -2
  143. package/dist/modules/communication_channels/lib/dead-letter.js +3 -3
  144. package/dist/modules/communication_channels/lib/dead-letter.js.map +2 -2
  145. package/dist/modules/communication_channels/lib/email-mime.js +4 -6
  146. package/dist/modules/communication_channels/lib/email-mime.js.map +2 -2
  147. package/dist/modules/communication_channels/lib/oauth-client-config.js +5 -3
  148. package/dist/modules/communication_channels/lib/oauth-client-config.js.map +2 -2
  149. package/dist/modules/communication_channels/lib/send-as-user.js +3 -1
  150. package/dist/modules/communication_channels/lib/send-as-user.js.map +2 -2
  151. package/dist/modules/communication_channels/lib/thread-token.js +4 -2
  152. package/dist/modules/communication_channels/lib/thread-token.js.map +2 -2
  153. package/dist/modules/communication_channels/setup.js +3 -4
  154. package/dist/modules/communication_channels/setup.js.map +2 -2
  155. package/dist/modules/communication_channels/workers/channel-import-history.js +4 -6
  156. package/dist/modules/communication_channels/workers/channel-import-history.js.map +2 -2
  157. package/dist/modules/communication_channels/workers/gmail-history-sync.js +8 -16
  158. package/dist/modules/communication_channels/workers/gmail-history-sync.js.map +2 -2
  159. package/dist/modules/communication_channels/workers/gmail-renew-watch.js +5 -7
  160. package/dist/modules/communication_channels/workers/gmail-renew-watch.js.map +2 -2
  161. package/dist/modules/communication_channels/workers/outbound-delivery.js +6 -12
  162. package/dist/modules/communication_channels/workers/outbound-delivery.js.map +2 -2
  163. package/dist/modules/communication_channels/workers/poll-channel.js +7 -15
  164. package/dist/modules/communication_channels/workers/poll-channel.js.map +2 -2
  165. package/dist/modules/communication_channels/workers/poll-tick.js +5 -6
  166. package/dist/modules/communication_channels/workers/poll-tick.js.map +2 -2
  167. package/dist/modules/communication_channels/workers/reaction-processor.js +5 -9
  168. package/dist/modules/communication_channels/workers/reaction-processor.js.map +2 -2
  169. package/dist/modules/configs/api/cache/route.js +4 -2
  170. package/dist/modules/configs/api/cache/route.js.map +2 -2
  171. package/dist/modules/configs/api/system-status/route.js +4 -2
  172. package/dist/modules/configs/api/system-status/route.js.map +2 -2
  173. package/dist/modules/configs/api/upgrade-actions/route.js +4 -2
  174. package/dist/modules/configs/api/upgrade-actions/route.js.map +2 -2
  175. package/dist/modules/configs/components/ModuleTelemetryPanel.js +3 -1
  176. package/dist/modules/configs/components/ModuleTelemetryPanel.js.map +2 -2
  177. package/dist/modules/configs/lib/touchGeneratedBarrels.js +2 -1
  178. package/dist/modules/configs/lib/touchGeneratedBarrels.js.map +2 -2
  179. package/dist/modules/configs/services/upgradeActionsService.js +6 -3
  180. package/dist/modules/configs/services/upgradeActionsService.js.map +2 -2
  181. package/dist/modules/currencies/components/CurrencyFetchingConfig.js +3 -1
  182. package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +2 -2
  183. package/dist/modules/currencies/lib/exchangeRateFormConfig.js +3 -1
  184. package/dist/modules/currencies/lib/exchangeRateFormConfig.js.map +2 -2
  185. package/dist/modules/currencies/services/providers/nbp.js +6 -4
  186. package/dist/modules/currencies/services/providers/nbp.js.map +2 -2
  187. package/dist/modules/currencies/services/providers/raiffeisen.js +7 -7
  188. package/dist/modules/currencies/services/providers/raiffeisen.js.map +2 -2
  189. package/dist/modules/customer_accounts/api/domain-resolve/all.js +6 -5
  190. package/dist/modules/customer_accounts/api/domain-resolve/all.js.map +2 -2
  191. package/dist/modules/customer_accounts/api/signup.js +4 -2
  192. package/dist/modules/customer_accounts/api/signup.js.map +2 -2
  193. package/dist/modules/customer_accounts/lib/customerAuthServer.js +3 -1
  194. package/dist/modules/customer_accounts/lib/customerAuthServer.js.map +2 -2
  195. package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js +3 -1
  196. package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js.map +2 -2
  197. package/dist/modules/customer_accounts/subscribers/autoLinkCrmReverse.js +3 -1
  198. package/dist/modules/customer_accounts/subscribers/autoLinkCrmReverse.js.map +2 -2
  199. package/dist/modules/customer_accounts/subscribers/unlinkOnCompanyDelete.js +3 -1
  200. package/dist/modules/customer_accounts/subscribers/unlinkOnCompanyDelete.js.map +2 -2
  201. package/dist/modules/customer_accounts/subscribers/unlinkOnPersonDelete.js +3 -1
  202. package/dist/modules/customer_accounts/subscribers/unlinkOnPersonDelete.js.map +2 -2
  203. package/dist/modules/customers/ai-agents-context.js +4 -5
  204. package/dist/modules/customers/ai-agents-context.js.map +2 -2
  205. package/dist/modules/customers/api/activities/route.js +6 -4
  206. package/dist/modules/customers/api/activities/route.js.map +2 -2
  207. package/dist/modules/customers/api/comments/route.js +3 -1
  208. package/dist/modules/customers/api/comments/route.js.map +2 -2
  209. package/dist/modules/customers/api/companies/[id]/people/route.js +3 -1
  210. package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
  211. package/dist/modules/customers/api/companies/[id]/route.js +5 -3
  212. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  213. package/dist/modules/customers/api/companies/route.js +5 -3
  214. package/dist/modules/customers/api/companies/route.js.map +2 -2
  215. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js +3 -1
  216. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js.map +2 -2
  217. package/dist/modules/customers/api/dashboard/widgets/new-customers/route.js +3 -1
  218. package/dist/modules/customers/api/dashboard/widgets/new-customers/route.js.map +2 -2
  219. package/dist/modules/customers/api/dashboard/widgets/new-deals/route.js +3 -1
  220. package/dist/modules/customers/api/dashboard/widgets/new-deals/route.js.map +2 -2
  221. package/dist/modules/customers/api/dashboard/widgets/next-interactions/route.js +3 -1
  222. package/dist/modules/customers/api/dashboard/widgets/next-interactions/route.js.map +2 -2
  223. package/dist/modules/customers/api/deals/[id]/companies/route.js +3 -1
  224. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
  225. package/dist/modules/customers/api/deals/[id]/people/route.js +3 -1
  226. package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
  227. package/dist/modules/customers/api/deals/aggregate/route.js +3 -1
  228. package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
  229. package/dist/modules/customers/api/deals/bulk-update-owner/route.js +7 -5
  230. package/dist/modules/customers/api/deals/bulk-update-owner/route.js.map +2 -2
  231. package/dist/modules/customers/api/deals/bulk-update-stage/route.js +7 -5
  232. package/dist/modules/customers/api/deals/bulk-update-stage/route.js.map +2 -2
  233. package/dist/modules/customers/api/deals/route.js +3 -1
  234. package/dist/modules/customers/api/deals/route.js.map +2 -2
  235. package/dist/modules/customers/api/deals/summary/route.js +3 -1
  236. package/dist/modules/customers/api/deals/summary/route.js.map +2 -2
  237. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +4 -2
  238. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
  239. package/dist/modules/customers/api/dictionaries/[kind]/route.js +5 -3
  240. package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
  241. package/dist/modules/customers/api/dictionaries/cache.js +3 -1
  242. package/dist/modules/customers/api/dictionaries/cache.js.map +2 -2
  243. package/dist/modules/customers/api/dictionaries/context.js +3 -1
  244. package/dist/modules/customers/api/dictionaries/context.js.map +2 -2
  245. package/dist/modules/customers/api/dictionaries/currency/route.js +3 -1
  246. package/dist/modules/customers/api/dictionaries/currency/route.js.map +2 -2
  247. package/dist/modules/customers/api/dictionaries/kind-settings/route.js +4 -2
  248. package/dist/modules/customers/api/dictionaries/kind-settings/route.js.map +2 -2
  249. package/dist/modules/customers/api/entity-roles-factory.js +7 -5
  250. package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
  251. package/dist/modules/customers/api/interactions/cancel/route.js +3 -1
  252. package/dist/modules/customers/api/interactions/cancel/route.js.map +2 -2
  253. package/dist/modules/customers/api/interactions/complete/route.js +3 -1
  254. package/dist/modules/customers/api/interactions/complete/route.js.map +2 -2
  255. package/dist/modules/customers/api/interactions/conflicts/route.js +3 -1
  256. package/dist/modules/customers/api/interactions/conflicts/route.js.map +2 -2
  257. package/dist/modules/customers/api/interactions/counts/route.js +3 -1
  258. package/dist/modules/customers/api/interactions/counts/route.js.map +2 -2
  259. package/dist/modules/customers/api/interactions/route.js +7 -4
  260. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  261. package/dist/modules/customers/api/interactions/tasks/route.js +3 -1
  262. package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
  263. package/dist/modules/customers/api/labels/assign/route.js +3 -1
  264. package/dist/modules/customers/api/labels/assign/route.js.map +2 -2
  265. package/dist/modules/customers/api/labels/route.js +6 -3
  266. package/dist/modules/customers/api/labels/route.js.map +2 -2
  267. package/dist/modules/customers/api/labels/unassign/route.js +3 -1
  268. package/dist/modules/customers/api/labels/unassign/route.js.map +2 -2
  269. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +3 -1
  270. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
  271. package/dist/modules/customers/api/people/[id]/route.js +5 -3
  272. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  273. package/dist/modules/customers/api/people/route.js +5 -3
  274. package/dist/modules/customers/api/people/route.js.map +2 -2
  275. package/dist/modules/customers/api/pipeline-stages/reorder/route.js +3 -1
  276. package/dist/modules/customers/api/pipeline-stages/reorder/route.js.map +2 -2
  277. package/dist/modules/customers/api/pipeline-stages/route.js +6 -4
  278. package/dist/modules/customers/api/pipeline-stages/route.js.map +2 -2
  279. package/dist/modules/customers/api/pipelines/route.js +6 -4
  280. package/dist/modules/customers/api/pipelines/route.js.map +2 -2
  281. package/dist/modules/customers/api/settings/address-format/route.js +4 -2
  282. package/dist/modules/customers/api/settings/address-format/route.js.map +2 -2
  283. package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js +4 -2
  284. package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js.map +2 -2
  285. package/dist/modules/customers/api/settings/stuck-threshold/route.js +4 -2
  286. package/dist/modules/customers/api/settings/stuck-threshold/route.js.map +2 -2
  287. package/dist/modules/customers/api/tags/assign/route.js +3 -1
  288. package/dist/modules/customers/api/tags/assign/route.js.map +2 -2
  289. package/dist/modules/customers/api/tags/unassign/route.js +3 -1
  290. package/dist/modules/customers/api/tags/unassign/route.js.map +2 -2
  291. package/dist/modules/customers/api/todos/route.js +6 -4
  292. package/dist/modules/customers/api/todos/route.js.map +2 -2
  293. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +5 -3
  294. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
  295. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +3 -1
  296. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +2 -2
  297. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js +3 -1
  298. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js.map +2 -2
  299. package/dist/modules/customers/backend/customers/deals/map/components/DealsMapCanvasImpl.js +4 -2
  300. package/dist/modules/customers/backend/customers/deals/map/components/DealsMapCanvasImpl.js.map +2 -2
  301. package/dist/modules/customers/backend/customers/deals/page.js +4 -2
  302. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  303. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +5 -3
  304. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  305. package/dist/modules/customers/commands/deals.js +3 -1
  306. package/dist/modules/customers/commands/deals.js.map +2 -2
  307. package/dist/modules/customers/commands/dictionaries.js +3 -1
  308. package/dist/modules/customers/commands/dictionaries.js.map +2 -2
  309. package/dist/modules/customers/commands/interactions.js +4 -2
  310. package/dist/modules/customers/commands/interactions.js.map +2 -2
  311. package/dist/modules/customers/commands/shared.js +4 -2
  312. package/dist/modules/customers/commands/shared.js.map +2 -2
  313. package/dist/modules/customers/commands/todos.js +3 -1
  314. package/dist/modules/customers/commands/todos.js.map +2 -2
  315. package/dist/modules/customers/components/DictionarySettings.js +5 -3
  316. package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
  317. package/dist/modules/customers/components/DictionarySortSettings.js +3 -1
  318. package/dist/modules/customers/components/DictionarySortSettings.js.map +2 -2
  319. package/dist/modules/customers/components/detail/ActivitiesCard.js +3 -1
  320. package/dist/modules/customers/components/detail/ActivitiesCard.js.map +2 -2
  321. package/dist/modules/customers/components/detail/ActivitiesDayStrip.js +3 -1
  322. package/dist/modules/customers/components/detail/ActivitiesDayStrip.js.map +2 -2
  323. package/dist/modules/customers/components/detail/ActivitiesSection.js +6 -4
  324. package/dist/modules/customers/components/detail/ActivitiesSection.js.map +2 -2
  325. package/dist/modules/customers/components/detail/ActivityCard.js +3 -1
  326. package/dist/modules/customers/components/detail/ActivityCard.js.map +2 -2
  327. package/dist/modules/customers/components/detail/ChangelogTab.js +3 -1
  328. package/dist/modules/customers/components/detail/ChangelogTab.js.map +2 -2
  329. package/dist/modules/customers/components/detail/CompanyCard.js +3 -1
  330. package/dist/modules/customers/components/detail/CompanyCard.js.map +2 -2
  331. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +3 -1
  332. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +2 -2
  333. package/dist/modules/customers/components/detail/EntityTagsDialog.js +3 -1
  334. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
  335. package/dist/modules/customers/components/detail/InlineActivityComposer.js +3 -1
  336. package/dist/modules/customers/components/detail/InlineActivityComposer.js.map +2 -2
  337. package/dist/modules/customers/components/detail/ManageTagsDialog.js +3 -1
  338. package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +2 -2
  339. package/dist/modules/customers/components/detail/RoleAssignmentRow.js +5 -3
  340. package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +2 -2
  341. package/dist/modules/customers/components/detail/RolesSection.js +4 -2
  342. package/dist/modules/customers/components/detail/RolesSection.js.map +2 -2
  343. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +5 -3
  344. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +2 -2
  345. package/dist/modules/customers/components/linking/LinkEntityDialog.js +4 -2
  346. package/dist/modules/customers/components/linking/LinkEntityDialog.js.map +2 -2
  347. package/dist/modules/customers/inbox-actions.js +3 -1
  348. package/dist/modules/customers/inbox-actions.js.map +2 -2
  349. package/dist/modules/customers/lib/bulkDeals.js +3 -1
  350. package/dist/modules/customers/lib/bulkDeals.js.map +2 -2
  351. package/dist/modules/customers/lib/dealClosureNotification.js +4 -2
  352. package/dist/modules/customers/lib/dealClosureNotification.js.map +2 -2
  353. package/dist/modules/customers/lib/dealStageTransitionTable.js +3 -1
  354. package/dist/modules/customers/lib/dealStageTransitionTable.js.map +2 -2
  355. package/dist/modules/customers/lib/interactionFeatureFlags.js +3 -1
  356. package/dist/modules/customers/lib/interactionFeatureFlags.js.map +2 -2
  357. package/dist/modules/customers/lib/todoCompatibility.js +3 -1
  358. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  359. package/dist/modules/customers/search.js +14 -7
  360. package/dist/modules/customers/search.js.map +2 -2
  361. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js +3 -1
  362. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js.map +2 -2
  363. package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js +3 -1
  364. package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js.map +2 -2
  365. package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js +3 -1
  366. package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js.map +2 -2
  367. package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js +3 -1
  368. package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js.map +2 -2
  369. package/dist/modules/dashboards/api/widgets/data/batch/route.js +3 -1
  370. package/dist/modules/dashboards/api/widgets/data/batch/route.js.map +2 -2
  371. package/dist/modules/dashboards/api/widgets/data/route.js +3 -1
  372. package/dist/modules/dashboards/api/widgets/data/route.js.map +2 -2
  373. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +5 -3
  374. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
  375. package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.js +3 -1
  376. package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.js.map +2 -2
  377. package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.client.js +3 -1
  378. package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.client.js.map +2 -2
  379. package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js +3 -1
  380. package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js.map +2 -2
  381. package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.client.js +3 -1
  382. package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.client.js.map +2 -2
  383. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.js +3 -1
  384. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.js.map +2 -2
  385. package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.js +3 -1
  386. package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.js.map +2 -2
  387. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js +3 -1
  388. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js.map +2 -2
  389. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js +3 -1
  390. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js.map +2 -2
  391. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js +3 -1
  392. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js.map +2 -2
  393. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js +3 -1
  394. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js.map +2 -2
  395. package/dist/modules/data_sync/api/run.js +3 -1
  396. package/dist/modules/data_sync/api/run.js.map +2 -2
  397. package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js +1 -1
  398. package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js.map +2 -2
  399. package/dist/modules/data_sync/lib/adapter-registry.js +11 -4
  400. package/dist/modules/data_sync/lib/adapter-registry.js.map +2 -2
  401. package/dist/modules/data_sync/lib/sync-engine.js +23 -2
  402. package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
  403. package/dist/modules/data_sync/workers/sync-export.js +3 -1
  404. package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
  405. package/dist/modules/data_sync/workers/sync-import.js +3 -1
  406. package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
  407. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +4 -2
  408. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  409. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js +3 -1
  410. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js.map +2 -2
  411. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +4 -2
  412. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
  413. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js +3 -1
  414. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js.map +2 -2
  415. package/dist/modules/dictionaries/api/[dictionaryId]/route.js +5 -3
  416. package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
  417. package/dist/modules/dictionaries/api/context.js +3 -1
  418. package/dist/modules/dictionaries/api/context.js.map +2 -2
  419. package/dist/modules/dictionaries/api/route.js +4 -2
  420. package/dist/modules/dictionaries/api/route.js.map +2 -2
  421. package/dist/modules/dictionaries/components/DictionariesManager.js +5 -3
  422. package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
  423. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +4 -2
  424. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
  425. package/dist/modules/dictionaries/components/DictionaryEntrySelect.js +4 -2
  426. package/dist/modules/dictionaries/components/DictionaryEntrySelect.js.map +2 -2
  427. package/dist/modules/dictionaries/components/DictionarySelectControl.js +3 -1
  428. package/dist/modules/dictionaries/components/DictionarySelectControl.js.map +2 -2
  429. package/dist/modules/dictionaries/fields/dictionary.js +3 -1
  430. package/dist/modules/dictionaries/fields/dictionary.js.map +2 -2
  431. package/dist/modules/directory/api/organization-branding/route.js +3 -1
  432. package/dist/modules/directory/api/organization-branding/route.js.map +2 -2
  433. package/dist/modules/directory/api/organization-switcher/route.js +3 -1
  434. package/dist/modules/directory/api/organization-switcher/route.js.map +2 -2
  435. package/dist/modules/directory/commands/tenants.js +5 -3
  436. package/dist/modules/directory/commands/tenants.js.map +2 -2
  437. package/dist/modules/directory/utils/organizationScope.js +6 -4
  438. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  439. package/dist/modules/entities/api/definitions.cache.js +3 -1
  440. package/dist/modules/entities/api/definitions.cache.js.map +2 -2
  441. package/dist/modules/entities/api/definitions.js +7 -5
  442. package/dist/modules/entities/api/definitions.js.map +2 -2
  443. package/dist/modules/entities/api/records.js +4 -8
  444. package/dist/modules/entities/api/records.js.map +2 -2
  445. package/dist/modules/entities/components/EncryptionManager.js +3 -1
  446. package/dist/modules/entities/components/EncryptionManager.js.map +2 -2
  447. package/dist/modules/entities/lib/makeActivityRoute.js +3 -1
  448. package/dist/modules/entities/lib/makeActivityRoute.js.map +2 -2
  449. package/dist/modules/feature_toggles/api/overrides/route.js +3 -1
  450. package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
  451. package/dist/modules/feature_toggles/lib/feature-flag-check.js +5 -9
  452. package/dist/modules/feature_toggles/lib/feature-flag-check.js.map +2 -2
  453. package/dist/modules/inbox_ops/api/emails/[id]/reprocess/route.js +4 -2
  454. package/dist/modules/inbox_ops/api/emails/[id]/reprocess/route.js.map +2 -2
  455. package/dist/modules/inbox_ops/api/emails/[id]/route.js +4 -2
  456. package/dist/modules/inbox_ops/api/emails/[id]/route.js.map +2 -2
  457. package/dist/modules/inbox_ops/api/emails/route.js +3 -1
  458. package/dist/modules/inbox_ops/api/emails/route.js.map +2 -2
  459. package/dist/modules/inbox_ops/api/extract/route.js +3 -1
  460. package/dist/modules/inbox_ops/api/extract/route.js.map +2 -2
  461. package/dist/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.js +3 -1
  462. package/dist/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.js.map +2 -2
  463. package/dist/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.js +4 -2
  464. package/dist/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.js.map +2 -2
  465. package/dist/modules/inbox_ops/api/proposals/counts/route.js +4 -2
  466. package/dist/modules/inbox_ops/api/proposals/counts/route.js.map +2 -2
  467. package/dist/modules/inbox_ops/api/proposals/route.js +3 -1
  468. package/dist/modules/inbox_ops/api/proposals/route.js.map +2 -2
  469. package/dist/modules/inbox_ops/api/routeHelpers.js +3 -1
  470. package/dist/modules/inbox_ops/api/routeHelpers.js.map +2 -2
  471. package/dist/modules/inbox_ops/api/settings/route.js +3 -1
  472. package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
  473. package/dist/modules/inbox_ops/api/webhook/inbound.js +7 -5
  474. package/dist/modules/inbox_ops/api/webhook/inbound.js.map +2 -2
  475. package/dist/modules/inbox_ops/lib/cache.js +4 -2
  476. package/dist/modules/inbox_ops/lib/cache.js.map +2 -2
  477. package/dist/modules/inbox_ops/lib/catalogLookup.js +3 -1
  478. package/dist/modules/inbox_ops/lib/catalogLookup.js.map +2 -2
  479. package/dist/modules/inbox_ops/lib/eventBus.js +3 -4
  480. package/dist/modules/inbox_ops/lib/eventBus.js.map +2 -2
  481. package/dist/modules/inbox_ops/lib/messagesIntegration.js +4 -8
  482. package/dist/modules/inbox_ops/lib/messagesIntegration.js.map +2 -2
  483. package/dist/modules/inbox_ops/subscribers/executionAuditor.js +3 -1
  484. package/dist/modules/inbox_ops/subscribers/executionAuditor.js.map +2 -2
  485. package/dist/modules/inbox_ops/subscribers/extractionWorker.js +10 -8
  486. package/dist/modules/inbox_ops/subscribers/extractionWorker.js.map +2 -2
  487. package/dist/modules/inbox_ops/subscribers/proposalNotifier.js +3 -1
  488. package/dist/modules/inbox_ops/subscribers/proposalNotifier.js.map +2 -2
  489. package/dist/modules/messages/api/[id]/route.js +3 -4
  490. package/dist/modules/messages/api/[id]/route.js.map +2 -2
  491. package/dist/modules/messages/commands/actions.js +3 -1
  492. package/dist/modules/messages/commands/actions.js.map +2 -2
  493. package/dist/modules/messages/components/MessagesInboxPageClient.js +3 -1
  494. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
  495. package/dist/modules/messages/lib/email-sender.js +3 -7
  496. package/dist/modules/messages/lib/email-sender.js.map +2 -2
  497. package/dist/modules/messages/lib/message-objects-registry.js +3 -1
  498. package/dist/modules/messages/lib/message-objects-registry.js.map +2 -2
  499. package/dist/modules/messages/lib/message-types-registry.js +3 -1
  500. package/dist/modules/messages/lib/message-types-registry.js.map +2 -2
  501. package/dist/modules/messages/workers/send-email.worker.js +6 -4
  502. package/dist/modules/messages/workers/send-email.worker.js.map +2 -2
  503. package/dist/modules/notifications/lib/notificationMapper.js +3 -4
  504. package/dist/modules/notifications/lib/notificationMapper.js.map +2 -2
  505. package/dist/modules/notifications/lib/notificationService.js +4 -5
  506. package/dist/modules/notifications/lib/notificationService.js.map +2 -2
  507. package/dist/modules/notifications/subscribers/deliver-notification.js +8 -13
  508. package/dist/modules/notifications/subscribers/deliver-notification.js.map +2 -2
  509. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +3 -1
  510. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
  511. package/dist/modules/perspectives/services/perspectiveService.js +3 -3
  512. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  513. package/dist/modules/planner/api/access.js +3 -3
  514. package/dist/modules/planner/api/access.js.map +2 -2
  515. package/dist/modules/planner/api/availability-date-specific.js +3 -1
  516. package/dist/modules/planner/api/availability-date-specific.js.map +2 -2
  517. package/dist/modules/planner/api/availability-weekly.js +3 -1
  518. package/dist/modules/planner/api/availability-weekly.js.map +2 -2
  519. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +4 -2
  520. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  521. package/dist/modules/planner/components/AvailabilityRulesEditor.js +3 -1
  522. package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
  523. package/dist/modules/progress/api/jobs/route.js +3 -1
  524. package/dist/modules/progress/api/jobs/route.js.map +2 -2
  525. package/dist/modules/query_index/components/QueryIndexesTable.js +5 -3
  526. package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
  527. package/dist/modules/query_index/lib/batch.js +4 -2
  528. package/dist/modules/query_index/lib/batch.js.map +2 -2
  529. package/dist/modules/query_index/lib/coverage.js +3 -1
  530. package/dist/modules/query_index/lib/coverage.js.map +2 -2
  531. package/dist/modules/query_index/lib/engine.js +13 -18
  532. package/dist/modules/query_index/lib/engine.js.map +2 -2
  533. package/dist/modules/query_index/lib/reindexer.js +8 -6
  534. package/dist/modules/query_index/lib/reindexer.js.map +2 -2
  535. package/dist/modules/query_index/lib/search-tokens.js +3 -1
  536. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  537. package/dist/modules/query_index/subscribers/coverage_refresh.js +3 -1
  538. package/dist/modules/query_index/subscribers/coverage_refresh.js.map +2 -2
  539. package/dist/modules/resources/api/comments.js +3 -1
  540. package/dist/modules/resources/api/comments.js.map +2 -2
  541. package/dist/modules/resources/api/resources/tags/assign/route.js +3 -1
  542. package/dist/modules/resources/api/resources/tags/assign/route.js.map +2 -2
  543. package/dist/modules/resources/api/resources/tags/unassign/route.js +3 -1
  544. package/dist/modules/resources/api/resources/tags/unassign/route.js.map +2 -2
  545. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +3 -1
  546. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +2 -2
  547. package/dist/modules/resources/backend/resources/resource-types/page.js +4 -2
  548. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  549. package/dist/modules/resources/commands/activities.js +6 -5
  550. package/dist/modules/resources/commands/activities.js.map +2 -2
  551. package/dist/modules/resources/commands/comments.js +6 -4
  552. package/dist/modules/resources/commands/comments.js.map +2 -2
  553. package/dist/modules/resources/commands/shared.js +24 -1
  554. package/dist/modules/resources/commands/shared.js.map +2 -2
  555. package/dist/modules/sales/api/channels/route.js +3 -1
  556. package/dist/modules/sales/api/channels/route.js.map +2 -2
  557. package/dist/modules/sales/api/document-history/route.js +3 -1
  558. package/dist/modules/sales/api/document-history/route.js.map +2 -2
  559. package/dist/modules/sales/api/document-numbers/route.js +3 -1
  560. package/dist/modules/sales/api/document-numbers/route.js.map +2 -2
  561. package/dist/modules/sales/api/quotes/accept/route.js +4 -2
  562. package/dist/modules/sales/api/quotes/accept/route.js.map +2 -2
  563. package/dist/modules/sales/api/quotes/convert/route.js +3 -1
  564. package/dist/modules/sales/api/quotes/convert/route.js.map +2 -2
  565. package/dist/modules/sales/api/quotes/public/[token]/route.js +3 -1
  566. package/dist/modules/sales/api/quotes/public/[token]/route.js.map +2 -2
  567. package/dist/modules/sales/api/quotes/send/route.js +3 -1
  568. package/dist/modules/sales/api/quotes/send/route.js.map +2 -2
  569. package/dist/modules/sales/api/returns/[id]/route.js +3 -1
  570. package/dist/modules/sales/api/returns/[id]/route.js.map +2 -2
  571. package/dist/modules/sales/api/settings/document-numbers/route.js +4 -2
  572. package/dist/modules/sales/api/settings/document-numbers/route.js.map +2 -2
  573. package/dist/modules/sales/api/settings/order-editing/route.js +4 -2
  574. package/dist/modules/sales/api/settings/order-editing/route.js.map +2 -2
  575. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +3 -1
  576. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
  577. package/dist/modules/sales/backend/sales/channels/offers/page.js +6 -4
  578. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  579. package/dist/modules/sales/backend/sales/channels/page.js +4 -2
  580. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  581. package/dist/modules/sales/backend/sales/documents/[id]/page.js +20 -18
  582. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  583. package/dist/modules/sales/commands/documents.js +4 -8
  584. package/dist/modules/sales/commands/documents.js.map +2 -2
  585. package/dist/modules/sales/commands/payments.js +3 -1
  586. package/dist/modules/sales/commands/payments.js.map +2 -2
  587. package/dist/modules/sales/commands/shipments.js +3 -1
  588. package/dist/modules/sales/commands/shipments.js.map +2 -2
  589. package/dist/modules/sales/components/AdjustmentKindSettings.js +5 -3
  590. package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
  591. package/dist/modules/sales/components/DocumentNumberSettings.js +4 -2
  592. package/dist/modules/sales/components/DocumentNumberSettings.js.map +2 -2
  593. package/dist/modules/sales/components/OrderEditingSettings.js +4 -2
  594. package/dist/modules/sales/components/OrderEditingSettings.js.map +2 -2
  595. package/dist/modules/sales/components/PaymentMethodsSettings.js +5 -3
  596. package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
  597. package/dist/modules/sales/components/ShippingMethodsSettings.js +5 -3
  598. package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
  599. package/dist/modules/sales/components/StatusSettings.js +5 -3
  600. package/dist/modules/sales/components/StatusSettings.js.map +2 -2
  601. package/dist/modules/sales/components/TaxRatesSettings.js +5 -3
  602. package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
  603. package/dist/modules/sales/components/channels/ChannelOfferForm.js +16 -14
  604. package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
  605. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +4 -2
  606. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  607. package/dist/modules/sales/components/documents/AddressesSection.js +5 -3
  608. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  609. package/dist/modules/sales/components/documents/AdjustmentDialog.js +3 -1
  610. package/dist/modules/sales/components/documents/AdjustmentDialog.js.map +2 -2
  611. package/dist/modules/sales/components/documents/AdjustmentsSection.js +5 -3
  612. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  613. package/dist/modules/sales/components/documents/ItemsSection.js +6 -4
  614. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  615. package/dist/modules/sales/components/documents/LineItemDialog.js +8 -6
  616. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  617. package/dist/modules/sales/components/documents/PaymentDialog.js +5 -3
  618. package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
  619. package/dist/modules/sales/components/documents/PaymentsSection.js +4 -2
  620. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  621. package/dist/modules/sales/components/documents/SalesDocumentForm.js +14 -12
  622. package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
  623. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +5 -3
  624. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  625. package/dist/modules/sales/components/documents/ShipmentDialog.js +9 -7
  626. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  627. package/dist/modules/sales/components/documents/ShipmentsSection.js +4 -2
  628. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  629. package/dist/modules/sales/frontend/quote/[token]/page.js +4 -2
  630. package/dist/modules/sales/frontend/quote/[token]/page.js.map +2 -2
  631. package/dist/modules/sales/seed/examples.js +7 -9
  632. package/dist/modules/sales/seed/examples.js.map +2 -2
  633. package/dist/modules/sales/subscribers/quote-expiring-notification.js +3 -1
  634. package/dist/modules/sales/subscribers/quote-expiring-notification.js.map +2 -2
  635. package/dist/modules/sales/subscribers/reconcileOnAddressDelete.js +3 -1
  636. package/dist/modules/sales/subscribers/reconcileOnAddressDelete.js.map +2 -2
  637. package/dist/modules/sales/subscribers/reconcileOnCompanyDelete.js +3 -1
  638. package/dist/modules/sales/subscribers/reconcileOnCompanyDelete.js.map +2 -2
  639. package/dist/modules/sales/subscribers/reconcileOnCustomerDelete.js +3 -1
  640. package/dist/modules/sales/subscribers/reconcileOnCustomerDelete.js.map +2 -2
  641. package/dist/modules/sales/widgets/dashboard/makeDashboardWidgetRoute.js +5 -3
  642. package/dist/modules/sales/widgets/dashboard/makeDashboardWidgetRoute.js.map +2 -2
  643. package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js +3 -1
  644. package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js.map +2 -2
  645. package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js +3 -1
  646. package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js.map +2 -2
  647. package/dist/modules/shipping_carriers/api/tracking/route.js +5 -0
  648. package/dist/modules/shipping_carriers/api/tracking/route.js.map +2 -2
  649. package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js +3 -1
  650. package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js.map +2 -2
  651. package/dist/modules/shipping_carriers/lib/shipping-service.js +41 -19
  652. package/dist/modules/shipping_carriers/lib/shipping-service.js.map +2 -2
  653. package/dist/modules/shipping_carriers/lib/upstream-error-response.js +3 -1
  654. package/dist/modules/shipping_carriers/lib/upstream-error-response.js.map +2 -2
  655. package/dist/modules/shipping_carriers/workers/webhook-processor.js +3 -5
  656. package/dist/modules/shipping_carriers/workers/webhook-processor.js.map +2 -2
  657. package/dist/modules/staff/api/comments.js +3 -1
  658. package/dist/modules/staff/api/comments.js.map +2 -2
  659. package/dist/modules/staff/api/leave-requests/accept/route.js +3 -1
  660. package/dist/modules/staff/api/leave-requests/accept/route.js.map +2 -2
  661. package/dist/modules/staff/api/leave-requests/reject/route.js +3 -1
  662. package/dist/modules/staff/api/leave-requests/reject/route.js.map +2 -2
  663. package/dist/modules/staff/api/team-members/assignable/route.js +3 -1
  664. package/dist/modules/staff/api/team-members/assignable/route.js.map +2 -2
  665. package/dist/modules/staff/api/team-members/self/route.js +4 -2
  666. package/dist/modules/staff/api/team-members/self/route.js.map +2 -2
  667. package/dist/modules/staff/api/team-members/tags/assign/route.js +3 -1
  668. package/dist/modules/staff/api/team-members/tags/assign/route.js.map +2 -2
  669. package/dist/modules/staff/api/team-members/tags/unassign/route.js +3 -1
  670. package/dist/modules/staff/api/team-members/tags/unassign/route.js.map +2 -2
  671. package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js +3 -1
  672. package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js.map +2 -2
  673. package/dist/modules/staff/api/timesheets/my-projects/route.js +3 -1
  674. package/dist/modules/staff/api/timesheets/my-projects/route.js.map +2 -2
  675. package/dist/modules/staff/api/timesheets/projects/kpis/route.js +3 -1
  676. package/dist/modules/staff/api/timesheets/projects/kpis/route.js.map +2 -2
  677. package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js +3 -1
  678. package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js.map +2 -2
  679. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js +4 -2
  680. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js.map +2 -2
  681. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js +4 -2
  682. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js.map +2 -2
  683. package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js +3 -1
  684. package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js.map +2 -2
  685. package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js +3 -1
  686. package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js.map +2 -2
  687. package/dist/modules/staff/backend/staff/team-members/page.js +4 -2
  688. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  689. package/dist/modules/staff/backend/staff/team-roles/page.js +4 -2
  690. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  691. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +4 -2
  692. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  693. package/dist/modules/staff/backend/staff/teams/page.js +4 -2
  694. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  695. package/dist/modules/staff/backend/staff/timesheets/page.js +7 -5
  696. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  697. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js +3 -1
  698. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +2 -2
  699. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +4 -2
  700. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  701. package/dist/modules/staff/commands/timesheets-entries.js +3 -1
  702. package/dist/modules/staff/commands/timesheets-entries.js.map +2 -2
  703. package/dist/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.client.js +3 -1
  704. package/dist/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.client.js.map +2 -2
  705. package/dist/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.client.js +5 -3
  706. package/dist/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.client.js.map +2 -2
  707. package/dist/modules/sync_excel/api/import/route.js +3 -1
  708. package/dist/modules/sync_excel/api/import/route.js.map +2 -2
  709. package/dist/modules/translations/api/[entityType]/[entityId]/route.js +5 -3
  710. package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
  711. package/dist/modules/translations/api/get/locales.js +3 -1
  712. package/dist/modules/translations/api/get/locales.js.map +2 -2
  713. package/dist/modules/translations/api/put/locales.js +3 -1
  714. package/dist/modules/translations/api/put/locales.js.map +2 -2
  715. package/dist/modules/translations/components/TranslationManager.js +3 -1
  716. package/dist/modules/translations/components/TranslationManager.js.map +2 -2
  717. package/dist/modules/translations/subscribers/cleanup.js +3 -1
  718. package/dist/modules/translations/subscribers/cleanup.js.map +2 -2
  719. package/dist/modules/workflows/api/definitions/[id]/customize/route.js +4 -2
  720. package/dist/modules/workflows/api/definitions/[id]/customize/route.js.map +2 -2
  721. package/dist/modules/workflows/api/definitions/[id]/reset-to-code/route.js +4 -2
  722. package/dist/modules/workflows/api/definitions/[id]/reset-to-code/route.js.map +2 -2
  723. package/dist/modules/workflows/api/definitions/[id]/route.js +6 -4
  724. package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
  725. package/dist/modules/workflows/api/definitions/route.js +4 -2
  726. package/dist/modules/workflows/api/definitions/route.js.map +2 -2
  727. package/dist/modules/workflows/api/events/[id]/route.js +3 -1
  728. package/dist/modules/workflows/api/events/[id]/route.js.map +2 -2
  729. package/dist/modules/workflows/api/events/route.js +3 -1
  730. package/dist/modules/workflows/api/events/route.js.map +2 -2
  731. package/dist/modules/workflows/api/instances/[id]/advance/route.js +3 -1
  732. package/dist/modules/workflows/api/instances/[id]/advance/route.js.map +2 -2
  733. package/dist/modules/workflows/api/instances/[id]/cancel/route.js +3 -1
  734. package/dist/modules/workflows/api/instances/[id]/cancel/route.js.map +2 -2
  735. package/dist/modules/workflows/api/instances/[id]/events/route.js +3 -1
  736. package/dist/modules/workflows/api/instances/[id]/events/route.js.map +2 -2
  737. package/dist/modules/workflows/api/instances/[id]/retry/route.js +3 -1
  738. package/dist/modules/workflows/api/instances/[id]/retry/route.js.map +2 -2
  739. package/dist/modules/workflows/api/instances/[id]/route.js +3 -1
  740. package/dist/modules/workflows/api/instances/[id]/route.js.map +2 -2
  741. package/dist/modules/workflows/api/instances/[id]/signal/route.js +5 -7
  742. package/dist/modules/workflows/api/instances/[id]/signal/route.js.map +2 -2
  743. package/dist/modules/workflows/api/instances/route.js +5 -3
  744. package/dist/modules/workflows/api/instances/route.js.map +2 -2
  745. package/dist/modules/workflows/api/instances/validate-start/route.js +3 -1
  746. package/dist/modules/workflows/api/instances/validate-start/route.js.map +2 -2
  747. package/dist/modules/workflows/api/signals/route.js +3 -1
  748. package/dist/modules/workflows/api/signals/route.js.map +2 -2
  749. package/dist/modules/workflows/api/tasks/[id]/claim/route.js +3 -1
  750. package/dist/modules/workflows/api/tasks/[id]/claim/route.js.map +2 -2
  751. package/dist/modules/workflows/api/tasks/[id]/complete/route.js +3 -1
  752. package/dist/modules/workflows/api/tasks/[id]/complete/route.js.map +2 -2
  753. package/dist/modules/workflows/api/tasks/[id]/route.js +3 -1
  754. package/dist/modules/workflows/api/tasks/[id]/route.js.map +2 -2
  755. package/dist/modules/workflows/api/tasks/route.js +3 -1
  756. package/dist/modules/workflows/api/tasks/route.js.map +2 -2
  757. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +4 -2
  758. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  759. package/dist/modules/workflows/backend/instances/[id]/page.js +5 -3
  760. package/dist/modules/workflows/backend/instances/[id]/page.js.map +2 -2
  761. package/dist/modules/workflows/backend/tasks/[id]/page.js +3 -1
  762. package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
  763. package/dist/modules/workflows/components/BusinessRulesSelector.js +5 -3
  764. package/dist/modules/workflows/components/BusinessRulesSelector.js.map +2 -2
  765. package/dist/modules/workflows/components/WorkflowSelector.js +5 -3
  766. package/dist/modules/workflows/components/WorkflowSelector.js.map +2 -2
  767. package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js +3 -1
  768. package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js.map +2 -2
  769. package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js +3 -1
  770. package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js.map +2 -2
  771. package/dist/modules/workflows/components/fields/WorkflowSelectorField.js +3 -1
  772. package/dist/modules/workflows/components/fields/WorkflowSelectorField.js.map +2 -2
  773. package/dist/modules/workflows/frontend/checkout-demo/page.js +8 -7
  774. package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
  775. package/dist/modules/workflows/lib/activity-executor.js +25 -21
  776. package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
  777. package/dist/modules/workflows/lib/activity-worker-handler.js +8 -15
  778. package/dist/modules/workflows/lib/activity-worker-handler.js.map +2 -2
  779. package/dist/modules/workflows/lib/code-registry.js +7 -7
  780. package/dist/modules/workflows/lib/code-registry.js.map +2 -2
  781. package/dist/modules/workflows/lib/compensation-handler.js +4 -2
  782. package/dist/modules/workflows/lib/compensation-handler.js.map +2 -2
  783. package/dist/modules/workflows/lib/edgeFormTransforms.js +3 -1
  784. package/dist/modules/workflows/lib/edgeFormTransforms.js.map +2 -2
  785. package/dist/modules/workflows/lib/event-trigger-service.js +5 -3
  786. package/dist/modules/workflows/lib/event-trigger-service.js.map +2 -2
  787. package/dist/modules/workflows/lib/nodeFormTransforms.js +3 -1
  788. package/dist/modules/workflows/lib/nodeFormTransforms.js.map +2 -2
  789. package/dist/modules/workflows/lib/seeds.js +16 -2
  790. package/dist/modules/workflows/lib/seeds.js.map +2 -2
  791. package/dist/modules/workflows/lib/signal-handler.js +3 -1
  792. package/dist/modules/workflows/lib/signal-handler.js.map +2 -2
  793. package/dist/modules/workflows/lib/start-validator.js +9 -3
  794. package/dist/modules/workflows/lib/start-validator.js.map +2 -2
  795. package/dist/modules/workflows/lib/step-handler.js +3 -1
  796. package/dist/modules/workflows/lib/step-handler.js.map +2 -2
  797. package/dist/modules/workflows/lib/task-handler.js +3 -1
  798. package/dist/modules/workflows/lib/task-handler.js.map +2 -2
  799. package/dist/modules/workflows/lib/transition-handler.js +5 -3
  800. package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
  801. package/dist/modules/workflows/lib/workflow-executor.js +27 -15
  802. package/dist/modules/workflows/lib/workflow-executor.js.map +2 -2
  803. package/dist/modules/workflows/subscribers/event-trigger.js +21 -18
  804. package/dist/modules/workflows/subscribers/event-trigger.js.map +2 -2
  805. package/dist/modules/workflows/subscribers/task-assigned-notification.js +3 -1
  806. package/dist/modules/workflows/subscribers/task-assigned-notification.js.map +2 -2
  807. package/dist/modules/workflows/workers/workflow-activities.worker.js +30 -20
  808. package/dist/modules/workflows/workers/workflow-activities.worker.js.map +2 -2
  809. package/package.json +7 -7
  810. package/src/bootstrap.ts +14 -11
  811. package/src/helpers/integration/queue-runner.ts +2 -2
  812. package/src/modules/api_keys/services/apiKeyService.ts +6 -3
  813. package/src/modules/attachments/api/image/[id]/[[...slug]]/route.ts +5 -2
  814. package/src/modules/attachments/api/library/[id]/route.ts +4 -1
  815. package/src/modules/attachments/api/route.ts +9 -6
  816. package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +6 -3
  817. package/src/modules/attachments/lib/assignmentDetails.ts +4 -1
  818. package/src/modules/attachments/lib/drivers/driverFactory.ts +4 -1
  819. package/src/modules/attachments/lib/ocrQueue.ts +11 -11
  820. package/src/modules/attachments/lib/ocrService.ts +7 -4
  821. package/src/modules/audit_logs/api/audit-logs/actions/redo/route.ts +4 -1
  822. package/src/modules/audit_logs/api/audit-logs/actions/undo/route.ts +4 -1
  823. package/src/modules/audit_logs/backend/audit-logs/page.tsx +4 -1
  824. package/src/modules/audit_logs/components/AuditLogsActions.tsx +5 -2
  825. package/src/modules/audit_logs/services/accessLogService.ts +5 -4
  826. package/src/modules/audit_logs/services/actionLogService.ts +5 -2
  827. package/src/modules/auth/api/profile/route.ts +5 -2
  828. package/src/modules/auth/api/reset/confirm.ts +4 -1
  829. package/src/modules/auth/api/reset.ts +5 -2
  830. package/src/modules/auth/api/roles/route.ts +4 -1
  831. package/src/modules/auth/api/sidebar/variants/route.ts +4 -2
  832. package/src/modules/auth/api/users/resend-invite/route.ts +5 -2
  833. package/src/modules/auth/api/users/route.ts +4 -1
  834. package/src/modules/auth/backend/auth/profile/page.tsx +4 -1
  835. package/src/modules/auth/backend/profile/change-password/page.tsx +4 -1
  836. package/src/modules/auth/backend/users/[id]/edit/page.tsx +6 -3
  837. package/src/modules/auth/backend/users/create/page.tsx +5 -2
  838. package/src/modules/auth/cli.ts +10 -0
  839. package/src/modules/auth/commands/users.ts +5 -2
  840. package/src/modules/auth/lib/consentIntegrity.ts +4 -4
  841. package/src/modules/auth/lib/setup-app.ts +10 -10
  842. package/src/modules/auth/lib/tenantAccess.ts +4 -1
  843. package/src/modules/auth/lib/tokenHash.ts +4 -4
  844. package/src/modules/business_rules/api/rules/route.ts +5 -2
  845. package/src/modules/business_rules/lib/expression-evaluator.ts +8 -6
  846. package/src/modules/business_rules/lib/rule-engine.ts +6 -3
  847. package/src/modules/business_rules/lib/rule-evaluator.ts +11 -11
  848. package/src/modules/business_rules/subscribers/crud-rule-trigger.ts +4 -1
  849. package/src/modules/business_rules/subscribers/rule-execution-failed-notification.ts +4 -1
  850. package/src/modules/catalog/ai-agents-context.ts +5 -5
  851. package/src/modules/catalog/ai-tools/_shared.ts +4 -1
  852. package/src/modules/catalog/ai-tools/authoring-pack.ts +4 -1
  853. package/src/modules/catalog/ai-tools/merchandising-pack.ts +4 -1
  854. package/src/modules/catalog/api/dictionaries/[key]/route.ts +4 -1
  855. package/src/modules/catalog/api/prices/route.ts +4 -1
  856. package/src/modules/catalog/api/products/route.ts +6 -3
  857. package/src/modules/catalog/api/settings/route.ts +5 -2
  858. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +15 -12
  859. package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +9 -6
  860. package/src/modules/catalog/backend/catalog/products/[productId]/variants/create/page.tsx +6 -3
  861. package/src/modules/catalog/backend/catalog/products/create/page.tsx +6 -6
  862. package/src/modules/catalog/backend/catalog/products/optionSchemaClient.ts +4 -1
  863. package/src/modules/catalog/components/PriceKindSettings.tsx +6 -3
  864. package/src/modules/catalog/components/UnitPriceDisplaySettings.tsx +5 -2
  865. package/src/modules/catalog/inbox-actions.ts +5 -2
  866. package/src/modules/catalog/seed/examples.ts +5 -5
  867. package/src/modules/catalog/subscribers/low-stock-notification.ts +4 -1
  868. package/src/modules/catalog/widgets/injection/product-seo/state.ts +4 -1
  869. package/src/modules/communication_channels/api/get/oauth/[provider]/callback/route.ts +13 -13
  870. package/src/modules/communication_channels/api/post/channels/[id]/import-history/route.ts +4 -1
  871. package/src/modules/communication_channels/api/post/channels/[id]/push/register/route.ts +4 -1
  872. package/src/modules/communication_channels/api/post/webhook/[provider]/route.ts +6 -3
  873. package/src/modules/communication_channels/api/post/webhooks/gmail/route.ts +7 -6
  874. package/src/modules/communication_channels/commands/connect-credential-channel.ts +5 -10
  875. package/src/modules/communication_channels/commands/delete-channel.ts +4 -5
  876. package/src/modules/communication_channels/commands/deliver-outbound-message.ts +5 -5
  877. package/src/modules/communication_channels/commands/disconnect-channel.ts +4 -5
  878. package/src/modules/communication_channels/commands/ingest-inbound-message.ts +6 -12
  879. package/src/modules/communication_channels/commands/push-unregister.ts +4 -3
  880. package/src/modules/communication_channels/commands/reassign-conversation.ts +6 -3
  881. package/src/modules/communication_channels/lib/dead-letter.ts +4 -5
  882. package/src/modules/communication_channels/lib/email-mime.ts +5 -6
  883. package/src/modules/communication_channels/lib/oauth-client-config.ts +7 -3
  884. package/src/modules/communication_channels/lib/send-as-user.ts +4 -1
  885. package/src/modules/communication_channels/lib/thread-token.ts +5 -2
  886. package/src/modules/communication_channels/setup.ts +4 -4
  887. package/src/modules/communication_channels/workers/channel-import-history.ts +5 -8
  888. package/src/modules/communication_channels/workers/gmail-history-sync.ts +9 -18
  889. package/src/modules/communication_channels/workers/gmail-renew-watch.ts +6 -9
  890. package/src/modules/communication_channels/workers/outbound-delivery.ts +7 -12
  891. package/src/modules/communication_channels/workers/poll-channel.ts +8 -15
  892. package/src/modules/communication_channels/workers/poll-tick.ts +6 -6
  893. package/src/modules/communication_channels/workers/reaction-processor.ts +6 -9
  894. package/src/modules/configs/api/cache/route.ts +5 -2
  895. package/src/modules/configs/api/system-status/route.ts +5 -2
  896. package/src/modules/configs/api/upgrade-actions/route.ts +5 -2
  897. package/src/modules/configs/components/ModuleTelemetryPanel.tsx +4 -1
  898. package/src/modules/configs/lib/touchGeneratedBarrels.ts +1 -1
  899. package/src/modules/configs/services/upgradeActionsService.ts +7 -3
  900. package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +4 -1
  901. package/src/modules/currencies/lib/exchangeRateFormConfig.ts +4 -1
  902. package/src/modules/currencies/services/providers/nbp.ts +7 -4
  903. package/src/modules/currencies/services/providers/raiffeisen.ts +8 -7
  904. package/src/modules/customer_accounts/api/domain-resolve/all.ts +7 -5
  905. package/src/modules/customer_accounts/api/signup.ts +5 -2
  906. package/src/modules/customer_accounts/lib/customerAuthServer.ts +4 -1
  907. package/src/modules/customer_accounts/subscribers/autoLinkCrm.ts +4 -1
  908. package/src/modules/customer_accounts/subscribers/autoLinkCrmReverse.ts +4 -1
  909. package/src/modules/customer_accounts/subscribers/unlinkOnCompanyDelete.ts +4 -1
  910. package/src/modules/customer_accounts/subscribers/unlinkOnPersonDelete.ts +4 -1
  911. package/src/modules/customers/ai-agents-context.ts +5 -5
  912. package/src/modules/customers/api/activities/route.ts +7 -4
  913. package/src/modules/customers/api/comments/route.ts +4 -1
  914. package/src/modules/customers/api/companies/[id]/people/route.ts +4 -1
  915. package/src/modules/customers/api/companies/[id]/route.ts +6 -3
  916. package/src/modules/customers/api/companies/route.ts +6 -3
  917. package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +4 -1
  918. package/src/modules/customers/api/dashboard/widgets/new-customers/route.ts +4 -1
  919. package/src/modules/customers/api/dashboard/widgets/new-deals/route.ts +4 -1
  920. package/src/modules/customers/api/dashboard/widgets/next-interactions/route.ts +4 -1
  921. package/src/modules/customers/api/deals/[id]/companies/route.ts +4 -1
  922. package/src/modules/customers/api/deals/[id]/people/route.ts +4 -1
  923. package/src/modules/customers/api/deals/aggregate/route.ts +4 -1
  924. package/src/modules/customers/api/deals/bulk-update-owner/route.ts +8 -5
  925. package/src/modules/customers/api/deals/bulk-update-stage/route.ts +8 -5
  926. package/src/modules/customers/api/deals/route.ts +4 -1
  927. package/src/modules/customers/api/deals/summary/route.ts +4 -1
  928. package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +5 -2
  929. package/src/modules/customers/api/dictionaries/[kind]/route.ts +6 -3
  930. package/src/modules/customers/api/dictionaries/cache.ts +4 -1
  931. package/src/modules/customers/api/dictionaries/context.ts +4 -1
  932. package/src/modules/customers/api/dictionaries/currency/route.ts +4 -1
  933. package/src/modules/customers/api/dictionaries/kind-settings/route.ts +5 -2
  934. package/src/modules/customers/api/entity-roles-factory.ts +8 -5
  935. package/src/modules/customers/api/interactions/cancel/route.ts +4 -1
  936. package/src/modules/customers/api/interactions/complete/route.ts +4 -1
  937. package/src/modules/customers/api/interactions/conflicts/route.ts +4 -1
  938. package/src/modules/customers/api/interactions/counts/route.ts +4 -1
  939. package/src/modules/customers/api/interactions/route.ts +8 -4
  940. package/src/modules/customers/api/interactions/tasks/route.ts +4 -1
  941. package/src/modules/customers/api/labels/assign/route.ts +4 -1
  942. package/src/modules/customers/api/labels/route.ts +7 -3
  943. package/src/modules/customers/api/labels/unassign/route.ts +4 -1
  944. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +4 -1
  945. package/src/modules/customers/api/people/[id]/route.ts +6 -3
  946. package/src/modules/customers/api/people/route.ts +6 -3
  947. package/src/modules/customers/api/pipeline-stages/reorder/route.ts +4 -1
  948. package/src/modules/customers/api/pipeline-stages/route.ts +7 -4
  949. package/src/modules/customers/api/pipelines/route.ts +7 -4
  950. package/src/modules/customers/api/settings/address-format/route.ts +5 -2
  951. package/src/modules/customers/api/settings/dictionary-sort-modes/route.ts +5 -2
  952. package/src/modules/customers/api/settings/stuck-threshold/route.ts +5 -2
  953. package/src/modules/customers/api/tags/assign/route.ts +4 -1
  954. package/src/modules/customers/api/tags/unassign/route.ts +4 -1
  955. package/src/modules/customers/api/todos/route.ts +7 -4
  956. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +6 -3
  957. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +4 -1
  958. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.ts +4 -1
  959. package/src/modules/customers/backend/customers/deals/map/components/DealsMapCanvasImpl.tsx +5 -3
  960. package/src/modules/customers/backend/customers/deals/page.tsx +5 -2
  961. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +6 -3
  962. package/src/modules/customers/commands/deals.ts +4 -1
  963. package/src/modules/customers/commands/dictionaries.ts +4 -1
  964. package/src/modules/customers/commands/interactions.ts +5 -2
  965. package/src/modules/customers/commands/shared.ts +5 -2
  966. package/src/modules/customers/commands/todos.ts +4 -1
  967. package/src/modules/customers/components/DictionarySettings.tsx +6 -3
  968. package/src/modules/customers/components/DictionarySortSettings.tsx +4 -1
  969. package/src/modules/customers/components/detail/ActivitiesCard.tsx +4 -1
  970. package/src/modules/customers/components/detail/ActivitiesDayStrip.tsx +4 -1
  971. package/src/modules/customers/components/detail/ActivitiesSection.tsx +7 -4
  972. package/src/modules/customers/components/detail/ActivityCard.tsx +4 -1
  973. package/src/modules/customers/components/detail/ChangelogTab.tsx +4 -1
  974. package/src/modules/customers/components/detail/CompanyCard.tsx +4 -1
  975. package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +4 -1
  976. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +4 -1
  977. package/src/modules/customers/components/detail/InlineActivityComposer.tsx +4 -1
  978. package/src/modules/customers/components/detail/ManageTagsDialog.tsx +4 -1
  979. package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +6 -3
  980. package/src/modules/customers/components/detail/RolesSection.tsx +5 -2
  981. package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +6 -3
  982. package/src/modules/customers/components/linking/LinkEntityDialog.tsx +5 -2
  983. package/src/modules/customers/inbox-actions.ts +4 -1
  984. package/src/modules/customers/lib/bulkDeals.ts +4 -1
  985. package/src/modules/customers/lib/dealClosureNotification.ts +5 -2
  986. package/src/modules/customers/lib/dealStageTransitionTable.ts +4 -1
  987. package/src/modules/customers/lib/interactionFeatureFlags.ts +5 -1
  988. package/src/modules/customers/lib/todoCompatibility.ts +4 -1
  989. package/src/modules/customers/search.ts +15 -7
  990. package/src/modules/customers/widgets/dashboard/customer-todos/widget.client.tsx +4 -1
  991. package/src/modules/customers/widgets/dashboard/new-customers/widget.client.tsx +4 -1
  992. package/src/modules/customers/widgets/dashboard/new-deals/widget.client.tsx +4 -1
  993. package/src/modules/customers/widgets/dashboard/next-interactions/widget.client.tsx +4 -1
  994. package/src/modules/dashboards/api/widgets/data/batch/route.ts +4 -1
  995. package/src/modules/dashboards/api/widgets/data/route.ts +4 -1
  996. package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +6 -3
  997. package/src/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.tsx +4 -1
  998. package/src/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.client.tsx +4 -1
  999. package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.tsx +4 -1
  1000. package/src/modules/dashboards/widgets/dashboard/orders-kpi/widget.client.tsx +4 -1
  1001. package/src/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.tsx +4 -1
  1002. package/src/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.tsx +4 -1
  1003. package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.tsx +4 -1
  1004. package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.tsx +4 -1
  1005. package/src/modules/dashboards/widgets/dashboard/top-customers/widget.client.tsx +4 -1
  1006. package/src/modules/dashboards/widgets/dashboard/top-products/widget.client.tsx +4 -1
  1007. package/src/modules/data_sync/api/run.ts +4 -1
  1008. package/src/modules/data_sync/backend/data-sync/runs/[id]/page.tsx +3 -1
  1009. package/src/modules/data_sync/lib/adapter-registry.ts +16 -4
  1010. package/src/modules/data_sync/lib/sync-engine.ts +31 -2
  1011. package/src/modules/data_sync/workers/sync-export.ts +4 -1
  1012. package/src/modules/data_sync/workers/sync-import.ts +4 -1
  1013. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +5 -2
  1014. package/src/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.ts +4 -1
  1015. package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +5 -2
  1016. package/src/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.ts +4 -1
  1017. package/src/modules/dictionaries/api/[dictionaryId]/route.ts +6 -3
  1018. package/src/modules/dictionaries/api/context.ts +4 -1
  1019. package/src/modules/dictionaries/api/route.ts +5 -2
  1020. package/src/modules/dictionaries/components/DictionariesManager.tsx +6 -3
  1021. package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +5 -2
  1022. package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +5 -2
  1023. package/src/modules/dictionaries/components/DictionarySelectControl.tsx +4 -1
  1024. package/src/modules/dictionaries/fields/dictionary.tsx +4 -1
  1025. package/src/modules/directory/api/organization-branding/route.ts +4 -1
  1026. package/src/modules/directory/api/organization-switcher/route.ts +4 -1
  1027. package/src/modules/directory/commands/tenants.ts +6 -3
  1028. package/src/modules/directory/utils/organizationScope.ts +7 -4
  1029. package/src/modules/entities/api/definitions.cache.ts +4 -1
  1030. package/src/modules/entities/api/definitions.ts +8 -5
  1031. package/src/modules/entities/api/records.ts +5 -2
  1032. package/src/modules/entities/components/EncryptionManager.tsx +4 -1
  1033. package/src/modules/entities/lib/makeActivityRoute.ts +4 -1
  1034. package/src/modules/feature_toggles/api/overrides/route.ts +4 -1
  1035. package/src/modules/feature_toggles/lib/feature-flag-check.ts +6 -9
  1036. package/src/modules/inbox_ops/api/emails/[id]/reprocess/route.ts +5 -2
  1037. package/src/modules/inbox_ops/api/emails/[id]/route.ts +5 -2
  1038. package/src/modules/inbox_ops/api/emails/route.ts +4 -1
  1039. package/src/modules/inbox_ops/api/extract/route.ts +4 -1
  1040. package/src/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.ts +4 -1
  1041. package/src/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.ts +5 -2
  1042. package/src/modules/inbox_ops/api/proposals/counts/route.ts +5 -2
  1043. package/src/modules/inbox_ops/api/proposals/route.ts +4 -1
  1044. package/src/modules/inbox_ops/api/routeHelpers.ts +4 -1
  1045. package/src/modules/inbox_ops/api/settings/route.ts +4 -1
  1046. package/src/modules/inbox_ops/api/webhook/inbound.ts +8 -5
  1047. package/src/modules/inbox_ops/lib/cache.ts +5 -2
  1048. package/src/modules/inbox_ops/lib/catalogLookup.ts +4 -1
  1049. package/src/modules/inbox_ops/lib/eventBus.ts +4 -4
  1050. package/src/modules/inbox_ops/lib/messagesIntegration.ts +5 -8
  1051. package/src/modules/inbox_ops/subscribers/executionAuditor.ts +5 -1
  1052. package/src/modules/inbox_ops/subscribers/extractionWorker.ts +11 -8
  1053. package/src/modules/inbox_ops/subscribers/proposalNotifier.ts +4 -1
  1054. package/src/modules/messages/api/[id]/route.ts +4 -4
  1055. package/src/modules/messages/commands/actions.ts +4 -1
  1056. package/src/modules/messages/components/MessagesInboxPageClient.tsx +4 -1
  1057. package/src/modules/messages/lib/email-sender.ts +4 -7
  1058. package/src/modules/messages/lib/message-objects-registry.ts +4 -1
  1059. package/src/modules/messages/lib/message-types-registry.ts +4 -1
  1060. package/src/modules/messages/workers/send-email.worker.ts +7 -4
  1061. package/src/modules/notifications/lib/notificationMapper.ts +4 -4
  1062. package/src/modules/notifications/lib/notificationService.ts +4 -5
  1063. package/src/modules/notifications/subscribers/deliver-notification.ts +9 -14
  1064. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +4 -1
  1065. package/src/modules/perspectives/services/perspectiveService.ts +4 -3
  1066. package/src/modules/planner/api/access.ts +4 -3
  1067. package/src/modules/planner/api/availability-date-specific.ts +4 -1
  1068. package/src/modules/planner/api/availability-weekly.ts +4 -1
  1069. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +5 -2
  1070. package/src/modules/planner/components/AvailabilityRulesEditor.tsx +4 -1
  1071. package/src/modules/progress/api/jobs/route.ts +4 -1
  1072. package/src/modules/query_index/components/QueryIndexesTable.tsx +6 -3
  1073. package/src/modules/query_index/lib/batch.ts +5 -2
  1074. package/src/modules/query_index/lib/coverage.ts +4 -1
  1075. package/src/modules/query_index/lib/engine.ts +14 -17
  1076. package/src/modules/query_index/lib/reindexer.ts +9 -6
  1077. package/src/modules/query_index/lib/search-tokens.ts +4 -2
  1078. package/src/modules/query_index/subscribers/coverage_refresh.ts +4 -1
  1079. package/src/modules/resources/api/comments.ts +4 -1
  1080. package/src/modules/resources/api/resources/tags/assign/route.ts +4 -1
  1081. package/src/modules/resources/api/resources/tags/unassign/route.ts +4 -1
  1082. package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +4 -1
  1083. package/src/modules/resources/backend/resources/resource-types/page.tsx +5 -2
  1084. package/src/modules/resources/commands/activities.ts +5 -4
  1085. package/src/modules/resources/commands/comments.ts +6 -4
  1086. package/src/modules/resources/commands/shared.ts +36 -0
  1087. package/src/modules/sales/api/channels/route.ts +4 -1
  1088. package/src/modules/sales/api/document-history/route.ts +4 -1
  1089. package/src/modules/sales/api/document-numbers/route.ts +4 -1
  1090. package/src/modules/sales/api/quotes/accept/route.ts +5 -2
  1091. package/src/modules/sales/api/quotes/convert/route.ts +4 -1
  1092. package/src/modules/sales/api/quotes/public/[token]/route.ts +4 -1
  1093. package/src/modules/sales/api/quotes/send/route.ts +4 -1
  1094. package/src/modules/sales/api/returns/[id]/route.ts +4 -1
  1095. package/src/modules/sales/api/settings/document-numbers/route.ts +5 -2
  1096. package/src/modules/sales/api/settings/order-editing/route.ts +5 -2
  1097. package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +4 -1
  1098. package/src/modules/sales/backend/sales/channels/offers/page.tsx +7 -4
  1099. package/src/modules/sales/backend/sales/channels/page.tsx +5 -2
  1100. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +21 -18
  1101. package/src/modules/sales/commands/documents.ts +5 -8
  1102. package/src/modules/sales/commands/payments.ts +4 -1
  1103. package/src/modules/sales/commands/shipments.ts +4 -2
  1104. package/src/modules/sales/components/AdjustmentKindSettings.tsx +6 -3
  1105. package/src/modules/sales/components/DocumentNumberSettings.tsx +5 -2
  1106. package/src/modules/sales/components/OrderEditingSettings.tsx +5 -2
  1107. package/src/modules/sales/components/PaymentMethodsSettings.tsx +6 -3
  1108. package/src/modules/sales/components/ShippingMethodsSettings.tsx +6 -3
  1109. package/src/modules/sales/components/StatusSettings.tsx +6 -3
  1110. package/src/modules/sales/components/TaxRatesSettings.tsx +6 -3
  1111. package/src/modules/sales/components/channels/ChannelOfferForm.tsx +17 -14
  1112. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +5 -2
  1113. package/src/modules/sales/components/documents/AddressesSection.tsx +6 -3
  1114. package/src/modules/sales/components/documents/AdjustmentDialog.tsx +4 -1
  1115. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +6 -3
  1116. package/src/modules/sales/components/documents/ItemsSection.tsx +7 -4
  1117. package/src/modules/sales/components/documents/LineItemDialog.tsx +9 -6
  1118. package/src/modules/sales/components/documents/PaymentDialog.tsx +6 -3
  1119. package/src/modules/sales/components/documents/PaymentsSection.tsx +5 -2
  1120. package/src/modules/sales/components/documents/SalesDocumentForm.tsx +15 -12
  1121. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +6 -3
  1122. package/src/modules/sales/components/documents/ShipmentDialog.tsx +10 -7
  1123. package/src/modules/sales/components/documents/ShipmentsSection.tsx +5 -2
  1124. package/src/modules/sales/frontend/quote/[token]/page.tsx +5 -2
  1125. package/src/modules/sales/seed/examples.ts +8 -9
  1126. package/src/modules/sales/subscribers/quote-expiring-notification.ts +4 -1
  1127. package/src/modules/sales/subscribers/reconcileOnAddressDelete.ts +4 -1
  1128. package/src/modules/sales/subscribers/reconcileOnCompanyDelete.ts +4 -1
  1129. package/src/modules/sales/subscribers/reconcileOnCustomerDelete.ts +4 -1
  1130. package/src/modules/sales/widgets/dashboard/makeDashboardWidgetRoute.ts +6 -3
  1131. package/src/modules/sales/widgets/dashboard/new-orders/widget.client.tsx +274 -271
  1132. package/src/modules/sales/widgets/dashboard/new-quotes/widget.client.tsx +280 -277
  1133. package/src/modules/shipping_carriers/api/tracking/route.ts +5 -1
  1134. package/src/modules/shipping_carriers/api/webhook/[provider]/route.ts +4 -1
  1135. package/src/modules/shipping_carriers/lib/shipping-service.ts +47 -22
  1136. package/src/modules/shipping_carriers/lib/upstream-error-response.ts +4 -1
  1137. package/src/modules/shipping_carriers/workers/webhook-processor.ts +4 -5
  1138. package/src/modules/staff/api/comments.ts +4 -1
  1139. package/src/modules/staff/api/leave-requests/accept/route.ts +4 -1
  1140. package/src/modules/staff/api/leave-requests/reject/route.ts +4 -1
  1141. package/src/modules/staff/api/team-members/assignable/route.ts +4 -1
  1142. package/src/modules/staff/api/team-members/self/route.ts +5 -2
  1143. package/src/modules/staff/api/team-members/tags/assign/route.ts +4 -1
  1144. package/src/modules/staff/api/team-members/tags/unassign/route.ts +4 -1
  1145. package/src/modules/staff/api/timesheets/my-projects/[projectId]/route.ts +4 -1
  1146. package/src/modules/staff/api/timesheets/my-projects/route.ts +4 -1
  1147. package/src/modules/staff/api/timesheets/projects/kpis/route.ts +4 -1
  1148. package/src/modules/staff/api/timesheets/time-entries/[id]/segments/route.ts +4 -1
  1149. package/src/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.ts +5 -2
  1150. package/src/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.ts +5 -2
  1151. package/src/modules/staff/api/timesheets/time-entries/bulk/route.ts +4 -1
  1152. package/src/modules/staff/api/timesheets/time-entries/start-timer/route.ts +4 -1
  1153. package/src/modules/staff/backend/staff/team-members/page.tsx +5 -2
  1154. package/src/modules/staff/backend/staff/team-roles/page.tsx +5 -2
  1155. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +5 -2
  1156. package/src/modules/staff/backend/staff/teams/page.tsx +5 -2
  1157. package/src/modules/staff/backend/staff/timesheets/page.tsx +8 -5
  1158. package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +4 -1
  1159. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +5 -2
  1160. package/src/modules/staff/commands/timesheets-entries.ts +4 -1
  1161. package/src/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.client.tsx +4 -1
  1162. package/src/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.client.tsx +6 -3
  1163. package/src/modules/sync_excel/api/import/route.ts +4 -1
  1164. package/src/modules/translations/api/[entityType]/[entityId]/route.ts +6 -3
  1165. package/src/modules/translations/api/get/locales.ts +4 -1
  1166. package/src/modules/translations/api/put/locales.ts +4 -1
  1167. package/src/modules/translations/components/TranslationManager.tsx +4 -1
  1168. package/src/modules/translations/subscribers/cleanup.ts +4 -1
  1169. package/src/modules/workflows/api/definitions/[id]/customize/route.ts +5 -2
  1170. package/src/modules/workflows/api/definitions/[id]/reset-to-code/route.ts +5 -2
  1171. package/src/modules/workflows/api/definitions/[id]/route.ts +7 -4
  1172. package/src/modules/workflows/api/definitions/route.ts +5 -2
  1173. package/src/modules/workflows/api/events/[id]/route.ts +4 -1
  1174. package/src/modules/workflows/api/events/route.ts +4 -1
  1175. package/src/modules/workflows/api/instances/[id]/advance/route.ts +4 -1
  1176. package/src/modules/workflows/api/instances/[id]/cancel/route.ts +4 -1
  1177. package/src/modules/workflows/api/instances/[id]/events/route.ts +4 -1
  1178. package/src/modules/workflows/api/instances/[id]/retry/route.ts +4 -1
  1179. package/src/modules/workflows/api/instances/[id]/route.ts +4 -1
  1180. package/src/modules/workflows/api/instances/[id]/signal/route.ts +6 -7
  1181. package/src/modules/workflows/api/instances/route.ts +6 -3
  1182. package/src/modules/workflows/api/instances/validate-start/route.ts +4 -1
  1183. package/src/modules/workflows/api/signals/route.ts +4 -1
  1184. package/src/modules/workflows/api/tasks/[id]/claim/route.ts +4 -1
  1185. package/src/modules/workflows/api/tasks/[id]/complete/route.ts +4 -1
  1186. package/src/modules/workflows/api/tasks/[id]/route.ts +4 -1
  1187. package/src/modules/workflows/api/tasks/route.ts +4 -1
  1188. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +5 -2
  1189. package/src/modules/workflows/backend/instances/[id]/page.tsx +6 -3
  1190. package/src/modules/workflows/backend/tasks/[id]/page.tsx +4 -1
  1191. package/src/modules/workflows/components/BusinessRulesSelector.tsx +6 -3
  1192. package/src/modules/workflows/components/WorkflowSelector.tsx +6 -3
  1193. package/src/modules/workflows/components/fields/BusinessRuleConditionsEditor.tsx +4 -1
  1194. package/src/modules/workflows/components/fields/StartPreConditionsEditor.tsx +4 -1
  1195. package/src/modules/workflows/components/fields/WorkflowSelectorField.tsx +4 -1
  1196. package/src/modules/workflows/frontend/checkout-demo/page.tsx +9 -7
  1197. package/src/modules/workflows/lib/activity-executor.ts +26 -21
  1198. package/src/modules/workflows/lib/activity-worker-handler.ts +9 -15
  1199. package/src/modules/workflows/lib/code-registry.ts +8 -7
  1200. package/src/modules/workflows/lib/compensation-handler.ts +5 -2
  1201. package/src/modules/workflows/lib/edgeFormTransforms.ts +4 -1
  1202. package/src/modules/workflows/lib/event-trigger-service.ts +6 -3
  1203. package/src/modules/workflows/lib/nodeFormTransforms.ts +4 -1
  1204. package/src/modules/workflows/lib/seeds.ts +17 -2
  1205. package/src/modules/workflows/lib/signal-handler.ts +4 -1
  1206. package/src/modules/workflows/lib/start-validator.ts +10 -3
  1207. package/src/modules/workflows/lib/step-handler.ts +4 -1
  1208. package/src/modules/workflows/lib/task-handler.ts +4 -1
  1209. package/src/modules/workflows/lib/transition-handler.ts +6 -3
  1210. package/src/modules/workflows/lib/workflow-executor.ts +28 -15
  1211. package/src/modules/workflows/subscribers/event-trigger.ts +22 -24
  1212. package/src/modules/workflows/subscribers/task-assigned-notification.ts +4 -1
  1213. package/src/modules/workflows/workers/workflow-activities.worker.ts +31 -20
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/catalog/seed/examples.ts"],
4
- "sourcesContent": ["import { randomUUID } from \"node:crypto\";\nimport path from \"node:path\";\nimport { promises as fs } from \"node:fs\";\nimport type { EntityManager } from \"@mikro-orm/postgresql\";\nimport type { AwilixContainer } from \"awilix\";\nimport { SalesChannel } from \"@open-mercato/core/modules/sales/data/entities\";\nimport {\n CatalogOffer,\n CatalogPriceKind,\n CatalogProduct,\n CatalogProductCategory,\n CatalogProductCategoryAssignment,\n CatalogProductPrice,\n CatalogProductVariant,\n} from \"../data/entities\";\nimport { DefaultDataEngine } from \"@open-mercato/shared/lib/data/engine\";\nimport {\n ensureCustomFieldDefinitions,\n type FieldSetInput,\n} from \"@open-mercato/core/modules/entities/lib/field-definitions\";\nimport { CustomFieldEntityConfig } from \"@open-mercato/core/modules/entities/data/entities\";\nimport { rebuildCategoryHierarchyForOrganization } from \"../lib/categoryHierarchy\";\nimport { defineFields, cf } from \"@open-mercato/shared/modules/dsl\";\nimport { E } from \"#generated/entities.ids.generated\";\nimport { SalesTaxRate } from \"@open-mercato/core/modules/sales/data/entities\";\nimport {\n Attachment,\n AttachmentPartition,\n} from \"@open-mercato/core/modules/attachments/data/entities\";\nimport {\n ensureDefaultPartitions,\n resolveDefaultPartitionCode,\n} from \"@open-mercato/core/modules/attachments/lib/partitions\";\nimport { storePartitionFile } from \"@open-mercato/core/modules/attachments/lib/storage\";\nimport { mergeAttachmentMetadata } from \"@open-mercato/core/modules/attachments/lib/metadata\";\nimport {\n buildAttachmentFileUrl,\n buildAttachmentImageUrl,\n slugifyAttachmentFileName,\n} from \"@open-mercato/core/modules/attachments/lib/imageUrls\";\nimport { canonicalizeUnitCode } from \"../lib/unitCodes\";\n\ntype SeedScope = { tenantId: string; organizationId: string };\n\nconst EXAMPLES_MEDIA_ROOT = path.join(process.cwd(), \"public\", \"examples\");\n\nfunction detectMimeType(fileName: string): string {\n const ext = fileName.toLowerCase().split(\".\").pop() || \"\";\n if (ext === \"png\") return \"image/png\";\n if (ext === \"jpg\" || ext === \"jpeg\") return \"image/jpeg\";\n if (ext === \"webp\") return \"image/webp\";\n return \"application/octet-stream\";\n}\n\nasync function ensureAttachmentPartition(\n em: EntityManager,\n code: string,\n): Promise<AttachmentPartition> {\n let partition = await em.findOne(AttachmentPartition, { code });\n if (!partition) {\n await ensureDefaultPartitions(em);\n partition = await em.findOne(AttachmentPartition, { code });\n }\n if (!partition) {\n throw new Error(`Attachment partition \"${code}\" is not configured.`);\n }\n return partition;\n}\n\nasync function attachMediaFromExamples(\n em: EntityManager,\n scope: SeedScope,\n entityId: string,\n recordId: string,\n mediaSeeds?: MediaSeed[],\n): Promise<Array<{ id: string; imageUrl: string }>> {\n if (!mediaSeeds?.length) return [];\n const partitionCode = resolveDefaultPartitionCode(entityId);\n const partition = await ensureAttachmentPartition(em, partitionCode);\n const results: Array<{ id: string; imageUrl: string }> = [];\n for (const media of mediaSeeds) {\n const sourcePath = path.join(EXAMPLES_MEDIA_ROOT, media.file);\n let buffer: Buffer;\n try {\n buffer = await fs.readFile(sourcePath);\n } catch (error) {\n console.warn(`[catalog.seed] Example media missing: ${sourcePath}`);\n continue;\n }\n const stored = await storePartitionFile({\n partitionCode: partition.code,\n orgId: scope.organizationId,\n tenantId: scope.tenantId,\n fileName: media.file,\n buffer,\n });\n const attachmentId = randomUUID();\n const slug = slugifyAttachmentFileName(media.file, \"media\");\n const metadata = mergeAttachmentMetadata(null, {\n assignments: [{ type: entityId, id: recordId }],\n });\n const attachment = em.create(Attachment, {\n id: attachmentId,\n entityId,\n recordId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n partitionCode: partition.code,\n fileName: media.file,\n mimeType: detectMimeType(media.file),\n fileSize: buffer.length,\n storageDriver: partition.storageDriver || \"local\",\n storagePath: stored.storagePath,\n storageMetadata: metadata,\n url: buildAttachmentFileUrl(attachmentId),\n });\n em.persist(attachment);\n results.push({\n id: attachmentId,\n imageUrl: buildAttachmentImageUrl(attachmentId, { slug }),\n });\n }\n return results;\n}\n\nconst PRODUCT_FIELDSETS = [\n {\n code: \"fashion_mens_footwear\",\n label: \"Fashion \u00B7 Men \u00B7 Footwear\",\n icon: \"carbon:sneaker\",\n description:\n \"Material, construction, and care metadata for men\u2019s performance footwear.\",\n groups: [\n { code: \"identity\", title: \"Identity\" },\n { code: \"materials\", title: \"Materials & Build\" },\n { code: \"care\", title: \"Care instructions\" },\n ],\n },\n {\n code: \"fashion_womens_dresses\",\n label: \"Fashion \u00B7 Women \u00B7 Dresses & Jumpsuits\",\n icon: \"solar:dress-linear\",\n description: \"Silhouette, fabric, and care metadata for womenswear.\",\n groups: [\n { code: \"identity\", title: \"Identity\" },\n { code: \"materials\", title: \"Materials\" },\n { code: \"fit\", title: \"Fit & Length\" },\n { code: \"care\", title: \"Care instructions\" },\n ],\n },\n {\n code: \"service_schedule\",\n label: \"Services \u00B7 Scheduling\",\n icon: \"solar:calendar-linear\",\n description:\n \"Scheduling, preparation, and delivery metadata for service offerings.\",\n groups: [\n { code: \"identity\", title: \"Identity\" },\n { code: \"timing\", title: \"Timing rules\" },\n { code: \"resources\", title: \"Resources & Delivery\" },\n ],\n },\n] as const;\n\nconst VARIANT_FIELDSETS = [\n {\n code: \"fashion_mens_footwear\",\n label: \"Fashion \u00B7 Men \u00B7 Footwear\",\n icon: \"carbon:sneaker\",\n description: \"Variant-level sizing metadata for men\u2019s footwear.\",\n groups: [\n { code: \"fit\", title: \"Fit\" },\n { code: \"finish\", title: \"Finish\" },\n ],\n },\n {\n code: \"fashion_womens_dresses\",\n label: \"Fashion \u00B7 Women \u00B7 Dresses & Jumpsuits\",\n icon: \"solar:dress-linear\",\n description: \"Variant-level sizing metadata for womenswear.\",\n groups: [\n { code: \"fit\", title: \"Fit\" },\n { code: \"finish\", title: \"Finish\" },\n ],\n },\n {\n code: \"service_schedule\",\n label: \"Services \u00B7 Scheduling\",\n icon: \"solar:calendar-linear\",\n description:\n \"Provider, duration, and environment metadata for service slots.\",\n groups: [\n { code: \"provider\", title: \"Provider\" },\n { code: \"environment\", title: \"Environment\" },\n ],\n },\n] as const;\n\nconst CUSTOM_FIELD_SETS: FieldSetInput[] = [\n defineFields(E.catalog.catalog_product, [\n cf.text(\"style_code\", {\n label: \"Style code\",\n description: \"Reference code shared with merchandising teams.\",\n filterable: true,\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"identity\" },\n }),\n cf.select(\n \"upper_material\",\n [\"engineered_knit\", \"full_grain_leather\", \"recycled_mesh\"],\n {\n label: \"Upper material\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"materials\" },\n filterable: true,\n },\n ),\n cf.select(\"cushioning_profile\", [\"responsive\", \"plush\", \"stability\"], {\n label: \"Cushioning profile\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"materials\" },\n }),\n cf.multiline(\"care_notes\", {\n label: \"Care notes\",\n editor: \"markdown\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"care\" },\n }),\n ]),\n defineFields(E.catalog.catalog_product, [\n cf.select(\"silhouette\", [\"wrap\", \"column\", \"fit_and_flare\", \"jumpsuit\"], {\n label: \"Silhouette\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"identity\" },\n filterable: true,\n }),\n cf.select(\"fabric_mix\", [\"silk_blend\", \"recycled_poly\", \"linen\", \"cupro\"], {\n label: \"Fabric mix\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"materials\" },\n }),\n cf.select(\"occasion_ready\", [\"daytime\", \"evening\", \"resort\"], {\n label: \"Occasion\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"fit\" },\n }),\n cf.multiline(\"finishing_details\", {\n label: \"Finishing details\",\n editor: \"markdown\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"care\" },\n }),\n ]),\n defineFields(E.catalog.catalog_product_variant, [\n cf.integer(\"shoe_size\", {\n label: \"US size\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"fit\" },\n filterable: true,\n }),\n cf.select(\"shoe_width\", [\"B\", \"D\", \"EE\"], {\n label: \"Width\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"fit\" },\n }),\n cf.text(\"colorway\", {\n label: \"Colorway\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"finish\" },\n }),\n ]),\n defineFields(E.catalog.catalog_product_variant, [\n cf.integer(\"numeric_size\", {\n label: \"Numeric size\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"fit\" },\n }),\n cf.select(\"length_profile\", [\"mini\", \"midi\", \"maxi\"], {\n label: \"Length\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"fit\" },\n }),\n cf.text(\"color_story\", {\n label: \"Color story\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"finish\" },\n }),\n ]),\n defineFields(E.catalog.catalog_product, [\n cf.integer(\"service_duration_minutes\", {\n label: \"Duration (minutes)\",\n description: \"Length of a single service slot.\",\n fieldset: \"service_schedule\",\n group: { code: \"timing\" },\n filterable: true,\n required: true,\n }),\n cf.integer(\"service_buffer_minutes\", {\n label: \"Buffer between appointments\",\n description:\n \"Minimum downtime between consecutive service slots (minutes).\",\n fieldset: \"service_schedule\",\n group: { code: \"timing\" },\n }),\n cf.text(\"service_location\", {\n label: \"Location / Room\",\n description: \"Where the service is delivered.\",\n fieldset: \"service_schedule\",\n group: { code: \"identity\" },\n }),\n cf.select(\n \"service_resources\",\n [\"stylist\", \"therapist\", \"treatment_room\", \"wash_station\", \"steam_room\"],\n {\n label: \"Required resources\",\n description: \"Staff or rooms required to perform the service.\",\n fieldset: \"service_schedule\",\n group: { code: \"resources\" },\n multi: true,\n },\n ),\n cf.boolean(\"service_remote_available\", {\n label: \"Remote session available\",\n description:\n \"Indicates whether the service can be performed remotely or virtually.\",\n fieldset: \"service_schedule\",\n group: { code: \"resources\" },\n defaultValue: false,\n }),\n ]),\n defineFields(E.catalog.catalog_product_variant, [\n cf.select(\"provider_level\", [\"junior\", \"senior\", \"master\"], {\n label: \"Provider level\",\n description: \"Seniority of the assigned specialist.\",\n fieldset: \"service_schedule\",\n group: { code: \"provider\" },\n filterable: true,\n }),\n cf.text(\"staff_member\", {\n label: \"Staff member\",\n description:\n \"Optional name of the staff member who usually delivers this variant.\",\n fieldset: \"service_schedule\",\n group: { code: \"provider\" },\n }),\n cf.select(\"environment_type\", [\"studio\", \"suite\", \"on_site\"], {\n label: \"Environment\",\n description: \"Where the session is hosted.\",\n fieldset: \"service_schedule\",\n group: { code: \"environment\" },\n }),\n ]),\n];\n\ntype CategorySeed = {\n slug: string;\n name: string;\n description?: string;\n children?: CategorySeed[];\n};\n\nconst CATEGORY_TREE: CategorySeed[] = [\n {\n slug: \"fashion\",\n name: \"Fashion\",\n description: \"Seasonal assortments and vertical-specific collections.\",\n children: [\n {\n slug: \"fashion-men\",\n name: \"Men\",\n children: [\n {\n slug: \"fashion-men-footwear\",\n name: \"Footwear\",\n description: \"Premium sneakers, boots, and sandals.\",\n },\n ],\n },\n {\n slug: \"fashion-women\",\n name: \"Women\",\n children: [\n {\n slug: \"fashion-women-dresses-jumpsuits\",\n name: \"Dresses & Jumpsuits\",\n description: \"Occasion-ready dresses and tailored jumpsuits.\",\n },\n ],\n },\n ],\n },\n {\n slug: \"services\",\n name: \"Services\",\n description: \"Bookable in-person and virtual experiences.\",\n children: [\n {\n slug: \"services-hairdresser\",\n name: \"Hairdresser\",\n description:\n \"Salon services ranging from quick trims to signature looks.\",\n },\n {\n slug: \"services-massage\",\n name: \"Massage\",\n description: \"Wellness treatments and bodywork sessions.\",\n },\n ],\n },\n];\n\ntype MediaSeed = {\n file: string;\n title?: string;\n};\n\ntype VariantSeed = {\n name: string;\n sku: string;\n isDefault?: boolean;\n optionValues?: Record<string, string>;\n prices: {\n regular: number;\n sale?: number;\n };\n customFields?: Record<string, string | number | boolean | null>;\n media?: MediaSeed[];\n};\n\ntype ProductSeed = {\n title: string;\n handle: string;\n sku?: string;\n description: string;\n categorySlug: string;\n customFieldsetCode: string;\n variantFieldsetCode: string;\n unit: string;\n metadata?: Record<string, unknown>;\n customFields?: Record<string, string | number | boolean | null>;\n media?: MediaSeed[];\n variants: VariantSeed[];\n};\n\nconst PRODUCT_SEEDS: ProductSeed[] = [\n {\n title: \"Atlas Runner Sneaker\",\n handle: \"atlas-runner-sneaker\",\n sku: \"ATLAS-RUNNER\",\n description:\n \"Lightweight road sneaker engineered with a breathable knit upper, recycled TPU overlays, and a decoupled heel for smooth transitions.\",\n categorySlug: \"fashion-men-footwear\",\n customFieldsetCode: \"fashion_mens_footwear\",\n variantFieldsetCode: \"fashion_mens_footwear\",\n unit: \"pair\",\n metadata: { division: \"RunLab\", season: \"SS25\" },\n customFields: {\n style_code: \"AR-2025\",\n upper_material: \"engineered_knit\",\n cushioning_profile: \"responsive\",\n care_notes:\n \"Spot clean after each run and air dry. Avoid machine drying.\",\n },\n media: [{ file: \"atlas-runner-midnight-1.png\" }],\n variants: [\n {\n name: \"Midnight Navy \u00B7 US 8\",\n sku: \"ATLAS-RUN-NAVY-8\",\n isDefault: true,\n optionValues: { color: \"Midnight Navy\", size: \"US 8\" },\n prices: { regular: 168, sale: 148 },\n customFields: {\n shoe_size: 8,\n shoe_width: \"D\",\n colorway: \"Midnight Navy\",\n },\n media: [\n { file: \"atlas-runner-midnight-1.png\" },\n { file: \"atlas-runner-midnight-2.png\" },\n ],\n },\n {\n name: \"Glacier Grey \u00B7 US 10\",\n sku: \"ATLAS-RUN-GLACIER-10\",\n optionValues: { color: \"Glacier Grey\", size: \"US 10\" },\n prices: { regular: 168, sale: 138 },\n customFields: {\n shoe_size: 10,\n shoe_width: \"EE\",\n colorway: \"Glacier Grey\",\n },\n media: [\n { file: \"atlas-runner-glacier-1.png\" },\n { file: \"atlas-runner-glacier-2.png\" },\n ],\n },\n ],\n },\n {\n title: \"Aurora Wrap Dress\",\n handle: \"aurora-wrap-dress\",\n sku: \"AURORA-WRAP\",\n description:\n \"Bias-cut wrap dress with blouson sleeves, matte silk blend, and hidden interior snaps so the placket stays put at events.\",\n categorySlug: \"fashion-women-dresses-jumpsuits\",\n customFieldsetCode: \"fashion_womens_dresses\",\n variantFieldsetCode: \"fashion_womens_dresses\",\n unit: \"unit\",\n metadata: { capsule: \"Evening Atelier\", season: \"Resort 25\" },\n customFields: {\n silhouette: \"wrap\",\n fabric_mix: \"silk_blend\",\n occasion_ready: \"evening\",\n finishing_details:\n \"Hand-finished hem with subtle tonal beading along the wrap edge.\",\n },\n media: [{ file: \"aurora-wrap-rosewood.png\" }],\n variants: [\n {\n name: \"Rosewood \u00B7 Medium\",\n sku: \"AURORA-ROSE-M\",\n isDefault: true,\n optionValues: { color: \"Rosewood\", size: \"Medium\" },\n prices: { regular: 248, sale: 212 },\n customFields: {\n numeric_size: 6,\n length_profile: \"midi\",\n color_story: \"Rosewood\",\n },\n media: [{ file: \"aurora-wrap-rosewood.png\" }],\n },\n {\n name: \"Celestial \u00B7 Large\",\n sku: \"AURORA-CELESTIAL-L\",\n optionValues: { color: \"Celestial\", size: \"Large\" },\n prices: { regular: 248, sale: 198 },\n customFields: {\n numeric_size: 8,\n length_profile: \"maxi\",\n color_story: \"Celestial blue\",\n },\n media: [{ file: \"aurora-wrap-celestial.png\" }],\n },\n ],\n },\n {\n title: \"Signature Haircut & Finish\",\n handle: \"signature-haircut-service\",\n sku: \"SERV-HAIR-60\",\n description:\n \"Tailored haircut with relaxing wash, scalp massage, and styling finish. Designed for repeat visits in the demo portal.\",\n categorySlug: \"services-hairdresser\",\n customFieldsetCode: \"service_schedule\",\n variantFieldsetCode: \"service_schedule\",\n unit: \"hour\",\n metadata: { channel: \"salon\", serviceType: \"hairdresser\" },\n customFields: {\n service_duration_minutes: 60,\n service_buffer_minutes: 15,\n service_location: \"Salon Studio 3\",\n service_resources: \"stylist,wash_station\",\n service_remote_available: false,\n },\n media: [{ file: \"hairdresser-service.png\" }],\n variants: [\n {\n name: \"Senior Stylist \u00B7 60 min\",\n sku: \"SERV-HAIR-60-SENIOR\",\n isDefault: true,\n optionValues: { stylist: \"Senior\", duration: \"60\" },\n prices: { regular: 95, sale: 85 },\n customFields: {\n provider_level: \"senior\",\n staff_member: \"Amelia Hart\",\n environment_type: \"studio\",\n },\n media: [{ file: \"hairdresser-service.png\" }],\n },\n ],\n },\n {\n title: \"Restorative Massage Session\",\n handle: \"restorative-massage-service\",\n sku: \"SERV-MASSAGE-90\",\n description:\n \"Full-body massage with aromatherapy oils and guided breathing. Includes complimentary refreshments and studio amenities.\",\n categorySlug: \"services-massage\",\n customFieldsetCode: \"service_schedule\",\n variantFieldsetCode: \"service_schedule\",\n unit: \"hour\",\n metadata: { channel: \"wellness\", serviceType: \"massage\" },\n customFields: {\n service_duration_minutes: 90,\n service_buffer_minutes: 20,\n service_location: \"Wellness Suite B\",\n service_resources: \"therapist,treatment_room,steam_room\",\n service_remote_available: false,\n },\n media: [{ file: \"massage-service.png\" }],\n variants: [\n {\n name: \"Master Therapist \u00B7 90 min\",\n sku: \"SERV-MASSAGE-90-MASTER\",\n isDefault: true,\n optionValues: { therapist: \"Master\", duration: \"90\" },\n prices: { regular: 140, sale: 120 },\n customFields: {\n provider_level: \"master\",\n staff_member: \"Noah Li\",\n environment_type: \"suite\",\n },\n media: [{ file: \"massage-service.png\" }],\n },\n ],\n },\n];\n\nconst CHANNEL_DEFINITION = {\n code: \"fashion-online\",\n name: \"Mercato Fashion Online\",\n description: \"Direct-to-consumer storefront showcasing premium demos.\",\n websiteUrl: \"https://demo.open-mercato.com\",\n contactEmail: \"store@open-mercato.com\",\n};\n\nfunction formatMoney(value: number): string {\n return value.toFixed(2);\n}\n\nasync function resolveDefaultTaxRate(\n em: EntityManager,\n scope: SeedScope,\n): Promise<SalesTaxRate | null> {\n const [rate] = await em.find(\n SalesTaxRate,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n deletedAt: null,\n },\n {\n limit: 1,\n orderBy: {\n isDefault: \"DESC\",\n priority: \"ASC\",\n rate: \"DESC\",\n createdAt: \"ASC\",\n },\n },\n );\n return rate ?? null;\n}\n\nasync function ensureFieldsetConfig(\n em: EntityManager,\n scope: SeedScope,\n entityId: string,\n fieldsets: typeof PRODUCT_FIELDSETS | typeof VARIANT_FIELDSETS,\n): Promise<void> {\n const now = new Date();\n let config = await em.findOne(CustomFieldEntityConfig, {\n entityId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n });\n if (!config) {\n config = em.create(CustomFieldEntityConfig, {\n id: randomUUID(),\n entityId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n isActive: true,\n createdAt: now,\n updatedAt: now,\n });\n }\n config.configJson = {\n fieldsets,\n singleFieldsetPerRecord: true,\n };\n config.isActive = true;\n config.updatedAt = now;\n em.persist(config);\n}\n\nasync function ensureFieldsetsAndDefinitions(\n em: EntityManager,\n scope: SeedScope,\n): Promise<void> {\n await ensureFieldsetConfig(\n em,\n scope,\n E.catalog.catalog_product,\n PRODUCT_FIELDSETS,\n );\n await ensureFieldsetConfig(\n em,\n scope,\n E.catalog.catalog_product_variant,\n VARIANT_FIELDSETS,\n );\n await ensureCustomFieldDefinitions(em, CUSTOM_FIELD_SETS, {\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n });\n await em.flush();\n}\n\nasync function ensureCategories(\n em: EntityManager,\n scope: SeedScope,\n): Promise<Map<string, CatalogProductCategory>> {\n const map = new Map<string, CatalogProductCategory>();\n const now = new Date();\n\n const upsert = async (\n seed: CategorySeed,\n parent: CatalogProductCategory | null,\n ) => {\n let record = await em.findOne(CatalogProductCategory, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n slug: seed.slug,\n });\n if (!record) {\n record = em.create(CatalogProductCategory, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n name: seed.name,\n slug: seed.slug,\n description: seed.description ?? null,\n parentId: parent ? parent.id : null,\n rootId: parent ? (parent.rootId ?? parent.id) : null,\n treePath: null,\n depth: parent ? (parent.depth ?? 0) + 1 : 0,\n ancestorIds: [],\n childIds: [],\n descendantIds: [],\n metadata: null,\n isActive: true,\n createdAt: now,\n updatedAt: now,\n });\n em.persist(record);\n } else {\n record.name = seed.name;\n record.description = seed.description ?? null;\n record.parentId = parent ? parent.id : null;\n record.isActive = true;\n record.updatedAt = now;\n }\n map.set(seed.slug, record);\n if (Array.isArray(seed.children)) {\n for (const child of seed.children) {\n await upsert(child, record);\n }\n }\n };\n\n for (const seed of CATEGORY_TREE) {\n await upsert(seed, null);\n }\n\n await em.flush();\n await rebuildCategoryHierarchyForOrganization(\n em,\n scope.organizationId,\n scope.tenantId,\n );\n\n return map;\n}\n\nasync function ensureChannel(\n em: EntityManager,\n scope: SeedScope,\n): Promise<SalesChannel> {\n const now = new Date();\n let channel = await em.findOne(SalesChannel, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n code: CHANNEL_DEFINITION.code,\n deletedAt: null,\n });\n if (!channel) {\n channel = em.create(SalesChannel, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n code: CHANNEL_DEFINITION.code,\n name: CHANNEL_DEFINITION.name,\n description: CHANNEL_DEFINITION.description,\n websiteUrl: CHANNEL_DEFINITION.websiteUrl,\n contactEmail: CHANNEL_DEFINITION.contactEmail,\n status: \"active\",\n isActive: true,\n metadata: { locale: \"en-US\" },\n createdAt: now,\n updatedAt: now,\n });\n em.persist(channel);\n await em.flush();\n }\n return channel;\n}\n\nasync function loadPriceKinds(\n em: EntityManager,\n scope: SeedScope,\n): Promise<Map<string, CatalogPriceKind>> {\n const kinds = await em.find(CatalogPriceKind, {\n tenantId: scope.tenantId,\n code: { $in: [\"regular\", \"sale\"] },\n deletedAt: null,\n });\n const map = new Map<string, CatalogPriceKind>();\n for (const kind of kinds) {\n map.set(kind.code.toLowerCase(), kind);\n }\n return map;\n}\n\nexport async function seedCatalogExamples(\n em: EntityManager,\n container: AwilixContainer,\n scope: SeedScope,\n): Promise<boolean> {\n await ensureFieldsetsAndDefinitions(em, scope);\n await ensureDefaultPartitions(em);\n\n const handles = PRODUCT_SEEDS.map((seed) => seed.handle);\n const existingProducts = await em.find(CatalogProduct, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n handle: { $in: [...handles] },\n });\n const existingByHandle = new Map(\n existingProducts.map((product) => [product.handle?.toLowerCase(), product]),\n );\n\n const categoryMap = await ensureCategories(em, scope);\n const channel = await ensureChannel(em, scope);\n const priceKinds = await loadPriceKinds(em, scope);\n const regularKind = priceKinds.get(\"regular\");\n const saleKind = priceKinds.get(\"sale\");\n const defaultTaxRate = await resolveDefaultTaxRate(em, scope);\n const defaultTaxRateId = defaultTaxRate?.id ?? null;\n const defaultTaxRateValue = defaultTaxRate?.rate ?? null;\n if (!regularKind || !saleKind) {\n throw new Error(\n \"Missing catalog price kinds; run `mercato catalog seed-price-kinds` first.\",\n );\n }\n\n const dataEngine = new DefaultDataEngine(em, container);\n const customFieldAssignments: Array<() => Promise<void>> = [];\n let createdAny = false;\n\n for (const productSeed of PRODUCT_SEEDS) {\n const existing = existingByHandle.get(productSeed.handle.toLowerCase());\n if (existing) {\n continue;\n }\n createdAny = true;\n const product = em.create(CatalogProduct, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n title: productSeed.title,\n description: productSeed.description,\n sku: productSeed.sku ?? null,\n handle: productSeed.handle,\n productType: \"configurable\",\n primaryCurrencyCode: \"USD\",\n defaultUnit: canonicalizeUnitCode(productSeed.unit) ?? productSeed.unit,\n customFieldsetCode: productSeed.customFieldsetCode,\n metadata: productSeed.metadata ?? null,\n taxRateId: defaultTaxRateId,\n taxRate: defaultTaxRateValue,\n isConfigurable: true,\n isActive: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(product);\n\n const category = categoryMap.get(productSeed.categorySlug);\n if (category) {\n const assignment = em.create(CatalogProductCategoryAssignment, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n product,\n category,\n position: 0,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(assignment);\n }\n\n const offer = em.create(CatalogOffer, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n product,\n channelId: channel.id,\n title: `${productSeed.title} \u00B7 Online`,\n description: \"Offer curated for the demo storefront channel.\",\n metadata: { channelCode: CHANNEL_DEFINITION.code },\n isActive: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(offer);\n\n if (\n productSeed.customFields &&\n Object.keys(productSeed.customFields).length\n ) {\n const payload = { ...productSeed.customFields };\n customFieldAssignments.push(() =>\n dataEngine.setCustomFields({\n entityId: E.catalog.catalog_product,\n recordId: product.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n values: payload,\n }),\n );\n }\n\n const productMedia = await attachMediaFromExamples(\n em,\n scope,\n E.catalog.catalog_product,\n product.id,\n productSeed.media,\n );\n if (productMedia.length) {\n const hero = productMedia[0];\n product.defaultMediaId = hero.id;\n product.defaultMediaUrl = hero.imageUrl;\n offer.defaultMediaId = hero.id;\n offer.defaultMediaUrl = hero.imageUrl;\n }\n\n for (const variantSeed of productSeed.variants) {\n const variant = em.create(CatalogProductVariant, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n product,\n name: variantSeed.name,\n sku: variantSeed.sku,\n isDefault: variantSeed.isDefault ?? false,\n optionValues: variantSeed.optionValues ?? null,\n customFieldsetCode: productSeed.variantFieldsetCode,\n metadata: null,\n taxRateId: defaultTaxRateId,\n taxRate: defaultTaxRateValue,\n isActive: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(variant);\n\n const variantMedia = await attachMediaFromExamples(\n em,\n scope,\n E.catalog.catalog_product_variant,\n variant.id,\n variantSeed.media,\n );\n const regularPrice = em.create(CatalogProductPrice, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n product,\n variant,\n offer,\n priceKind: regularKind,\n currencyCode: \"USD\",\n kind: regularKind.code,\n minQuantity: 1,\n taxRate: defaultTaxRateValue,\n unitPriceGross: formatMoney(variantSeed.prices.regular),\n unitPriceNet: formatMoney(variantSeed.prices.regular),\n channelId: channel.id,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(regularPrice);\n\n if (variantSeed.prices.sale !== undefined) {\n const salePrice = em.create(CatalogProductPrice, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n product,\n variant,\n offer,\n priceKind: saleKind,\n currencyCode: \"USD\",\n kind: saleKind.code,\n minQuantity: 1,\n taxRate: defaultTaxRateValue,\n unitPriceGross: formatMoney(variantSeed.prices.sale),\n unitPriceNet: formatMoney(variantSeed.prices.sale),\n channelId: channel.id,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(salePrice);\n }\n\n if (\n variantSeed.customFields &&\n Object.keys(variantSeed.customFields).length\n ) {\n const payload = { ...variantSeed.customFields };\n customFieldAssignments.push(() =>\n dataEngine.setCustomFields({\n entityId: E.catalog.catalog_product_variant,\n recordId: variant.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n values: payload,\n }),\n );\n }\n }\n }\n\n if (!createdAny) {\n return false;\n }\n\n await em.flush();\n\n for (const assign of customFieldAssignments) {\n try {\n await assign();\n } catch (err) {\n console.warn(\n \"[catalog.seed] Failed to set example custom field values\",\n err,\n );\n }\n }\n\n return true;\n}\n"],
5
- "mappings": "AAAA,SAAS,kBAAkB;AAC3B,OAAO,UAAU;AACjB,SAAS,YAAY,UAAU;AAG/B,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AAClC;AAAA,EACE;AAAA,OAEK;AACP,SAAS,+BAA+B;AACxC,SAAS,+CAA+C;AACxD,SAAS,cAAc,UAAU;AACjC,SAAS,SAAS;AAClB,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,4BAA4B;AAIrC,MAAM,sBAAsB,KAAK,KAAK,QAAQ,IAAI,GAAG,UAAU,UAAU;AAEzE,SAAS,eAAe,UAA0B;AAChD,QAAM,MAAM,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,IAAI,KAAK;AACvD,MAAI,QAAQ,MAAO,QAAO;AAC1B,MAAI,QAAQ,SAAS,QAAQ,OAAQ,QAAO;AAC5C,MAAI,QAAQ,OAAQ,QAAO;AAC3B,SAAO;AACT;AAEA,eAAe,0BACb,IACA,MAC8B;AAC9B,MAAI,YAAY,MAAM,GAAG,QAAQ,qBAAqB,EAAE,KAAK,CAAC;AAC9D,MAAI,CAAC,WAAW;AACd,UAAM,wBAAwB,EAAE;AAChC,gBAAY,MAAM,GAAG,QAAQ,qBAAqB,EAAE,KAAK,CAAC;AAAA,EAC5D;AACA,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,yBAAyB,IAAI,sBAAsB;AAAA,EACrE;AACA,SAAO;AACT;AAEA,eAAe,wBACb,IACA,OACA,UACA,UACA,YACkD;AAClD,MAAI,CAAC,YAAY,OAAQ,QAAO,CAAC;AACjC,QAAM,gBAAgB,4BAA4B,QAAQ;AAC1D,QAAM,YAAY,MAAM,0BAA0B,IAAI,aAAa;AACnE,QAAM,UAAmD,CAAC;AAC1D,aAAW,SAAS,YAAY;AAC9B,UAAM,aAAa,KAAK,KAAK,qBAAqB,MAAM,IAAI;AAC5D,QAAI;AACJ,QAAI;AACF,eAAS,MAAM,GAAG,SAAS,UAAU;AAAA,IACvC,SAAS,OAAO;AACd,cAAQ,KAAK,yCAAyC,UAAU,EAAE;AAClE;AAAA,IACF;AACA,UAAM,SAAS,MAAM,mBAAmB;AAAA,MACtC,eAAe,UAAU;AAAA,MACzB,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,UAAU,MAAM;AAAA,MAChB;AAAA,IACF,CAAC;AACD,UAAM,eAAe,WAAW;AAChC,UAAM,OAAO,0BAA0B,MAAM,MAAM,OAAO;AAC1D,UAAM,WAAW,wBAAwB,MAAM;AAAA,MAC7C,aAAa,CAAC,EAAE,MAAM,UAAU,IAAI,SAAS,CAAC;AAAA,IAChD,CAAC;AACD,UAAM,aAAa,GAAG,OAAO,YAAY;AAAA,MACvC,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,MACA,gBAAgB,MAAM;AAAA,MACtB,UAAU,MAAM;AAAA,MAChB,eAAe,UAAU;AAAA,MACzB,UAAU,MAAM;AAAA,MAChB,UAAU,eAAe,MAAM,IAAI;AAAA,MACnC,UAAU,OAAO;AAAA,MACjB,eAAe,UAAU,iBAAiB;AAAA,MAC1C,aAAa,OAAO;AAAA,MACpB,iBAAiB;AAAA,MACjB,KAAK,uBAAuB,YAAY;AAAA,IAC1C,CAAC;AACD,OAAG,QAAQ,UAAU;AACrB,YAAQ,KAAK;AAAA,MACX,IAAI;AAAA,MACJ,UAAU,wBAAwB,cAAc,EAAE,KAAK,CAAC;AAAA,IAC1D,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,MAAM,oBAAoB;AAAA,EACxB;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aACE;AAAA,IACF,QAAQ;AAAA,MACN,EAAE,MAAM,YAAY,OAAO,WAAW;AAAA,MACtC,EAAE,MAAM,aAAa,OAAO,oBAAoB;AAAA,MAChD,EAAE,MAAM,QAAQ,OAAO,oBAAoB;AAAA,IAC7C;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,EAAE,MAAM,YAAY,OAAO,WAAW;AAAA,MACtC,EAAE,MAAM,aAAa,OAAO,YAAY;AAAA,MACxC,EAAE,MAAM,OAAO,OAAO,eAAe;AAAA,MACrC,EAAE,MAAM,QAAQ,OAAO,oBAAoB;AAAA,IAC7C;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aACE;AAAA,IACF,QAAQ;AAAA,MACN,EAAE,MAAM,YAAY,OAAO,WAAW;AAAA,MACtC,EAAE,MAAM,UAAU,OAAO,eAAe;AAAA,MACxC,EAAE,MAAM,aAAa,OAAO,uBAAuB;AAAA,IACrD;AAAA,EACF;AACF;AAEA,MAAM,oBAAoB;AAAA,EACxB;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,EAAE,MAAM,OAAO,OAAO,MAAM;AAAA,MAC5B,EAAE,MAAM,UAAU,OAAO,SAAS;AAAA,IACpC;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,EAAE,MAAM,OAAO,OAAO,MAAM;AAAA,MAC5B,EAAE,MAAM,UAAU,OAAO,SAAS;AAAA,IACpC;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aACE;AAAA,IACF,QAAQ;AAAA,MACN,EAAE,MAAM,YAAY,OAAO,WAAW;AAAA,MACtC,EAAE,MAAM,eAAe,OAAO,cAAc;AAAA,IAC9C;AAAA,EACF;AACF;AAEA,MAAM,oBAAqC;AAAA,EACzC,aAAa,EAAE,QAAQ,iBAAiB;AAAA,IACtC,GAAG,KAAK,cAAc;AAAA,MACpB,OAAO;AAAA,MACP,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,WAAW;AAAA,IAC5B,CAAC;AAAA,IACD,GAAG;AAAA,MACD;AAAA,MACA,CAAC,mBAAmB,sBAAsB,eAAe;AAAA,MACzD;AAAA,QACE,OAAO;AAAA,QACP,UAAU;AAAA,QACV,OAAO,EAAE,MAAM,YAAY;AAAA,QAC3B,YAAY;AAAA,MACd;AAAA,IACF;AAAA,IACA,GAAG,OAAO,sBAAsB,CAAC,cAAc,SAAS,WAAW,GAAG;AAAA,MACpE,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,YAAY;AAAA,IAC7B,CAAC;AAAA,IACD,GAAG,UAAU,cAAc;AAAA,MACzB,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,OAAO;AAAA,IACxB,CAAC;AAAA,EACH,CAAC;AAAA,EACD,aAAa,EAAE,QAAQ,iBAAiB;AAAA,IACtC,GAAG,OAAO,cAAc,CAAC,QAAQ,UAAU,iBAAiB,UAAU,GAAG;AAAA,MACvE,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,WAAW;AAAA,MAC1B,YAAY;AAAA,IACd,CAAC;AAAA,IACD,GAAG,OAAO,cAAc,CAAC,cAAc,iBAAiB,SAAS,OAAO,GAAG;AAAA,MACzE,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,YAAY;AAAA,IAC7B,CAAC;AAAA,IACD,GAAG,OAAO,kBAAkB,CAAC,WAAW,WAAW,QAAQ,GAAG;AAAA,MAC5D,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,MAAM;AAAA,IACvB,CAAC;AAAA,IACD,GAAG,UAAU,qBAAqB;AAAA,MAChC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,OAAO;AAAA,IACxB,CAAC;AAAA,EACH,CAAC;AAAA,EACD,aAAa,EAAE,QAAQ,yBAAyB;AAAA,IAC9C,GAAG,QAAQ,aAAa;AAAA,MACtB,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,MAAM;AAAA,MACrB,YAAY;AAAA,IACd,CAAC;AAAA,IACD,GAAG,OAAO,cAAc,CAAC,KAAK,KAAK,IAAI,GAAG;AAAA,MACxC,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,MAAM;AAAA,IACvB,CAAC;AAAA,IACD,GAAG,KAAK,YAAY;AAAA,MAClB,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,SAAS;AAAA,IAC1B,CAAC;AAAA,EACH,CAAC;AAAA,EACD,aAAa,EAAE,QAAQ,yBAAyB;AAAA,IAC9C,GAAG,QAAQ,gBAAgB;AAAA,MACzB,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,MAAM;AAAA,IACvB,CAAC;AAAA,IACD,GAAG,OAAO,kBAAkB,CAAC,QAAQ,QAAQ,MAAM,GAAG;AAAA,MACpD,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,MAAM;AAAA,IACvB,CAAC;AAAA,IACD,GAAG,KAAK,eAAe;AAAA,MACrB,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,SAAS;AAAA,IAC1B,CAAC;AAAA,EACH,CAAC;AAAA,EACD,aAAa,EAAE,QAAQ,iBAAiB;AAAA,IACtC,GAAG,QAAQ,4BAA4B;AAAA,MACrC,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,YAAY;AAAA,MACZ,UAAU;AAAA,IACZ,CAAC;AAAA,IACD,GAAG,QAAQ,0BAA0B;AAAA,MACnC,OAAO;AAAA,MACP,aACE;AAAA,MACF,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,SAAS;AAAA,IAC1B,CAAC;AAAA,IACD,GAAG,KAAK,oBAAoB;AAAA,MAC1B,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,WAAW;AAAA,IAC5B,CAAC;AAAA,IACD,GAAG;AAAA,MACD;AAAA,MACA,CAAC,WAAW,aAAa,kBAAkB,gBAAgB,YAAY;AAAA,MACvE;AAAA,QACE,OAAO;AAAA,QACP,aAAa;AAAA,QACb,UAAU;AAAA,QACV,OAAO,EAAE,MAAM,YAAY;AAAA,QAC3B,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,GAAG,QAAQ,4BAA4B;AAAA,MACrC,OAAO;AAAA,MACP,aACE;AAAA,MACF,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,YAAY;AAAA,MAC3B,cAAc;AAAA,IAChB,CAAC;AAAA,EACH,CAAC;AAAA,EACD,aAAa,EAAE,QAAQ,yBAAyB;AAAA,IAC9C,GAAG,OAAO,kBAAkB,CAAC,UAAU,UAAU,QAAQ,GAAG;AAAA,MAC1D,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,WAAW;AAAA,MAC1B,YAAY;AAAA,IACd,CAAC;AAAA,IACD,GAAG,KAAK,gBAAgB;AAAA,MACtB,OAAO;AAAA,MACP,aACE;AAAA,MACF,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,WAAW;AAAA,IAC5B,CAAC;AAAA,IACD,GAAG,OAAO,oBAAoB,CAAC,UAAU,SAAS,SAAS,GAAG;AAAA,MAC5D,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,MACV,OAAO,EAAE,MAAM,cAAc;AAAA,IAC/B,CAAC;AAAA,EACH,CAAC;AACH;AASA,MAAM,gBAAgC;AAAA,EACpC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AAmCA,MAAM,gBAA+B;AAAA,EACnC;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,aACE;AAAA,IACF,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,MAAM;AAAA,IACN,UAAU,EAAE,UAAU,UAAU,QAAQ,OAAO;AAAA,IAC/C,cAAc;AAAA,MACZ,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,oBAAoB;AAAA,MACpB,YACE;AAAA,IACJ;AAAA,IACA,OAAO,CAAC,EAAE,MAAM,8BAA8B,CAAC;AAAA,IAC/C,UAAU;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN,KAAK;AAAA,QACL,WAAW;AAAA,QACX,cAAc,EAAE,OAAO,iBAAiB,MAAM,OAAO;AAAA,QACrD,QAAQ,EAAE,SAAS,KAAK,MAAM,IAAI;AAAA,QAClC,cAAc;AAAA,UACZ,WAAW;AAAA,UACX,YAAY;AAAA,UACZ,UAAU;AAAA,QACZ;AAAA,QACA,OAAO;AAAA,UACL,EAAE,MAAM,8BAA8B;AAAA,UACtC,EAAE,MAAM,8BAA8B;AAAA,QACxC;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,KAAK;AAAA,QACL,cAAc,EAAE,OAAO,gBAAgB,MAAM,QAAQ;AAAA,QACrD,QAAQ,EAAE,SAAS,KAAK,MAAM,IAAI;AAAA,QAClC,cAAc;AAAA,UACZ,WAAW;AAAA,UACX,YAAY;AAAA,UACZ,UAAU;AAAA,QACZ;AAAA,QACA,OAAO;AAAA,UACL,EAAE,MAAM,6BAA6B;AAAA,UACrC,EAAE,MAAM,6BAA6B;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,aACE;AAAA,IACF,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,MAAM;AAAA,IACN,UAAU,EAAE,SAAS,mBAAmB,QAAQ,YAAY;AAAA,IAC5D,cAAc;AAAA,MACZ,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,mBACE;AAAA,IACJ;AAAA,IACA,OAAO,CAAC,EAAE,MAAM,2BAA2B,CAAC;AAAA,IAC5C,UAAU;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN,KAAK;AAAA,QACL,WAAW;AAAA,QACX,cAAc,EAAE,OAAO,YAAY,MAAM,SAAS;AAAA,QAClD,QAAQ,EAAE,SAAS,KAAK,MAAM,IAAI;AAAA,QAClC,cAAc;AAAA,UACZ,cAAc;AAAA,UACd,gBAAgB;AAAA,UAChB,aAAa;AAAA,QACf;AAAA,QACA,OAAO,CAAC,EAAE,MAAM,2BAA2B,CAAC;AAAA,MAC9C;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,KAAK;AAAA,QACL,cAAc,EAAE,OAAO,aAAa,MAAM,QAAQ;AAAA,QAClD,QAAQ,EAAE,SAAS,KAAK,MAAM,IAAI;AAAA,QAClC,cAAc;AAAA,UACZ,cAAc;AAAA,UACd,gBAAgB;AAAA,UAChB,aAAa;AAAA,QACf;AAAA,QACA,OAAO,CAAC,EAAE,MAAM,4BAA4B,CAAC;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,aACE;AAAA,IACF,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,MAAM;AAAA,IACN,UAAU,EAAE,SAAS,SAAS,aAAa,cAAc;AAAA,IACzD,cAAc;AAAA,MACZ,0BAA0B;AAAA,MAC1B,wBAAwB;AAAA,MACxB,kBAAkB;AAAA,MAClB,mBAAmB;AAAA,MACnB,0BAA0B;AAAA,IAC5B;AAAA,IACA,OAAO,CAAC,EAAE,MAAM,0BAA0B,CAAC;AAAA,IAC3C,UAAU;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN,KAAK;AAAA,QACL,WAAW;AAAA,QACX,cAAc,EAAE,SAAS,UAAU,UAAU,KAAK;AAAA,QAClD,QAAQ,EAAE,SAAS,IAAI,MAAM,GAAG;AAAA,QAChC,cAAc;AAAA,UACZ,gBAAgB;AAAA,UAChB,cAAc;AAAA,UACd,kBAAkB;AAAA,QACpB;AAAA,QACA,OAAO,CAAC,EAAE,MAAM,0BAA0B,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,aACE;AAAA,IACF,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,MAAM;AAAA,IACN,UAAU,EAAE,SAAS,YAAY,aAAa,UAAU;AAAA,IACxD,cAAc;AAAA,MACZ,0BAA0B;AAAA,MAC1B,wBAAwB;AAAA,MACxB,kBAAkB;AAAA,MAClB,mBAAmB;AAAA,MACnB,0BAA0B;AAAA,IAC5B;AAAA,IACA,OAAO,CAAC,EAAE,MAAM,sBAAsB,CAAC;AAAA,IACvC,UAAU;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN,KAAK;AAAA,QACL,WAAW;AAAA,QACX,cAAc,EAAE,WAAW,UAAU,UAAU,KAAK;AAAA,QACpD,QAAQ,EAAE,SAAS,KAAK,MAAM,IAAI;AAAA,QAClC,cAAc;AAAA,UACZ,gBAAgB;AAAA,UAChB,cAAc;AAAA,UACd,kBAAkB;AAAA,QACpB;AAAA,QACA,OAAO,CAAC,EAAE,MAAM,sBAAsB,CAAC;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AACF;AAEA,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,cAAc;AAChB;AAEA,SAAS,YAAY,OAAuB;AAC1C,SAAO,MAAM,QAAQ,CAAC;AACxB;AAEA,eAAe,sBACb,IACA,OAC8B;AAC9B,QAAM,CAAC,IAAI,IAAI,MAAM,GAAG;AAAA,IACtB;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,WAAW;AAAA,IACb;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,SAAS;AAAA,QACP,WAAW;AAAA,QACX,UAAU;AAAA,QACV,MAAM;AAAA,QACN,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACA,SAAO,QAAQ;AACjB;AAEA,eAAe,qBACb,IACA,OACA,UACA,WACe;AACf,QAAM,MAAM,oBAAI,KAAK;AACrB,MAAI,SAAS,MAAM,GAAG,QAAQ,yBAAyB;AAAA,IACrD;AAAA,IACA,gBAAgB,MAAM;AAAA,IACtB,UAAU,MAAM;AAAA,EAClB,CAAC;AACD,MAAI,CAAC,QAAQ;AACX,aAAS,GAAG,OAAO,yBAAyB;AAAA,MAC1C,IAAI,WAAW;AAAA,MACf;AAAA,MACA,gBAAgB,MAAM;AAAA,MACtB,UAAU,MAAM;AAAA,MAChB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,SAAO,aAAa;AAAA,IAClB;AAAA,IACA,yBAAyB;AAAA,EAC3B;AACA,SAAO,WAAW;AAClB,SAAO,YAAY;AACnB,KAAG,QAAQ,MAAM;AACnB;AAEA,eAAe,8BACb,IACA,OACe;AACf,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,EAAE,QAAQ;AAAA,IACV;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,EAAE,QAAQ;AAAA,IACV;AAAA,EACF;AACA,QAAM,6BAA6B,IAAI,mBAAmB;AAAA,IACxD,gBAAgB,MAAM;AAAA,IACtB,UAAU,MAAM;AAAA,EAClB,CAAC;AACD,QAAM,GAAG,MAAM;AACjB;AAEA,eAAe,iBACb,IACA,OAC8C;AAC9C,QAAM,MAAM,oBAAI,IAAoC;AACpD,QAAM,MAAM,oBAAI,KAAK;AAErB,QAAM,SAAS,OACb,MACA,WACG;AACH,QAAI,SAAS,MAAM,GAAG,QAAQ,wBAAwB;AAAA,MACpD,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,MAAM,KAAK;AAAA,IACb,CAAC;AACD,QAAI,CAAC,QAAQ;AACX,eAAS,GAAG,OAAO,wBAAwB;AAAA,QACzC,IAAI,WAAW;AAAA,QACf,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,QAChB,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,QACX,aAAa,KAAK,eAAe;AAAA,QACjC,UAAU,SAAS,OAAO,KAAK;AAAA,QAC/B,QAAQ,SAAU,OAAO,UAAU,OAAO,KAAM;AAAA,QAChD,UAAU;AAAA,QACV,OAAO,UAAU,OAAO,SAAS,KAAK,IAAI;AAAA,QAC1C,aAAa,CAAC;AAAA,QACd,UAAU,CAAC;AAAA,QACX,eAAe,CAAC;AAAA,QAChB,UAAU;AAAA,QACV,UAAU;AAAA,QACV,WAAW;AAAA,QACX,WAAW;AAAA,MACb,CAAC;AACD,SAAG,QAAQ,MAAM;AAAA,IACnB,OAAO;AACL,aAAO,OAAO,KAAK;AACnB,aAAO,cAAc,KAAK,eAAe;AACzC,aAAO,WAAW,SAAS,OAAO,KAAK;AACvC,aAAO,WAAW;AAClB,aAAO,YAAY;AAAA,IACrB;AACA,QAAI,IAAI,KAAK,MAAM,MAAM;AACzB,QAAI,MAAM,QAAQ,KAAK,QAAQ,GAAG;AAChC,iBAAW,SAAS,KAAK,UAAU;AACjC,cAAM,OAAO,OAAO,MAAM;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAEA,aAAW,QAAQ,eAAe;AAChC,UAAM,OAAO,MAAM,IAAI;AAAA,EACzB;AAEA,QAAM,GAAG,MAAM;AACf,QAAM;AAAA,IACJ;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAEA,SAAO;AACT;AAEA,eAAe,cACb,IACA,OACuB;AACvB,QAAM,MAAM,oBAAI,KAAK;AACrB,MAAI,UAAU,MAAM,GAAG,QAAQ,cAAc;AAAA,IAC3C,UAAU,MAAM;AAAA,IAChB,gBAAgB,MAAM;AAAA,IACtB,MAAM,mBAAmB;AAAA,IACzB,WAAW;AAAA,EACb,CAAC;AACD,MAAI,CAAC,SAAS;AACZ,cAAU,GAAG,OAAO,cAAc;AAAA,MAChC,IAAI,WAAW;AAAA,MACf,gBAAgB,MAAM;AAAA,MACtB,UAAU,MAAM;AAAA,MAChB,MAAM,mBAAmB;AAAA,MACzB,MAAM,mBAAmB;AAAA,MACzB,aAAa,mBAAmB;AAAA,MAChC,YAAY,mBAAmB;AAAA,MAC/B,cAAc,mBAAmB;AAAA,MACjC,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU,EAAE,QAAQ,QAAQ;AAAA,MAC5B,WAAW;AAAA,MACX,WAAW;AAAA,IACb,CAAC;AACD,OAAG,QAAQ,OAAO;AAClB,UAAM,GAAG,MAAM;AAAA,EACjB;AACA,SAAO;AACT;AAEA,eAAe,eACb,IACA,OACwC;AACxC,QAAM,QAAQ,MAAM,GAAG,KAAK,kBAAkB;AAAA,IAC5C,UAAU,MAAM;AAAA,IAChB,MAAM,EAAE,KAAK,CAAC,WAAW,MAAM,EAAE;AAAA,IACjC,WAAW;AAAA,EACb,CAAC;AACD,QAAM,MAAM,oBAAI,IAA8B;AAC9C,aAAW,QAAQ,OAAO;AACxB,QAAI,IAAI,KAAK,KAAK,YAAY,GAAG,IAAI;AAAA,EACvC;AACA,SAAO;AACT;AAEA,eAAsB,oBACpB,IACA,WACA,OACkB;AAClB,QAAM,8BAA8B,IAAI,KAAK;AAC7C,QAAM,wBAAwB,EAAE;AAEhC,QAAM,UAAU,cAAc,IAAI,CAAC,SAAS,KAAK,MAAM;AACvD,QAAM,mBAAmB,MAAM,GAAG,KAAK,gBAAgB;AAAA,IACrD,UAAU,MAAM;AAAA,IAChB,gBAAgB,MAAM;AAAA,IACtB,QAAQ,EAAE,KAAK,CAAC,GAAG,OAAO,EAAE;AAAA,EAC9B,CAAC;AACD,QAAM,mBAAmB,IAAI;AAAA,IAC3B,iBAAiB,IAAI,CAAC,YAAY,CAAC,QAAQ,QAAQ,YAAY,GAAG,OAAO,CAAC;AAAA,EAC5E;AAEA,QAAM,cAAc,MAAM,iBAAiB,IAAI,KAAK;AACpD,QAAM,UAAU,MAAM,cAAc,IAAI,KAAK;AAC7C,QAAM,aAAa,MAAM,eAAe,IAAI,KAAK;AACjD,QAAM,cAAc,WAAW,IAAI,SAAS;AAC5C,QAAM,WAAW,WAAW,IAAI,MAAM;AACtC,QAAM,iBAAiB,MAAM,sBAAsB,IAAI,KAAK;AAC5D,QAAM,mBAAmB,gBAAgB,MAAM;AAC/C,QAAM,sBAAsB,gBAAgB,QAAQ;AACpD,MAAI,CAAC,eAAe,CAAC,UAAU;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,kBAAkB,IAAI,SAAS;AACtD,QAAM,yBAAqD,CAAC;AAC5D,MAAI,aAAa;AAEjB,aAAW,eAAe,eAAe;AACvC,UAAM,WAAW,iBAAiB,IAAI,YAAY,OAAO,YAAY,CAAC;AACtE,QAAI,UAAU;AACZ;AAAA,IACF;AACA,iBAAa;AACb,UAAM,UAAU,GAAG,OAAO,gBAAgB;AAAA,MACxC,IAAI,WAAW;AAAA,MACf,gBAAgB,MAAM;AAAA,MACtB,UAAU,MAAM;AAAA,MAChB,OAAO,YAAY;AAAA,MACnB,aAAa,YAAY;AAAA,MACzB,KAAK,YAAY,OAAO;AAAA,MACxB,QAAQ,YAAY;AAAA,MACpB,aAAa;AAAA,MACb,qBAAqB;AAAA,MACrB,aAAa,qBAAqB,YAAY,IAAI,KAAK,YAAY;AAAA,MACnE,oBAAoB,YAAY;AAAA,MAChC,UAAU,YAAY,YAAY;AAAA,MAClC,WAAW;AAAA,MACX,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,WAAW,oBAAI,KAAK;AAAA,MACpB,WAAW,oBAAI,KAAK;AAAA,IACtB,CAAC;AACD,OAAG,QAAQ,OAAO;AAElB,UAAM,WAAW,YAAY,IAAI,YAAY,YAAY;AACzD,QAAI,UAAU;AACZ,YAAM,aAAa,GAAG,OAAO,kCAAkC;AAAA,QAC7D,IAAI,WAAW;AAAA,QACf,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,QAChB;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV,WAAW,oBAAI,KAAK;AAAA,QACpB,WAAW,oBAAI,KAAK;AAAA,MACtB,CAAC;AACD,SAAG,QAAQ,UAAU;AAAA,IACvB;AAEA,UAAM,QAAQ,GAAG,OAAO,cAAc;AAAA,MACpC,IAAI,WAAW;AAAA,MACf,gBAAgB,MAAM;AAAA,MACtB,UAAU,MAAM;AAAA,MAChB;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,OAAO,GAAG,YAAY,KAAK;AAAA,MAC3B,aAAa;AAAA,MACb,UAAU,EAAE,aAAa,mBAAmB,KAAK;AAAA,MACjD,UAAU;AAAA,MACV,WAAW,oBAAI,KAAK;AAAA,MACpB,WAAW,oBAAI,KAAK;AAAA,IACtB,CAAC;AACD,OAAG,QAAQ,KAAK;AAEhB,QACE,YAAY,gBACZ,OAAO,KAAK,YAAY,YAAY,EAAE,QACtC;AACA,YAAM,UAAU,EAAE,GAAG,YAAY,aAAa;AAC9C,6BAAuB;AAAA,QAAK,MAC1B,WAAW,gBAAgB;AAAA,UACzB,UAAU,EAAE,QAAQ;AAAA,UACpB,UAAU,QAAQ;AAAA,UAClB,gBAAgB,MAAM;AAAA,UACtB,UAAU,MAAM;AAAA,UAChB,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,eAAe,MAAM;AAAA,MACzB;AAAA,MACA;AAAA,MACA,EAAE,QAAQ;AAAA,MACV,QAAQ;AAAA,MACR,YAAY;AAAA,IACd;AACA,QAAI,aAAa,QAAQ;AACvB,YAAM,OAAO,aAAa,CAAC;AAC3B,cAAQ,iBAAiB,KAAK;AAC9B,cAAQ,kBAAkB,KAAK;AAC/B,YAAM,iBAAiB,KAAK;AAC5B,YAAM,kBAAkB,KAAK;AAAA,IAC/B;AAEA,eAAW,eAAe,YAAY,UAAU;AAC9C,YAAM,UAAU,GAAG,OAAO,uBAAuB;AAAA,QAC/C,IAAI,WAAW;AAAA,QACf,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,QAChB;AAAA,QACA,MAAM,YAAY;AAAA,QAClB,KAAK,YAAY;AAAA,QACjB,WAAW,YAAY,aAAa;AAAA,QACpC,cAAc,YAAY,gBAAgB;AAAA,QAC1C,oBAAoB,YAAY;AAAA,QAChC,UAAU;AAAA,QACV,WAAW;AAAA,QACX,SAAS;AAAA,QACT,UAAU;AAAA,QACV,WAAW,oBAAI,KAAK;AAAA,QACpB,WAAW,oBAAI,KAAK;AAAA,MACtB,CAAC;AACD,SAAG,QAAQ,OAAO;AAElB,YAAM,eAAe,MAAM;AAAA,QACzB;AAAA,QACA;AAAA,QACA,EAAE,QAAQ;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA,MACd;AACA,YAAM,eAAe,GAAG,OAAO,qBAAqB;AAAA,QAClD,IAAI,WAAW;AAAA,QACf,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,cAAc;AAAA,QACd,MAAM,YAAY;AAAA,QAClB,aAAa;AAAA,QACb,SAAS;AAAA,QACT,gBAAgB,YAAY,YAAY,OAAO,OAAO;AAAA,QACtD,cAAc,YAAY,YAAY,OAAO,OAAO;AAAA,QACpD,WAAW,QAAQ;AAAA,QACnB,WAAW,oBAAI,KAAK;AAAA,QACpB,WAAW,oBAAI,KAAK;AAAA,MACtB,CAAC;AACD,SAAG,QAAQ,YAAY;AAEvB,UAAI,YAAY,OAAO,SAAS,QAAW;AACzC,cAAM,YAAY,GAAG,OAAO,qBAAqB;AAAA,UAC/C,IAAI,WAAW;AAAA,UACf,gBAAgB,MAAM;AAAA,UACtB,UAAU,MAAM;AAAA,UAChB;AAAA,UACA;AAAA,UACA;AAAA,UACA,WAAW;AAAA,UACX,cAAc;AAAA,UACd,MAAM,SAAS;AAAA,UACf,aAAa;AAAA,UACb,SAAS;AAAA,UACT,gBAAgB,YAAY,YAAY,OAAO,IAAI;AAAA,UACnD,cAAc,YAAY,YAAY,OAAO,IAAI;AAAA,UACjD,WAAW,QAAQ;AAAA,UACnB,WAAW,oBAAI,KAAK;AAAA,UACpB,WAAW,oBAAI,KAAK;AAAA,QACtB,CAAC;AACD,WAAG,QAAQ,SAAS;AAAA,MACtB;AAEA,UACE,YAAY,gBACZ,OAAO,KAAK,YAAY,YAAY,EAAE,QACtC;AACA,cAAM,UAAU,EAAE,GAAG,YAAY,aAAa;AAC9C,+BAAuB;AAAA,UAAK,MAC1B,WAAW,gBAAgB;AAAA,YACzB,UAAU,EAAE,QAAQ;AAAA,YACpB,UAAU,QAAQ;AAAA,YAClB,gBAAgB,MAAM;AAAA,YACtB,UAAU,MAAM;AAAA,YAChB,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,QAAM,GAAG,MAAM;AAEf,aAAW,UAAU,wBAAwB;AAC3C,QAAI;AACF,YAAM,OAAO;AAAA,IACf,SAAS,KAAK;AACZ,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;",
4
+ "sourcesContent": ["import { randomUUID } from \"node:crypto\";\nimport path from \"node:path\";\nimport { promises as fs } from \"node:fs\";\nimport type { EntityManager } from \"@mikro-orm/postgresql\";\nimport type { AwilixContainer } from \"awilix\";\nimport { SalesChannel } from \"@open-mercato/core/modules/sales/data/entities\";\nimport {\n CatalogOffer,\n CatalogPriceKind,\n CatalogProduct,\n CatalogProductCategory,\n CatalogProductCategoryAssignment,\n CatalogProductPrice,\n CatalogProductVariant,\n} from \"../data/entities\";\nimport { DefaultDataEngine } from \"@open-mercato/shared/lib/data/engine\";\nimport {\n ensureCustomFieldDefinitions,\n type FieldSetInput,\n} from \"@open-mercato/core/modules/entities/lib/field-definitions\";\nimport { CustomFieldEntityConfig } from \"@open-mercato/core/modules/entities/data/entities\";\nimport { rebuildCategoryHierarchyForOrganization } from \"../lib/categoryHierarchy\";\nimport { defineFields, cf } from \"@open-mercato/shared/modules/dsl\";\nimport { E } from \"#generated/entities.ids.generated\";\nimport { SalesTaxRate } from \"@open-mercato/core/modules/sales/data/entities\";\nimport {\n Attachment,\n AttachmentPartition,\n} from \"@open-mercato/core/modules/attachments/data/entities\";\nimport {\n ensureDefaultPartitions,\n resolveDefaultPartitionCode,\n} from \"@open-mercato/core/modules/attachments/lib/partitions\";\nimport { storePartitionFile } from \"@open-mercato/core/modules/attachments/lib/storage\";\nimport { mergeAttachmentMetadata } from \"@open-mercato/core/modules/attachments/lib/metadata\";\nimport {\n buildAttachmentFileUrl,\n buildAttachmentImageUrl,\n slugifyAttachmentFileName,\n} from \"@open-mercato/core/modules/attachments/lib/imageUrls\";\nimport { canonicalizeUnitCode } from \"../lib/unitCodes\";\nimport { createLogger } from '@open-mercato/shared/lib/logger';\n\nconst logger = createLogger('catalog');\n\ntype SeedScope = { tenantId: string; organizationId: string };\n\nconst EXAMPLES_MEDIA_ROOT = path.join(process.cwd(), \"public\", \"examples\");\n\nfunction detectMimeType(fileName: string): string {\n const ext = fileName.toLowerCase().split(\".\").pop() || \"\";\n if (ext === \"png\") return \"image/png\";\n if (ext === \"jpg\" || ext === \"jpeg\") return \"image/jpeg\";\n if (ext === \"webp\") return \"image/webp\";\n return \"application/octet-stream\";\n}\n\nasync function ensureAttachmentPartition(\n em: EntityManager,\n code: string,\n): Promise<AttachmentPartition> {\n let partition = await em.findOne(AttachmentPartition, { code });\n if (!partition) {\n await ensureDefaultPartitions(em);\n partition = await em.findOne(AttachmentPartition, { code });\n }\n if (!partition) {\n throw new Error(`Attachment partition \"${code}\" is not configured.`);\n }\n return partition;\n}\n\nasync function attachMediaFromExamples(\n em: EntityManager,\n scope: SeedScope,\n entityId: string,\n recordId: string,\n mediaSeeds?: MediaSeed[],\n): Promise<Array<{ id: string; imageUrl: string }>> {\n if (!mediaSeeds?.length) return [];\n const partitionCode = resolveDefaultPartitionCode(entityId);\n const partition = await ensureAttachmentPartition(em, partitionCode);\n const results: Array<{ id: string; imageUrl: string }> = [];\n for (const media of mediaSeeds) {\n const sourcePath = path.join(EXAMPLES_MEDIA_ROOT, media.file);\n let buffer: Buffer;\n try {\n buffer = await fs.readFile(sourcePath);\n } catch (error) {\n logger.warn('catalog.seed example media missing', { sourcePath });\n continue;\n }\n const stored = await storePartitionFile({\n partitionCode: partition.code,\n orgId: scope.organizationId,\n tenantId: scope.tenantId,\n fileName: media.file,\n buffer,\n });\n const attachmentId = randomUUID();\n const slug = slugifyAttachmentFileName(media.file, \"media\");\n const metadata = mergeAttachmentMetadata(null, {\n assignments: [{ type: entityId, id: recordId }],\n });\n const attachment = em.create(Attachment, {\n id: attachmentId,\n entityId,\n recordId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n partitionCode: partition.code,\n fileName: media.file,\n mimeType: detectMimeType(media.file),\n fileSize: buffer.length,\n storageDriver: partition.storageDriver || \"local\",\n storagePath: stored.storagePath,\n storageMetadata: metadata,\n url: buildAttachmentFileUrl(attachmentId),\n });\n em.persist(attachment);\n results.push({\n id: attachmentId,\n imageUrl: buildAttachmentImageUrl(attachmentId, { slug }),\n });\n }\n return results;\n}\n\nconst PRODUCT_FIELDSETS = [\n {\n code: \"fashion_mens_footwear\",\n label: \"Fashion \u00B7 Men \u00B7 Footwear\",\n icon: \"carbon:sneaker\",\n description:\n \"Material, construction, and care metadata for men\u2019s performance footwear.\",\n groups: [\n { code: \"identity\", title: \"Identity\" },\n { code: \"materials\", title: \"Materials & Build\" },\n { code: \"care\", title: \"Care instructions\" },\n ],\n },\n {\n code: \"fashion_womens_dresses\",\n label: \"Fashion \u00B7 Women \u00B7 Dresses & Jumpsuits\",\n icon: \"solar:dress-linear\",\n description: \"Silhouette, fabric, and care metadata for womenswear.\",\n groups: [\n { code: \"identity\", title: \"Identity\" },\n { code: \"materials\", title: \"Materials\" },\n { code: \"fit\", title: \"Fit & Length\" },\n { code: \"care\", title: \"Care instructions\" },\n ],\n },\n {\n code: \"service_schedule\",\n label: \"Services \u00B7 Scheduling\",\n icon: \"solar:calendar-linear\",\n description:\n \"Scheduling, preparation, and delivery metadata for service offerings.\",\n groups: [\n { code: \"identity\", title: \"Identity\" },\n { code: \"timing\", title: \"Timing rules\" },\n { code: \"resources\", title: \"Resources & Delivery\" },\n ],\n },\n] as const;\n\nconst VARIANT_FIELDSETS = [\n {\n code: \"fashion_mens_footwear\",\n label: \"Fashion \u00B7 Men \u00B7 Footwear\",\n icon: \"carbon:sneaker\",\n description: \"Variant-level sizing metadata for men\u2019s footwear.\",\n groups: [\n { code: \"fit\", title: \"Fit\" },\n { code: \"finish\", title: \"Finish\" },\n ],\n },\n {\n code: \"fashion_womens_dresses\",\n label: \"Fashion \u00B7 Women \u00B7 Dresses & Jumpsuits\",\n icon: \"solar:dress-linear\",\n description: \"Variant-level sizing metadata for womenswear.\",\n groups: [\n { code: \"fit\", title: \"Fit\" },\n { code: \"finish\", title: \"Finish\" },\n ],\n },\n {\n code: \"service_schedule\",\n label: \"Services \u00B7 Scheduling\",\n icon: \"solar:calendar-linear\",\n description:\n \"Provider, duration, and environment metadata for service slots.\",\n groups: [\n { code: \"provider\", title: \"Provider\" },\n { code: \"environment\", title: \"Environment\" },\n ],\n },\n] as const;\n\nconst CUSTOM_FIELD_SETS: FieldSetInput[] = [\n defineFields(E.catalog.catalog_product, [\n cf.text(\"style_code\", {\n label: \"Style code\",\n description: \"Reference code shared with merchandising teams.\",\n filterable: true,\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"identity\" },\n }),\n cf.select(\n \"upper_material\",\n [\"engineered_knit\", \"full_grain_leather\", \"recycled_mesh\"],\n {\n label: \"Upper material\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"materials\" },\n filterable: true,\n },\n ),\n cf.select(\"cushioning_profile\", [\"responsive\", \"plush\", \"stability\"], {\n label: \"Cushioning profile\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"materials\" },\n }),\n cf.multiline(\"care_notes\", {\n label: \"Care notes\",\n editor: \"markdown\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"care\" },\n }),\n ]),\n defineFields(E.catalog.catalog_product, [\n cf.select(\"silhouette\", [\"wrap\", \"column\", \"fit_and_flare\", \"jumpsuit\"], {\n label: \"Silhouette\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"identity\" },\n filterable: true,\n }),\n cf.select(\"fabric_mix\", [\"silk_blend\", \"recycled_poly\", \"linen\", \"cupro\"], {\n label: \"Fabric mix\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"materials\" },\n }),\n cf.select(\"occasion_ready\", [\"daytime\", \"evening\", \"resort\"], {\n label: \"Occasion\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"fit\" },\n }),\n cf.multiline(\"finishing_details\", {\n label: \"Finishing details\",\n editor: \"markdown\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"care\" },\n }),\n ]),\n defineFields(E.catalog.catalog_product_variant, [\n cf.integer(\"shoe_size\", {\n label: \"US size\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"fit\" },\n filterable: true,\n }),\n cf.select(\"shoe_width\", [\"B\", \"D\", \"EE\"], {\n label: \"Width\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"fit\" },\n }),\n cf.text(\"colorway\", {\n label: \"Colorway\",\n fieldset: \"fashion_mens_footwear\",\n group: { code: \"finish\" },\n }),\n ]),\n defineFields(E.catalog.catalog_product_variant, [\n cf.integer(\"numeric_size\", {\n label: \"Numeric size\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"fit\" },\n }),\n cf.select(\"length_profile\", [\"mini\", \"midi\", \"maxi\"], {\n label: \"Length\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"fit\" },\n }),\n cf.text(\"color_story\", {\n label: \"Color story\",\n fieldset: \"fashion_womens_dresses\",\n group: { code: \"finish\" },\n }),\n ]),\n defineFields(E.catalog.catalog_product, [\n cf.integer(\"service_duration_minutes\", {\n label: \"Duration (minutes)\",\n description: \"Length of a single service slot.\",\n fieldset: \"service_schedule\",\n group: { code: \"timing\" },\n filterable: true,\n required: true,\n }),\n cf.integer(\"service_buffer_minutes\", {\n label: \"Buffer between appointments\",\n description:\n \"Minimum downtime between consecutive service slots (minutes).\",\n fieldset: \"service_schedule\",\n group: { code: \"timing\" },\n }),\n cf.text(\"service_location\", {\n label: \"Location / Room\",\n description: \"Where the service is delivered.\",\n fieldset: \"service_schedule\",\n group: { code: \"identity\" },\n }),\n cf.select(\n \"service_resources\",\n [\"stylist\", \"therapist\", \"treatment_room\", \"wash_station\", \"steam_room\"],\n {\n label: \"Required resources\",\n description: \"Staff or rooms required to perform the service.\",\n fieldset: \"service_schedule\",\n group: { code: \"resources\" },\n multi: true,\n },\n ),\n cf.boolean(\"service_remote_available\", {\n label: \"Remote session available\",\n description:\n \"Indicates whether the service can be performed remotely or virtually.\",\n fieldset: \"service_schedule\",\n group: { code: \"resources\" },\n defaultValue: false,\n }),\n ]),\n defineFields(E.catalog.catalog_product_variant, [\n cf.select(\"provider_level\", [\"junior\", \"senior\", \"master\"], {\n label: \"Provider level\",\n description: \"Seniority of the assigned specialist.\",\n fieldset: \"service_schedule\",\n group: { code: \"provider\" },\n filterable: true,\n }),\n cf.text(\"staff_member\", {\n label: \"Staff member\",\n description:\n \"Optional name of the staff member who usually delivers this variant.\",\n fieldset: \"service_schedule\",\n group: { code: \"provider\" },\n }),\n cf.select(\"environment_type\", [\"studio\", \"suite\", \"on_site\"], {\n label: \"Environment\",\n description: \"Where the session is hosted.\",\n fieldset: \"service_schedule\",\n group: { code: \"environment\" },\n }),\n ]),\n];\n\ntype CategorySeed = {\n slug: string;\n name: string;\n description?: string;\n children?: CategorySeed[];\n};\n\nconst CATEGORY_TREE: CategorySeed[] = [\n {\n slug: \"fashion\",\n name: \"Fashion\",\n description: \"Seasonal assortments and vertical-specific collections.\",\n children: [\n {\n slug: \"fashion-men\",\n name: \"Men\",\n children: [\n {\n slug: \"fashion-men-footwear\",\n name: \"Footwear\",\n description: \"Premium sneakers, boots, and sandals.\",\n },\n ],\n },\n {\n slug: \"fashion-women\",\n name: \"Women\",\n children: [\n {\n slug: \"fashion-women-dresses-jumpsuits\",\n name: \"Dresses & Jumpsuits\",\n description: \"Occasion-ready dresses and tailored jumpsuits.\",\n },\n ],\n },\n ],\n },\n {\n slug: \"services\",\n name: \"Services\",\n description: \"Bookable in-person and virtual experiences.\",\n children: [\n {\n slug: \"services-hairdresser\",\n name: \"Hairdresser\",\n description:\n \"Salon services ranging from quick trims to signature looks.\",\n },\n {\n slug: \"services-massage\",\n name: \"Massage\",\n description: \"Wellness treatments and bodywork sessions.\",\n },\n ],\n },\n];\n\ntype MediaSeed = {\n file: string;\n title?: string;\n};\n\ntype VariantSeed = {\n name: string;\n sku: string;\n isDefault?: boolean;\n optionValues?: Record<string, string>;\n prices: {\n regular: number;\n sale?: number;\n };\n customFields?: Record<string, string | number | boolean | null>;\n media?: MediaSeed[];\n};\n\ntype ProductSeed = {\n title: string;\n handle: string;\n sku?: string;\n description: string;\n categorySlug: string;\n customFieldsetCode: string;\n variantFieldsetCode: string;\n unit: string;\n metadata?: Record<string, unknown>;\n customFields?: Record<string, string | number | boolean | null>;\n media?: MediaSeed[];\n variants: VariantSeed[];\n};\n\nconst PRODUCT_SEEDS: ProductSeed[] = [\n {\n title: \"Atlas Runner Sneaker\",\n handle: \"atlas-runner-sneaker\",\n sku: \"ATLAS-RUNNER\",\n description:\n \"Lightweight road sneaker engineered with a breathable knit upper, recycled TPU overlays, and a decoupled heel for smooth transitions.\",\n categorySlug: \"fashion-men-footwear\",\n customFieldsetCode: \"fashion_mens_footwear\",\n variantFieldsetCode: \"fashion_mens_footwear\",\n unit: \"pair\",\n metadata: { division: \"RunLab\", season: \"SS25\" },\n customFields: {\n style_code: \"AR-2025\",\n upper_material: \"engineered_knit\",\n cushioning_profile: \"responsive\",\n care_notes:\n \"Spot clean after each run and air dry. Avoid machine drying.\",\n },\n media: [{ file: \"atlas-runner-midnight-1.png\" }],\n variants: [\n {\n name: \"Midnight Navy \u00B7 US 8\",\n sku: \"ATLAS-RUN-NAVY-8\",\n isDefault: true,\n optionValues: { color: \"Midnight Navy\", size: \"US 8\" },\n prices: { regular: 168, sale: 148 },\n customFields: {\n shoe_size: 8,\n shoe_width: \"D\",\n colorway: \"Midnight Navy\",\n },\n media: [\n { file: \"atlas-runner-midnight-1.png\" },\n { file: \"atlas-runner-midnight-2.png\" },\n ],\n },\n {\n name: \"Glacier Grey \u00B7 US 10\",\n sku: \"ATLAS-RUN-GLACIER-10\",\n optionValues: { color: \"Glacier Grey\", size: \"US 10\" },\n prices: { regular: 168, sale: 138 },\n customFields: {\n shoe_size: 10,\n shoe_width: \"EE\",\n colorway: \"Glacier Grey\",\n },\n media: [\n { file: \"atlas-runner-glacier-1.png\" },\n { file: \"atlas-runner-glacier-2.png\" },\n ],\n },\n ],\n },\n {\n title: \"Aurora Wrap Dress\",\n handle: \"aurora-wrap-dress\",\n sku: \"AURORA-WRAP\",\n description:\n \"Bias-cut wrap dress with blouson sleeves, matte silk blend, and hidden interior snaps so the placket stays put at events.\",\n categorySlug: \"fashion-women-dresses-jumpsuits\",\n customFieldsetCode: \"fashion_womens_dresses\",\n variantFieldsetCode: \"fashion_womens_dresses\",\n unit: \"unit\",\n metadata: { capsule: \"Evening Atelier\", season: \"Resort 25\" },\n customFields: {\n silhouette: \"wrap\",\n fabric_mix: \"silk_blend\",\n occasion_ready: \"evening\",\n finishing_details:\n \"Hand-finished hem with subtle tonal beading along the wrap edge.\",\n },\n media: [{ file: \"aurora-wrap-rosewood.png\" }],\n variants: [\n {\n name: \"Rosewood \u00B7 Medium\",\n sku: \"AURORA-ROSE-M\",\n isDefault: true,\n optionValues: { color: \"Rosewood\", size: \"Medium\" },\n prices: { regular: 248, sale: 212 },\n customFields: {\n numeric_size: 6,\n length_profile: \"midi\",\n color_story: \"Rosewood\",\n },\n media: [{ file: \"aurora-wrap-rosewood.png\" }],\n },\n {\n name: \"Celestial \u00B7 Large\",\n sku: \"AURORA-CELESTIAL-L\",\n optionValues: { color: \"Celestial\", size: \"Large\" },\n prices: { regular: 248, sale: 198 },\n customFields: {\n numeric_size: 8,\n length_profile: \"maxi\",\n color_story: \"Celestial blue\",\n },\n media: [{ file: \"aurora-wrap-celestial.png\" }],\n },\n ],\n },\n {\n title: \"Signature Haircut & Finish\",\n handle: \"signature-haircut-service\",\n sku: \"SERV-HAIR-60\",\n description:\n \"Tailored haircut with relaxing wash, scalp massage, and styling finish. Designed for repeat visits in the demo portal.\",\n categorySlug: \"services-hairdresser\",\n customFieldsetCode: \"service_schedule\",\n variantFieldsetCode: \"service_schedule\",\n unit: \"hour\",\n metadata: { channel: \"salon\", serviceType: \"hairdresser\" },\n customFields: {\n service_duration_minutes: 60,\n service_buffer_minutes: 15,\n service_location: \"Salon Studio 3\",\n service_resources: \"stylist,wash_station\",\n service_remote_available: false,\n },\n media: [{ file: \"hairdresser-service.png\" }],\n variants: [\n {\n name: \"Senior Stylist \u00B7 60 min\",\n sku: \"SERV-HAIR-60-SENIOR\",\n isDefault: true,\n optionValues: { stylist: \"Senior\", duration: \"60\" },\n prices: { regular: 95, sale: 85 },\n customFields: {\n provider_level: \"senior\",\n staff_member: \"Amelia Hart\",\n environment_type: \"studio\",\n },\n media: [{ file: \"hairdresser-service.png\" }],\n },\n ],\n },\n {\n title: \"Restorative Massage Session\",\n handle: \"restorative-massage-service\",\n sku: \"SERV-MASSAGE-90\",\n description:\n \"Full-body massage with aromatherapy oils and guided breathing. Includes complimentary refreshments and studio amenities.\",\n categorySlug: \"services-massage\",\n customFieldsetCode: \"service_schedule\",\n variantFieldsetCode: \"service_schedule\",\n unit: \"hour\",\n metadata: { channel: \"wellness\", serviceType: \"massage\" },\n customFields: {\n service_duration_minutes: 90,\n service_buffer_minutes: 20,\n service_location: \"Wellness Suite B\",\n service_resources: \"therapist,treatment_room,steam_room\",\n service_remote_available: false,\n },\n media: [{ file: \"massage-service.png\" }],\n variants: [\n {\n name: \"Master Therapist \u00B7 90 min\",\n sku: \"SERV-MASSAGE-90-MASTER\",\n isDefault: true,\n optionValues: { therapist: \"Master\", duration: \"90\" },\n prices: { regular: 140, sale: 120 },\n customFields: {\n provider_level: \"master\",\n staff_member: \"Noah Li\",\n environment_type: \"suite\",\n },\n media: [{ file: \"massage-service.png\" }],\n },\n ],\n },\n];\n\nconst CHANNEL_DEFINITION = {\n code: \"fashion-online\",\n name: \"Mercato Fashion Online\",\n description: \"Direct-to-consumer storefront showcasing premium demos.\",\n websiteUrl: \"https://demo.open-mercato.com\",\n contactEmail: \"store@open-mercato.com\",\n};\n\nfunction formatMoney(value: number): string {\n return value.toFixed(2);\n}\n\nasync function resolveDefaultTaxRate(\n em: EntityManager,\n scope: SeedScope,\n): Promise<SalesTaxRate | null> {\n const [rate] = await em.find(\n SalesTaxRate,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n deletedAt: null,\n },\n {\n limit: 1,\n orderBy: {\n isDefault: \"DESC\",\n priority: \"ASC\",\n rate: \"DESC\",\n createdAt: \"ASC\",\n },\n },\n );\n return rate ?? null;\n}\n\nasync function ensureFieldsetConfig(\n em: EntityManager,\n scope: SeedScope,\n entityId: string,\n fieldsets: typeof PRODUCT_FIELDSETS | typeof VARIANT_FIELDSETS,\n): Promise<void> {\n const now = new Date();\n let config = await em.findOne(CustomFieldEntityConfig, {\n entityId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n });\n if (!config) {\n config = em.create(CustomFieldEntityConfig, {\n id: randomUUID(),\n entityId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n isActive: true,\n createdAt: now,\n updatedAt: now,\n });\n }\n config.configJson = {\n fieldsets,\n singleFieldsetPerRecord: true,\n };\n config.isActive = true;\n config.updatedAt = now;\n em.persist(config);\n}\n\nasync function ensureFieldsetsAndDefinitions(\n em: EntityManager,\n scope: SeedScope,\n): Promise<void> {\n await ensureFieldsetConfig(\n em,\n scope,\n E.catalog.catalog_product,\n PRODUCT_FIELDSETS,\n );\n await ensureFieldsetConfig(\n em,\n scope,\n E.catalog.catalog_product_variant,\n VARIANT_FIELDSETS,\n );\n await ensureCustomFieldDefinitions(em, CUSTOM_FIELD_SETS, {\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n });\n await em.flush();\n}\n\nasync function ensureCategories(\n em: EntityManager,\n scope: SeedScope,\n): Promise<Map<string, CatalogProductCategory>> {\n const map = new Map<string, CatalogProductCategory>();\n const now = new Date();\n\n const upsert = async (\n seed: CategorySeed,\n parent: CatalogProductCategory | null,\n ) => {\n let record = await em.findOne(CatalogProductCategory, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n slug: seed.slug,\n });\n if (!record) {\n record = em.create(CatalogProductCategory, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n name: seed.name,\n slug: seed.slug,\n description: seed.description ?? null,\n parentId: parent ? parent.id : null,\n rootId: parent ? (parent.rootId ?? parent.id) : null,\n treePath: null,\n depth: parent ? (parent.depth ?? 0) + 1 : 0,\n ancestorIds: [],\n childIds: [],\n descendantIds: [],\n metadata: null,\n isActive: true,\n createdAt: now,\n updatedAt: now,\n });\n em.persist(record);\n } else {\n record.name = seed.name;\n record.description = seed.description ?? null;\n record.parentId = parent ? parent.id : null;\n record.isActive = true;\n record.updatedAt = now;\n }\n map.set(seed.slug, record);\n if (Array.isArray(seed.children)) {\n for (const child of seed.children) {\n await upsert(child, record);\n }\n }\n };\n\n for (const seed of CATEGORY_TREE) {\n await upsert(seed, null);\n }\n\n await em.flush();\n await rebuildCategoryHierarchyForOrganization(\n em,\n scope.organizationId,\n scope.tenantId,\n );\n\n return map;\n}\n\nasync function ensureChannel(\n em: EntityManager,\n scope: SeedScope,\n): Promise<SalesChannel> {\n const now = new Date();\n let channel = await em.findOne(SalesChannel, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n code: CHANNEL_DEFINITION.code,\n deletedAt: null,\n });\n if (!channel) {\n channel = em.create(SalesChannel, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n code: CHANNEL_DEFINITION.code,\n name: CHANNEL_DEFINITION.name,\n description: CHANNEL_DEFINITION.description,\n websiteUrl: CHANNEL_DEFINITION.websiteUrl,\n contactEmail: CHANNEL_DEFINITION.contactEmail,\n status: \"active\",\n isActive: true,\n metadata: { locale: \"en-US\" },\n createdAt: now,\n updatedAt: now,\n });\n em.persist(channel);\n await em.flush();\n }\n return channel;\n}\n\nasync function loadPriceKinds(\n em: EntityManager,\n scope: SeedScope,\n): Promise<Map<string, CatalogPriceKind>> {\n const kinds = await em.find(CatalogPriceKind, {\n tenantId: scope.tenantId,\n code: { $in: [\"regular\", \"sale\"] },\n deletedAt: null,\n });\n const map = new Map<string, CatalogPriceKind>();\n for (const kind of kinds) {\n map.set(kind.code.toLowerCase(), kind);\n }\n return map;\n}\n\nexport async function seedCatalogExamples(\n em: EntityManager,\n container: AwilixContainer,\n scope: SeedScope,\n): Promise<boolean> {\n await ensureFieldsetsAndDefinitions(em, scope);\n await ensureDefaultPartitions(em);\n\n const handles = PRODUCT_SEEDS.map((seed) => seed.handle);\n const existingProducts = await em.find(CatalogProduct, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n handle: { $in: [...handles] },\n });\n const existingByHandle = new Map(\n existingProducts.map((product) => [product.handle?.toLowerCase(), product]),\n );\n\n const categoryMap = await ensureCategories(em, scope);\n const channel = await ensureChannel(em, scope);\n const priceKinds = await loadPriceKinds(em, scope);\n const regularKind = priceKinds.get(\"regular\");\n const saleKind = priceKinds.get(\"sale\");\n const defaultTaxRate = await resolveDefaultTaxRate(em, scope);\n const defaultTaxRateId = defaultTaxRate?.id ?? null;\n const defaultTaxRateValue = defaultTaxRate?.rate ?? null;\n if (!regularKind || !saleKind) {\n throw new Error(\n \"Missing catalog price kinds; run `mercato catalog seed-price-kinds` first.\",\n );\n }\n\n const dataEngine = new DefaultDataEngine(em, container);\n const customFieldAssignments: Array<() => Promise<void>> = [];\n let createdAny = false;\n\n for (const productSeed of PRODUCT_SEEDS) {\n const existing = existingByHandle.get(productSeed.handle.toLowerCase());\n if (existing) {\n continue;\n }\n createdAny = true;\n const product = em.create(CatalogProduct, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n title: productSeed.title,\n description: productSeed.description,\n sku: productSeed.sku ?? null,\n handle: productSeed.handle,\n productType: \"configurable\",\n primaryCurrencyCode: \"USD\",\n defaultUnit: canonicalizeUnitCode(productSeed.unit) ?? productSeed.unit,\n customFieldsetCode: productSeed.customFieldsetCode,\n metadata: productSeed.metadata ?? null,\n taxRateId: defaultTaxRateId,\n taxRate: defaultTaxRateValue,\n isConfigurable: true,\n isActive: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(product);\n\n const category = categoryMap.get(productSeed.categorySlug);\n if (category) {\n const assignment = em.create(CatalogProductCategoryAssignment, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n product,\n category,\n position: 0,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(assignment);\n }\n\n const offer = em.create(CatalogOffer, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n product,\n channelId: channel.id,\n title: `${productSeed.title} \u00B7 Online`,\n description: \"Offer curated for the demo storefront channel.\",\n metadata: { channelCode: CHANNEL_DEFINITION.code },\n isActive: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(offer);\n\n if (\n productSeed.customFields &&\n Object.keys(productSeed.customFields).length\n ) {\n const payload = { ...productSeed.customFields };\n customFieldAssignments.push(() =>\n dataEngine.setCustomFields({\n entityId: E.catalog.catalog_product,\n recordId: product.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n values: payload,\n }),\n );\n }\n\n const productMedia = await attachMediaFromExamples(\n em,\n scope,\n E.catalog.catalog_product,\n product.id,\n productSeed.media,\n );\n if (productMedia.length) {\n const hero = productMedia[0];\n product.defaultMediaId = hero.id;\n product.defaultMediaUrl = hero.imageUrl;\n offer.defaultMediaId = hero.id;\n offer.defaultMediaUrl = hero.imageUrl;\n }\n\n for (const variantSeed of productSeed.variants) {\n const variant = em.create(CatalogProductVariant, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n product,\n name: variantSeed.name,\n sku: variantSeed.sku,\n isDefault: variantSeed.isDefault ?? false,\n optionValues: variantSeed.optionValues ?? null,\n customFieldsetCode: productSeed.variantFieldsetCode,\n metadata: null,\n taxRateId: defaultTaxRateId,\n taxRate: defaultTaxRateValue,\n isActive: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(variant);\n\n const variantMedia = await attachMediaFromExamples(\n em,\n scope,\n E.catalog.catalog_product_variant,\n variant.id,\n variantSeed.media,\n );\n const regularPrice = em.create(CatalogProductPrice, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n product,\n variant,\n offer,\n priceKind: regularKind,\n currencyCode: \"USD\",\n kind: regularKind.code,\n minQuantity: 1,\n taxRate: defaultTaxRateValue,\n unitPriceGross: formatMoney(variantSeed.prices.regular),\n unitPriceNet: formatMoney(variantSeed.prices.regular),\n channelId: channel.id,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(regularPrice);\n\n if (variantSeed.prices.sale !== undefined) {\n const salePrice = em.create(CatalogProductPrice, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n product,\n variant,\n offer,\n priceKind: saleKind,\n currencyCode: \"USD\",\n kind: saleKind.code,\n minQuantity: 1,\n taxRate: defaultTaxRateValue,\n unitPriceGross: formatMoney(variantSeed.prices.sale),\n unitPriceNet: formatMoney(variantSeed.prices.sale),\n channelId: channel.id,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n em.persist(salePrice);\n }\n\n if (\n variantSeed.customFields &&\n Object.keys(variantSeed.customFields).length\n ) {\n const payload = { ...variantSeed.customFields };\n customFieldAssignments.push(() =>\n dataEngine.setCustomFields({\n entityId: E.catalog.catalog_product_variant,\n recordId: variant.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n values: payload,\n }),\n );\n }\n }\n }\n\n if (!createdAny) {\n return false;\n }\n\n await em.flush();\n\n for (const assign of customFieldAssignments) {\n try {\n await assign();\n } catch (err) {\n logger.warn(\"catalog.seed failed to set example custom field values\", { err });\n }\n }\n\n return true;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,8 @@
1
1
  import { resolveNotificationService } from "../../notifications/lib/notificationService.js";
2
2
  import { buildFeatureNotificationFromType } from "../../notifications/lib/notificationBuilder.js";
3
3
  import { notificationTypes } from "../notifications.js";
4
+ import { createLogger } from "@open-mercato/shared/lib/logger";
5
+ const logger = createLogger("catalog");
4
6
  const metadata = {
5
7
  event: "catalog.product.stock_low",
6
8
  persistent: true,
@@ -28,7 +30,7 @@ async function handle(payload, ctx) {
28
30
  organizationId: payload.organizationId ?? null
29
31
  });
30
32
  } catch (err) {
31
- console.error("[catalog:low-stock-notification] Failed to create notification:", err);
33
+ logger.error("catalog.low-stock-notification Failed to create notification", { err });
32
34
  }
33
35
  }
34
36
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/catalog/subscribers/low-stock-notification.ts"],
4
- "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { resolveNotificationService } from '../../notifications/lib/notificationService'\nimport { buildFeatureNotificationFromType } from '../../notifications/lib/notificationBuilder'\nimport { notificationTypes } from '../notifications'\n\nexport const metadata = {\n event: 'catalog.product.stock_low',\n persistent: true,\n id: 'catalog:low-stock-notification',\n}\n\ntype LowStockPayload = {\n productId: string\n productName: string\n sku?: string | null\n currentStock: number\n threshold: number\n tenantId: string\n organizationId?: string | null\n}\n\ntype ResolverContext = {\n resolve: <T = unknown>(name: string) => T\n}\n\nexport default async function handle(payload: LowStockPayload, ctx: ResolverContext) {\n try {\n const notificationService = resolveNotificationService(ctx)\n const typeDef = notificationTypes.find((type) => type.type === 'catalog.product.low_stock')\n if (!typeDef) return\n\n const notificationInput = buildFeatureNotificationFromType(typeDef, {\n requiredFeature: 'catalog.products.manage',\n bodyVariables: {\n productName: payload.productName,\n sku: payload.sku ?? '',\n currentStock: String(payload.currentStock),\n threshold: String(payload.threshold),\n },\n sourceEntityType: 'catalog:product',\n sourceEntityId: payload.productId,\n linkHref: `/backend/catalog/products/${payload.productId}`,\n })\n\n await notificationService.createForFeature(notificationInput, {\n tenantId: payload.tenantId,\n organizationId: payload.organizationId ?? null,\n })\n } catch (err) {\n console.error('[catalog:low-stock-notification] Failed to create notification:', err)\n }\n}\n"],
5
- "mappings": "AACA,SAAS,kCAAkC;AAC3C,SAAS,wCAAwC;AACjD,SAAS,yBAAyB;AAE3B,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,IAAI;AACN;AAgBA,eAAO,OAA8B,SAA0B,KAAsB;AACnF,MAAI;AACF,UAAM,sBAAsB,2BAA2B,GAAG;AAC1D,UAAM,UAAU,kBAAkB,KAAK,CAAC,SAAS,KAAK,SAAS,2BAA2B;AAC1F,QAAI,CAAC,QAAS;AAEd,UAAM,oBAAoB,iCAAiC,SAAS;AAAA,MAClE,iBAAiB;AAAA,MACjB,eAAe;AAAA,QACb,aAAa,QAAQ;AAAA,QACrB,KAAK,QAAQ,OAAO;AAAA,QACpB,cAAc,OAAO,QAAQ,YAAY;AAAA,QACzC,WAAW,OAAO,QAAQ,SAAS;AAAA,MACrC;AAAA,MACA,kBAAkB;AAAA,MAClB,gBAAgB,QAAQ;AAAA,MACxB,UAAU,6BAA6B,QAAQ,SAAS;AAAA,IAC1D,CAAC;AAED,UAAM,oBAAoB,iBAAiB,mBAAmB;AAAA,MAC5D,UAAU,QAAQ;AAAA,MAClB,gBAAgB,QAAQ,kBAAkB;AAAA,IAC5C,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,MAAM,mEAAmE,GAAG;AAAA,EACtF;AACF;",
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { resolveNotificationService } from '../../notifications/lib/notificationService'\nimport { buildFeatureNotificationFromType } from '../../notifications/lib/notificationBuilder'\nimport { notificationTypes } from '../notifications'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('catalog')\n\nexport const metadata = {\n event: 'catalog.product.stock_low',\n persistent: true,\n id: 'catalog:low-stock-notification',\n}\n\ntype LowStockPayload = {\n productId: string\n productName: string\n sku?: string | null\n currentStock: number\n threshold: number\n tenantId: string\n organizationId?: string | null\n}\n\ntype ResolverContext = {\n resolve: <T = unknown>(name: string) => T\n}\n\nexport default async function handle(payload: LowStockPayload, ctx: ResolverContext) {\n try {\n const notificationService = resolveNotificationService(ctx)\n const typeDef = notificationTypes.find((type) => type.type === 'catalog.product.low_stock')\n if (!typeDef) return\n\n const notificationInput = buildFeatureNotificationFromType(typeDef, {\n requiredFeature: 'catalog.products.manage',\n bodyVariables: {\n productName: payload.productName,\n sku: payload.sku ?? '',\n currentStock: String(payload.currentStock),\n threshold: String(payload.threshold),\n },\n sourceEntityType: 'catalog:product',\n sourceEntityId: payload.productId,\n linkHref: `/backend/catalog/products/${payload.productId}`,\n })\n\n await notificationService.createForFeature(notificationInput, {\n tenantId: payload.tenantId,\n organizationId: payload.organizationId ?? null,\n })\n } catch (err) {\n logger.error('catalog.low-stock-notification Failed to create notification', { err })\n }\n}\n"],
5
+ "mappings": "AACA,SAAS,kCAAkC;AAC3C,SAAS,wCAAwC;AACjD,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAE7B,MAAM,SAAS,aAAa,SAAS;AAE9B,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,IAAI;AACN;AAgBA,eAAO,OAA8B,SAA0B,KAAsB;AACnF,MAAI;AACF,UAAM,sBAAsB,2BAA2B,GAAG;AAC1D,UAAM,UAAU,kBAAkB,KAAK,CAAC,SAAS,KAAK,SAAS,2BAA2B;AAC1F,QAAI,CAAC,QAAS;AAEd,UAAM,oBAAoB,iCAAiC,SAAS;AAAA,MAClE,iBAAiB;AAAA,MACjB,eAAe;AAAA,QACb,aAAa,QAAQ;AAAA,QACrB,KAAK,QAAQ,OAAO;AAAA,QACpB,cAAc,OAAO,QAAQ,YAAY;AAAA,QACzC,WAAW,OAAO,QAAQ,SAAS;AAAA,MACrC;AAAA,MACA,kBAAkB;AAAA,MAClB,gBAAgB,QAAQ;AAAA,MACxB,UAAU,6BAA6B,QAAQ,SAAS;AAAA,IAC1D,CAAC;AAED,UAAM,oBAAoB,iBAAiB,mBAAmB;AAAA,MAC5D,UAAU,QAAQ;AAAA,MAClB,gBAAgB,QAAQ,kBAAkB;AAAA,IAC5C,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,WAAO,MAAM,gEAAgE,EAAE,IAAI,CAAC;AAAA,EACtF;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,3 +1,5 @@
1
+ import { createLogger } from "@open-mercato/shared/lib/logger";
2
+ const logger = createLogger("catalog");
1
3
  let productSeoTranslator = null;
2
4
  function setProductSeoTranslator(t) {
3
5
  productSeoTranslator = t;
@@ -11,7 +13,7 @@ function publishProductSeoValidation(payload) {
11
13
  try {
12
14
  listener(payload);
13
15
  } catch (err) {
14
- console.error("[product-seo] Failed to notify listener", err);
16
+ logger.error("product-seo Failed to notify listener", { err });
15
17
  }
16
18
  });
17
19
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/catalog/widgets/injection/product-seo/state.ts"],
4
- "sourcesContent": ["import type { TranslateFn } from '@open-mercato/shared/lib/i18n/context'\n\nexport type ProductSeoValidationPayload = {\n ok: boolean\n issues: string[]\n message?: string\n}\n\n// The `onBeforeSave` validation hook (widget.ts) is a plain side-effect handler\n// with no React context, so it cannot call `useT`. The widget component (which\n// does have `useT`) publishes its translator here on mount; the hook reads it to\n// localize the save-block message (#3299). Undefined until the widget mounts \u2014\n// callers fall back to English via `evaluateProductSeo`'s default translator.\nlet productSeoTranslator: TranslateFn | null = null\n\nexport function setProductSeoTranslator(t: TranslateFn | null) {\n productSeoTranslator = t\n}\n\nexport function getProductSeoTranslator(): TranslateFn | undefined {\n return productSeoTranslator ?? undefined\n}\n\ntype Listener = (payload: ProductSeoValidationPayload) => void\n\nconst listeners = new Set<Listener>()\n\nexport function publishProductSeoValidation(payload: ProductSeoValidationPayload) {\n listeners.forEach((listener) => {\n try {\n listener(payload)\n } catch (err) {\n console.error('[product-seo] Failed to notify listener', err)\n }\n })\n}\n\nexport function subscribeProductSeoValidation(listener: Listener): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n"],
5
- "mappings": "AAaA,IAAI,uBAA2C;AAExC,SAAS,wBAAwB,GAAuB;AAC7D,yBAAuB;AACzB;AAEO,SAAS,0BAAmD;AACjE,SAAO,wBAAwB;AACjC;AAIA,MAAM,YAAY,oBAAI,IAAc;AAE7B,SAAS,4BAA4B,SAAsC;AAChF,YAAU,QAAQ,CAAC,aAAa;AAC9B,QAAI;AACF,eAAS,OAAO;AAAA,IAClB,SAAS,KAAK;AACZ,cAAQ,MAAM,2CAA2C,GAAG;AAAA,IAC9D;AAAA,EACF,CAAC;AACH;AAEO,SAAS,8BAA8B,UAAgC;AAC5E,YAAU,IAAI,QAAQ;AACtB,SAAO,MAAM,UAAU,OAAO,QAAQ;AACxC;",
4
+ "sourcesContent": ["import type { TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('catalog')\n\nexport type ProductSeoValidationPayload = {\n ok: boolean\n issues: string[]\n message?: string\n}\n\n// The `onBeforeSave` validation hook (widget.ts) is a plain side-effect handler\n// with no React context, so it cannot call `useT`. The widget component (which\n// does have `useT`) publishes its translator here on mount; the hook reads it to\n// localize the save-block message (#3299). Undefined until the widget mounts \u2014\n// callers fall back to English via `evaluateProductSeo`'s default translator.\nlet productSeoTranslator: TranslateFn | null = null\n\nexport function setProductSeoTranslator(t: TranslateFn | null) {\n productSeoTranslator = t\n}\n\nexport function getProductSeoTranslator(): TranslateFn | undefined {\n return productSeoTranslator ?? undefined\n}\n\ntype Listener = (payload: ProductSeoValidationPayload) => void\n\nconst listeners = new Set<Listener>()\n\nexport function publishProductSeoValidation(payload: ProductSeoValidationPayload) {\n listeners.forEach((listener) => {\n try {\n listener(payload)\n } catch (err) {\n logger.error('product-seo Failed to notify listener', { err })\n }\n })\n}\n\nexport function subscribeProductSeoValidation(listener: Listener): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n"],
5
+ "mappings": "AACA,SAAS,oBAAoB;AAE7B,MAAM,SAAS,aAAa,SAAS;AAarC,IAAI,uBAA2C;AAExC,SAAS,wBAAwB,GAAuB;AAC7D,yBAAuB;AACzB;AAEO,SAAS,0BAAmD;AACjE,SAAO,wBAAwB;AACjC;AAIA,MAAM,YAAY,oBAAI,IAAc;AAE7B,SAAS,4BAA4B,SAAsC;AAChF,YAAU,QAAQ,CAAC,aAAa;AAC9B,QAAI;AACF,eAAS,OAAO;AAAA,IAClB,SAAS,KAAK;AACZ,aAAO,MAAM,yCAAyC,EAAE,IAAI,CAAC;AAAA,IAC/D;AAAA,EACF,CAAC;AACH;AAEO,SAAS,8BAA8B,UAAgC;AAC5E,YAAU,IAAI,QAAQ;AACtB,SAAO,MAAM,UAAU,OAAO,QAAQ;AACxC;",
6
6
  "names": []
7
7
  }
@@ -12,6 +12,8 @@ import {
12
12
  OAuthStateError,
13
13
  verifyOAuthState
14
14
  } from "../../../../../lib/oauth-state.js";
15
+ import { createLogger } from "@open-mercato/shared/lib/logger";
16
+ const logger = createLogger("communication_channels").child({ component: "oauth-callback" });
15
17
  const metadata = {
16
18
  path: "/communication_channels/oauth/[provider]/callback",
17
19
  // No auth feature gate — the state cookie carries identity. The route still
@@ -130,9 +132,9 @@ async function GET(req, context) {
130
132
  stateExtra: statePayload.extra
131
133
  });
132
134
  } catch (err) {
133
- console.warn(
134
- `[communication_channels:oauth] code exchange failed for provider ${provider}:`,
135
- err instanceof Error ? err.message : err
135
+ logger.warn(
136
+ "code exchange failed for provider",
137
+ { provider, err }
136
138
  );
137
139
  return redirectWithFlash(req, returnUrl, {
138
140
  type: "error",
@@ -161,9 +163,9 @@ async function GET(req, context) {
161
163
  );
162
164
  credentialsPersisted = true;
163
165
  } catch (err) {
164
- console.warn(
165
- `[communication_channels:oauth] persisting credentials failed for provider ${provider}:`,
166
- err instanceof Error ? err.message : err
166
+ logger.warn(
167
+ "persisting credentials failed for provider",
168
+ { provider, err }
167
169
  );
168
170
  }
169
171
  }
@@ -205,9 +207,7 @@ async function GET(req, context) {
205
207
  });
206
208
  } catch (err) {
207
209
  if (err instanceof MailboxAlreadyConnectedError) {
208
- console.warn(
209
- `[communication_channels:oauth] mailbox ${err.externalIdentifier} already connected via ${err.existingProviderKey}`
210
- );
210
+ logger.warn("mailbox already connected via another provider", { existingProviderKey: err.existingProviderKey });
211
211
  return redirectWithFlash(req, returnUrl, {
212
212
  type: "error",
213
213
  code: "mailbox_already_connected",
@@ -230,8 +230,9 @@ async function GET(req, context) {
230
230
  input: { channelId: channel.id }
231
231
  });
232
232
  } catch (err) {
233
- console.warn(
234
- `[oauth-callback] best-effort pushRegister failed for ${channel.id}: ${err instanceof Error ? err.message : String(err)}`
233
+ logger.warn(
234
+ "best-effort pushRegister failed for channel",
235
+ { channelId: channel.id, err }
235
236
  );
236
237
  }
237
238
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../src/modules/communication_channels/api/get/oauth/%5Bprovider%5D/callback/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { toAbsoluteUrl } from '@open-mercato/shared/lib/url'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { createConnectedChannelRow, MailboxAlreadyConnectedError } from '../../../../../lib/connect-channel'\nimport { getChannelAdapter } from '../../../../../lib/adapter-registry-singleton'\nimport { resolveOAuthClientCredentials } from '../../../../../lib/oauth-client-config'\nimport {\n COMMUNICATION_CHANNELS_OAUTH_STATE_COOKIE_NAME,\n DEFAULT_OAUTH_RETURN_URL,\n normalizeOAuthReturnUrl,\n OAuthStateError,\n verifyOAuthState,\n} from '../../../../../lib/oauth-state'\n\nexport const metadata = {\n path: '/communication_channels/oauth/[provider]/callback',\n // No auth feature gate \u2014 the state cookie carries identity. The route still\n // verifies the session below to bind the callback to its initiator.\n GET: { requireAuth: true },\n}\n\ntype RouteContext = {\n params: Promise<{ provider: string }> | { provider: string }\n}\n\ntype CredentialsServiceLike = {\n resolve: (\n integrationId: string,\n scope: { organizationId: string; tenantId: string; userId?: string | null },\n ) => Promise<Record<string, unknown> | null>\n save?: (\n integrationId: string,\n credentials: Record<string, unknown>,\n scope: { organizationId: string; tenantId: string; userId?: string | null },\n ) => Promise<void>\n}\n\nfunction redirectWithFlash(\n req: Request,\n returnUrl: string,\n flash: { type: 'connected' | 'error'; code?: string; provider?: string; channelId?: string },\n): Response {\n const base = new URL(\n normalizeOAuthReturnUrl(returnUrl, DEFAULT_OAUTH_RETURN_URL),\n new URL(req.url).origin,\n )\n base.searchParams.set('flash', flash.type)\n if (flash.code) base.searchParams.set('code', flash.code)\n if (flash.provider) base.searchParams.set('provider', flash.provider)\n if (flash.channelId) base.searchParams.set('channelId', flash.channelId)\n const response = NextResponse.redirect(base.toString(), 302)\n response.cookies.set({\n name: COMMUNICATION_CHANNELS_OAUTH_STATE_COOKIE_NAME,\n value: '',\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n path: '/',\n maxAge: 0,\n })\n return response\n}\n\nexport async function GET(req: Request, context: RouteContext): Promise<Response> {\n const { provider } = await context.params\n const url = new URL(req.url)\n const code = url.searchParams.get('code') ?? ''\n const stateParam = url.searchParams.get('state') ?? ''\n const error = url.searchParams.get('error')\n\n if (error) {\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, { type: 'error', code: error, provider })\n }\n if (!code || !stateParam) {\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, {\n type: 'error',\n code: 'missing_code_or_state',\n provider,\n })\n }\n\n const auth = await getAuthFromRequest(req)\n if (!auth?.sub || !auth?.tenantId) {\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, {\n type: 'error',\n code: 'unauthorized',\n provider,\n })\n }\n\n const adapter = getChannelAdapter(provider)\n if (!adapter || typeof adapter.exchangeOAuthCode !== 'function') {\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, {\n type: 'error',\n code: 'unknown_provider',\n provider,\n })\n }\n\n const cookieValue = req.headers.get('cookie') ?? ''\n const stateCookie = parseCookie(cookieValue, COMMUNICATION_CHANNELS_OAUTH_STATE_COOKIE_NAME)\n\n let statePayload\n try {\n statePayload = verifyOAuthState({\n cookie: stateCookie,\n expectedUserId: auth.sub as string,\n expectedProviderKey: provider,\n expectedState: stateParam,\n })\n } catch (err) {\n const errCode = err instanceof OAuthStateError ? err.code : 'invalid_state'\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, {\n type: 'error',\n code: errCode,\n provider,\n })\n }\n\n // Defense-in-depth: the signed state is minted for a specific tenant at\n // initiate time and `verifyOAuthState` already binds it to `auth.sub`. Assert\n // the session tenant matches too, so a token/session anomaly can never create\n // a channel under a different tenant than the one that started the flow.\n if (statePayload.tenantId !== auth.tenantId) {\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, {\n type: 'error',\n code: 'tenant_mismatch',\n provider,\n })\n }\n\n const returnUrl = normalizeOAuthReturnUrl(statePayload.returnUrl, DEFAULT_OAUTH_RETURN_URL)\n\n // Exchange the code via the adapter.\n const container = await createRequestContainer()\n const credentialsService = (() => {\n try {\n return container.resolve('integrationCredentialsService') as CredentialsServiceLike\n } catch {\n return null\n }\n })()\n // Resolve the tenant's OAuth client app config from the `channel_<provider>`\n // integration (userId = null). Same source the `initiate` route uses; a\n // missing row means the provider was never configured, so bounce back with an\n // actionable code rather than attempting an exchange with empty credentials.\n const oauthClientCredentials = await resolveOAuthClientCredentials(credentialsService, provider, {\n tenantId: statePayload.tenantId,\n organizationId: statePayload.organizationId ?? null,\n })\n if (!oauthClientCredentials) {\n return redirectWithFlash(req, returnUrl, {\n type: 'error',\n code: 'oauth_client_not_configured',\n provider,\n })\n }\n\n // Must byte-for-byte match the redirect_uri sent at authorize time (the\n // `initiate` route), including behind a reverse proxy \u2014 derive it from the\n // configured app origin rather than the raw request URL.\n const redirectUri = toAbsoluteUrl(req, `/api/communication_channels/oauth/${provider}/callback`)\n\n let exchange\n try {\n exchange = await adapter.exchangeOAuthCode({\n code,\n redirectUri,\n credentials: oauthClientCredentials,\n scope: {\n tenantId: statePayload.tenantId,\n organizationId: statePayload.organizationId ?? statePayload.tenantId,\n },\n stateExtra: statePayload.extra,\n })\n } catch (err) {\n console.warn(\n `[communication_channels:oauth] code exchange failed for provider ${provider}:`,\n err instanceof Error ? err.message : err,\n )\n return redirectWithFlash(req, returnUrl, {\n type: 'error',\n code: 'exchange_failed',\n provider,\n })\n }\n\n // Persist the encrypted credentials under a per-user `integration_credentials`\n // row, then create / update the per-user `CommunicationChannel`.\n const em = (container.resolve('em') as EntityManager).fork()\n // Per-user scope: pass `userId` so the credentials service writes to a\n // user-scoped row instead of overwriting the tenant-wide row. Without this,\n // two users on the same tenant share one credentials row (see review R2-C1\n // / N1, 2026-05-26).\n const credentialsScope = {\n tenantId: statePayload.tenantId,\n organizationId: statePayload.organizationId ?? statePayload.tenantId,\n userId: auth.sub as string,\n }\n let credentialsRefId: string | null = null\n let credentialsPersisted = false\n if (credentialsService?.save) {\n try {\n // Save under a per-provider integration id namespace; per-user scoping is\n // recorded on `IntegrationCredentials.user_id` via the `scope.userId`.\n // Arg order MUST be (integrationId, credentials, scope) \u2014 matches the real\n // CredentialsService signature; the legacy reversed order corrupted the\n // saved row by writing the scope object into the credentials field.\n await credentialsService.save(\n `channel_${provider}`,\n {\n ...exchange.credentials,\n userId: auth.sub,\n expiresAt: exchange.expiresAt ? exchange.expiresAt.toISOString() : undefined,\n },\n credentialsScope,\n )\n credentialsPersisted = true\n } catch (err) {\n console.warn(\n `[communication_channels:oauth] persisting credentials failed for provider ${provider}:`,\n err instanceof Error ? err.message : err,\n )\n }\n }\n // Resolve the saved row's id so we can link `channel.credentialsRef` to it.\n // `credentialsService.save` is `void`-returning by contract, so we re-find the\n // row immediately afterwards. Best-effort \u2014 null is acceptable; the channel\n // creation below will downgrade to `requires_reauth` so workers don't poll\n // a credential-less channel.\n if (credentialsPersisted) {\n try {\n const { IntegrationCredentials } = await import('@open-mercato/core/modules/integrations/data/entities')\n const { findOneWithDecryption } = await import('@open-mercato/shared/lib/encryption/find')\n const row = await findOneWithDecryption(\n em,\n IntegrationCredentials,\n {\n integrationId: `channel_${provider}`,\n tenantId: credentialsScope.tenantId,\n organizationId: credentialsScope.organizationId,\n userId: credentialsScope.userId,\n deletedAt: null,\n },\n undefined,\n credentialsScope,\n )\n credentialsRefId = (row as { id?: string } | null)?.id ?? null\n } catch {\n credentialsRefId = null\n }\n }\n\n const displayName =\n exchange.displayName ?? exchange.externalIdentifier ?? `${provider} channel`\n // Fail-safe: if credentials persistence failed (no `credentialsRef` available),\n // create the channel in `requires_reauth` so workers don't poll a channel that\n // has no usable credentials. The user can re-run the OAuth flow to recover\n // (see review R2-H4 / F6, 2026-05-26).\n const credentialsAvailable = credentialsRefId !== null\n let channel\n try {\n channel = await createConnectedChannelRow({\n em,\n adapter,\n providerKey: provider,\n displayName,\n externalIdentifier: exchange.externalIdentifier ?? null,\n credentialsRefId,\n userId: auth.sub as string,\n scope: { tenantId: statePayload.tenantId, organizationId: statePayload.organizationId ?? null },\n })\n } catch (err) {\n // Same mailbox already connected via another provider \u2014 don't create a second\n // channel that double-ingests every message; send the user back with a flash.\n if (err instanceof MailboxAlreadyConnectedError) {\n console.warn(\n `[communication_channels:oauth] mailbox ${err.externalIdentifier} already connected via ${err.existingProviderKey}`,\n )\n return redirectWithFlash(req, returnUrl, {\n type: 'error',\n code: 'mailbox_already_connected',\n provider,\n })\n }\n throw err\n }\n\n // Spec C \u00A7 Phase C5 \u2014 best-effort push registration for OAuth providers\n // that support it (Gmail). Same shape as the credential-connect\n // path: failures persist as `pushStatus='failed'` on channelState and DO\n // NOT fail the connect \u2014 polling fallback covers until the operator clicks\n // \"Re-register push\" on the channels page.\n const adapterSupportsPush =\n typeof adapter.registerPush === 'function' && typeof adapter.unregisterPush === 'function'\n if (\n credentialsAvailable &&\n adapterSupportsPush &&\n statePayload.organizationId &&\n provider === 'gmail'\n ) {\n try {\n const { pushRegister } = await import('../../../../../commands/push-register')\n await pushRegister({\n container,\n scope: {\n tenantId: statePayload.tenantId,\n organizationId: statePayload.organizationId,\n userId: auth.sub as string,\n },\n input: { channelId: channel.id },\n })\n } catch (err) {\n console.warn(\n `[oauth-callback] best-effort pushRegister failed for ${channel.id}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n }\n\n return redirectWithFlash(req, returnUrl, {\n type: 'connected',\n provider,\n channelId: channel.id,\n })\n}\n\nfunction parseCookie(header: string, name: string): string | null {\n if (!header) return null\n const segments = header.split(';')\n for (const segment of segments) {\n const trimmed = segment.trim()\n if (trimmed.startsWith(`${name}=`)) {\n return decodeURIComponent(trimmed.slice(name.length + 1))\n }\n }\n return null\n}\n\nexport const openApi = {\n tags: ['CommunicationChannels'],\n methods: {\n GET: {\n summary: 'OAuth callback \u2014 exchange code, persist credentials, create per-user channel',\n tags: ['CommunicationChannels'],\n responses: [\n { status: 302, description: 'Redirect back to returnUrl with flash query params' },\n ],\n },\n },\n}\nexport default GET\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { toAbsoluteUrl } from '@open-mercato/shared/lib/url'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { createConnectedChannelRow, MailboxAlreadyConnectedError } from '../../../../../lib/connect-channel'\nimport { getChannelAdapter } from '../../../../../lib/adapter-registry-singleton'\nimport { resolveOAuthClientCredentials } from '../../../../../lib/oauth-client-config'\nimport {\n COMMUNICATION_CHANNELS_OAUTH_STATE_COOKIE_NAME,\n DEFAULT_OAUTH_RETURN_URL,\n normalizeOAuthReturnUrl,\n OAuthStateError,\n verifyOAuthState,\n} from '../../../../../lib/oauth-state'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('communication_channels').child({ component: 'oauth-callback' })\n\nexport const metadata = {\n path: '/communication_channels/oauth/[provider]/callback',\n // No auth feature gate \u2014 the state cookie carries identity. The route still\n // verifies the session below to bind the callback to its initiator.\n GET: { requireAuth: true },\n}\n\ntype RouteContext = {\n params: Promise<{ provider: string }> | { provider: string }\n}\n\ntype CredentialsServiceLike = {\n resolve: (\n integrationId: string,\n scope: { organizationId: string; tenantId: string; userId?: string | null },\n ) => Promise<Record<string, unknown> | null>\n save?: (\n integrationId: string,\n credentials: Record<string, unknown>,\n scope: { organizationId: string; tenantId: string; userId?: string | null },\n ) => Promise<void>\n}\n\nfunction redirectWithFlash(\n req: Request,\n returnUrl: string,\n flash: { type: 'connected' | 'error'; code?: string; provider?: string; channelId?: string },\n): Response {\n const base = new URL(\n normalizeOAuthReturnUrl(returnUrl, DEFAULT_OAUTH_RETURN_URL),\n new URL(req.url).origin,\n )\n base.searchParams.set('flash', flash.type)\n if (flash.code) base.searchParams.set('code', flash.code)\n if (flash.provider) base.searchParams.set('provider', flash.provider)\n if (flash.channelId) base.searchParams.set('channelId', flash.channelId)\n const response = NextResponse.redirect(base.toString(), 302)\n response.cookies.set({\n name: COMMUNICATION_CHANNELS_OAUTH_STATE_COOKIE_NAME,\n value: '',\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n path: '/',\n maxAge: 0,\n })\n return response\n}\n\nexport async function GET(req: Request, context: RouteContext): Promise<Response> {\n const { provider } = await context.params\n const url = new URL(req.url)\n const code = url.searchParams.get('code') ?? ''\n const stateParam = url.searchParams.get('state') ?? ''\n const error = url.searchParams.get('error')\n\n if (error) {\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, { type: 'error', code: error, provider })\n }\n if (!code || !stateParam) {\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, {\n type: 'error',\n code: 'missing_code_or_state',\n provider,\n })\n }\n\n const auth = await getAuthFromRequest(req)\n if (!auth?.sub || !auth?.tenantId) {\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, {\n type: 'error',\n code: 'unauthorized',\n provider,\n })\n }\n\n const adapter = getChannelAdapter(provider)\n if (!adapter || typeof adapter.exchangeOAuthCode !== 'function') {\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, {\n type: 'error',\n code: 'unknown_provider',\n provider,\n })\n }\n\n const cookieValue = req.headers.get('cookie') ?? ''\n const stateCookie = parseCookie(cookieValue, COMMUNICATION_CHANNELS_OAUTH_STATE_COOKIE_NAME)\n\n let statePayload\n try {\n statePayload = verifyOAuthState({\n cookie: stateCookie,\n expectedUserId: auth.sub as string,\n expectedProviderKey: provider,\n expectedState: stateParam,\n })\n } catch (err) {\n const errCode = err instanceof OAuthStateError ? err.code : 'invalid_state'\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, {\n type: 'error',\n code: errCode,\n provider,\n })\n }\n\n // Defense-in-depth: the signed state is minted for a specific tenant at\n // initiate time and `verifyOAuthState` already binds it to `auth.sub`. Assert\n // the session tenant matches too, so a token/session anomaly can never create\n // a channel under a different tenant than the one that started the flow.\n if (statePayload.tenantId !== auth.tenantId) {\n return redirectWithFlash(req, DEFAULT_OAUTH_RETURN_URL, {\n type: 'error',\n code: 'tenant_mismatch',\n provider,\n })\n }\n\n const returnUrl = normalizeOAuthReturnUrl(statePayload.returnUrl, DEFAULT_OAUTH_RETURN_URL)\n\n // Exchange the code via the adapter.\n const container = await createRequestContainer()\n const credentialsService = (() => {\n try {\n return container.resolve('integrationCredentialsService') as CredentialsServiceLike\n } catch {\n return null\n }\n })()\n // Resolve the tenant's OAuth client app config from the `channel_<provider>`\n // integration (userId = null). Same source the `initiate` route uses; a\n // missing row means the provider was never configured, so bounce back with an\n // actionable code rather than attempting an exchange with empty credentials.\n const oauthClientCredentials = await resolveOAuthClientCredentials(credentialsService, provider, {\n tenantId: statePayload.tenantId,\n organizationId: statePayload.organizationId ?? null,\n })\n if (!oauthClientCredentials) {\n return redirectWithFlash(req, returnUrl, {\n type: 'error',\n code: 'oauth_client_not_configured',\n provider,\n })\n }\n\n // Must byte-for-byte match the redirect_uri sent at authorize time (the\n // `initiate` route), including behind a reverse proxy \u2014 derive it from the\n // configured app origin rather than the raw request URL.\n const redirectUri = toAbsoluteUrl(req, `/api/communication_channels/oauth/${provider}/callback`)\n\n let exchange\n try {\n exchange = await adapter.exchangeOAuthCode({\n code,\n redirectUri,\n credentials: oauthClientCredentials,\n scope: {\n tenantId: statePayload.tenantId,\n organizationId: statePayload.organizationId ?? statePayload.tenantId,\n },\n stateExtra: statePayload.extra,\n })\n } catch (err) {\n logger.warn(\n 'code exchange failed for provider',\n { provider, err },\n )\n return redirectWithFlash(req, returnUrl, {\n type: 'error',\n code: 'exchange_failed',\n provider,\n })\n }\n\n // Persist the encrypted credentials under a per-user `integration_credentials`\n // row, then create / update the per-user `CommunicationChannel`.\n const em = (container.resolve('em') as EntityManager).fork()\n // Per-user scope: pass `userId` so the credentials service writes to a\n // user-scoped row instead of overwriting the tenant-wide row. Without this,\n // two users on the same tenant share one credentials row (see review R2-C1\n // / N1, 2026-05-26).\n const credentialsScope = {\n tenantId: statePayload.tenantId,\n organizationId: statePayload.organizationId ?? statePayload.tenantId,\n userId: auth.sub as string,\n }\n let credentialsRefId: string | null = null\n let credentialsPersisted = false\n if (credentialsService?.save) {\n try {\n // Save under a per-provider integration id namespace; per-user scoping is\n // recorded on `IntegrationCredentials.user_id` via the `scope.userId`.\n // Arg order MUST be (integrationId, credentials, scope) \u2014 matches the real\n // CredentialsService signature; the legacy reversed order corrupted the\n // saved row by writing the scope object into the credentials field.\n await credentialsService.save(\n `channel_${provider}`,\n {\n ...exchange.credentials,\n userId: auth.sub,\n expiresAt: exchange.expiresAt ? exchange.expiresAt.toISOString() : undefined,\n },\n credentialsScope,\n )\n credentialsPersisted = true\n } catch (err) {\n logger.warn(\n 'persisting credentials failed for provider',\n { provider, err },\n )\n }\n }\n // Resolve the saved row's id so we can link `channel.credentialsRef` to it.\n // `credentialsService.save` is `void`-returning by contract, so we re-find the\n // row immediately afterwards. Best-effort \u2014 null is acceptable; the channel\n // creation below will downgrade to `requires_reauth` so workers don't poll\n // a credential-less channel.\n if (credentialsPersisted) {\n try {\n const { IntegrationCredentials } = await import('@open-mercato/core/modules/integrations/data/entities')\n const { findOneWithDecryption } = await import('@open-mercato/shared/lib/encryption/find')\n const row = await findOneWithDecryption(\n em,\n IntegrationCredentials,\n {\n integrationId: `channel_${provider}`,\n tenantId: credentialsScope.tenantId,\n organizationId: credentialsScope.organizationId,\n userId: credentialsScope.userId,\n deletedAt: null,\n },\n undefined,\n credentialsScope,\n )\n credentialsRefId = (row as { id?: string } | null)?.id ?? null\n } catch {\n credentialsRefId = null\n }\n }\n\n const displayName =\n exchange.displayName ?? exchange.externalIdentifier ?? `${provider} channel`\n // Fail-safe: if credentials persistence failed (no `credentialsRef` available),\n // create the channel in `requires_reauth` so workers don't poll a channel that\n // has no usable credentials. The user can re-run the OAuth flow to recover\n // (see review R2-H4 / F6, 2026-05-26).\n const credentialsAvailable = credentialsRefId !== null\n let channel\n try {\n channel = await createConnectedChannelRow({\n em,\n adapter,\n providerKey: provider,\n displayName,\n externalIdentifier: exchange.externalIdentifier ?? null,\n credentialsRefId,\n userId: auth.sub as string,\n scope: { tenantId: statePayload.tenantId, organizationId: statePayload.organizationId ?? null },\n })\n } catch (err) {\n // Same mailbox already connected via another provider \u2014 don't create a second\n // channel that double-ingests every message; send the user back with a flash.\n if (err instanceof MailboxAlreadyConnectedError) {\n logger.warn('mailbox already connected via another provider', { existingProviderKey: err.existingProviderKey })\n return redirectWithFlash(req, returnUrl, {\n type: 'error',\n code: 'mailbox_already_connected',\n provider,\n })\n }\n throw err\n }\n\n // Spec C \u00A7 Phase C5 \u2014 best-effort push registration for OAuth providers\n // that support it (Gmail). Same shape as the credential-connect\n // path: failures persist as `pushStatus='failed'` on channelState and DO\n // NOT fail the connect \u2014 polling fallback covers until the operator clicks\n // \"Re-register push\" on the channels page.\n const adapterSupportsPush =\n typeof adapter.registerPush === 'function' && typeof adapter.unregisterPush === 'function'\n if (\n credentialsAvailable &&\n adapterSupportsPush &&\n statePayload.organizationId &&\n provider === 'gmail'\n ) {\n try {\n const { pushRegister } = await import('../../../../../commands/push-register')\n await pushRegister({\n container,\n scope: {\n tenantId: statePayload.tenantId,\n organizationId: statePayload.organizationId,\n userId: auth.sub as string,\n },\n input: { channelId: channel.id },\n })\n } catch (err) {\n logger.warn(\n 'best-effort pushRegister failed for channel',\n { channelId: channel.id, err },\n )\n }\n }\n\n return redirectWithFlash(req, returnUrl, {\n type: 'connected',\n provider,\n channelId: channel.id,\n })\n}\n\nfunction parseCookie(header: string, name: string): string | null {\n if (!header) return null\n const segments = header.split(';')\n for (const segment of segments) {\n const trimmed = segment.trim()\n if (trimmed.startsWith(`${name}=`)) {\n return decodeURIComponent(trimmed.slice(name.length + 1))\n }\n }\n return null\n}\n\nexport const openApi = {\n tags: ['CommunicationChannels'],\n methods: {\n GET: {\n summary: 'OAuth callback \u2014 exchange code, persist credentials, create per-user channel',\n tags: ['CommunicationChannels'],\n responses: [\n { status: 302, description: 'Redirect back to returnUrl with flash query params' },\n ],\n },\n },\n}\nexport default GET\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -10,6 +10,8 @@ import {
10
10
  queueImportHistorySchema
11
11
  } from "../../../../../commands/queue-import-history.js";
12
12
  import { validateRouteMutationGuard } from "../../../../../lib/route-mutation-guard.js";
13
+ import { createLogger } from "@open-mercato/shared/lib/logger";
14
+ const logger = createLogger("communication_channels").child({ component: "import-history" });
13
15
  const metadata = {
14
16
  path: "/communication_channels/channels/[id]/import-history",
15
17
  POST: {
@@ -126,7 +128,7 @@ async function POST(req, context) {
126
128
  { status: candidate.status }
127
129
  );
128
130
  }
129
- console.error(`[import-history] failed to enqueue for channel ${id}:`, err);
131
+ logger.error("failed to enqueue for channel", { channelId: id, err });
130
132
  return NextResponse.json(
131
133
  { error: err instanceof Error ? err.message : "Failed to queue import-history" },
132
134
  { status: 500 }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../src/modules/communication_channels/api/post/channels/%5Bid%5D/import-history/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { CrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { CommunicationChannel } from '../../../../../data/entities'\nimport { ChannelAccessDeniedError, assertCanManageChannel } from '../../../../../lib/access-control'\nimport {\n queueImportHistory,\n queueImportHistorySchema,\n} from '../../../../../commands/queue-import-history'\nimport { validateRouteMutationGuard } from '../../../../../lib/route-mutation-guard'\n\ntype RbacServiceLike = {\n loadAcl: (\n userId: string,\n scope: { tenantId: string | null; organizationId: string | null },\n ) => Promise<{ isSuperAdmin: boolean; features: string[]; organizations: string[] | null }>\n}\n\n/**\n * Spec B \u00A7 Phase B6 \u2014 operator-triggered backlog import.\n *\n * Enqueues a `channel-import-history` job that calls\n * `adapter.importHistory(...)` paginated up to `maxMessages`, routes each\n * message through `ingest-inbound-message`, and reports progress on a\n * `ProgressJob` consumed by the existing ProgressTopBar.\n *\n * Owner self-service: a user may import history for their OWN mailbox (gated by\n * `connect_user_channel`). Importing into a shared/tenant-wide channel still\n * requires `communication_channels.channel.import_history` \u2014 enforced per\n * channel type by `assertCanManageChannel` in the handler.\n */\nexport const metadata = {\n path: '/communication_channels/channels/[id]/import-history',\n POST: {\n requireAuth: true,\n requireFeatures: ['communication_channels.connect_user_channel'],\n },\n}\n\ntype RouteContext = {\n params: Promise<{ id: string }> | { id: string }\n}\n\nconst bodySchema = queueImportHistorySchema.omit({ channelId: true })\n\nexport async function POST(req: Request, context: RouteContext): Promise<Response> {\n const { id } = await context.params\n if (!z.string().uuid().safeParse(id).success) {\n return NextResponse.json({ error: 'Invalid channel id' }, { status: 400 })\n }\n\n const auth = await getAuthFromRequest(req)\n if (!auth?.sub || !auth?.tenantId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n // Parse body defensively \u2014 the route is called from a CrudForm dialog, but\n // also from automated tests / scripts.\n let rawBody: unknown\n try {\n const text = await req.text()\n rawBody = text ? JSON.parse(text) : {}\n } catch {\n return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 })\n }\n const parsed = bodySchema.safeParse(rawBody)\n if (!parsed.success) {\n const first = parsed.error.issues[0]\n return NextResponse.json(\n {\n error: first?.message ?? 'Invalid request',\n fieldErrors: first ? { [first.path.join('.')]: first.message } : undefined,\n },\n { status: 400 },\n )\n }\n\n const container = await createRequestContainer()\n const em = (container.resolve('em') as EntityManager).fork()\n const organizationId = (auth as { orgId?: string | null }).orgId ?? null\n if (!organizationId) {\n return NextResponse.json({ error: 'No organization scope' }, { status: 400 })\n }\n const dscope = { tenantId: auth.tenantId as string, organizationId }\n\n // Per-user access guard \u2014 load the channel just to check ownership; the\n // command repeats the lookup but at the cost of one extra read we get a\n // clean 404 for non-owners (instead of a generic 500 from inside the cmd).\n const channel = await findOneWithDecryption(\n em,\n CommunicationChannel,\n {\n id,\n tenantId: auth.tenantId as string,\n organizationId,\n deletedAt: null,\n },\n undefined,\n dscope,\n )\n if (!channel) {\n return NextResponse.json({ error: 'Channel not found' }, { status: 404 })\n }\n\n let userFeatures: string[] = []\n try {\n const rbac = container.resolve('rbacService') as RbacServiceLike\n const acl = await rbac.loadAcl(auth.sub as string, {\n tenantId: auth.tenantId as string,\n organizationId,\n })\n userFeatures = acl?.isSuperAdmin ? ['*'] : Array.isArray(acl?.features) ? acl.features : []\n } catch {\n userFeatures = []\n }\n try {\n assertCanManageChannel(\n { userId: (channel as { userId?: string | null }).userId },\n auth.sub as string,\n userFeatures,\n 'communication_channels.channel.import_history',\n )\n } catch (err) {\n if (err instanceof ChannelAccessDeniedError) {\n return NextResponse.json({ error: 'Channel not found' }, { status: 404 })\n }\n throw err\n }\n\n const guard = await validateRouteMutationGuard({\n container,\n req,\n auth,\n input: {\n resourceKind: 'communication_channels.channel',\n resourceId: id,\n operation: 'custom',\n mutationPayload: parsed.data as unknown as Record<string, unknown>,\n },\n })\n if ('response' in guard) return guard.response\n\n try {\n const result = await queueImportHistory({\n container,\n scope: {\n tenantId: auth.tenantId as string,\n organizationId,\n userId: auth.sub as string,\n },\n input: { channelId: id, ...parsed.data },\n })\n await guard.afterSuccess()\n // 202 Accepted: durable work runs in the channel-import-history worker; the\n // response carries progressJobId for the ProgressTopBar (progress module contract).\n return NextResponse.json({ ok: true, ...result }, { status: 202 })\n } catch (err) {\n const candidate = err as CrudFormError\n if (candidate && typeof candidate.status === 'number') {\n return NextResponse.json(\n {\n error: candidate.message,\n fieldErrors: candidate.fieldErrors,\n },\n { status: candidate.status },\n )\n }\n console.error(`[import-history] failed to enqueue for channel ${id}:`, err)\n return NextResponse.json(\n { error: err instanceof Error ? err.message : 'Failed to queue import-history' },\n { status: 500 },\n )\n }\n}\n\nexport const openApi = {\n tags: ['CommunicationChannels'],\n methods: {\n POST: {\n summary: 'Queue a backlog import for a channel (Spec B \u00A7 Phase B6)',\n tags: ['CommunicationChannels'],\n requestBody: {\n required: true,\n contentType: 'application/json',\n schema: bodySchema,\n },\n responses: [\n { status: 202, description: 'Import job queued; returns { progressJobId }' },\n { status: 400, description: 'Invalid channel id or unsupported provider' },\n { status: 401, description: 'Unauthorized' },\n { status: 404, description: 'Channel not found / not accessible' },\n { status: 409, description: 'Channel is not connected (requires reauth / error)' },\n {\n status: 429,\n description: 'Another import is already running for this channel',\n },\n ],\n },\n },\n}\n\nexport default POST\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { CrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { CommunicationChannel } from '../../../../../data/entities'\nimport { ChannelAccessDeniedError, assertCanManageChannel } from '../../../../../lib/access-control'\nimport {\n queueImportHistory,\n queueImportHistorySchema,\n} from '../../../../../commands/queue-import-history'\nimport { validateRouteMutationGuard } from '../../../../../lib/route-mutation-guard'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('communication_channels').child({ component: 'import-history' })\n\ntype RbacServiceLike = {\n loadAcl: (\n userId: string,\n scope: { tenantId: string | null; organizationId: string | null },\n ) => Promise<{ isSuperAdmin: boolean; features: string[]; organizations: string[] | null }>\n}\n\n/**\n * Spec B \u00A7 Phase B6 \u2014 operator-triggered backlog import.\n *\n * Enqueues a `channel-import-history` job that calls\n * `adapter.importHistory(...)` paginated up to `maxMessages`, routes each\n * message through `ingest-inbound-message`, and reports progress on a\n * `ProgressJob` consumed by the existing ProgressTopBar.\n *\n * Owner self-service: a user may import history for their OWN mailbox (gated by\n * `connect_user_channel`). Importing into a shared/tenant-wide channel still\n * requires `communication_channels.channel.import_history` \u2014 enforced per\n * channel type by `assertCanManageChannel` in the handler.\n */\nexport const metadata = {\n path: '/communication_channels/channels/[id]/import-history',\n POST: {\n requireAuth: true,\n requireFeatures: ['communication_channels.connect_user_channel'],\n },\n}\n\ntype RouteContext = {\n params: Promise<{ id: string }> | { id: string }\n}\n\nconst bodySchema = queueImportHistorySchema.omit({ channelId: true })\n\nexport async function POST(req: Request, context: RouteContext): Promise<Response> {\n const { id } = await context.params\n if (!z.string().uuid().safeParse(id).success) {\n return NextResponse.json({ error: 'Invalid channel id' }, { status: 400 })\n }\n\n const auth = await getAuthFromRequest(req)\n if (!auth?.sub || !auth?.tenantId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n // Parse body defensively \u2014 the route is called from a CrudForm dialog, but\n // also from automated tests / scripts.\n let rawBody: unknown\n try {\n const text = await req.text()\n rawBody = text ? JSON.parse(text) : {}\n } catch {\n return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 })\n }\n const parsed = bodySchema.safeParse(rawBody)\n if (!parsed.success) {\n const first = parsed.error.issues[0]\n return NextResponse.json(\n {\n error: first?.message ?? 'Invalid request',\n fieldErrors: first ? { [first.path.join('.')]: first.message } : undefined,\n },\n { status: 400 },\n )\n }\n\n const container = await createRequestContainer()\n const em = (container.resolve('em') as EntityManager).fork()\n const organizationId = (auth as { orgId?: string | null }).orgId ?? null\n if (!organizationId) {\n return NextResponse.json({ error: 'No organization scope' }, { status: 400 })\n }\n const dscope = { tenantId: auth.tenantId as string, organizationId }\n\n // Per-user access guard \u2014 load the channel just to check ownership; the\n // command repeats the lookup but at the cost of one extra read we get a\n // clean 404 for non-owners (instead of a generic 500 from inside the cmd).\n const channel = await findOneWithDecryption(\n em,\n CommunicationChannel,\n {\n id,\n tenantId: auth.tenantId as string,\n organizationId,\n deletedAt: null,\n },\n undefined,\n dscope,\n )\n if (!channel) {\n return NextResponse.json({ error: 'Channel not found' }, { status: 404 })\n }\n\n let userFeatures: string[] = []\n try {\n const rbac = container.resolve('rbacService') as RbacServiceLike\n const acl = await rbac.loadAcl(auth.sub as string, {\n tenantId: auth.tenantId as string,\n organizationId,\n })\n userFeatures = acl?.isSuperAdmin ? ['*'] : Array.isArray(acl?.features) ? acl.features : []\n } catch {\n userFeatures = []\n }\n try {\n assertCanManageChannel(\n { userId: (channel as { userId?: string | null }).userId },\n auth.sub as string,\n userFeatures,\n 'communication_channels.channel.import_history',\n )\n } catch (err) {\n if (err instanceof ChannelAccessDeniedError) {\n return NextResponse.json({ error: 'Channel not found' }, { status: 404 })\n }\n throw err\n }\n\n const guard = await validateRouteMutationGuard({\n container,\n req,\n auth,\n input: {\n resourceKind: 'communication_channels.channel',\n resourceId: id,\n operation: 'custom',\n mutationPayload: parsed.data as unknown as Record<string, unknown>,\n },\n })\n if ('response' in guard) return guard.response\n\n try {\n const result = await queueImportHistory({\n container,\n scope: {\n tenantId: auth.tenantId as string,\n organizationId,\n userId: auth.sub as string,\n },\n input: { channelId: id, ...parsed.data },\n })\n await guard.afterSuccess()\n // 202 Accepted: durable work runs in the channel-import-history worker; the\n // response carries progressJobId for the ProgressTopBar (progress module contract).\n return NextResponse.json({ ok: true, ...result }, { status: 202 })\n } catch (err) {\n const candidate = err as CrudFormError\n if (candidate && typeof candidate.status === 'number') {\n return NextResponse.json(\n {\n error: candidate.message,\n fieldErrors: candidate.fieldErrors,\n },\n { status: candidate.status },\n )\n }\n logger.error('failed to enqueue for channel', { channelId: id, err })\n return NextResponse.json(\n { error: err instanceof Error ? err.message : 'Failed to queue import-history' },\n { status: 500 },\n )\n }\n}\n\nexport const openApi = {\n tags: ['CommunicationChannels'],\n methods: {\n POST: {\n summary: 'Queue a backlog import for a channel (Spec B \u00A7 Phase B6)',\n tags: ['CommunicationChannels'],\n requestBody: {\n required: true,\n contentType: 'application/json',\n schema: bodySchema,\n },\n responses: [\n { status: 202, description: 'Import job queued; returns { progressJobId }' },\n { status: 400, description: 'Invalid channel id or unsupported provider' },\n { status: 401, description: 'Unauthorized' },\n { status: 404, description: 'Channel not found / not accessible' },\n { status: 409, description: 'Channel is not connected (requires reauth / error)' },\n {\n status: 429,\n description: 'Another import is already running for this channel',\n },\n ],\n },\n },\n}\n\nexport default POST\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -7,6 +7,8 @@ import { CommunicationChannel } from "../../../../../../data/entities.js";
7
7
  import { ChannelAccessDeniedError, assertCanManageChannel } from "../../../../../../lib/access-control.js";
8
8
  import { pushRegister } from "../../../../../../commands/push-register.js";
9
9
  import { validateRouteMutationGuard } from "../../../../../../lib/route-mutation-guard.js";
10
+ import { createLogger } from "@open-mercato/shared/lib/logger";
11
+ const logger = createLogger("communication_channels").child({ component: "push-register" });
10
12
  const metadata = {
11
13
  path: "/communication_channels/channels/[id]/push/register",
12
14
  POST: {
@@ -91,7 +93,7 @@ async function POST(req, context) {
91
93
  { status: candidate.status }
92
94
  );
93
95
  }
94
- console.error(`[push-register] failed for channel ${id}:`, err);
96
+ logger.error("push register failed for channel", { channelId: id, err });
95
97
  return NextResponse.json(
96
98
  { error: err instanceof Error ? err.message : "Failed to register push" },
97
99
  { status: 500 }