@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/dictionaries/components/DictionaryEntrySelect.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { usePathname, useSearchParams } from 'next/navigation'\nimport { Plus, Settings, Save } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@open-mercato/ui/primitives/dialog'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { buildHrefWithReturnTo } from '@open-mercato/shared/lib/navigation/returnTo'\nimport { DictionaryValue, renderDictionaryColor, renderDictionaryIcon } from './dictionaryAppearance'\nimport { AppearanceSelector, type AppearanceSelectorLabels, useAppearanceState } from './AppearanceSelector'\n\nconst DEFAULT_APPEARANCE_LABELS: AppearanceSelectorLabels = {\n colorLabel: 'Color',\n colorHelp: 'Pick a highlight color for this entry.',\n colorClearLabel: 'Remove color',\n iconLabel: 'Icon or emoji',\n iconPlaceholder: 'Type an emoji or icon token.',\n iconPickerTriggerLabel: 'Browse icons and emoji',\n iconSearchPlaceholder: 'Search icons or emojis\u2026',\n iconSearchEmptyLabel: 'No icons match your search.',\n iconSuggestionsLabel: 'Suggestions',\n iconClearLabel: 'Remove icon',\n previewEmptyLabel: 'No appearance selected',\n}\n\nexport type DictionaryOption = {\n value: string\n label: string\n color: string | null\n icon: string | null\n}\n\nexport type DictionarySelectLabels = {\n placeholder: string\n addLabel: string\n addPrompt?: string\n dialogTitle: string\n valueLabel: string\n valuePlaceholder: string\n labelLabel: string\n labelPlaceholder: string\n emptyError: string\n cancelLabel: string\n saveLabel: string\n saveShortcutHint?: string\n successCreateLabel?: string\n errorLoad: string\n errorSave: string\n loadingLabel: string\n manageTitle: string\n}\n\nexport type DictionaryEntrySelectProps = {\n id?: string\n value?: string\n onChange: (value: string | undefined) => void\n fetchOptions: () => Promise<DictionaryOption[]>\n createOption?: (input: { value: string; label?: string; color?: string | null; icon?: string | null }) => Promise<DictionaryOption | null>\n labels: DictionarySelectLabels\n manageHref?: string\n selectClassName?: string\n seedOptions?: DictionaryOption[]\n allowInlineCreate?: boolean\n allowAppearance?: boolean\n appearanceLabels?: AppearanceSelectorLabels\n disabled?: boolean\n showLabelInput?: boolean\n showManage?: boolean\n sortOptions?: 'label_asc' | 'none'\n /**\n * When false, hides the read-only appearance preview (color swatch + icon + hex)\n * rendered below the trigger for the currently-selected entry. Defaults to true to\n * preserve existing behavior; set false where the host only wants a plain select\n * (e.g. a create form that shouldn't surface dictionary styling).\n */\n showActiveAppearance?: boolean\n}\n\nexport function DictionaryEntrySelect({\n id,\n value,\n onChange,\n fetchOptions,\n createOption,\n labels,\n manageHref,\n selectClassName,\n seedOptions,\n allowInlineCreate = true,\n allowAppearance = false,\n appearanceLabels,\n disabled: disabledProp = false,\n showLabelInput = true,\n showManage = true,\n sortOptions = 'label_asc',\n showActiveAppearance = true,\n}: DictionaryEntrySelectProps) {\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const [options, setOptions] = React.useState<DictionaryOption[]>([])\n const [loading, setLoading] = React.useState(true)\n const [saving, setSaving] = React.useState(false)\n const [dialogOpen, setDialogOpen] = React.useState(false)\n const [newValue, setNewValue] = React.useState('')\n const [newLabel, setNewLabel] = React.useState('')\n const [formError, setFormError] = React.useState<string | null>(null)\n const appearance = useAppearanceState(null, null)\n\n const loadOptions = React.useCallback(async () => {\n setLoading(true)\n try {\n const items = await fetchOptions()\n setOptions(sortOptions === 'none' ? items : items.slice().sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' })))\n } catch (err) {\n console.error('DictionaryEntrySelect.fetchOptions failed', err)\n flash(labels.errorLoad, 'error')\n setOptions([])\n } finally {\n setLoading(false)\n }\n }, [fetchOptions, labels.errorLoad, sortOptions])\n\n React.useEffect(() => {\n loadOptions().catch(() => {})\n }, [loadOptions])\n\n const resetDialogState = React.useCallback(() => {\n setNewValue('')\n setNewLabel('')\n setFormError(null)\n appearance.setColor(null)\n appearance.setIcon(null)\n setSaving(false)\n }, [appearance])\n\n React.useEffect(() => {\n if (!dialogOpen) resetDialogState()\n }, [dialogOpen, resetDialogState])\n\n const mergedOptions = React.useMemo(() => {\n if (!Array.isArray(seedOptions) || !seedOptions.length) return options\n const merged: DictionaryOption[] = []\n const seen = new Set<string>()\n for (const option of seedOptions) {\n if (!option.value || seen.has(option.value)) continue\n seen.add(option.value)\n merged.push(option)\n }\n for (const option of options) {\n if (seen.has(option.value)) continue\n seen.add(option.value)\n merged.push(option)\n }\n return merged\n }, [options, seedOptions])\n\n const activeOption = React.useMemo(\n () => mergedOptions.find((option) => option.value === value) ?? null,\n [mergedOptions, value],\n )\n const displayOptions = React.useMemo(() => {\n if (!value || activeOption) return mergedOptions\n return [\n {\n value,\n label: value,\n color: null,\n icon: null,\n },\n ...mergedOptions,\n ]\n }, [activeOption, mergedOptions, value])\n\n const handleCreate = React.useCallback(async () => {\n if (!createOption) return\n const trimmedValue = newValue.trim()\n if (!trimmedValue.length) {\n setFormError(labels.emptyError)\n return\n }\n setSaving(true)\n try {\n const payload = await createOption({\n value: trimmedValue,\n label: showLabelInput ? newLabel.trim() || undefined : undefined,\n color: allowAppearance && appearance.color ? appearance.color : undefined,\n icon: allowAppearance && appearance.icon ? appearance.icon : undefined,\n })\n if (!payload) throw new Error('createOption did not return an entry')\n setOptions((previous) => {\n const map = new Map(previous.map((option) => [option.value, option]))\n map.set(payload.value, {\n value: payload.value,\n label: payload.label,\n color: payload.color ?? null,\n icon: payload.icon ?? null,\n })\n const nextOptions = Array.from(map.values())\n return sortOptions === 'none'\n ? nextOptions\n : nextOptions.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))\n })\n await loadOptions()\n onChange(payload.value)\n setDialogOpen(false)\n if (labels.successCreateLabel) {\n flash(labels.successCreateLabel, 'success')\n }\n } catch (err) {\n console.error('DictionaryEntrySelect.createOption failed', err)\n flash(labels.errorSave, 'error')\n } finally {\n setSaving(false)\n }\n }, [\n allowAppearance,\n appearance.color,\n appearance.icon,\n createOption,\n labels.emptyError,\n labels.errorSave,\n labels.successCreateLabel,\n loadOptions,\n newLabel,\n newValue,\n onChange,\n sortOptions,\n ])\n\n const handleDialogKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n if (!saving) {\n setDialogOpen(false)\n }\n return\n }\n if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n if (!saving && newValue.trim().length) {\n handleCreate().catch(() => {})\n } else if (!saving && !newValue.trim().length) {\n setFormError(labels.emptyError)\n }\n }\n },\n [handleCreate, labels.emptyError, newValue, saving],\n )\n\n const shortcutHint = React.useMemo(() => {\n const provided = typeof labels.saveShortcutHint === 'string' ? labels.saveShortcutHint.trim() : ''\n if (provided.length) return provided\n return '\u2318/Ctrl + Enter'\n }, [labels.saveShortcutHint])\n\n const disabled = disabledProp || loading || saving\n const manageLink = manageHref ?? '/backend/config/dictionaries'\n const returnTo = React.useMemo(() => {\n const query = searchParams?.toString() ?? ''\n if (!pathname) return null\n return query.length ? `${pathname}?${query}` : pathname\n }, [pathname, searchParams])\n const manageLinkWithReturnTo = React.useMemo(\n () => buildHrefWithReturnTo(manageLink, returnTo),\n [manageLink, returnTo],\n )\n const optionsKey = React.useMemo(\n () => displayOptions.map((option) => `${option.value}:${option.label}`).join('\\0'),\n [displayOptions],\n )\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <Select\n key={`dictionary-entry:${value ?? ''}:${optionsKey}`}\n value={value ?? ''}\n onValueChange={(next) => {\n if (!next) return\n onChange(next)\n }}\n disabled={disabled}\n >\n <SelectTrigger\n id={id}\n className={selectClassName}\n title={activeOption?.label ?? undefined}\n >\n <SelectValue placeholder={labels.placeholder}>\n {activeOption?.label}\n </SelectValue>\n </SelectTrigger>\n <SelectContent>\n {displayOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <div className=\"flex items-center gap-1\">\n {allowInlineCreate && createOption ? (\n <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>\n <DialogTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n disabled={disabled}\n title={labels.addLabel}\n aria-label={labels.addLabel}\n >\n <Plus className=\"h-4 w-4\" />\n </Button>\n </DialogTrigger>\n <DialogContent className=\"sm:max-w-md\" onKeyDown={handleDialogKeyDown}>\n <DialogHeader>\n <DialogTitle>{labels.dialogTitle}</DialogTitle>\n {labels.addPrompt ? <DialogDescription>{labels.addPrompt}</DialogDescription> : null}\n </DialogHeader>\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">{labels.valueLabel}</label>\n <Input\n type=\"text\"\n value={newValue}\n onChange={(event) => {\n setNewValue(event.target.value)\n if (formError) setFormError(null)\n }}\n placeholder={labels.valuePlaceholder}\n autoFocus\n disabled={saving}\n />\n </div>\n {showLabelInput ? (\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">{labels.labelLabel}</label>\n <Input\n type=\"text\"\n value={newLabel}\n onChange={(event) => setNewLabel(event.target.value)}\n placeholder={labels.labelPlaceholder}\n disabled={saving}\n />\n </div>\n ) : null}\n {allowAppearance ? (\n <AppearanceSelector\n icon={appearance.icon}\n color={appearance.color}\n onIconChange={appearance.setIcon}\n onColorChange={appearance.setColor}\n labels={appearanceLabels ?? DEFAULT_APPEARANCE_LABELS}\n />\n ) : null}\n {formError ? <p className=\"text-sm text-red-600\">{formError}</p> : null}\n </div>\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setDialogOpen(false)} disabled={saving}>\n {labels.cancelLabel}\n </Button>\n <Button type=\"button\" onClick={handleCreate} disabled={saving || !newValue.trim()}>\n {saving ? <Spinner className=\"mr-2 h-4 w-4\" /> : <Save className=\"mr-2 h-4 w-4\" />}\n <span className=\"flex items-center gap-2\">\n <span>{labels.saveLabel}</span>\n {!saving ? (\n <span className=\"text-xs text-muted-foreground\">{`(${shortcutHint})`}</span>\n ) : null}\n </span>\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n ) : null}\n {showManage ? (\n <Button asChild variant=\"ghost\" size=\"icon\" title={labels.manageTitle} aria-label={labels.manageTitle}>\n <Link href={manageLinkWithReturnTo}>\n <Settings className=\"h-4 w-4\" />\n <span className=\"sr-only\">{labels.manageTitle}</span>\n </Link>\n </Button>\n ) : null}\n </div>\n </div>\n {showActiveAppearance && activeOption && (activeOption.icon || activeOption.color) ? (\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"inline-flex items-center gap-2 rounded border border-dashed px-2 py-1\">\n {activeOption.icon ? renderDictionaryIcon(activeOption.icon, 'h-4 w-4') : null}\n {activeOption.color ? renderDictionaryColor(activeOption.color, 'h-4 w-4 rounded-sm') : null}\n </span>\n {activeOption.color ? <span>{activeOption.color}</span> : null}\n </div>\n ) : null}\n {loading ? <div className=\"text-xs text-muted-foreground\">{labels.loadingLabel}</div> : null}\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { usePathname, useSearchParams } from 'next/navigation'\nimport { Plus, Settings, Save } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@open-mercato/ui/primitives/dialog'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { buildHrefWithReturnTo } from '@open-mercato/shared/lib/navigation/returnTo'\nimport { DictionaryValue, renderDictionaryColor, renderDictionaryIcon } from './dictionaryAppearance'\nimport { AppearanceSelector, type AppearanceSelectorLabels, useAppearanceState } from './AppearanceSelector'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('dictionaries').child({ component: 'DictionaryEntrySelect' })\n\nconst DEFAULT_APPEARANCE_LABELS: AppearanceSelectorLabels = {\n colorLabel: 'Color',\n colorHelp: 'Pick a highlight color for this entry.',\n colorClearLabel: 'Remove color',\n iconLabel: 'Icon or emoji',\n iconPlaceholder: 'Type an emoji or icon token.',\n iconPickerTriggerLabel: 'Browse icons and emoji',\n iconSearchPlaceholder: 'Search icons or emojis\u2026',\n iconSearchEmptyLabel: 'No icons match your search.',\n iconSuggestionsLabel: 'Suggestions',\n iconClearLabel: 'Remove icon',\n previewEmptyLabel: 'No appearance selected',\n}\n\nexport type DictionaryOption = {\n value: string\n label: string\n color: string | null\n icon: string | null\n}\n\nexport type DictionarySelectLabels = {\n placeholder: string\n addLabel: string\n addPrompt?: string\n dialogTitle: string\n valueLabel: string\n valuePlaceholder: string\n labelLabel: string\n labelPlaceholder: string\n emptyError: string\n cancelLabel: string\n saveLabel: string\n saveShortcutHint?: string\n successCreateLabel?: string\n errorLoad: string\n errorSave: string\n loadingLabel: string\n manageTitle: string\n}\n\nexport type DictionaryEntrySelectProps = {\n id?: string\n value?: string\n onChange: (value: string | undefined) => void\n fetchOptions: () => Promise<DictionaryOption[]>\n createOption?: (input: { value: string; label?: string; color?: string | null; icon?: string | null }) => Promise<DictionaryOption | null>\n labels: DictionarySelectLabels\n manageHref?: string\n selectClassName?: string\n seedOptions?: DictionaryOption[]\n allowInlineCreate?: boolean\n allowAppearance?: boolean\n appearanceLabels?: AppearanceSelectorLabels\n disabled?: boolean\n showLabelInput?: boolean\n showManage?: boolean\n sortOptions?: 'label_asc' | 'none'\n /**\n * When false, hides the read-only appearance preview (color swatch + icon + hex)\n * rendered below the trigger for the currently-selected entry. Defaults to true to\n * preserve existing behavior; set false where the host only wants a plain select\n * (e.g. a create form that shouldn't surface dictionary styling).\n */\n showActiveAppearance?: boolean\n}\n\nexport function DictionaryEntrySelect({\n id,\n value,\n onChange,\n fetchOptions,\n createOption,\n labels,\n manageHref,\n selectClassName,\n seedOptions,\n allowInlineCreate = true,\n allowAppearance = false,\n appearanceLabels,\n disabled: disabledProp = false,\n showLabelInput = true,\n showManage = true,\n sortOptions = 'label_asc',\n showActiveAppearance = true,\n}: DictionaryEntrySelectProps) {\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const [options, setOptions] = React.useState<DictionaryOption[]>([])\n const [loading, setLoading] = React.useState(true)\n const [saving, setSaving] = React.useState(false)\n const [dialogOpen, setDialogOpen] = React.useState(false)\n const [newValue, setNewValue] = React.useState('')\n const [newLabel, setNewLabel] = React.useState('')\n const [formError, setFormError] = React.useState<string | null>(null)\n const appearance = useAppearanceState(null, null)\n\n const loadOptions = React.useCallback(async () => {\n setLoading(true)\n try {\n const items = await fetchOptions()\n setOptions(sortOptions === 'none' ? items : items.slice().sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' })))\n } catch (err) {\n logger.error('Failed to fetch options', { err })\n flash(labels.errorLoad, 'error')\n setOptions([])\n } finally {\n setLoading(false)\n }\n }, [fetchOptions, labels.errorLoad, sortOptions])\n\n React.useEffect(() => {\n loadOptions().catch(() => {})\n }, [loadOptions])\n\n const resetDialogState = React.useCallback(() => {\n setNewValue('')\n setNewLabel('')\n setFormError(null)\n appearance.setColor(null)\n appearance.setIcon(null)\n setSaving(false)\n }, [appearance])\n\n React.useEffect(() => {\n if (!dialogOpen) resetDialogState()\n }, [dialogOpen, resetDialogState])\n\n const mergedOptions = React.useMemo(() => {\n if (!Array.isArray(seedOptions) || !seedOptions.length) return options\n const merged: DictionaryOption[] = []\n const seen = new Set<string>()\n for (const option of seedOptions) {\n if (!option.value || seen.has(option.value)) continue\n seen.add(option.value)\n merged.push(option)\n }\n for (const option of options) {\n if (seen.has(option.value)) continue\n seen.add(option.value)\n merged.push(option)\n }\n return merged\n }, [options, seedOptions])\n\n const activeOption = React.useMemo(\n () => mergedOptions.find((option) => option.value === value) ?? null,\n [mergedOptions, value],\n )\n const displayOptions = React.useMemo(() => {\n if (!value || activeOption) return mergedOptions\n return [\n {\n value,\n label: value,\n color: null,\n icon: null,\n },\n ...mergedOptions,\n ]\n }, [activeOption, mergedOptions, value])\n\n const handleCreate = React.useCallback(async () => {\n if (!createOption) return\n const trimmedValue = newValue.trim()\n if (!trimmedValue.length) {\n setFormError(labels.emptyError)\n return\n }\n setSaving(true)\n try {\n const payload = await createOption({\n value: trimmedValue,\n label: showLabelInput ? newLabel.trim() || undefined : undefined,\n color: allowAppearance && appearance.color ? appearance.color : undefined,\n icon: allowAppearance && appearance.icon ? appearance.icon : undefined,\n })\n if (!payload) throw new Error('createOption did not return an entry')\n setOptions((previous) => {\n const map = new Map(previous.map((option) => [option.value, option]))\n map.set(payload.value, {\n value: payload.value,\n label: payload.label,\n color: payload.color ?? null,\n icon: payload.icon ?? null,\n })\n const nextOptions = Array.from(map.values())\n return sortOptions === 'none'\n ? nextOptions\n : nextOptions.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))\n })\n await loadOptions()\n onChange(payload.value)\n setDialogOpen(false)\n if (labels.successCreateLabel) {\n flash(labels.successCreateLabel, 'success')\n }\n } catch (err) {\n logger.error('Failed to create option', { err })\n flash(labels.errorSave, 'error')\n } finally {\n setSaving(false)\n }\n }, [\n allowAppearance,\n appearance.color,\n appearance.icon,\n createOption,\n labels.emptyError,\n labels.errorSave,\n labels.successCreateLabel,\n loadOptions,\n newLabel,\n newValue,\n onChange,\n sortOptions,\n ])\n\n const handleDialogKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n if (!saving) {\n setDialogOpen(false)\n }\n return\n }\n if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n if (!saving && newValue.trim().length) {\n handleCreate().catch(() => {})\n } else if (!saving && !newValue.trim().length) {\n setFormError(labels.emptyError)\n }\n }\n },\n [handleCreate, labels.emptyError, newValue, saving],\n )\n\n const shortcutHint = React.useMemo(() => {\n const provided = typeof labels.saveShortcutHint === 'string' ? labels.saveShortcutHint.trim() : ''\n if (provided.length) return provided\n return '\u2318/Ctrl + Enter'\n }, [labels.saveShortcutHint])\n\n const disabled = disabledProp || loading || saving\n const manageLink = manageHref ?? '/backend/config/dictionaries'\n const returnTo = React.useMemo(() => {\n const query = searchParams?.toString() ?? ''\n if (!pathname) return null\n return query.length ? `${pathname}?${query}` : pathname\n }, [pathname, searchParams])\n const manageLinkWithReturnTo = React.useMemo(\n () => buildHrefWithReturnTo(manageLink, returnTo),\n [manageLink, returnTo],\n )\n const optionsKey = React.useMemo(\n () => displayOptions.map((option) => `${option.value}:${option.label}`).join('\\0'),\n [displayOptions],\n )\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <Select\n key={`dictionary-entry:${value ?? ''}:${optionsKey}`}\n value={value ?? ''}\n onValueChange={(next) => {\n if (!next) return\n onChange(next)\n }}\n disabled={disabled}\n >\n <SelectTrigger\n id={id}\n className={selectClassName}\n title={activeOption?.label ?? undefined}\n >\n <SelectValue placeholder={labels.placeholder}>\n {activeOption?.label}\n </SelectValue>\n </SelectTrigger>\n <SelectContent>\n {displayOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <div className=\"flex items-center gap-1\">\n {allowInlineCreate && createOption ? (\n <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>\n <DialogTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n disabled={disabled}\n title={labels.addLabel}\n aria-label={labels.addLabel}\n >\n <Plus className=\"h-4 w-4\" />\n </Button>\n </DialogTrigger>\n <DialogContent className=\"sm:max-w-md\" onKeyDown={handleDialogKeyDown}>\n <DialogHeader>\n <DialogTitle>{labels.dialogTitle}</DialogTitle>\n {labels.addPrompt ? <DialogDescription>{labels.addPrompt}</DialogDescription> : null}\n </DialogHeader>\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">{labels.valueLabel}</label>\n <Input\n type=\"text\"\n value={newValue}\n onChange={(event) => {\n setNewValue(event.target.value)\n if (formError) setFormError(null)\n }}\n placeholder={labels.valuePlaceholder}\n autoFocus\n disabled={saving}\n />\n </div>\n {showLabelInput ? (\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">{labels.labelLabel}</label>\n <Input\n type=\"text\"\n value={newLabel}\n onChange={(event) => setNewLabel(event.target.value)}\n placeholder={labels.labelPlaceholder}\n disabled={saving}\n />\n </div>\n ) : null}\n {allowAppearance ? (\n <AppearanceSelector\n icon={appearance.icon}\n color={appearance.color}\n onIconChange={appearance.setIcon}\n onColorChange={appearance.setColor}\n labels={appearanceLabels ?? DEFAULT_APPEARANCE_LABELS}\n />\n ) : null}\n {formError ? <p className=\"text-sm text-red-600\">{formError}</p> : null}\n </div>\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setDialogOpen(false)} disabled={saving}>\n {labels.cancelLabel}\n </Button>\n <Button type=\"button\" onClick={handleCreate} disabled={saving || !newValue.trim()}>\n {saving ? <Spinner className=\"mr-2 h-4 w-4\" /> : <Save className=\"mr-2 h-4 w-4\" />}\n <span className=\"flex items-center gap-2\">\n <span>{labels.saveLabel}</span>\n {!saving ? (\n <span className=\"text-xs text-muted-foreground\">{`(${shortcutHint})`}</span>\n ) : null}\n </span>\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n ) : null}\n {showManage ? (\n <Button asChild variant=\"ghost\" size=\"icon\" title={labels.manageTitle} aria-label={labels.manageTitle}>\n <Link href={manageLinkWithReturnTo}>\n <Settings className=\"h-4 w-4\" />\n <span className=\"sr-only\">{labels.manageTitle}</span>\n </Link>\n </Button>\n ) : null}\n </div>\n </div>\n {showActiveAppearance && activeOption && (activeOption.icon || activeOption.color) ? (\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"inline-flex items-center gap-2 rounded border border-dashed px-2 py-1\">\n {activeOption.icon ? renderDictionaryIcon(activeOption.icon, 'h-4 w-4') : null}\n {activeOption.color ? renderDictionaryColor(activeOption.color, 'h-4 w-4 rounded-sm') : null}\n </span>\n {activeOption.color ? <span>{activeOption.color}</span> : null}\n </div>\n ) : null}\n {loading ? <div className=\"text-xs text-muted-foreground\">{labels.loadingLabel}</div> : null}\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -11,6 +11,8 @@ import {
11
11
  ensureDictionaryEntries,
12
12
  invalidateDictionaryEntries
13
13
  } from "./hooks/useDictionaryEntries.js";
14
+ import { createLogger } from "@open-mercato/shared/lib/logger";
15
+ const logger = createLogger("dictionaries").child({ component: "DictionarySelectControl" });
14
16
  function DictionarySelectControl({
15
17
  dictionaryId,
16
18
  value,
@@ -49,7 +51,7 @@ function DictionarySelectControl({
49
51
  }
50
52
  setInlineCreateEnabled(true);
51
53
  } catch (err) {
52
- console.warn("DictionarySelectControl.inlineCreate check failed", err);
54
+ logger.warn("Inline create check failed", { err });
53
55
  if (!cancelled) {
54
56
  setInlineCreateEnabled(allowInlineCreate);
55
57
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/dictionaries/components/DictionarySelectControl.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { DictionaryEntrySelect } from './DictionaryEntrySelect'\nimport {\n ensureDictionaryEntries,\n invalidateDictionaryEntries,\n} from './hooks/useDictionaryEntries'\n\ntype DictionarySelectControlProps = {\n dictionaryId: string\n value?: string | null\n onChange: (value: string | undefined) => void\n allowInlineCreate?: boolean\n selectClassName?: string\n disabled?: boolean\n priorityValues?: string[]\n seedOptions?: Array<{ value: string; label: string; color?: string | null; icon?: string | null }>\n}\n\nexport function DictionarySelectControl({\n dictionaryId,\n value,\n onChange,\n allowInlineCreate = true,\n selectClassName,\n disabled = false,\n priorityValues,\n seedOptions,\n}: DictionarySelectControlProps) {\n const t = useT()\n const queryClient = useQueryClient()\n const scopeVersion = useOrganizationScopeVersion()\n const mutationContextId = React.useMemo(\n () => `dictionaries:dictionary_entry:inline:${dictionaryId}`,\n [dictionaryId],\n )\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const [inlineCreateEnabled, setInlineCreateEnabled] = React.useState<boolean>(allowInlineCreate)\n\n React.useEffect(() => {\n let cancelled = false\n async function evaluateInlineCreate() {\n if (!allowInlineCreate) {\n setInlineCreateEnabled(false)\n return\n }\n try {\n const call = await apiCall<{ isInherited?: boolean }>(`/api/dictionaries/${dictionaryId}`)\n if (cancelled) return\n if (call.ok && call.result && call.result.isInherited === true) {\n setInlineCreateEnabled(false)\n return\n }\n setInlineCreateEnabled(true)\n } catch (err) {\n console.warn('DictionarySelectControl.inlineCreate check failed', err)\n if (!cancelled) {\n setInlineCreateEnabled(allowInlineCreate)\n }\n }\n }\n evaluateInlineCreate().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [allowInlineCreate, dictionaryId, scopeVersion])\n\n const effectiveAllowInlineCreate = allowInlineCreate && inlineCreateEnabled\n\n const normalizedPriority = React.useMemo(() => {\n if (!Array.isArray(priorityValues) || !priorityValues.length) return []\n const seen = new Set<string>()\n const ordered: string[] = []\n priorityValues.forEach((code) => {\n if (typeof code !== 'string') return\n const normalized = code.trim().toLowerCase()\n if (!normalized.length || seen.has(normalized)) return\n seen.add(normalized)\n ordered.push(normalized)\n })\n return ordered\n }, [priorityValues])\n\n const fetchOptions = React.useCallback(async () => {\n const data = await ensureDictionaryEntries(queryClient, dictionaryId, scopeVersion)\n const options = data.entries.map((entry) => ({\n value: entry.value,\n label: entry.label,\n color: entry.color ?? null,\n icon: entry.icon ?? null,\n }))\n if (!normalizedPriority.length) return options\n const byValue = new Map<string, (typeof options)[number]>()\n options.forEach((option) => {\n const key = option.value.trim().toLowerCase()\n if (!byValue.has(key)) byValue.set(key, option)\n })\n const prioritized: typeof options = []\n normalizedPriority.forEach((key) => {\n const match = byValue.get(key)\n if (match) {\n prioritized.push(match)\n byValue.delete(key)\n }\n })\n const remaining: typeof options = []\n byValue.forEach((option) => remaining.push(option))\n return [...prioritized, ...remaining]\n }, [dictionaryId, normalizedPriority, queryClient, scopeVersion])\n\n const createOption = React.useCallback(\n async (input: { value: string; label?: string; color?: string | null; icon?: string | null }) => {\n const payload = {\n value: input.value,\n label: input.label ?? input.value,\n color: input.color,\n icon: input.icon,\n }\n const call = await runMutation({\n operation: async () => {\n const result = await apiCall<Record<string, unknown>>(\n `/api/dictionaries/${dictionaryId}/entries`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n },\n )\n if (!result.ok) {\n throw new Error(\n typeof result.result?.error === 'string' ? result.result.error : 'Failed to create dictionary entry',\n )\n }\n return result\n },\n context: {\n formId: mutationContextId,\n resourceKind: 'dictionaries.dictionary_entry',\n retryLastMutation,\n },\n mutationPayload: payload,\n })\n await invalidateDictionaryEntries(queryClient, dictionaryId)\n return {\n value: String(call.result?.value ?? input.value),\n label:\n typeof call.result?.label === 'string' && call.result.label.length\n ? call.result.label\n : String(call.result?.value ?? input.value),\n color: typeof call.result?.color === 'string' ? call.result.color : null,\n icon: typeof call.result?.icon === 'string' ? call.result.icon : null,\n }\n },\n [dictionaryId, mutationContextId, queryClient, runMutation, retryLastMutation],\n )\n\n const labels = React.useMemo(\n () => ({\n placeholder: t('dictionaries.customFields.selector.placeholder', 'Select an entry'),\n addLabel: t('dictionaries.customFields.selector.add', 'Add entry'),\n addPrompt: t('dictionaries.customFields.selector.dialogDescription', 'Create a new entry and reuse it across records.'),\n dialogTitle: t('dictionaries.config.entries.dialog.addTitle', 'Add dictionary entry'),\n valueLabel: t('dictionaries.config.entries.dialog.valueLabel', 'Value'),\n valuePlaceholder: t('dictionaries.config.entries.dialog.valueLabel', 'Value'),\n labelLabel: t('dictionaries.config.entries.dialog.labelLabel', 'Label'),\n labelPlaceholder: t('dictionaries.config.entries.dialog.labelPlaceholder', 'Display name shown in UI'),\n emptyError: t('dictionaries.config.entries.error.required', 'Value is required.'),\n cancelLabel: t('dictionaries.config.entries.dialog.cancel', 'Cancel'),\n saveLabel: t('dictionaries.config.entries.dialog.save', 'Save'),\n saveShortcutHint: t('dictionaries.config.entries.dialog.saveShortcut', '\u2318/Ctrl + Enter'),\n successCreateLabel: t('dictionaries.config.entries.success.create', 'Dictionary entry created.'),\n errorLoad: t('dictionaries.config.entries.error.load', 'Failed to load dictionary entries.'),\n errorSave: t('dictionaries.config.entries.error.save', 'Failed to save dictionary entry.'),\n loadingLabel: t('dictionaries.config.entries.loading', 'Loading entries\u2026'),\n manageTitle: t('dictionaries.customFields.manageLink', 'Manage dictionaries'),\n }),\n [t],\n )\n\n const appearanceLabels = React.useMemo(\n () => ({\n colorLabel: t('dictionaries.config.entries.dialog.colorLabel', 'Color'),\n colorHelp: t('dictionaries.config.entries.dialog.colorHelp', 'Pick a highlight color for this entry.'),\n colorClearLabel: t('dictionaries.config.entries.dialog.colorClear', 'Remove color'),\n iconLabel: t('dictionaries.config.entries.dialog.iconLabel', 'Icon or emoji'),\n iconPlaceholder: t('dictionaries.config.entries.dialog.iconPlaceholder', 'Type an emoji or icon token.'),\n iconPickerTriggerLabel: t('dictionaries.config.entries.dialog.iconBrowse', 'Browse icons and emoji'),\n iconSearchPlaceholder: t('dictionaries.config.entries.dialog.iconSearchPlaceholder', 'Search icons or emojis\u2026'),\n iconSearchEmptyLabel: t('dictionaries.config.entries.dialog.iconSearchEmpty', 'No icons match your search.'),\n iconSuggestionsLabel: t('dictionaries.config.entries.dialog.iconSuggestions', 'Suggestions'),\n iconClearLabel: t('dictionaries.config.entries.dialog.iconClear', 'Remove icon'),\n previewEmptyLabel: t('dictionaries.config.entries.dialog.previewEmpty', 'No appearance selected'),\n }),\n [t],\n )\n\n return (\n <DictionaryEntrySelect\n value={typeof value === 'string' ? value : undefined}\n onChange={onChange}\n fetchOptions={fetchOptions}\n createOption={effectiveAllowInlineCreate ? createOption : undefined}\n labels={labels}\n appearanceLabels={appearanceLabels}\n allowAppearance\n allowInlineCreate={effectiveAllowInlineCreate}\n selectClassName={selectClassName}\n seedOptions={seedOptions?.map((option) => ({\n value: option.value,\n label: option.label,\n color: option.color ?? null,\n icon: option.icon ?? null,\n }))}\n sortOptions=\"none\"\n disabled={disabled}\n manageHref=\"/backend/config/dictionaries\"\n />\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { DictionaryEntrySelect } from './DictionaryEntrySelect'\nimport {\n ensureDictionaryEntries,\n invalidateDictionaryEntries,\n} from './hooks/useDictionaryEntries'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('dictionaries').child({ component: 'DictionarySelectControl' })\n\ntype DictionarySelectControlProps = {\n dictionaryId: string\n value?: string | null\n onChange: (value: string | undefined) => void\n allowInlineCreate?: boolean\n selectClassName?: string\n disabled?: boolean\n priorityValues?: string[]\n seedOptions?: Array<{ value: string; label: string; color?: string | null; icon?: string | null }>\n}\n\nexport function DictionarySelectControl({\n dictionaryId,\n value,\n onChange,\n allowInlineCreate = true,\n selectClassName,\n disabled = false,\n priorityValues,\n seedOptions,\n}: DictionarySelectControlProps) {\n const t = useT()\n const queryClient = useQueryClient()\n const scopeVersion = useOrganizationScopeVersion()\n const mutationContextId = React.useMemo(\n () => `dictionaries:dictionary_entry:inline:${dictionaryId}`,\n [dictionaryId],\n )\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const [inlineCreateEnabled, setInlineCreateEnabled] = React.useState<boolean>(allowInlineCreate)\n\n React.useEffect(() => {\n let cancelled = false\n async function evaluateInlineCreate() {\n if (!allowInlineCreate) {\n setInlineCreateEnabled(false)\n return\n }\n try {\n const call = await apiCall<{ isInherited?: boolean }>(`/api/dictionaries/${dictionaryId}`)\n if (cancelled) return\n if (call.ok && call.result && call.result.isInherited === true) {\n setInlineCreateEnabled(false)\n return\n }\n setInlineCreateEnabled(true)\n } catch (err) {\n logger.warn('Inline create check failed', { err })\n if (!cancelled) {\n setInlineCreateEnabled(allowInlineCreate)\n }\n }\n }\n evaluateInlineCreate().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [allowInlineCreate, dictionaryId, scopeVersion])\n\n const effectiveAllowInlineCreate = allowInlineCreate && inlineCreateEnabled\n\n const normalizedPriority = React.useMemo(() => {\n if (!Array.isArray(priorityValues) || !priorityValues.length) return []\n const seen = new Set<string>()\n const ordered: string[] = []\n priorityValues.forEach((code) => {\n if (typeof code !== 'string') return\n const normalized = code.trim().toLowerCase()\n if (!normalized.length || seen.has(normalized)) return\n seen.add(normalized)\n ordered.push(normalized)\n })\n return ordered\n }, [priorityValues])\n\n const fetchOptions = React.useCallback(async () => {\n const data = await ensureDictionaryEntries(queryClient, dictionaryId, scopeVersion)\n const options = data.entries.map((entry) => ({\n value: entry.value,\n label: entry.label,\n color: entry.color ?? null,\n icon: entry.icon ?? null,\n }))\n if (!normalizedPriority.length) return options\n const byValue = new Map<string, (typeof options)[number]>()\n options.forEach((option) => {\n const key = option.value.trim().toLowerCase()\n if (!byValue.has(key)) byValue.set(key, option)\n })\n const prioritized: typeof options = []\n normalizedPriority.forEach((key) => {\n const match = byValue.get(key)\n if (match) {\n prioritized.push(match)\n byValue.delete(key)\n }\n })\n const remaining: typeof options = []\n byValue.forEach((option) => remaining.push(option))\n return [...prioritized, ...remaining]\n }, [dictionaryId, normalizedPriority, queryClient, scopeVersion])\n\n const createOption = React.useCallback(\n async (input: { value: string; label?: string; color?: string | null; icon?: string | null }) => {\n const payload = {\n value: input.value,\n label: input.label ?? input.value,\n color: input.color,\n icon: input.icon,\n }\n const call = await runMutation({\n operation: async () => {\n const result = await apiCall<Record<string, unknown>>(\n `/api/dictionaries/${dictionaryId}/entries`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n },\n )\n if (!result.ok) {\n throw new Error(\n typeof result.result?.error === 'string' ? result.result.error : 'Failed to create dictionary entry',\n )\n }\n return result\n },\n context: {\n formId: mutationContextId,\n resourceKind: 'dictionaries.dictionary_entry',\n retryLastMutation,\n },\n mutationPayload: payload,\n })\n await invalidateDictionaryEntries(queryClient, dictionaryId)\n return {\n value: String(call.result?.value ?? input.value),\n label:\n typeof call.result?.label === 'string' && call.result.label.length\n ? call.result.label\n : String(call.result?.value ?? input.value),\n color: typeof call.result?.color === 'string' ? call.result.color : null,\n icon: typeof call.result?.icon === 'string' ? call.result.icon : null,\n }\n },\n [dictionaryId, mutationContextId, queryClient, runMutation, retryLastMutation],\n )\n\n const labels = React.useMemo(\n () => ({\n placeholder: t('dictionaries.customFields.selector.placeholder', 'Select an entry'),\n addLabel: t('dictionaries.customFields.selector.add', 'Add entry'),\n addPrompt: t('dictionaries.customFields.selector.dialogDescription', 'Create a new entry and reuse it across records.'),\n dialogTitle: t('dictionaries.config.entries.dialog.addTitle', 'Add dictionary entry'),\n valueLabel: t('dictionaries.config.entries.dialog.valueLabel', 'Value'),\n valuePlaceholder: t('dictionaries.config.entries.dialog.valueLabel', 'Value'),\n labelLabel: t('dictionaries.config.entries.dialog.labelLabel', 'Label'),\n labelPlaceholder: t('dictionaries.config.entries.dialog.labelPlaceholder', 'Display name shown in UI'),\n emptyError: t('dictionaries.config.entries.error.required', 'Value is required.'),\n cancelLabel: t('dictionaries.config.entries.dialog.cancel', 'Cancel'),\n saveLabel: t('dictionaries.config.entries.dialog.save', 'Save'),\n saveShortcutHint: t('dictionaries.config.entries.dialog.saveShortcut', '\u2318/Ctrl + Enter'),\n successCreateLabel: t('dictionaries.config.entries.success.create', 'Dictionary entry created.'),\n errorLoad: t('dictionaries.config.entries.error.load', 'Failed to load dictionary entries.'),\n errorSave: t('dictionaries.config.entries.error.save', 'Failed to save dictionary entry.'),\n loadingLabel: t('dictionaries.config.entries.loading', 'Loading entries\u2026'),\n manageTitle: t('dictionaries.customFields.manageLink', 'Manage dictionaries'),\n }),\n [t],\n )\n\n const appearanceLabels = React.useMemo(\n () => ({\n colorLabel: t('dictionaries.config.entries.dialog.colorLabel', 'Color'),\n colorHelp: t('dictionaries.config.entries.dialog.colorHelp', 'Pick a highlight color for this entry.'),\n colorClearLabel: t('dictionaries.config.entries.dialog.colorClear', 'Remove color'),\n iconLabel: t('dictionaries.config.entries.dialog.iconLabel', 'Icon or emoji'),\n iconPlaceholder: t('dictionaries.config.entries.dialog.iconPlaceholder', 'Type an emoji or icon token.'),\n iconPickerTriggerLabel: t('dictionaries.config.entries.dialog.iconBrowse', 'Browse icons and emoji'),\n iconSearchPlaceholder: t('dictionaries.config.entries.dialog.iconSearchPlaceholder', 'Search icons or emojis\u2026'),\n iconSearchEmptyLabel: t('dictionaries.config.entries.dialog.iconSearchEmpty', 'No icons match your search.'),\n iconSuggestionsLabel: t('dictionaries.config.entries.dialog.iconSuggestions', 'Suggestions'),\n iconClearLabel: t('dictionaries.config.entries.dialog.iconClear', 'Remove icon'),\n previewEmptyLabel: t('dictionaries.config.entries.dialog.previewEmpty', 'No appearance selected'),\n }),\n [t],\n )\n\n return (\n <DictionaryEntrySelect\n value={typeof value === 'string' ? value : undefined}\n onChange={onChange}\n fetchOptions={fetchOptions}\n createOption={effectiveAllowInlineCreate ? createOption : undefined}\n labels={labels}\n appearanceLabels={appearanceLabels}\n allowAppearance\n allowInlineCreate={effectiveAllowInlineCreate}\n selectClassName={selectClassName}\n seedOptions={seedOptions?.map((option) => ({\n value: option.value,\n label: option.label,\n color: option.color ?? null,\n icon: option.icon ?? null,\n }))}\n sortOptions=\"none\"\n disabled={disabled}\n manageHref=\"/backend/config/dictionaries\"\n />\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -14,6 +14,8 @@ import {
14
14
  } from "@open-mercato/ui/primitives/select";
15
15
  import { DictionarySelectControl } from "../components/DictionarySelectControl.js";
16
16
  import { useDictionaryEntries } from "../components/hooks/useDictionaryEntries.js";
17
+ import { createLogger } from "@open-mercato/shared/lib/logger";
18
+ const logger = createLogger("dictionaries").child({ component: "dictionary-field" });
17
19
  function DictionaryDefaultSelector({
18
20
  dictionaryId,
19
21
  defaultValue,
@@ -77,7 +79,7 @@ function DictionaryFieldDefEditor({ def, onChange }) {
77
79
  }
78
80
  } catch (err) {
79
81
  if (!cancelled) {
80
- console.error("Failed to load dictionaries list", err);
82
+ logger.error("Failed to load dictionaries list", { err });
81
83
  setError(errorLoadLabel);
82
84
  }
83
85
  } finally {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/dictionaries/fields/dictionary.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { CrudCustomFieldRenderProps } from '@open-mercato/ui/backend/CrudForm'\nimport { FieldRegistry } from '@open-mercato/ui/backend/fields/registry'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Checkbox } from '@open-mercato/ui/primitives/checkbox'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { DictionarySelectControl } from '../components/DictionarySelectControl'\nimport { useDictionaryEntries } from '../components/hooks/useDictionaryEntries'\n\ntype DictionaryFieldDefinition = {\n dictionaryId?: string\n dictionaryInlineCreate?: boolean\n multi?: boolean\n defaultValue?: string\n}\n\ntype Props = CrudCustomFieldRenderProps & { def?: DictionaryFieldDefinition }\n\ntype DictionarySummary = {\n id: string\n name: string\n key: string\n isActive: boolean\n}\n\nfunction DictionaryDefaultSelector({\n dictionaryId,\n defaultValue,\n onChange,\n}: {\n dictionaryId: string\n defaultValue: string\n onChange: (value: string) => void\n}) {\n const t = useT()\n const { data, isLoading } = useDictionaryEntries(dictionaryId)\n const entries = data?.entries ?? []\n const isStale = defaultValue && entries.length > 0 && !entries.some((e) => e.value === defaultValue)\n\n return (\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('dictionaries.customFields.defaultValue', 'Default value')}\n </label>\n <Select\n value={defaultValue ?? ''}\n onValueChange={(next) => onChange(next ?? '')}\n >\n <SelectTrigger size=\"sm\">\n <SelectValue placeholder={t('dictionaries.customFields.defaultValueNone', 'No default')} />\n </SelectTrigger>\n <SelectContent>\n {entries.map((entry) => (\n <SelectItem key={entry.value} value={entry.value}>\n {entry.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {isLoading ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.loading', 'Loading dictionaries\u2026')}\n </p>\n ) : null}\n {isStale ? (\n <p className=\"text-xs text-status-warning-text\">\n {t('dictionaries.customFields.defaultValueStale', 'Default entry not found \u2014 it may have been deleted or renamed.')}\n </p>\n ) : null}\n </div>\n )\n}\n\nfunction DictionaryFieldDefEditor({ def, onChange }: { def: { configJson?: DictionaryFieldDefinition } | undefined; onChange: (patch: Partial<DictionaryFieldDefinition>) => void }) {\n const t = useT()\n const [items, setItems] = React.useState<DictionarySummary[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const multiId = React.useId()\n const inlineCreateId = React.useId()\n const selectedId = typeof def?.configJson?.dictionaryId === 'string' ? def?.configJson?.dictionaryId : ''\n const inlineCreate = def?.configJson?.dictionaryInlineCreate !== false\n const isMulti = def?.configJson?.multi === true\n const errorLoadLabel = t('dictionaries.customFields.errorLoad', 'Failed to load dictionaries.')\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setLoading(true)\n setError(null)\n try {\n const call = await apiCall<{ items?: unknown[]; error?: string }>(\n '/api/dictionaries?includeInactive=true',\n )\n if (!call.ok) {\n const message =\n typeof call.result?.error === 'string' ? call.result.error : 'Failed to load dictionaries'\n throw new Error(message)\n }\n const entries = Array.isArray(call.result?.items) ? call.result!.items : []\n if (!cancelled) {\n setItems(\n entries.map((entry: any) => ({\n id: String(entry.id),\n name: typeof entry.name === 'string' && entry.name.trim().length ? entry.name : String(entry.key ?? entry.id),\n key: typeof entry.key === 'string' ? entry.key : '',\n isActive: entry.isActive !== false,\n })),\n )\n }\n } catch (err) {\n if (!cancelled) {\n console.error('Failed to load dictionaries list', err)\n setError(errorLoadLabel)\n }\n } finally {\n if (!cancelled) {\n setLoading(false)\n }\n }\n }\n load().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [errorLoadLabel])\n\n const manageHref = '/backend/config/dictionaries'\n\n return (\n <div className=\"mt-3 space-y-3 rounded border border-dashed border-muted-foreground/40 bg-muted/30 p-3\">\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('dictionaries.customFields.dictionaryLabel', 'Dictionary source')}\n </label>\n <Select\n value={selectedId ?? ''}\n onValueChange={(next) => onChange({ dictionaryId: next || undefined })}\n >\n <SelectTrigger size=\"sm\">\n <SelectValue placeholder={t('dictionaries.customFields.dictionaryPlaceholder', 'Select a dictionary')} />\n </SelectTrigger>\n <SelectContent>\n {items.map((item) => (\n <SelectItem key={item.id} value={item.id}>\n {item.name}\n {item.isActive ? '' : ` (${t('dictionaries.customFields.inactive', 'inactive')})`}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {loading ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.loading', 'Loading dictionaries\u2026')}\n </p>\n ) : null}\n {error ? <p className=\"text-xs text-status-error-text\">{error}</p> : null}\n {!loading && !error && items.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.empty', 'No dictionaries available yet. Create one first.')}\n </p>\n ) : null}\n </div>\n {selectedId ? (\n <div className=\"flex flex-wrap items-center justify-between gap-2 rounded bg-background/80 px-2 py-1 text-xs text-muted-foreground\">\n <span>{t('dictionaries.customFields.selectedHint', 'Entries from this dictionary populate the field.')}</span>\n <a href={manageHref} className=\"font-medium text-primary hover:underline\" target=\"_blank\" rel=\"noreferrer\">\n {t('dictionaries.customFields.manageLink', 'Manage dictionaries')}\n </a>\n </div>\n ) : null}\n <div className=\"inline-flex items-center gap-2 text-xs\">\n <Checkbox\n id={multiId}\n checked={isMulti}\n onCheckedChange={(checked) => {\n const enabled = checked === true\n onChange({ multi: enabled, defaultValue: enabled ? undefined : def?.configJson?.defaultValue })\n }}\n disabled={!selectedId}\n />\n <label\n htmlFor={multiId}\n className={selectedId ? 'cursor-pointer select-none' : 'cursor-not-allowed opacity-60'}\n >\n {t('dictionaries.customFields.allowMultiple', 'Allow selecting multiple entries')}\n </label>\n </div>\n {!isMulti ? (\n <div className=\"inline-flex items-center gap-2 text-xs\">\n <Checkbox\n id={inlineCreateId}\n checked={inlineCreate}\n onCheckedChange={(checked) => onChange({ dictionaryInlineCreate: checked === true })}\n disabled={!selectedId}\n />\n <label\n htmlFor={inlineCreateId}\n className={selectedId ? 'cursor-pointer select-none' : 'cursor-not-allowed opacity-60'}\n >\n {t('dictionaries.customFields.allowInlineCreate', 'Allow inline creation inside forms')}\n </label>\n </div>\n ) : null}\n {selectedId && !isMulti ? (\n <DictionaryDefaultSelector\n dictionaryId={selectedId}\n defaultValue={typeof def?.configJson?.defaultValue === 'string' ? def.configJson.defaultValue : ''}\n onChange={(value) => onChange({ defaultValue: value || undefined })}\n />\n ) : null}\n </div>\n )\n}\n\nfunction DictionaryFieldInput({ value, setValue, disabled, def }: Props) {\n const t = useT()\n const dictionaryId = def?.dictionaryId\n if (!dictionaryId) {\n return (\n <div className=\"rounded border border-dashed p-3 text-sm text-muted-foreground\">\n {t('dictionaries.config.entries.error.load', 'Failed to load dictionary entries.')}\n </div>\n )\n }\n const normalizedValue = typeof value === 'string' ? value : Array.isArray(value) ? String(value[0] ?? '') : undefined\n return (\n <DictionarySelectControl\n dictionaryId={dictionaryId}\n value={normalizedValue ?? ''}\n onChange={(next) => setValue(next ?? undefined)}\n allowInlineCreate={def?.dictionaryInlineCreate !== false}\n disabled={disabled}\n />\n )\n}\n\nFieldRegistry.register('dictionary', {\n input: DictionaryFieldInput,\n defEditor: (props) => <DictionaryFieldDefEditor {...props} />,\n})\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { CrudCustomFieldRenderProps } from '@open-mercato/ui/backend/CrudForm'\nimport { FieldRegistry } from '@open-mercato/ui/backend/fields/registry'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Checkbox } from '@open-mercato/ui/primitives/checkbox'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { DictionarySelectControl } from '../components/DictionarySelectControl'\nimport { useDictionaryEntries } from '../components/hooks/useDictionaryEntries'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('dictionaries').child({ component: 'dictionary-field' })\n\ntype DictionaryFieldDefinition = {\n dictionaryId?: string\n dictionaryInlineCreate?: boolean\n multi?: boolean\n defaultValue?: string\n}\n\ntype Props = CrudCustomFieldRenderProps & { def?: DictionaryFieldDefinition }\n\ntype DictionarySummary = {\n id: string\n name: string\n key: string\n isActive: boolean\n}\n\nfunction DictionaryDefaultSelector({\n dictionaryId,\n defaultValue,\n onChange,\n}: {\n dictionaryId: string\n defaultValue: string\n onChange: (value: string) => void\n}) {\n const t = useT()\n const { data, isLoading } = useDictionaryEntries(dictionaryId)\n const entries = data?.entries ?? []\n const isStale = defaultValue && entries.length > 0 && !entries.some((e) => e.value === defaultValue)\n\n return (\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('dictionaries.customFields.defaultValue', 'Default value')}\n </label>\n <Select\n value={defaultValue ?? ''}\n onValueChange={(next) => onChange(next ?? '')}\n >\n <SelectTrigger size=\"sm\">\n <SelectValue placeholder={t('dictionaries.customFields.defaultValueNone', 'No default')} />\n </SelectTrigger>\n <SelectContent>\n {entries.map((entry) => (\n <SelectItem key={entry.value} value={entry.value}>\n {entry.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {isLoading ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.loading', 'Loading dictionaries\u2026')}\n </p>\n ) : null}\n {isStale ? (\n <p className=\"text-xs text-status-warning-text\">\n {t('dictionaries.customFields.defaultValueStale', 'Default entry not found \u2014 it may have been deleted or renamed.')}\n </p>\n ) : null}\n </div>\n )\n}\n\nfunction DictionaryFieldDefEditor({ def, onChange }: { def: { configJson?: DictionaryFieldDefinition } | undefined; onChange: (patch: Partial<DictionaryFieldDefinition>) => void }) {\n const t = useT()\n const [items, setItems] = React.useState<DictionarySummary[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const multiId = React.useId()\n const inlineCreateId = React.useId()\n const selectedId = typeof def?.configJson?.dictionaryId === 'string' ? def?.configJson?.dictionaryId : ''\n const inlineCreate = def?.configJson?.dictionaryInlineCreate !== false\n const isMulti = def?.configJson?.multi === true\n const errorLoadLabel = t('dictionaries.customFields.errorLoad', 'Failed to load dictionaries.')\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setLoading(true)\n setError(null)\n try {\n const call = await apiCall<{ items?: unknown[]; error?: string }>(\n '/api/dictionaries?includeInactive=true',\n )\n if (!call.ok) {\n const message =\n typeof call.result?.error === 'string' ? call.result.error : 'Failed to load dictionaries'\n throw new Error(message)\n }\n const entries = Array.isArray(call.result?.items) ? call.result!.items : []\n if (!cancelled) {\n setItems(\n entries.map((entry: any) => ({\n id: String(entry.id),\n name: typeof entry.name === 'string' && entry.name.trim().length ? entry.name : String(entry.key ?? entry.id),\n key: typeof entry.key === 'string' ? entry.key : '',\n isActive: entry.isActive !== false,\n })),\n )\n }\n } catch (err) {\n if (!cancelled) {\n logger.error('Failed to load dictionaries list', { err })\n setError(errorLoadLabel)\n }\n } finally {\n if (!cancelled) {\n setLoading(false)\n }\n }\n }\n load().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [errorLoadLabel])\n\n const manageHref = '/backend/config/dictionaries'\n\n return (\n <div className=\"mt-3 space-y-3 rounded border border-dashed border-muted-foreground/40 bg-muted/30 p-3\">\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('dictionaries.customFields.dictionaryLabel', 'Dictionary source')}\n </label>\n <Select\n value={selectedId ?? ''}\n onValueChange={(next) => onChange({ dictionaryId: next || undefined })}\n >\n <SelectTrigger size=\"sm\">\n <SelectValue placeholder={t('dictionaries.customFields.dictionaryPlaceholder', 'Select a dictionary')} />\n </SelectTrigger>\n <SelectContent>\n {items.map((item) => (\n <SelectItem key={item.id} value={item.id}>\n {item.name}\n {item.isActive ? '' : ` (${t('dictionaries.customFields.inactive', 'inactive')})`}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {loading ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.loading', 'Loading dictionaries\u2026')}\n </p>\n ) : null}\n {error ? <p className=\"text-xs text-status-error-text\">{error}</p> : null}\n {!loading && !error && items.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.empty', 'No dictionaries available yet. Create one first.')}\n </p>\n ) : null}\n </div>\n {selectedId ? (\n <div className=\"flex flex-wrap items-center justify-between gap-2 rounded bg-background/80 px-2 py-1 text-xs text-muted-foreground\">\n <span>{t('dictionaries.customFields.selectedHint', 'Entries from this dictionary populate the field.')}</span>\n <a href={manageHref} className=\"font-medium text-primary hover:underline\" target=\"_blank\" rel=\"noreferrer\">\n {t('dictionaries.customFields.manageLink', 'Manage dictionaries')}\n </a>\n </div>\n ) : null}\n <div className=\"inline-flex items-center gap-2 text-xs\">\n <Checkbox\n id={multiId}\n checked={isMulti}\n onCheckedChange={(checked) => {\n const enabled = checked === true\n onChange({ multi: enabled, defaultValue: enabled ? undefined : def?.configJson?.defaultValue })\n }}\n disabled={!selectedId}\n />\n <label\n htmlFor={multiId}\n className={selectedId ? 'cursor-pointer select-none' : 'cursor-not-allowed opacity-60'}\n >\n {t('dictionaries.customFields.allowMultiple', 'Allow selecting multiple entries')}\n </label>\n </div>\n {!isMulti ? (\n <div className=\"inline-flex items-center gap-2 text-xs\">\n <Checkbox\n id={inlineCreateId}\n checked={inlineCreate}\n onCheckedChange={(checked) => onChange({ dictionaryInlineCreate: checked === true })}\n disabled={!selectedId}\n />\n <label\n htmlFor={inlineCreateId}\n className={selectedId ? 'cursor-pointer select-none' : 'cursor-not-allowed opacity-60'}\n >\n {t('dictionaries.customFields.allowInlineCreate', 'Allow inline creation inside forms')}\n </label>\n </div>\n ) : null}\n {selectedId && !isMulti ? (\n <DictionaryDefaultSelector\n dictionaryId={selectedId}\n defaultValue={typeof def?.configJson?.defaultValue === 'string' ? def.configJson.defaultValue : ''}\n onChange={(value) => onChange({ defaultValue: value || undefined })}\n />\n ) : null}\n </div>\n )\n}\n\nfunction DictionaryFieldInput({ value, setValue, disabled, def }: Props) {\n const t = useT()\n const dictionaryId = def?.dictionaryId\n if (!dictionaryId) {\n return (\n <div className=\"rounded border border-dashed p-3 text-sm text-muted-foreground\">\n {t('dictionaries.config.entries.error.load', 'Failed to load dictionary entries.')}\n </div>\n )\n }\n const normalizedValue = typeof value === 'string' ? value : Array.isArray(value) ? String(value[0] ?? '') : undefined\n return (\n <DictionarySelectControl\n dictionaryId={dictionaryId}\n value={normalizedValue ?? ''}\n onChange={(next) => setValue(next ?? undefined)}\n allowInlineCreate={def?.dictionaryInlineCreate !== false}\n disabled={disabled}\n />\n )\n}\n\nFieldRegistry.register('dictionary', {\n input: DictionaryFieldInput,\n defEditor: (props) => <DictionaryFieldDefEditor {...props} />,\n})\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -15,6 +15,8 @@ import { Organization } from "@open-mercato/core/modules/directory/data/entities
15
15
  import { organizationUpdateSchema } from "@open-mercato/core/modules/directory/data/validators";
16
16
  import { resolveOrganizationScopeForRequest } from "@open-mercato/core/modules/directory/utils/organizationScope";
17
17
  import "@open-mercato/core/modules/directory/commands/organizations";
18
+ import { createLogger } from "@open-mercato/shared/lib/logger";
19
+ const logger = createLogger("directory").child({ component: "organization-branding" });
18
20
  const metadata = {
19
21
  GET: { requireAuth: true, requireFeatures: ["directory.organizations.view"] },
20
22
  PUT: { requireAuth: true, requireFeatures: ["directory.organizations.manage"] }
@@ -215,7 +217,7 @@ async function PUT(req) {
215
217
  if (isCrudHttpError(err)) {
216
218
  return NextResponse.json(err.body, { status: err.status });
217
219
  }
218
- console.error("directory.organization-branding.update failed", err);
220
+ logger.error("Organization branding update failed", { err });
219
221
  return NextResponse.json(
220
222
  { error: resolved.translate("directory.branding.errors.save", "Failed to update organization branding.") },
221
223
  { status: 400 }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/directory/api/organization-branding/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { runWithCacheTenant } from '@open-mercato/cache'\nimport type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { enforceCommandOptimisticLock } from '@open-mercato/shared/lib/crud/optimistic-lock-command'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { Organization } from '@open-mercato/core/modules/directory/data/entities'\nimport { organizationUpdateSchema } from '@open-mercato/core/modules/directory/data/validators'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport '@open-mercato/core/modules/directory/commands/organizations'\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['directory.organizations.view'] },\n PUT: { requireAuth: true, requireFeatures: ['directory.organizations.manage'] },\n}\n\nconst brandingResponseSchema = z.object({\n organizationId: z.string().uuid(),\n organizationName: z.string(),\n tenantId: z.string().uuid(),\n logoUrl: z.string().nullable(),\n updatedAt: z.string().nullable(),\n})\n\nconst brandingUpdateSchema = z.object({\n logoUrl: organizationUpdateSchema.shape.logoUrl,\n})\n\nconst errorSchema = z.object({\n error: z.string(),\n})\n\ntype RequestContainer = Awaited<ReturnType<typeof createRequestContainer>>\n\nfunction buildCommandContext(\n container: RequestContainer,\n auth: NonNullable<Awaited<ReturnType<typeof getAuthFromRequest>>>,\n req: Request,\n organizationId: string,\n tenantId: string,\n): CommandRuntimeContext {\n return {\n container,\n auth,\n organizationScope: {\n selectedId: organizationId,\n filterIds: [organizationId],\n allowedIds: null,\n tenantId,\n },\n selectedOrganizationId: organizationId,\n organizationIds: [organizationId],\n request: req,\n }\n}\n\nasync function resolveCurrentOrganization(req: Request) {\n const { translate } = await resolveTranslations()\n const auth = await getAuthFromRequest(req)\n if (!auth?.sub) {\n return {\n response: NextResponse.json({ error: translate('api.errors.unauthorized', 'Unauthorized') }, { status: 401 }),\n }\n }\n\n const container = await createRequestContainer()\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n const organizationId = scope.selectedId ?? auth.orgId ?? null\n const tenantId = scope.tenantId ?? auth.tenantId ?? null\n if (!organizationId || !tenantId) {\n return {\n response: NextResponse.json(\n {\n error: translate(\n 'directory.branding.errors.organizationRequired',\n 'Select a single organization before changing sidebar branding.',\n ),\n },\n { status: 400 },\n ),\n }\n }\n\n const em = container.resolve('em') as EntityManager\n const organization = await findOneWithDecryption(\n em,\n Organization,\n { id: organizationId, tenant: tenantId, deletedAt: null },\n { populate: ['tenant'] },\n { tenantId, organizationId },\n )\n if (!organization) {\n return {\n response: NextResponse.json(\n { error: translate('directory.branding.errors.notFound', 'Organization not found') },\n { status: 404 },\n ),\n }\n }\n\n return { auth, container, organization, organizationId, tenantId, translate }\n}\n\nfunction toIsoOrNull(value: Date | string | null | undefined): string | null {\n if (value == null) return null\n if (value instanceof Date) {\n const ms = value.getTime()\n return Number.isFinite(ms) ? new Date(ms).toISOString() : null\n }\n const trimmed = String(value).trim()\n if (!trimmed) return null\n const parsed = new Date(trimmed)\n return Number.isFinite(parsed.getTime()) ? parsed.toISOString() : null\n}\n\nfunction toResponsePayload(organization: Organization, tenantId: string) {\n return {\n organizationId: String(organization.id),\n organizationName: organization.name,\n tenantId,\n logoUrl: organization.logoUrl ?? null,\n updatedAt: toIsoOrNull(organization.updatedAt),\n }\n}\n\nasync function invalidateSidebarBrandingCache(container: RequestContainer, organizationId: string, tenantId: string) {\n try {\n const cache = container.resolve('cache') as {\n deleteByTags?: (tags: string[]) => Promise<unknown>\n } | null\n await runWithCacheTenant(tenantId, () =>\n cache?.deleteByTags?.([\n `nav:sidebar:organization:${organizationId}`,\n `nav:sidebar:tenant:${tenantId}`,\n ]),\n )\n } catch {\n // Cache invalidation is best-effort; the persisted branding is the source of truth.\n }\n}\n\nexport async function GET(req: Request) {\n const resolved = await resolveCurrentOrganization(req)\n if ('response' in resolved) return resolved.response\n\n return NextResponse.json(toResponsePayload(resolved.organization, resolved.tenantId))\n}\n\nexport async function PUT(req: Request) {\n const resolved = await resolveCurrentOrganization(req)\n if ('response' in resolved) return resolved.response\n\n let body: unknown\n try {\n body = await req.json()\n } catch {\n return NextResponse.json(\n { error: resolved.translate('directory.branding.errors.invalidLogoUrl', 'Enter a valid image URL.') },\n { status: 422 },\n )\n }\n if (!body || typeof body !== 'object' || !Object.prototype.hasOwnProperty.call(body, 'logoUrl')) {\n return NextResponse.json(\n { error: resolved.translate('directory.branding.errors.invalidLogoUrl', 'Enter a valid image URL.') },\n { status: 422 },\n )\n }\n\n const parsed = brandingUpdateSchema.safeParse(body)\n if (!parsed.success) {\n return NextResponse.json(\n {\n error: resolved.translate('directory.branding.errors.invalidLogoUrl', 'Enter a valid image URL.'),\n issues: parsed.error.issues,\n },\n { status: 422 },\n )\n }\n\n try {\n // Refuse a stale overwrite when two tabs edit the same organization branding.\n // Strictly additive \u2014 a no-op when the client omits the expected-version header.\n enforceCommandOptimisticLock({\n resourceKind: 'directory.organization',\n resourceId: resolved.organizationId,\n current: resolved.organization.updatedAt ?? null,\n request: req,\n })\n\n // Mutation-guard contract for custom write routes: validate before the write,\n // then run the after-success hook once the command persists.\n const guardResult = await validateCrudMutationGuard(resolved.container, {\n tenantId: resolved.tenantId,\n organizationId: resolved.organizationId,\n userId: resolved.auth.sub,\n resourceKind: 'directory.organization',\n resourceId: resolved.organizationId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: { logoUrl: parsed.data.logoUrl ?? null },\n })\n if (guardResult && !guardResult.ok) {\n return NextResponse.json(guardResult.body, { status: guardResult.status })\n }\n\n const commandBus = resolved.container.resolve('commandBus') as CommandBus\n const ctx = buildCommandContext(\n resolved.container,\n resolved.auth,\n req,\n resolved.organizationId,\n resolved.tenantId,\n )\n const { result } = await commandBus.execute<Record<string, unknown>, Organization>(\n 'directory.organizations.update',\n {\n input: {\n id: resolved.organizationId,\n tenantId: resolved.tenantId,\n logoUrl: parsed.data.logoUrl ?? null,\n },\n ctx,\n },\n )\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(resolved.container, {\n tenantId: resolved.tenantId,\n organizationId: resolved.organizationId,\n userId: resolved.auth.sub,\n resourceKind: 'directory.organization',\n resourceId: resolved.organizationId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n await invalidateSidebarBrandingCache(resolved.container, resolved.organizationId, resolved.tenantId)\n return NextResponse.json(toResponsePayload(result, resolved.tenantId))\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n console.error('directory.organization-branding.update failed', err)\n return NextResponse.json(\n { error: resolved.translate('directory.branding.errors.save', 'Failed to update organization branding.') },\n { status: 400 },\n )\n }\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Directory',\n summary: 'Current organization branding',\n methods: {\n GET: {\n summary: 'Read sidebar branding for the selected organization',\n description: 'Returns the logo URL used by the backend sidebar for the currently selected organization.',\n responses: [\n { status: 200, description: 'Organization branding', schema: brandingResponseSchema },\n ],\n errors: [\n { status: 400, description: 'A concrete organization scope is required', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 404, description: 'Organization not found', schema: errorSchema },\n ],\n },\n PUT: {\n summary: 'Update sidebar branding for the selected organization',\n description: 'Stores an external image URL or an internal attachment image URL as the selected organization logo.',\n requestBody: {\n contentType: 'application/json',\n schema: brandingUpdateSchema,\n },\n responses: [\n { status: 200, description: 'Updated organization branding', schema: brandingResponseSchema },\n ],\n errors: [\n { status: 400, description: 'Save failed', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 409, description: 'Organization branding changed since it was loaded', schema: errorSchema },\n { status: 422, description: 'Invalid logo URL', schema: errorSchema },\n ],\n },\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { runWithCacheTenant } from '@open-mercato/cache'\nimport type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { enforceCommandOptimisticLock } from '@open-mercato/shared/lib/crud/optimistic-lock-command'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { Organization } from '@open-mercato/core/modules/directory/data/entities'\nimport { organizationUpdateSchema } from '@open-mercato/core/modules/directory/data/validators'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport '@open-mercato/core/modules/directory/commands/organizations'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('directory').child({ component: 'organization-branding' })\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['directory.organizations.view'] },\n PUT: { requireAuth: true, requireFeatures: ['directory.organizations.manage'] },\n}\n\nconst brandingResponseSchema = z.object({\n organizationId: z.string().uuid(),\n organizationName: z.string(),\n tenantId: z.string().uuid(),\n logoUrl: z.string().nullable(),\n updatedAt: z.string().nullable(),\n})\n\nconst brandingUpdateSchema = z.object({\n logoUrl: organizationUpdateSchema.shape.logoUrl,\n})\n\nconst errorSchema = z.object({\n error: z.string(),\n})\n\ntype RequestContainer = Awaited<ReturnType<typeof createRequestContainer>>\n\nfunction buildCommandContext(\n container: RequestContainer,\n auth: NonNullable<Awaited<ReturnType<typeof getAuthFromRequest>>>,\n req: Request,\n organizationId: string,\n tenantId: string,\n): CommandRuntimeContext {\n return {\n container,\n auth,\n organizationScope: {\n selectedId: organizationId,\n filterIds: [organizationId],\n allowedIds: null,\n tenantId,\n },\n selectedOrganizationId: organizationId,\n organizationIds: [organizationId],\n request: req,\n }\n}\n\nasync function resolveCurrentOrganization(req: Request) {\n const { translate } = await resolveTranslations()\n const auth = await getAuthFromRequest(req)\n if (!auth?.sub) {\n return {\n response: NextResponse.json({ error: translate('api.errors.unauthorized', 'Unauthorized') }, { status: 401 }),\n }\n }\n\n const container = await createRequestContainer()\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n const organizationId = scope.selectedId ?? auth.orgId ?? null\n const tenantId = scope.tenantId ?? auth.tenantId ?? null\n if (!organizationId || !tenantId) {\n return {\n response: NextResponse.json(\n {\n error: translate(\n 'directory.branding.errors.organizationRequired',\n 'Select a single organization before changing sidebar branding.',\n ),\n },\n { status: 400 },\n ),\n }\n }\n\n const em = container.resolve('em') as EntityManager\n const organization = await findOneWithDecryption(\n em,\n Organization,\n { id: organizationId, tenant: tenantId, deletedAt: null },\n { populate: ['tenant'] },\n { tenantId, organizationId },\n )\n if (!organization) {\n return {\n response: NextResponse.json(\n { error: translate('directory.branding.errors.notFound', 'Organization not found') },\n { status: 404 },\n ),\n }\n }\n\n return { auth, container, organization, organizationId, tenantId, translate }\n}\n\nfunction toIsoOrNull(value: Date | string | null | undefined): string | null {\n if (value == null) return null\n if (value instanceof Date) {\n const ms = value.getTime()\n return Number.isFinite(ms) ? new Date(ms).toISOString() : null\n }\n const trimmed = String(value).trim()\n if (!trimmed) return null\n const parsed = new Date(trimmed)\n return Number.isFinite(parsed.getTime()) ? parsed.toISOString() : null\n}\n\nfunction toResponsePayload(organization: Organization, tenantId: string) {\n return {\n organizationId: String(organization.id),\n organizationName: organization.name,\n tenantId,\n logoUrl: organization.logoUrl ?? null,\n updatedAt: toIsoOrNull(organization.updatedAt),\n }\n}\n\nasync function invalidateSidebarBrandingCache(container: RequestContainer, organizationId: string, tenantId: string) {\n try {\n const cache = container.resolve('cache') as {\n deleteByTags?: (tags: string[]) => Promise<unknown>\n } | null\n await runWithCacheTenant(tenantId, () =>\n cache?.deleteByTags?.([\n `nav:sidebar:organization:${organizationId}`,\n `nav:sidebar:tenant:${tenantId}`,\n ]),\n )\n } catch {\n // Cache invalidation is best-effort; the persisted branding is the source of truth.\n }\n}\n\nexport async function GET(req: Request) {\n const resolved = await resolveCurrentOrganization(req)\n if ('response' in resolved) return resolved.response\n\n return NextResponse.json(toResponsePayload(resolved.organization, resolved.tenantId))\n}\n\nexport async function PUT(req: Request) {\n const resolved = await resolveCurrentOrganization(req)\n if ('response' in resolved) return resolved.response\n\n let body: unknown\n try {\n body = await req.json()\n } catch {\n return NextResponse.json(\n { error: resolved.translate('directory.branding.errors.invalidLogoUrl', 'Enter a valid image URL.') },\n { status: 422 },\n )\n }\n if (!body || typeof body !== 'object' || !Object.prototype.hasOwnProperty.call(body, 'logoUrl')) {\n return NextResponse.json(\n { error: resolved.translate('directory.branding.errors.invalidLogoUrl', 'Enter a valid image URL.') },\n { status: 422 },\n )\n }\n\n const parsed = brandingUpdateSchema.safeParse(body)\n if (!parsed.success) {\n return NextResponse.json(\n {\n error: resolved.translate('directory.branding.errors.invalidLogoUrl', 'Enter a valid image URL.'),\n issues: parsed.error.issues,\n },\n { status: 422 },\n )\n }\n\n try {\n // Refuse a stale overwrite when two tabs edit the same organization branding.\n // Strictly additive \u2014 a no-op when the client omits the expected-version header.\n enforceCommandOptimisticLock({\n resourceKind: 'directory.organization',\n resourceId: resolved.organizationId,\n current: resolved.organization.updatedAt ?? null,\n request: req,\n })\n\n // Mutation-guard contract for custom write routes: validate before the write,\n // then run the after-success hook once the command persists.\n const guardResult = await validateCrudMutationGuard(resolved.container, {\n tenantId: resolved.tenantId,\n organizationId: resolved.organizationId,\n userId: resolved.auth.sub,\n resourceKind: 'directory.organization',\n resourceId: resolved.organizationId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: { logoUrl: parsed.data.logoUrl ?? null },\n })\n if (guardResult && !guardResult.ok) {\n return NextResponse.json(guardResult.body, { status: guardResult.status })\n }\n\n const commandBus = resolved.container.resolve('commandBus') as CommandBus\n const ctx = buildCommandContext(\n resolved.container,\n resolved.auth,\n req,\n resolved.organizationId,\n resolved.tenantId,\n )\n const { result } = await commandBus.execute<Record<string, unknown>, Organization>(\n 'directory.organizations.update',\n {\n input: {\n id: resolved.organizationId,\n tenantId: resolved.tenantId,\n logoUrl: parsed.data.logoUrl ?? null,\n },\n ctx,\n },\n )\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(resolved.container, {\n tenantId: resolved.tenantId,\n organizationId: resolved.organizationId,\n userId: resolved.auth.sub,\n resourceKind: 'directory.organization',\n resourceId: resolved.organizationId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n await invalidateSidebarBrandingCache(resolved.container, resolved.organizationId, resolved.tenantId)\n return NextResponse.json(toResponsePayload(result, resolved.tenantId))\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n logger.error('Organization branding update failed', { err })\n return NextResponse.json(\n { error: resolved.translate('directory.branding.errors.save', 'Failed to update organization branding.') },\n { status: 400 },\n )\n }\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Directory',\n summary: 'Current organization branding',\n methods: {\n GET: {\n summary: 'Read sidebar branding for the selected organization',\n description: 'Returns the logo URL used by the backend sidebar for the currently selected organization.',\n responses: [\n { status: 200, description: 'Organization branding', schema: brandingResponseSchema },\n ],\n errors: [\n { status: 400, description: 'A concrete organization scope is required', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 404, description: 'Organization not found', schema: errorSchema },\n ],\n },\n PUT: {\n summary: 'Update sidebar branding for the selected organization',\n description: 'Stores an external image URL or an internal attachment image URL as the selected organization logo.',\n requestBody: {\n contentType: 'application/json',\n schema: brandingUpdateSchema,\n },\n responses: [\n { status: 200, description: 'Updated organization branding', schema: brandingResponseSchema },\n ],\n errors: [\n { status: 400, description: 'Save failed', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 409, description: 'Organization branding changed since it was loaded', schema: errorSchema },\n { status: 422, description: 'Invalid logo URL', schema: errorSchema },\n ],\n },\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -12,6 +12,8 @@ import {
12
12
  } from "@open-mercato/core/modules/directory/utils/organizationScope";
13
13
  import { directoryTag, directoryErrorSchema, organizationSwitcherResponseSchema } from "../openapi.js";
14
14
  import { Tenant } from "@open-mercato/core/modules/directory/data/entities";
15
+ import { createLogger } from "@open-mercato/shared/lib/logger";
16
+ const logger = createLogger("directory").child({ component: "organization-switcher" });
15
17
  function buildOrganizationMenu(hierarchy, accessible) {
16
18
  const roots = [];
17
19
  const selectableIds = /* @__PURE__ */ new Set();
@@ -181,7 +183,7 @@ async function GET(req) {
181
183
  });
182
184
  return NextResponse.json(response);
183
185
  } catch (err) {
184
- console.error("Failed to build organization switcher payload", err);
186
+ logger.error("Failed to build organization switcher payload", { err });
185
187
  return NextResponse.json({ items: [], selectedId: null, canManage: false, tenantId: null, tenants: [], isSuperAdmin: false }, { status: 500 });
186
188
  }
187
189
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/directory/api/organization-switcher/route.ts"],
4
- "sourcesContent": ["import { NextResponse, type NextRequest } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { logCrudAccess } from '@open-mercato/shared/lib/crud/factory'\nimport { Organization } from '@open-mercato/core/modules/directory/data/entities'\nimport { computeHierarchyForOrganizations, type ComputedHierarchy } from '@open-mercato/core/modules/directory/lib/hierarchy'\nimport { isAllOrganizationsSelection } from '@open-mercato/core/modules/directory/constants'\nimport {\n getSelectedOrganizationFromRequest,\n getSelectedTenantFromRequest,\n resolveOrganizationScope,\n} from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport type { OpenApiMethodDoc, OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { directoryTag, directoryErrorSchema, organizationSwitcherResponseSchema } from '../openapi'\nimport { Tenant } from '@open-mercato/core/modules/directory/data/entities'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\nimport type { FilterQuery } from '@mikro-orm/core'\n\ntype OrganizationMenuNode = {\n id: string\n name: string\n depth: number\n selectable: boolean\n children: OrganizationMenuNode[]\n}\n\nfunction buildOrganizationMenu(\n hierarchy: ComputedHierarchy,\n accessible: string[] | null,\n): { nodes: OrganizationMenuNode[]; selectableIds: Set<string> } {\n const roots: OrganizationMenuNode[] = []\n const selectableIds = new Set<string>()\n if (!hierarchy.ordered.length) return { nodes: roots, selectableIds }\n\n const includeSet = new Set<string>()\n if (accessible === null) {\n for (const node of hierarchy.ordered) {\n includeSet.add(node.id)\n selectableIds.add(node.id)\n }\n } else {\n const accessibleSet = new Set(accessible)\n for (const id of accessibleSet) {\n const node = hierarchy.map.get(id)\n if (!node) continue\n includeSet.add(id)\n selectableIds.add(id)\n for (const desc of node.descendantIds) {\n includeSet.add(desc)\n selectableIds.add(desc)\n }\n for (const anc of node.ancestorIds) includeSet.add(anc)\n }\n }\n\n const menuNodes = new Map<string, OrganizationMenuNode>()\n for (const node of hierarchy.ordered) {\n if (!includeSet.has(node.id)) continue\n const menuNode: OrganizationMenuNode = {\n id: node.id,\n name: node.name,\n depth: node.depth,\n selectable: accessible === null ? true : selectableIds.has(node.id),\n children: [],\n }\n menuNodes.set(node.id, menuNode)\n }\n\n const ensureChild = (parent: OrganizationMenuNode, child: OrganizationMenuNode) => {\n if (!parent.children.some((existing) => existing.id === child.id)) parent.children.push(child)\n }\n\n for (const node of hierarchy.ordered) {\n if (!includeSet.has(node.id)) continue\n const menuNode = menuNodes.get(node.id)!\n const parentId = node.parentId\n if (parentId && menuNodes.has(parentId)) {\n ensureChild(menuNodes.get(parentId)!, menuNode)\n } else if (!roots.some((existing) => existing.id === menuNode.id)) {\n roots.push(menuNode)\n }\n }\n\n return { nodes: roots, selectableIds }\n}\n\nexport const metadata = {\n GET: { requireAuth: true },\n}\n\nexport async function GET(req: NextRequest) {\n const auth = await getAuthFromRequest(req)\n if (!auth || !auth.sub) {\n return NextResponse.json({ items: [], selectedId: null, canManage: false, tenantId: null, tenants: [], isSuperAdmin: false }, { status: auth ? 200 : 401 })\n }\n\n const url = new URL(req.url)\n\n try {\n const container = await createRequestContainer()\n const em = container.resolve<EntityManager>('em')\n const rbac = container.resolve<RbacService>('rbacService')\n\n const rawTenantParam = url.searchParams.get('tenantId')\n const cookieTenant = getSelectedTenantFromRequest(req)\n const actorTenantId = typeof auth.tenantId === 'string' && auth.tenantId.trim().length > 0 ? auth.tenantId.trim() : null\n const actorIsSuperAdmin = auth.isSuperAdmin === true\n\n let requestedTenantId = rawTenantParam ?? (cookieTenant ?? undefined)\n if (requestedTenantId === '') requestedTenantId = undefined\n let tenantId = typeof requestedTenantId === 'string' && requestedTenantId.trim().length > 0 ? requestedTenantId.trim() : null\n\n let tenantRecords: { id: string; name: string; isActive: boolean }[] = []\n if (actorIsSuperAdmin) {\n const tenants = await em.find(Tenant, { deletedAt: null }, { orderBy: { name: 'ASC' } })\n tenantRecords = tenants.map((tenant: Tenant) => ({\n id: String(tenant.id),\n name: typeof tenant.name === 'string' && tenant.name.length > 0 ? tenant.name : String(tenant.id),\n isActive: tenant.isActive !== false,\n }))\n if (!tenantId) tenantId = actorTenantId ?? (tenantRecords[0]?.id ?? null)\n if (tenantId && tenantRecords.length && !tenantRecords.some((record) => record.id === tenantId)) {\n tenantId = tenantRecords[0]?.id ?? tenantId\n }\n } else {\n tenantId = actorTenantId\n }\n\n if (!tenantId) {\n return NextResponse.json({\n items: [],\n selectedId: null,\n canManage: false,\n tenantId: null,\n tenants: tenantRecords,\n isSuperAdmin: actorIsSuperAdmin,\n })\n }\n\n const scopedOrgId = actorTenantId && actorTenantId === tenantId ? auth.orgId ?? null : null\n const acl = await rbac.loadAcl(auth.sub, { tenantId, organizationId: scopedOrgId })\n const aclIsSuperAdmin = acl?.isSuperAdmin === true\n const effectiveIsSuperAdmin = actorIsSuperAdmin || aclIsSuperAdmin\n const hasManageFeature =\n aclIsSuperAdmin ||\n await rbac.userHasAllFeatures(auth.sub, ['directory.organizations.manage'], {\n tenantId,\n organizationId: scopedOrgId,\n }) ||\n actorIsSuperAdmin\n\n const orgFilter: FilterQuery<Organization> = {\n tenant: tenantId,\n deletedAt: null,\n }\n const orgEntities: Organization[] = await em.find(\n Organization,\n orgFilter,\n { orderBy: { name: 'ASC' } },\n )\n const hierarchy = computeHierarchyForOrganizations(orgEntities, tenantId)\n const rawSelected = getSelectedOrganizationFromRequest(req)\n let hasSelectionCookie = rawSelected !== null\n const requestedAll = isAllOrganizationsSelection(rawSelected)\n const scope = await resolveOrganizationScope({\n em,\n rbac,\n auth: {\n ...auth,\n tenantId,\n orgId: scopedOrgId,\n },\n selectedId: rawSelected,\n tenantId,\n })\n const accessible = scope.allowedIds\n const menuData = buildOrganizationMenu(hierarchy, accessible)\n\n let selectedId = requestedAll ? null : (scope.selectedId ?? null)\n if (selectedId && !menuData.selectableIds.has(selectedId)) {\n selectedId = null\n if (!requestedAll) {\n hasSelectionCookie = false\n }\n }\n if (!selectedId && !hasSelectionCookie && auth.orgId) {\n if (accessible === null || menuData.selectableIds.has(auth.orgId)) {\n selectedId = auth.orgId\n }\n }\n\n const showMenu = menuData.nodes.length > 0 || hasManageFeature || effectiveIsSuperAdmin\n if (!showMenu) {\n return NextResponse.json({ items: [], selectedId: null, canManage: false })\n }\n\n const canViewAllOrganizations = accessible === null\n const response = {\n items: menuData.nodes,\n selectedId,\n canManage: !!hasManageFeature,\n canViewAllOrganizations,\n tenantId,\n tenants: tenantRecords,\n isSuperAdmin: effectiveIsSuperAdmin,\n }\n\n await logCrudAccess({\n container,\n auth,\n request: req,\n items: response.items,\n idField: 'id',\n resourceKind: 'directory.organization_switcher',\n organizationId: response.selectedId,\n tenantId,\n query: Object.fromEntries(url.searchParams.entries()),\n })\n\n return NextResponse.json(response)\n } catch (err) {\n console.error('Failed to build organization switcher payload', err)\n return NextResponse.json({ items: [], selectedId: null, canManage: false, tenantId: null, tenants: [], isSuperAdmin: false }, { status: 500 })\n }\n}\n\nconst organizationSwitcherGetDoc: OpenApiMethodDoc = {\n summary: 'Load organization switcher menu',\n description: 'Returns the hierarchical menu of organizations the current user may switch to within the active tenant.',\n tags: [directoryTag],\n responses: [\n { status: 200, description: 'Organization switcher payload.', schema: organizationSwitcherResponseSchema },\n ],\n errors: [\n { status: 401, description: 'Authentication required', schema: directoryErrorSchema },\n ],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: directoryTag,\n summary: 'Organization switcher menu',\n methods: {\n GET: organizationSwitcherGetDoc,\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { NextResponse, type NextRequest } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { logCrudAccess } from '@open-mercato/shared/lib/crud/factory'\nimport { Organization } from '@open-mercato/core/modules/directory/data/entities'\nimport { computeHierarchyForOrganizations, type ComputedHierarchy } from '@open-mercato/core/modules/directory/lib/hierarchy'\nimport { isAllOrganizationsSelection } from '@open-mercato/core/modules/directory/constants'\nimport {\n getSelectedOrganizationFromRequest,\n getSelectedTenantFromRequest,\n resolveOrganizationScope,\n} from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport type { OpenApiMethodDoc, OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { directoryTag, directoryErrorSchema, organizationSwitcherResponseSchema } from '../openapi'\nimport { Tenant } from '@open-mercato/core/modules/directory/data/entities'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\nimport type { FilterQuery } from '@mikro-orm/core'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('directory').child({ component: 'organization-switcher' })\n\ntype OrganizationMenuNode = {\n id: string\n name: string\n depth: number\n selectable: boolean\n children: OrganizationMenuNode[]\n}\n\nfunction buildOrganizationMenu(\n hierarchy: ComputedHierarchy,\n accessible: string[] | null,\n): { nodes: OrganizationMenuNode[]; selectableIds: Set<string> } {\n const roots: OrganizationMenuNode[] = []\n const selectableIds = new Set<string>()\n if (!hierarchy.ordered.length) return { nodes: roots, selectableIds }\n\n const includeSet = new Set<string>()\n if (accessible === null) {\n for (const node of hierarchy.ordered) {\n includeSet.add(node.id)\n selectableIds.add(node.id)\n }\n } else {\n const accessibleSet = new Set(accessible)\n for (const id of accessibleSet) {\n const node = hierarchy.map.get(id)\n if (!node) continue\n includeSet.add(id)\n selectableIds.add(id)\n for (const desc of node.descendantIds) {\n includeSet.add(desc)\n selectableIds.add(desc)\n }\n for (const anc of node.ancestorIds) includeSet.add(anc)\n }\n }\n\n const menuNodes = new Map<string, OrganizationMenuNode>()\n for (const node of hierarchy.ordered) {\n if (!includeSet.has(node.id)) continue\n const menuNode: OrganizationMenuNode = {\n id: node.id,\n name: node.name,\n depth: node.depth,\n selectable: accessible === null ? true : selectableIds.has(node.id),\n children: [],\n }\n menuNodes.set(node.id, menuNode)\n }\n\n const ensureChild = (parent: OrganizationMenuNode, child: OrganizationMenuNode) => {\n if (!parent.children.some((existing) => existing.id === child.id)) parent.children.push(child)\n }\n\n for (const node of hierarchy.ordered) {\n if (!includeSet.has(node.id)) continue\n const menuNode = menuNodes.get(node.id)!\n const parentId = node.parentId\n if (parentId && menuNodes.has(parentId)) {\n ensureChild(menuNodes.get(parentId)!, menuNode)\n } else if (!roots.some((existing) => existing.id === menuNode.id)) {\n roots.push(menuNode)\n }\n }\n\n return { nodes: roots, selectableIds }\n}\n\nexport const metadata = {\n GET: { requireAuth: true },\n}\n\nexport async function GET(req: NextRequest) {\n const auth = await getAuthFromRequest(req)\n if (!auth || !auth.sub) {\n return NextResponse.json({ items: [], selectedId: null, canManage: false, tenantId: null, tenants: [], isSuperAdmin: false }, { status: auth ? 200 : 401 })\n }\n\n const url = new URL(req.url)\n\n try {\n const container = await createRequestContainer()\n const em = container.resolve<EntityManager>('em')\n const rbac = container.resolve<RbacService>('rbacService')\n\n const rawTenantParam = url.searchParams.get('tenantId')\n const cookieTenant = getSelectedTenantFromRequest(req)\n const actorTenantId = typeof auth.tenantId === 'string' && auth.tenantId.trim().length > 0 ? auth.tenantId.trim() : null\n const actorIsSuperAdmin = auth.isSuperAdmin === true\n\n let requestedTenantId = rawTenantParam ?? (cookieTenant ?? undefined)\n if (requestedTenantId === '') requestedTenantId = undefined\n let tenantId = typeof requestedTenantId === 'string' && requestedTenantId.trim().length > 0 ? requestedTenantId.trim() : null\n\n let tenantRecords: { id: string; name: string; isActive: boolean }[] = []\n if (actorIsSuperAdmin) {\n const tenants = await em.find(Tenant, { deletedAt: null }, { orderBy: { name: 'ASC' } })\n tenantRecords = tenants.map((tenant: Tenant) => ({\n id: String(tenant.id),\n name: typeof tenant.name === 'string' && tenant.name.length > 0 ? tenant.name : String(tenant.id),\n isActive: tenant.isActive !== false,\n }))\n if (!tenantId) tenantId = actorTenantId ?? (tenantRecords[0]?.id ?? null)\n if (tenantId && tenantRecords.length && !tenantRecords.some((record) => record.id === tenantId)) {\n tenantId = tenantRecords[0]?.id ?? tenantId\n }\n } else {\n tenantId = actorTenantId\n }\n\n if (!tenantId) {\n return NextResponse.json({\n items: [],\n selectedId: null,\n canManage: false,\n tenantId: null,\n tenants: tenantRecords,\n isSuperAdmin: actorIsSuperAdmin,\n })\n }\n\n const scopedOrgId = actorTenantId && actorTenantId === tenantId ? auth.orgId ?? null : null\n const acl = await rbac.loadAcl(auth.sub, { tenantId, organizationId: scopedOrgId })\n const aclIsSuperAdmin = acl?.isSuperAdmin === true\n const effectiveIsSuperAdmin = actorIsSuperAdmin || aclIsSuperAdmin\n const hasManageFeature =\n aclIsSuperAdmin ||\n await rbac.userHasAllFeatures(auth.sub, ['directory.organizations.manage'], {\n tenantId,\n organizationId: scopedOrgId,\n }) ||\n actorIsSuperAdmin\n\n const orgFilter: FilterQuery<Organization> = {\n tenant: tenantId,\n deletedAt: null,\n }\n const orgEntities: Organization[] = await em.find(\n Organization,\n orgFilter,\n { orderBy: { name: 'ASC' } },\n )\n const hierarchy = computeHierarchyForOrganizations(orgEntities, tenantId)\n const rawSelected = getSelectedOrganizationFromRequest(req)\n let hasSelectionCookie = rawSelected !== null\n const requestedAll = isAllOrganizationsSelection(rawSelected)\n const scope = await resolveOrganizationScope({\n em,\n rbac,\n auth: {\n ...auth,\n tenantId,\n orgId: scopedOrgId,\n },\n selectedId: rawSelected,\n tenantId,\n })\n const accessible = scope.allowedIds\n const menuData = buildOrganizationMenu(hierarchy, accessible)\n\n let selectedId = requestedAll ? null : (scope.selectedId ?? null)\n if (selectedId && !menuData.selectableIds.has(selectedId)) {\n selectedId = null\n if (!requestedAll) {\n hasSelectionCookie = false\n }\n }\n if (!selectedId && !hasSelectionCookie && auth.orgId) {\n if (accessible === null || menuData.selectableIds.has(auth.orgId)) {\n selectedId = auth.orgId\n }\n }\n\n const showMenu = menuData.nodes.length > 0 || hasManageFeature || effectiveIsSuperAdmin\n if (!showMenu) {\n return NextResponse.json({ items: [], selectedId: null, canManage: false })\n }\n\n const canViewAllOrganizations = accessible === null\n const response = {\n items: menuData.nodes,\n selectedId,\n canManage: !!hasManageFeature,\n canViewAllOrganizations,\n tenantId,\n tenants: tenantRecords,\n isSuperAdmin: effectiveIsSuperAdmin,\n }\n\n await logCrudAccess({\n container,\n auth,\n request: req,\n items: response.items,\n idField: 'id',\n resourceKind: 'directory.organization_switcher',\n organizationId: response.selectedId,\n tenantId,\n query: Object.fromEntries(url.searchParams.entries()),\n })\n\n return NextResponse.json(response)\n } catch (err) {\n logger.error('Failed to build organization switcher payload', { err })\n return NextResponse.json({ items: [], selectedId: null, canManage: false, tenantId: null, tenants: [], isSuperAdmin: false }, { status: 500 })\n }\n}\n\nconst organizationSwitcherGetDoc: OpenApiMethodDoc = {\n summary: 'Load organization switcher menu',\n description: 'Returns the hierarchical menu of organizations the current user may switch to within the active tenant.',\n tags: [directoryTag],\n responses: [\n { status: 200, description: 'Organization switcher payload.', schema: organizationSwitcherResponseSchema },\n ],\n errors: [\n { status: 401, description: 'Authentication required', schema: directoryErrorSchema },\n ],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: directoryTag,\n summary: 'Organization switcher menu',\n methods: {\n GET: organizationSwitcherGetDoc,\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -13,6 +13,8 @@ import {
13
13
  import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
14
14
  import { isTenantDataEncryptionEnabled } from "@open-mercato/shared/lib/encryption/toggles";
15
15
  import { makeCreateRedo } from "@open-mercato/shared/lib/commands/redo";
16
+ import { createLogger } from "@open-mercato/shared/lib/logger";
17
+ const logger = createLogger("directory").child({ component: "tenants" });
16
18
  const tenantCrudEvents = {
17
19
  module: "directory",
18
20
  entity: "tenant",
@@ -56,12 +58,12 @@ const createTenantCommand = {
56
58
  const kms = ctx.container.resolve("kmsService");
57
59
  if (kms?.isHealthy?.()) {
58
60
  await kms?.createTenantDek?.(String(tenant.id));
59
- console.info("\u{1F511} [encryption][tenant] created tenant DEK", { tenantId: String(tenant.id) });
61
+ logger.info("Created tenant DEK", { tenantId: String(tenant.id) });
60
62
  } else {
61
- console.warn("\u26A0\uFE0F [encryption][tenant] kms not healthy, skipping tenant DEK provisioning", { tenantId: String(tenant.id) });
63
+ logger.warn("KMS not healthy, skipping tenant DEK provisioning", { tenantId: String(tenant.id) });
62
64
  }
63
65
  } catch (err) {
64
- console.warn("\u26A0\uFE0F [encryption] Failed to provision tenant key", err);
66
+ logger.warn("Failed to provision tenant key", { err });
65
67
  }
66
68
  }
67
69
  const identifiers = {