@open-mercato/core 0.5.1-develop.2691.d8a0934b37 → 0.5.1-develop.2699.f8b50c8046

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 (414) hide show
  1. package/dist/modules/api_keys/data/entities.js +1 -1
  2. package/dist/modules/api_keys/data/entities.js.map +1 -1
  3. package/dist/modules/api_keys/services/apiKeyService.js +5 -5
  4. package/dist/modules/api_keys/services/apiKeyService.js.map +2 -2
  5. package/dist/modules/attachments/api/library/[id]/route.js +1 -1
  6. package/dist/modules/attachments/api/library/[id]/route.js.map +2 -2
  7. package/dist/modules/attachments/api/library/route.js +7 -9
  8. package/dist/modules/attachments/api/library/route.js.map +2 -2
  9. package/dist/modules/attachments/api/partitions/route.js +3 -3
  10. package/dist/modules/attachments/api/partitions/route.js.map +2 -2
  11. package/dist/modules/attachments/api/route.js +6 -5
  12. package/dist/modules/attachments/api/route.js.map +2 -2
  13. package/dist/modules/attachments/api/transfer/route.js +1 -1
  14. package/dist/modules/attachments/api/transfer/route.js.map +2 -2
  15. package/dist/modules/attachments/data/entities.js +2 -1
  16. package/dist/modules/attachments/data/entities.js.map +2 -2
  17. package/dist/modules/attachments/lib/ocrQueue.js +1 -1
  18. package/dist/modules/attachments/lib/ocrQueue.js.map +2 -2
  19. package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js.map +2 -2
  20. package/dist/modules/audit_logs/api/audit-logs/actions/route.js.map +2 -2
  21. package/dist/modules/audit_logs/data/entities.js +1 -1
  22. package/dist/modules/audit_logs/data/entities.js.map +1 -1
  23. package/dist/modules/audit_logs/services/actionLogService.js +77 -70
  24. package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
  25. package/dist/modules/auth/api/roles/acl/route.js +1 -1
  26. package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
  27. package/dist/modules/auth/api/users/acl/route.js +2 -2
  28. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  29. package/dist/modules/auth/api/users/resend-invite/route.js +1 -1
  30. package/dist/modules/auth/api/users/resend-invite/route.js.map +2 -2
  31. package/dist/modules/auth/cli.js +12 -6
  32. package/dist/modules/auth/cli.js.map +2 -2
  33. package/dist/modules/auth/commands/users.js +1 -1
  34. package/dist/modules/auth/commands/users.js.map +2 -2
  35. package/dist/modules/auth/data/entities.js +1 -1
  36. package/dist/modules/auth/data/entities.js.map +2 -2
  37. package/dist/modules/auth/lib/setup-app.js +3 -3
  38. package/dist/modules/auth/lib/setup-app.js.map +2 -2
  39. package/dist/modules/auth/services/authService.js +2 -2
  40. package/dist/modules/auth/services/authService.js.map +2 -2
  41. package/dist/modules/business_rules/api/rules/route.js +3 -3
  42. package/dist/modules/business_rules/api/rules/route.js.map +2 -2
  43. package/dist/modules/business_rules/api/sets/[id]/members/route.js +7 -4
  44. package/dist/modules/business_rules/api/sets/[id]/members/route.js.map +2 -2
  45. package/dist/modules/business_rules/api/sets/route.js +3 -3
  46. package/dist/modules/business_rules/api/sets/route.js.map +2 -2
  47. package/dist/modules/business_rules/cli.js +1 -1
  48. package/dist/modules/business_rules/cli.js.map +2 -2
  49. package/dist/modules/business_rules/data/entities.js +2 -9
  50. package/dist/modules/business_rules/data/entities.js.map +2 -2
  51. package/dist/modules/business_rules/lib/rule-engine.js +1 -1
  52. package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
  53. package/dist/modules/catalog/api/option-schemas/route.js +0 -1
  54. package/dist/modules/catalog/api/option-schemas/route.js.map +2 -2
  55. package/dist/modules/catalog/data/entities.js +2 -11
  56. package/dist/modules/catalog/data/entities.js.map +2 -2
  57. package/dist/modules/configs/data/entities.js +2 -1
  58. package/dist/modules/configs/data/entities.js.map +2 -2
  59. package/dist/modules/currencies/commands/fetch-configs.js +3 -3
  60. package/dist/modules/currencies/commands/fetch-configs.js.map +2 -2
  61. package/dist/modules/currencies/data/entities.js +1 -1
  62. package/dist/modules/currencies/data/entities.js.map +2 -2
  63. package/dist/modules/customer_accounts/api/signup.js +1 -1
  64. package/dist/modules/customer_accounts/api/signup.js.map +2 -2
  65. package/dist/modules/customer_accounts/data/entities.js +1 -1
  66. package/dist/modules/customer_accounts/data/entities.js.map +2 -2
  67. package/dist/modules/customer_accounts/services/customerInvitationService.js +1 -1
  68. package/dist/modules/customer_accounts/services/customerInvitationService.js.map +2 -2
  69. package/dist/modules/customer_accounts/services/customerSessionService.js +1 -1
  70. package/dist/modules/customer_accounts/services/customerSessionService.js.map +2 -2
  71. package/dist/modules/customer_accounts/services/customerTokenService.js +12 -7
  72. package/dist/modules/customer_accounts/services/customerTokenService.js.map +2 -2
  73. package/dist/modules/customers/api/interactions/conflicts/route.js +19 -17
  74. package/dist/modules/customers/api/interactions/conflicts/route.js.map +2 -2
  75. package/dist/modules/customers/api/interactions/counts/route.js +7 -6
  76. package/dist/modules/customers/api/interactions/counts/route.js.map +2 -2
  77. package/dist/modules/customers/api/interactions/route.js +28 -42
  78. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  79. package/dist/modules/customers/api/utils.js +29 -24
  80. package/dist/modules/customers/api/utils.js.map +2 -2
  81. package/dist/modules/customers/cli.js +45 -40
  82. package/dist/modules/customers/cli.js.map +2 -2
  83. package/dist/modules/customers/commands/dictionaries.js +1 -1
  84. package/dist/modules/customers/commands/dictionaries.js.map +2 -2
  85. package/dist/modules/customers/commands/tags.js +1 -1
  86. package/dist/modules/customers/commands/tags.js.map +2 -2
  87. package/dist/modules/customers/data/entities.js +2 -12
  88. package/dist/modules/customers/data/entities.js.map +2 -2
  89. package/dist/modules/customers/lib/interactionProjection.js +18 -15
  90. package/dist/modules/customers/lib/interactionProjection.js.map +2 -2
  91. package/dist/modules/customers/lib/personCompanyLinkTable.js +6 -8
  92. package/dist/modules/customers/lib/personCompanyLinkTable.js.map +2 -2
  93. package/dist/modules/dashboards/api/roles/widgets/route.js +1 -1
  94. package/dist/modules/dashboards/api/roles/widgets/route.js.map +2 -2
  95. package/dist/modules/dashboards/api/users/widgets/route.js +1 -1
  96. package/dist/modules/dashboards/api/users/widgets/route.js.map +2 -2
  97. package/dist/modules/dashboards/data/entities.js +1 -1
  98. package/dist/modules/dashboards/data/entities.js.map +1 -1
  99. package/dist/modules/data_sync/api/mappings/route.js +1 -1
  100. package/dist/modules/data_sync/api/mappings/route.js.map +2 -2
  101. package/dist/modules/data_sync/data/entities.js +2 -1
  102. package/dist/modules/data_sync/data/entities.js.map +2 -2
  103. package/dist/modules/data_sync/lib/id-mapping.js +1 -1
  104. package/dist/modules/data_sync/lib/id-mapping.js.map +2 -2
  105. package/dist/modules/data_sync/lib/sync-run-service.js +1 -1
  106. package/dist/modules/data_sync/lib/sync-run-service.js.map +2 -2
  107. package/dist/modules/dictionaries/commands/factory.js +1 -1
  108. package/dist/modules/dictionaries/commands/factory.js.map +2 -2
  109. package/dist/modules/dictionaries/data/entities.js +2 -9
  110. package/dist/modules/dictionaries/data/entities.js.map +2 -2
  111. package/dist/modules/directory/commands/organizations.js +4 -4
  112. package/dist/modules/directory/commands/organizations.js.map +2 -2
  113. package/dist/modules/directory/data/entities.js +2 -1
  114. package/dist/modules/directory/data/entities.js.map +2 -2
  115. package/dist/modules/entities/api/definitions.js +2 -2
  116. package/dist/modules/entities/api/definitions.js.map +2 -2
  117. package/dist/modules/entities/api/encryption.js +2 -2
  118. package/dist/modules/entities/api/encryption.js.map +2 -2
  119. package/dist/modules/entities/api/relations/options.js +2 -2
  120. package/dist/modules/entities/api/relations/options.js.map +2 -2
  121. package/dist/modules/entities/cli.js +4 -4
  122. package/dist/modules/entities/cli.js.map +2 -2
  123. package/dist/modules/entities/data/entities.js +1 -1
  124. package/dist/modules/entities/data/entities.js.map +2 -2
  125. package/dist/modules/entities/lib/field-definitions.js +2 -2
  126. package/dist/modules/entities/lib/field-definitions.js.map +2 -2
  127. package/dist/modules/entities/lib/register.js +1 -1
  128. package/dist/modules/entities/lib/register.js.map +2 -2
  129. package/dist/modules/feature_toggles/data/entities.js +2 -9
  130. package/dist/modules/feature_toggles/data/entities.js.map +2 -2
  131. package/dist/modules/inbox_ops/api/proposals/counts/route.js +3 -6
  132. package/dist/modules/inbox_ops/api/proposals/counts/route.js.map +2 -2
  133. package/dist/modules/inbox_ops/data/entities.js +2 -8
  134. package/dist/modules/inbox_ops/data/entities.js.map +2 -2
  135. package/dist/modules/inbox_ops/lib/messagesIntegration.js +6 -6
  136. package/dist/modules/inbox_ops/lib/messagesIntegration.js.map +2 -2
  137. package/dist/modules/integrations/data/entities.js +2 -1
  138. package/dist/modules/integrations/data/entities.js.map +2 -2
  139. package/dist/modules/integrations/lib/credentials-service.js +1 -1
  140. package/dist/modules/integrations/lib/credentials-service.js.map +2 -2
  141. package/dist/modules/integrations/lib/log-service.js +1 -1
  142. package/dist/modules/integrations/lib/log-service.js.map +2 -2
  143. package/dist/modules/integrations/lib/state-service.js +1 -1
  144. package/dist/modules/integrations/lib/state-service.js.map +2 -2
  145. package/dist/modules/messages/api/route.js +90 -93
  146. package/dist/modules/messages/api/route.js.map +2 -2
  147. package/dist/modules/messages/api/unread-count/route.js +8 -7
  148. package/dist/modules/messages/api/unread-count/route.js.map +2 -2
  149. package/dist/modules/messages/commands/confirmations.js +1 -1
  150. package/dist/modules/messages/commands/confirmations.js.map +2 -2
  151. package/dist/modules/messages/commands/messages.js +3 -3
  152. package/dist/modules/messages/commands/messages.js.map +2 -2
  153. package/dist/modules/messages/data/entities.js +2 -1
  154. package/dist/modules/messages/data/entities.js.map +2 -2
  155. package/dist/modules/messages/lib/email-sender.js +1 -1
  156. package/dist/modules/messages/lib/email-sender.js.map +2 -2
  157. package/dist/modules/messages/lib/searchLookup.js +8 -8
  158. package/dist/modules/messages/lib/searchLookup.js.map +2 -2
  159. package/dist/modules/messages/lib/tokenConsumption.js +9 -4
  160. package/dist/modules/messages/lib/tokenConsumption.js.map +2 -2
  161. package/dist/modules/notifications/data/entities.js +2 -1
  162. package/dist/modules/notifications/data/entities.js.map +2 -2
  163. package/dist/modules/notifications/lib/notificationRecipients.js +15 -5
  164. package/dist/modules/notifications/lib/notificationRecipients.js.map +2 -2
  165. package/dist/modules/notifications/lib/notificationService.js +39 -34
  166. package/dist/modules/notifications/lib/notificationService.js.map +2 -2
  167. package/dist/modules/notifications/workers/create-notification.worker.js +14 -13
  168. package/dist/modules/notifications/workers/create-notification.worker.js.map +2 -2
  169. package/dist/modules/payment_gateways/api/transactions/route.js +2 -2
  170. package/dist/modules/payment_gateways/api/transactions/route.js.map +2 -2
  171. package/dist/modules/payment_gateways/data/entities.js +2 -1
  172. package/dist/modules/payment_gateways/data/entities.js.map +2 -2
  173. package/dist/modules/payment_gateways/lib/gateway-service.js +1 -1
  174. package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
  175. package/dist/modules/payment_gateways/lib/webhook-utils.js +2 -2
  176. package/dist/modules/payment_gateways/lib/webhook-utils.js.map +2 -2
  177. package/dist/modules/perspectives/data/entities.js +1 -1
  178. package/dist/modules/perspectives/data/entities.js.map +2 -2
  179. package/dist/modules/planner/data/entities.js +1 -1
  180. package/dist/modules/planner/data/entities.js.map +2 -2
  181. package/dist/modules/progress/data/entities.js +2 -1
  182. package/dist/modules/progress/data/entities.js.map +2 -2
  183. package/dist/modules/progress/lib/progressServiceImpl.js +1 -1
  184. package/dist/modules/progress/lib/progressServiceImpl.js.map +2 -2
  185. package/dist/modules/query_index/api/status.js +66 -57
  186. package/dist/modules/query_index/api/status.js.map +2 -2
  187. package/dist/modules/query_index/cli.js +39 -24
  188. package/dist/modules/query_index/cli.js.map +2 -2
  189. package/dist/modules/query_index/data/entities.js +1 -1
  190. package/dist/modules/query_index/data/entities.js.map +2 -2
  191. package/dist/modules/query_index/di.js +25 -13
  192. package/dist/modules/query_index/di.js.map +2 -2
  193. package/dist/modules/query_index/lib/batch.js +31 -33
  194. package/dist/modules/query_index/lib/batch.js.map +2 -2
  195. package/dist/modules/query_index/lib/coverage.js +63 -50
  196. package/dist/modules/query_index/lib/coverage.js.map +2 -2
  197. package/dist/modules/query_index/lib/engine.js +592 -588
  198. package/dist/modules/query_index/lib/engine.js.map +2 -2
  199. package/dist/modules/query_index/lib/indexer.js +74 -47
  200. package/dist/modules/query_index/lib/indexer.js.map +2 -2
  201. package/dist/modules/query_index/lib/jobs.js +37 -24
  202. package/dist/modules/query_index/lib/jobs.js.map +2 -2
  203. package/dist/modules/query_index/lib/purge.js +19 -11
  204. package/dist/modules/query_index/lib/purge.js.map +2 -2
  205. package/dist/modules/query_index/lib/reindexer.js +47 -44
  206. package/dist/modules/query_index/lib/reindexer.js.map +2 -2
  207. package/dist/modules/query_index/lib/search-tokens.js +47 -25
  208. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  209. package/dist/modules/query_index/lib/stale.js +14 -12
  210. package/dist/modules/query_index/lib/stale.js.map +2 -2
  211. package/dist/modules/query_index/lib/subscriber-scope.js +2 -2
  212. package/dist/modules/query_index/lib/subscriber-scope.js.map +2 -2
  213. package/dist/modules/query_index/subscribers/delete_one.js +3 -2
  214. package/dist/modules/query_index/subscribers/delete_one.js.map +2 -2
  215. package/dist/modules/resources/commands/tag-assignments.js +1 -1
  216. package/dist/modules/resources/commands/tag-assignments.js.map +2 -2
  217. package/dist/modules/resources/commands/tags.js +1 -1
  218. package/dist/modules/resources/commands/tags.js.map +2 -2
  219. package/dist/modules/resources/data/entities.js +2 -1
  220. package/dist/modules/resources/data/entities.js.map +2 -2
  221. package/dist/modules/sales/commands/documentAddresses.js +2 -2
  222. package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
  223. package/dist/modules/sales/commands/notes.js.map +2 -2
  224. package/dist/modules/sales/commands/tags.js +1 -1
  225. package/dist/modules/sales/commands/tags.js.map +2 -2
  226. package/dist/modules/sales/data/enrichers.js +9 -8
  227. package/dist/modules/sales/data/enrichers.js.map +2 -2
  228. package/dist/modules/sales/data/entities.js +2 -11
  229. package/dist/modules/sales/data/entities.js.map +2 -2
  230. package/dist/modules/shipping_carriers/data/entities.js +2 -1
  231. package/dist/modules/shipping_carriers/data/entities.js.map +2 -2
  232. package/dist/modules/shipping_carriers/lib/shipping-service.js +1 -1
  233. package/dist/modules/shipping_carriers/lib/shipping-service.js.map +2 -2
  234. package/dist/modules/shipping_carriers/lib/webhook-utils.js +2 -2
  235. package/dist/modules/shipping_carriers/lib/webhook-utils.js.map +2 -2
  236. package/dist/modules/staff/data/entities.js +1 -1
  237. package/dist/modules/staff/data/entities.js.map +2 -2
  238. package/dist/modules/translations/api/[entityType]/[entityId]/route.js +3 -5
  239. package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
  240. package/dist/modules/translations/api/context.js +2 -2
  241. package/dist/modules/translations/api/context.js.map +2 -2
  242. package/dist/modules/translations/commands/translations.js +46 -39
  243. package/dist/modules/translations/commands/translations.js.map +2 -2
  244. package/dist/modules/translations/components/TranslationManager.js +19 -10
  245. package/dist/modules/translations/components/TranslationManager.js.map +2 -2
  246. package/dist/modules/translations/data/entities.js +1 -1
  247. package/dist/modules/translations/data/entities.js.map +2 -2
  248. package/dist/modules/translations/lib/apply.js +4 -4
  249. package/dist/modules/translations/lib/apply.js.map +2 -2
  250. package/dist/modules/translations/lib/batch.js +3 -2
  251. package/dist/modules/translations/lib/batch.js.map +2 -2
  252. package/dist/modules/translations/subscribers/cleanup.js +3 -5
  253. package/dist/modules/translations/subscribers/cleanup.js.map +2 -2
  254. package/dist/modules/workflows/api/definitions/route.js +1 -1
  255. package/dist/modules/workflows/api/definitions/route.js.map +2 -2
  256. package/dist/modules/workflows/cli.js +5 -5
  257. package/dist/modules/workflows/cli.js.map +2 -2
  258. package/dist/modules/workflows/data/entities.js +2 -1
  259. package/dist/modules/workflows/data/entities.js.map +2 -2
  260. package/dist/modules/workflows/lib/event-logger.js +2 -2
  261. package/dist/modules/workflows/lib/event-logger.js.map +2 -2
  262. package/dist/modules/workflows/lib/seeds.js +16 -1
  263. package/dist/modules/workflows/lib/seeds.js.map +2 -2
  264. package/dist/modules/workflows/lib/step-handler.js +3 -3
  265. package/dist/modules/workflows/lib/step-handler.js.map +2 -2
  266. package/dist/modules/workflows/lib/task-handler.js +1 -1
  267. package/dist/modules/workflows/lib/task-handler.js.map +2 -2
  268. package/dist/modules/workflows/lib/transition-handler.js +1 -1
  269. package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
  270. package/dist/modules/workflows/lib/workflow-executor.js +2 -2
  271. package/dist/modules/workflows/lib/workflow-executor.js.map +2 -2
  272. package/jest.config.cjs +4 -2
  273. package/package.json +3 -3
  274. package/src/modules/api_keys/data/entities.ts +1 -1
  275. package/src/modules/api_keys/services/apiKeyService.ts +5 -5
  276. package/src/modules/attachments/api/library/[id]/route.ts +1 -1
  277. package/src/modules/attachments/api/library/route.ts +10 -12
  278. package/src/modules/attachments/api/partitions/route.ts +3 -3
  279. package/src/modules/attachments/api/route.ts +10 -8
  280. package/src/modules/attachments/api/transfer/route.ts +1 -1
  281. package/src/modules/attachments/data/entities.ts +2 -1
  282. package/src/modules/attachments/lib/ocrQueue.ts +1 -1
  283. package/src/modules/audit_logs/api/audit-logs/actions/export/route.ts +4 -4
  284. package/src/modules/audit_logs/api/audit-logs/actions/route.ts +4 -4
  285. package/src/modules/audit_logs/data/entities.ts +1 -1
  286. package/src/modules/audit_logs/services/actionLogService.ts +96 -87
  287. package/src/modules/auth/api/roles/acl/route.ts +1 -1
  288. package/src/modules/auth/api/users/acl/route.ts +2 -2
  289. package/src/modules/auth/api/users/resend-invite/route.ts +1 -1
  290. package/src/modules/auth/cli.ts +46 -40
  291. package/src/modules/auth/commands/users.ts +1 -1
  292. package/src/modules/auth/data/entities.ts +1 -1
  293. package/src/modules/auth/lib/setup-app.ts +3 -3
  294. package/src/modules/auth/services/authService.ts +2 -2
  295. package/src/modules/business_rules/api/rules/route.ts +3 -3
  296. package/src/modules/business_rules/api/sets/[id]/members/route.ts +7 -4
  297. package/src/modules/business_rules/api/sets/route.ts +3 -3
  298. package/src/modules/business_rules/cli.ts +1 -1
  299. package/src/modules/business_rules/data/entities.ts +2 -9
  300. package/src/modules/business_rules/lib/rule-engine.ts +1 -1
  301. package/src/modules/catalog/api/option-schemas/route.ts +0 -1
  302. package/src/modules/catalog/data/entities.ts +2 -11
  303. package/src/modules/configs/data/entities.ts +2 -1
  304. package/src/modules/currencies/commands/fetch-configs.ts +3 -3
  305. package/src/modules/currencies/data/entities.ts +1 -1
  306. package/src/modules/customer_accounts/api/signup.ts +1 -1
  307. package/src/modules/customer_accounts/data/entities.ts +1 -1
  308. package/src/modules/customer_accounts/services/customerInvitationService.ts +1 -1
  309. package/src/modules/customer_accounts/services/customerSessionService.ts +1 -1
  310. package/src/modules/customer_accounts/services/customerTokenService.ts +26 -15
  311. package/src/modules/customers/api/interactions/conflicts/route.ts +26 -23
  312. package/src/modules/customers/api/interactions/counts/route.ts +13 -11
  313. package/src/modules/customers/api/interactions/route.ts +32 -44
  314. package/src/modules/customers/api/utils.ts +45 -37
  315. package/src/modules/customers/cli.ts +88 -67
  316. package/src/modules/customers/commands/dictionaries.ts +1 -1
  317. package/src/modules/customers/commands/tags.ts +1 -1
  318. package/src/modules/customers/data/entities.ts +2 -12
  319. package/src/modules/customers/lib/interactionProjection.ts +36 -25
  320. package/src/modules/customers/lib/personCompanyLinkTable.ts +13 -18
  321. package/src/modules/dashboards/api/roles/widgets/route.ts +1 -1
  322. package/src/modules/dashboards/api/users/widgets/route.ts +1 -1
  323. package/src/modules/dashboards/data/entities.ts +1 -1
  324. package/src/modules/data_sync/api/mappings/route.ts +1 -1
  325. package/src/modules/data_sync/data/entities.ts +2 -1
  326. package/src/modules/data_sync/lib/id-mapping.ts +1 -1
  327. package/src/modules/data_sync/lib/sync-run-service.ts +1 -1
  328. package/src/modules/dictionaries/commands/factory.ts +1 -1
  329. package/src/modules/dictionaries/data/entities.ts +2 -9
  330. package/src/modules/directory/commands/organizations.ts +4 -4
  331. package/src/modules/directory/data/entities.ts +2 -1
  332. package/src/modules/entities/api/definitions.ts +2 -2
  333. package/src/modules/entities/api/encryption.ts +2 -2
  334. package/src/modules/entities/api/relations/options.ts +8 -3
  335. package/src/modules/entities/cli.ts +4 -4
  336. package/src/modules/entities/data/entities.ts +1 -1
  337. package/src/modules/entities/lib/field-definitions.ts +2 -2
  338. package/src/modules/entities/lib/register.ts +1 -1
  339. package/src/modules/feature_toggles/data/entities.ts +2 -9
  340. package/src/modules/inbox_ops/api/proposals/counts/route.ts +10 -10
  341. package/src/modules/inbox_ops/data/entities.ts +2 -8
  342. package/src/modules/inbox_ops/lib/messagesIntegration.ts +12 -11
  343. package/src/modules/integrations/data/entities.ts +2 -1
  344. package/src/modules/integrations/lib/credentials-service.ts +1 -1
  345. package/src/modules/integrations/lib/log-service.ts +1 -1
  346. package/src/modules/integrations/lib/state-service.ts +1 -1
  347. package/src/modules/messages/api/route.ts +134 -123
  348. package/src/modules/messages/api/unread-count/route.ts +19 -16
  349. package/src/modules/messages/commands/confirmations.ts +1 -1
  350. package/src/modules/messages/commands/messages.ts +3 -3
  351. package/src/modules/messages/data/entities.ts +2 -1
  352. package/src/modules/messages/lib/email-sender.ts +1 -1
  353. package/src/modules/messages/lib/searchLookup.ts +16 -13
  354. package/src/modules/messages/lib/tokenConsumption.ts +16 -8
  355. package/src/modules/notifications/data/entities.ts +2 -1
  356. package/src/modules/notifications/lib/notificationRecipients.ts +42 -26
  357. package/src/modules/notifications/lib/notificationService.ts +53 -42
  358. package/src/modules/notifications/workers/create-notification.worker.ts +20 -17
  359. package/src/modules/payment_gateways/api/transactions/route.ts +2 -2
  360. package/src/modules/payment_gateways/data/entities.ts +2 -1
  361. package/src/modules/payment_gateways/lib/gateway-service.ts +1 -1
  362. package/src/modules/payment_gateways/lib/webhook-utils.ts +2 -2
  363. package/src/modules/perspectives/data/entities.ts +1 -1
  364. package/src/modules/planner/data/entities.ts +1 -1
  365. package/src/modules/progress/data/entities.ts +2 -1
  366. package/src/modules/progress/lib/progressServiceImpl.ts +1 -1
  367. package/src/modules/query_index/api/status.ts +85 -71
  368. package/src/modules/query_index/cli.ts +51 -31
  369. package/src/modules/query_index/data/entities.ts +1 -1
  370. package/src/modules/query_index/di.ts +41 -16
  371. package/src/modules/query_index/lib/batch.ts +68 -55
  372. package/src/modules/query_index/lib/coverage.ts +115 -88
  373. package/src/modules/query_index/lib/engine.ts +1036 -1096
  374. package/src/modules/query_index/lib/indexer.ts +115 -79
  375. package/src/modules/query_index/lib/jobs.ts +51 -31
  376. package/src/modules/query_index/lib/purge.ts +25 -19
  377. package/src/modules/query_index/lib/reindexer.ts +97 -84
  378. package/src/modules/query_index/lib/search-tokens.ts +67 -36
  379. package/src/modules/query_index/lib/stale.ts +14 -17
  380. package/src/modules/query_index/lib/subscriber-scope.ts +6 -5
  381. package/src/modules/query_index/subscribers/delete_one.ts +9 -6
  382. package/src/modules/resources/commands/tag-assignments.ts +1 -1
  383. package/src/modules/resources/commands/tags.ts +1 -1
  384. package/src/modules/resources/data/entities.ts +2 -1
  385. package/src/modules/sales/commands/documentAddresses.ts +2 -2
  386. package/src/modules/sales/commands/notes.ts +1 -1
  387. package/src/modules/sales/commands/tags.ts +1 -1
  388. package/src/modules/sales/data/enrichers.ts +17 -13
  389. package/src/modules/sales/data/entities.ts +2 -11
  390. package/src/modules/shipping_carriers/data/entities.ts +2 -1
  391. package/src/modules/shipping_carriers/lib/shipping-service.ts +1 -1
  392. package/src/modules/shipping_carriers/lib/webhook-utils.ts +2 -2
  393. package/src/modules/staff/data/entities.ts +1 -1
  394. package/src/modules/translations/api/[entityType]/[entityId]/route.ts +14 -11
  395. package/src/modules/translations/api/context.ts +4 -4
  396. package/src/modules/translations/commands/translations.ts +116 -81
  397. package/src/modules/translations/components/TranslationManager.tsx +23 -14
  398. package/src/modules/translations/data/entities.ts +1 -1
  399. package/src/modules/translations/i18n/de.json +1 -0
  400. package/src/modules/translations/i18n/en.json +1 -0
  401. package/src/modules/translations/i18n/es.json +1 -0
  402. package/src/modules/translations/i18n/pl.json +1 -0
  403. package/src/modules/translations/lib/apply.ts +6 -6
  404. package/src/modules/translations/lib/batch.ts +9 -7
  405. package/src/modules/translations/subscribers/cleanup.ts +10 -11
  406. package/src/modules/workflows/api/definitions/route.ts +1 -1
  407. package/src/modules/workflows/cli.ts +5 -5
  408. package/src/modules/workflows/data/entities.ts +2 -1
  409. package/src/modules/workflows/lib/event-logger.ts +2 -2
  410. package/src/modules/workflows/lib/seeds.ts +16 -1
  411. package/src/modules/workflows/lib/step-handler.ts +3 -3
  412. package/src/modules/workflows/lib/task-handler.ts +1 -1
  413. package/src/modules/workflows/lib/transition-handler.ts +1 -1
  414. package/src/modules/workflows/lib/workflow-executor.ts +2 -2
@@ -56,11 +56,16 @@ export async function GET(req: Request) {
56
56
  labelField = (cfg?.labelField as string | undefined) || ''
57
57
  }
58
58
  if (!labelField) {
59
- const candidates = ['name','title','code','email']
59
+ const candidates = ['name', 'title', 'code', 'email']
60
60
  const table = tableNameFromEntityId(entityId)
61
- const knex = (em as any).getConnection().getKnex()
61
+ const db = (em as any).getKysely() as any
62
62
  for (const c of candidates) {
63
- const exists = await knex('information_schema.columns').where({ table_name: table, column_name: c }).first()
63
+ const exists = await db
64
+ .selectFrom('information_schema.columns')
65
+ .select('column_name')
66
+ .where('table_name', '=', table)
67
+ .where('column_name', '=', c)
68
+ .executeTakeFirst()
64
69
  if (exists) { labelField = c; break }
65
70
  }
66
71
  if (!labelField) labelField = 'id'
@@ -223,7 +223,7 @@ const addField: ModuleCli = {
223
223
  if (description !== undefined) configJson.description = description
224
224
 
225
225
  if (!existing) {
226
- await em.persistAndFlush(em.create(CustomFieldDef, {
226
+ await em.persist(em.create(CustomFieldDef, {
227
227
  entityId,
228
228
  organizationId: orgId,
229
229
  tenantId: tenantId,
@@ -231,7 +231,7 @@ const addField: ModuleCli = {
231
231
  kind,
232
232
  configJson,
233
233
  isActive: true,
234
- }))
234
+ })).flush()
235
235
  console.log(`Created custom field: ${entityId}.${key} (${kind})${orgId == null ? ' [global]' : ` [org=${orgId}, tenant=${tenantId}]`}`)
236
236
  } else {
237
237
  existing.kind = kind as any
@@ -272,7 +272,7 @@ async function upsertEncryptionMaps(em: any, tenantId: string, organizationId: s
272
272
  existing.isActive = true
273
273
  existing.updatedAt = new Date()
274
274
  logger(`🔒 Updated encryption map for ${spec.entityId} ✨`)
275
- await em.persistAndFlush(existing)
275
+ await em.persist(existing).flush()
276
276
  continue
277
277
  }
278
278
  const map = em.create(EncryptionMap, {
@@ -282,7 +282,7 @@ async function upsertEncryptionMaps(em: any, tenantId: string, organizationId: s
282
282
  fieldsJson: spec.fields,
283
283
  isActive: true,
284
284
  })
285
- await em.persistAndFlush(map)
285
+ await em.persist(map).flush()
286
286
  logger(`Created encryption map for ${spec.entityId}`)
287
287
  }
288
288
  }
@@ -1,4 +1,4 @@
1
- import { Entity, PrimaryKey, Property, Index } from '@mikro-orm/core'
1
+ import { Entity, Index, PrimaryKey, Property } from '@mikro-orm/decorators/legacy'
2
2
 
3
3
  // Definitions of custom fields scoped to an entity type and organization
4
4
  @Entity({ tableName: 'custom_field_defs' })
@@ -91,7 +91,7 @@ export async function ensureCustomFieldDefinitions(
91
91
 
92
92
  if (!existing) {
93
93
  if (!scope.dryRun) {
94
- await em.persistAndFlush(
94
+ await em.persist(
95
95
  em.create(CustomFieldDef, {
96
96
  entityId: set.entity,
97
97
  organizationId: scope.organizationId,
@@ -103,7 +103,7 @@ export async function ensureCustomFieldDefinitions(
103
103
  createdAt: new Date(),
104
104
  updatedAt: new Date(),
105
105
  })
106
- )
106
+ ).flush()
107
107
  }
108
108
  created++
109
109
  continue
@@ -64,7 +64,7 @@ export async function upsertCustomEntity(em: EntityManager, entityId: string, op
64
64
  if (!ent) {
65
65
  if (dryRun) return 'created'
66
66
  ent = tem.create(CustomEntity as any, { ...where, ...desired, createdAt: now, updatedAt: now, deletedAt: null })
67
- await tem.persistAndFlush(ent)
67
+ await tem.persist(ent).flush()
68
68
  return 'created' as UpsertCustomEntityResult
69
69
  }
70
70
  if (createOnly) return 'unchanged'
@@ -1,12 +1,5 @@
1
- import {
2
- Entity,
3
- Index,
4
- OptionalProps,
5
- PrimaryKey,
6
- Property,
7
- Unique,
8
- ManyToOne,
9
- } from '@mikro-orm/core'
1
+ import { OptionalProps } from '@mikro-orm/core'
2
+ import { Entity, Index, ManyToOne, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'
10
3
  import type { JsonValue } from '@open-mercato/shared/lib/json'
11
4
 
12
5
 
@@ -1,4 +1,5 @@
1
1
  import { NextResponse } from 'next/server'
2
+ import { sql } from 'kysely'
2
3
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
3
4
  import { runWithCacheTenant } from '@open-mercato/cache'
4
5
  import { InboxProposal } from '../../../data/entities'
@@ -45,17 +46,16 @@ export async function GET(req: Request) {
45
46
  ])
46
47
 
47
48
  // Single GROUP BY query for category counts — O(1) queries
48
- const knex = ctx.em.getKnex()
49
- const categoryRows = await knex('inbox_proposals')
50
- .select('category')
51
- .count('* as count')
52
- .where({
53
- organization_id: ctx.organizationId,
54
- tenant_id: ctx.tenantId,
55
- is_active: true,
56
- })
57
- .whereNull('deleted_at')
49
+ const db = ctx.em.getKysely<any>() as any
50
+ const categoryRows = await db
51
+ .selectFrom('inbox_proposals')
52
+ .select(['category', sql<string>`count(*)`.as('count')])
53
+ .where('organization_id', '=', ctx.organizationId)
54
+ .where('tenant_id', '=', ctx.tenantId)
55
+ .where('is_active', '=', true)
56
+ .where('deleted_at', 'is', null)
58
57
  .groupBy('category')
58
+ .execute() as Array<{ category: string | null; count: string | number }>
59
59
 
60
60
  const byCategory: Record<string, number> = {}
61
61
  for (const cat of ALL_CATEGORIES) {
@@ -1,11 +1,5 @@
1
- import {
2
- Entity,
3
- PrimaryKey,
4
- Property,
5
- Index,
6
- Unique,
7
- OptionalProps,
8
- } from '@mikro-orm/core'
1
+ import { OptionalProps } from '@mikro-orm/core'
2
+ import { Entity, Index, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'
9
3
 
10
4
  // ---------------------------------------------------------------------------
11
5
  // Shared Types
@@ -54,16 +54,17 @@ export async function resolveMessageSenderUserId(
54
54
  scope: { tenantId: string; organizationId: string },
55
55
  ): Promise<string> {
56
56
  try {
57
- // Direct knex: users.email is a plaintext login field, not encrypted at
58
- // field level, so findOneWithDecryption is unnecessary here.
59
- const knex = em.getKnex()
57
+ // users.email is a plaintext login field, not encrypted at field level,
58
+ // so findOneWithDecryption is unnecessary here.
59
+ const db = em.getKysely<any>() as any
60
60
  const normalizedEmail = forwardedByEmail.trim().toLowerCase()
61
61
  if (normalizedEmail) {
62
- const row = await knex('users')
62
+ const row = await db
63
+ .selectFrom('users')
63
64
  .select('id')
64
- .where('email', normalizedEmail)
65
- .whereNull('deleted_at')
66
- .first()
65
+ .where('email', '=', normalizedEmail)
66
+ .where('deleted_at', 'is', null)
67
+ .executeTakeFirst() as { id?: string } | undefined
67
68
  if (row?.id) return row.id
68
69
  }
69
70
  } catch {
@@ -100,9 +101,9 @@ export async function createMessageRecordForEmail(
100
101
  if (!commandBus) return null
101
102
 
102
103
  const em = ctx.container.resolve('em') as EntityManager
103
- const knex = em.getKnex()
104
+ const db = em.getKysely<any>()
104
105
  const recipientUserIds = await getRecipientUserIdsForFeature(
105
- knex, ctx.scope.tenantId, 'inbox_ops.proposals.view',
106
+ db, ctx.scope.tenantId, 'inbox_ops.proposals.view',
106
107
  )
107
108
 
108
109
  const recipients = recipientUserIds.map((userId) => ({ userId, type: 'to' as const }))
@@ -174,9 +175,9 @@ export async function createMessageRecordForReply(
174
175
  if (!commandBus) return null
175
176
 
176
177
  const em = ctx.container.resolve('em') as EntityManager
177
- const knex = em.getKnex()
178
+ const db = em.getKysely<any>()
178
179
  const recipientUserIds = await getRecipientUserIdsForFeature(
179
- knex, ctx.scope.tenantId, 'inbox_ops.proposals.view',
180
+ db, ctx.scope.tenantId, 'inbox_ops.proposals.view',
180
181
  )
181
182
  if (recipientUserIds.length === 0) return null
182
183
 
@@ -1,4 +1,5 @@
1
- import { Entity, PrimaryKey, Property, Index, OptionalProps } from '@mikro-orm/core'
1
+ import { OptionalProps } from '@mikro-orm/core'
2
+ import { Entity, Index, PrimaryKey, Property } from '@mikro-orm/decorators/legacy'
2
3
 
3
4
  @Entity({ tableName: 'sync_external_id_mappings' })
4
5
  @Index({ properties: ['internalEntityType', 'internalEntityId', 'organizationId'] })
@@ -176,7 +176,7 @@ export function createCredentialsService(em: EntityManager) {
176
176
  organizationId: scope.organizationId,
177
177
  tenantId: scope.tenantId,
178
178
  })
179
- await em.persistAndFlush(created)
179
+ await em.persist(created).flush()
180
180
  },
181
181
 
182
182
  async saveField(
@@ -53,7 +53,7 @@ export function createIntegrationLogService(em: EntityManager) {
53
53
  organizationId: scope.organizationId,
54
54
  tenantId: scope.tenantId,
55
55
  })
56
- await em.persistAndFlush(row)
56
+ await em.persist(row).flush()
57
57
  return row
58
58
  },
59
59
 
@@ -110,7 +110,7 @@ export function createIntegrationStateService(em: EntityManager) {
110
110
  organizationId: scope.organizationId,
111
111
  tenantId: scope.tenantId,
112
112
  })
113
- await em.persistAndFlush(created)
113
+ await em.persist(created).flush()
114
114
  return created
115
115
  },
116
116
 
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod'
2
2
  import type { EntityManager } from '@mikro-orm/postgresql'
3
- import type { Knex } from 'knex'
3
+ import { type Kysely, sql } from 'kysely'
4
4
  import type { CommandBus } from '@open-mercato/shared/lib/commands/command-bus'
5
5
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'
6
6
  import { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'
@@ -28,8 +28,8 @@ type MessageCommandExecuteResultWithThreadId = MessageCommandExecuteResult & {
28
28
 
29
29
  const NO_MATCH_ID = '00000000-0000-0000-0000-000000000000'
30
30
 
31
- function getKnex(em: EntityManager): Knex {
32
- return (em.getConnection() as unknown as { getKnex: () => Knex }).getKnex()
31
+ function getDb(em: EntityManager): Kysely<any> {
32
+ return em.getKysely<any>()
33
33
  }
34
34
 
35
35
  type MessageListScopeRow = {
@@ -61,142 +61,151 @@ export async function GET(req: Request) {
61
61
  const url = new URL(req.url)
62
62
  const params = Object.fromEntries(url.searchParams)
63
63
  const input = listMessagesSchema.parse(params)
64
- const knex = getKnex(em)
64
+ const db = getDb(em) as any
65
65
 
66
- let query = knex('messages as m')
67
- .where('m.tenant_id', scope.tenantId)
68
- .whereNull('m.deleted_at')
69
-
70
- if (scope.organizationId) {
71
- query = query.where('m.organization_id', scope.organizationId)
72
- } else {
73
- query = query.whereNull('m.organization_id')
74
- }
75
-
76
- const joinRecipient = () => {
77
- query = query.leftJoin('message_recipients as r', function () {
78
- this.on('m.id', '=', 'r.message_id').andOn('r.recipient_user_id', '=', knex.raw('?', [scope.userId]))
79
- })
80
- }
81
-
82
- switch (input.folder) {
83
- case 'inbox':
84
- joinRecipient()
85
- query = query
86
- .whereNotNull('r.message_id')
87
- .whereNull('r.deleted_at')
88
- .whereNull('r.archived_at')
89
- .where('m.is_draft', false)
90
- break
91
- case 'archived':
92
- joinRecipient()
93
- query = query
94
- .whereNotNull('r.message_id')
95
- .whereNull('r.deleted_at')
96
- .whereNotNull('r.archived_at')
97
- break
98
- case 'sent':
99
- query = query
100
- .where('m.sender_user_id', scope.userId)
101
- .where('m.is_draft', false)
102
- joinRecipient()
103
- break
104
- case 'drafts':
105
- query = query
106
- .where('m.sender_user_id', scope.userId)
107
- .where('m.is_draft', true)
108
- joinRecipient()
109
- break
110
- case 'all':
111
- joinRecipient()
112
- query = query.where(function () {
113
- this.where('m.sender_user_id', scope.userId).orWhereNotNull('r.message_id')
66
+ const searchIds = input.search
67
+ ? await findMessageIdsBySearchTokens({
68
+ em,
69
+ query: input.search,
70
+ tenantId: scope.tenantId ?? null,
71
+ organizationId: scope.organizationId,
114
72
  })
115
- break
116
- default: {
117
- const unsupportedFolder: never = input.folder
118
- throw new Error(`Unsupported folder: ${String(unsupportedFolder)}`)
119
- }
120
- }
73
+ : undefined
121
74
 
122
- if (input.status) {
123
- query = query.where('r.status', input.status)
124
- }
125
-
126
- if (input.type) {
127
- query = query.where('m.type', input.type)
128
- }
75
+ const buildBaseQuery = () => {
76
+ let q: any = db
77
+ .selectFrom('messages as m')
78
+ .where('m.tenant_id', '=', scope.tenantId)
79
+ .where('m.deleted_at', 'is', null)
129
80
 
130
- if (input.visibility) {
131
- query = query.where('m.visibility', input.visibility)
132
- }
81
+ if (scope.organizationId) {
82
+ q = q.where('m.organization_id', '=', scope.organizationId)
83
+ } else {
84
+ q = q.where('m.organization_id', 'is', null)
85
+ }
133
86
 
134
- if (input.sourceEntityType) {
135
- query = query.where('m.source_entity_type', input.sourceEntityType)
136
- }
87
+ const joinRecipient = () => {
88
+ q = q.leftJoin('message_recipients as r', (jb: any) => jb
89
+ .onRef('m.id', '=', 'r.message_id')
90
+ .on('r.recipient_user_id', '=', scope.userId))
91
+ }
137
92
 
138
- if (input.sourceEntityId) {
139
- query = query.where('m.source_entity_id', input.sourceEntityId)
140
- }
93
+ switch (input.folder) {
94
+ case 'inbox':
95
+ joinRecipient()
96
+ q = q
97
+ .where('r.message_id', 'is not', null)
98
+ .where('r.deleted_at', 'is', null)
99
+ .where('r.archived_at', 'is', null)
100
+ .where('m.is_draft', '=', false)
101
+ break
102
+ case 'archived':
103
+ joinRecipient()
104
+ q = q
105
+ .where('r.message_id', 'is not', null)
106
+ .where('r.deleted_at', 'is', null)
107
+ .where('r.archived_at', 'is not', null)
108
+ break
109
+ case 'sent':
110
+ q = q
111
+ .where('m.sender_user_id', '=', scope.userId)
112
+ .where('m.is_draft', '=', false)
113
+ joinRecipient()
114
+ break
115
+ case 'drafts':
116
+ q = q
117
+ .where('m.sender_user_id', '=', scope.userId)
118
+ .where('m.is_draft', '=', true)
119
+ joinRecipient()
120
+ break
121
+ case 'all':
122
+ joinRecipient()
123
+ q = q.where((eb: any) => eb.or([
124
+ eb('m.sender_user_id', '=', scope.userId),
125
+ eb('r.message_id', 'is not', null),
126
+ ]))
127
+ break
128
+ default: {
129
+ const unsupportedFolder: never = input.folder
130
+ throw new Error(`Unsupported folder: ${String(unsupportedFolder)}`)
131
+ }
132
+ }
141
133
 
142
- if (input.externalEmail) {
143
- query = query.where('m.external_email_hash', hashForLookup(input.externalEmail))
144
- }
134
+ if (input.status) q = q.where('r.status', '=', input.status)
135
+ if (input.type) q = q.where('m.type', '=', input.type)
136
+ if (input.visibility) q = q.where('m.visibility', '=', input.visibility)
137
+ if (input.sourceEntityType) q = q.where('m.source_entity_type', '=', input.sourceEntityType)
138
+ if (input.sourceEntityId) q = q.where('m.source_entity_id', '=', input.sourceEntityId)
139
+ if (input.externalEmail) q = q.where('m.external_email_hash', '=', hashForLookup(input.externalEmail))
140
+ if (input.senderId) q = q.where('m.sender_user_id', '=', input.senderId)
141
+
142
+ if (input.search) {
143
+ if (!searchIds || searchIds.length === 0) {
144
+ q = q.where('m.id', '=', NO_MATCH_ID)
145
+ } else {
146
+ q = q.where('m.id', 'in', searchIds)
147
+ }
148
+ }
145
149
 
146
- if (input.senderId) {
147
- query = query.where('m.sender_user_id', input.senderId)
148
- }
150
+ if (input.since) q = q.where('m.sent_at', '>', new Date(input.since))
149
151
 
150
- if (input.search) {
151
- const matchedIds = await findMessageIdsBySearchTokens({
152
- em,
153
- query: input.search,
154
- tenantId: scope.tenantId ?? null,
155
- organizationId: scope.organizationId,
156
- })
157
- if (matchedIds === null || matchedIds.length === 0) {
158
- query = query.where('m.id', NO_MATCH_ID)
159
- } else {
160
- query = query.whereIn('m.id', matchedIds)
152
+ if (input.hasObjects !== undefined) {
153
+ const existsFn = (eb: any) => eb.exists(
154
+ eb.selectFrom('message_objects')
155
+ .select(sql<number>`1`.as('one'))
156
+ .whereRef('message_objects.message_id', '=', 'm.id')
157
+ )
158
+ const notExistsFn = (eb: any) => eb.not(eb.exists(
159
+ eb.selectFrom('message_objects')
160
+ .select(sql<number>`1`.as('one'))
161
+ .whereRef('message_objects.message_id', '=', 'm.id')
162
+ ))
163
+ q = input.hasObjects ? q.where(existsFn) : q.where(notExistsFn)
161
164
  }
162
- }
163
-
164
- if (input.since) {
165
- query = query.where('m.sent_at', '>', new Date(input.since))
166
- }
167
165
 
168
- if (input.hasObjects !== undefined) {
169
- const subquery = knex('message_objects').select(1).whereRaw('message_objects.message_id = m.id')
170
- query = input.hasObjects ? query.whereExists(subquery) : query.whereNotExists(subquery)
171
- }
166
+ if (input.hasAttachments !== undefined) {
167
+ const existsFn = (eb: any) => eb.exists(
168
+ eb.selectFrom('attachments')
169
+ .select(sql<number>`1`.as('one'))
170
+ .where('attachments.entity_id', '=', MESSAGE_ATTACHMENT_ENTITY_ID)
171
+ .whereRef('attachments.record_id', '=', 'm.id')
172
+ )
173
+ const notExistsFn = (eb: any) => eb.not(eb.exists(
174
+ eb.selectFrom('attachments')
175
+ .select(sql<number>`1`.as('one'))
176
+ .where('attachments.entity_id', '=', MESSAGE_ATTACHMENT_ENTITY_ID)
177
+ .whereRef('attachments.record_id', '=', 'm.id')
178
+ ))
179
+ q = input.hasAttachments ? q.where(existsFn) : q.where(notExistsFn)
180
+ }
172
181
 
173
- if (input.hasAttachments !== undefined) {
174
- const subquery = knex('attachments')
175
- .select(1)
176
- .where('attachments.entity_id', MESSAGE_ATTACHMENT_ENTITY_ID)
177
- .whereRaw('attachments.record_id = m.id')
178
- query = input.hasAttachments ? query.whereExists(subquery) : query.whereNotExists(subquery)
179
- }
182
+ if (input.hasActions !== undefined) {
183
+ q = input.hasActions
184
+ ? q.where('m.action_data', 'is not', null)
185
+ : q.where('m.action_data', 'is', null)
186
+ }
180
187
 
181
- if (input.hasActions !== undefined) {
182
- query = input.hasActions ? query.whereNotNull('m.action_data') : query.whereNull('m.action_data')
188
+ return q
183
189
  }
184
190
 
185
- const countResult = await query.clone().count('* as count').first()
191
+ const countResult = await buildBaseQuery()
192
+ .select(sql<number>`count(*)`.as('count'))
193
+ .executeTakeFirst() as { count: string | number } | undefined
186
194
  const total = Number(countResult?.count ?? 0)
187
195
 
188
196
  const offset = (input.page - 1) * input.pageSize
189
- const scopeRows = await query
190
- .select(
197
+ const scopeRows = await buildBaseQuery()
198
+ .select([
191
199
  'm.id',
192
200
  'm.sender_user_id',
193
201
  'm.is_draft',
194
202
  'r.status as recipient_status',
195
203
  'r.read_at',
196
- )
204
+ ])
197
205
  .orderBy('m.sent_at', 'desc')
198
206
  .offset(offset)
199
207
  .limit(input.pageSize)
208
+ .execute()
200
209
 
201
210
  const typedRows = scopeRows as MessageListScopeRow[]
202
211
  const messageIds = typedRows.map((row) => row.id)
@@ -227,12 +236,13 @@ export async function GET(req: Request) {
227
236
  }, {} as Record<string, MessageObject[]>)
228
237
 
229
238
  const attachmentCounts: AttachmentCountRow[] = messageIds.length > 0
230
- ? await getKnex(em)('attachments')
231
- .select('record_id')
232
- .count('* as count')
233
- .where('entity_id', MESSAGE_ATTACHMENT_ENTITY_ID)
234
- .whereIn('record_id', messageIds)
239
+ ? await (getDb(em) as any)
240
+ .selectFrom('attachments')
241
+ .select(['record_id', sql<string>`count(*)`.as('count')])
242
+ .where('entity_id', '=', MESSAGE_ATTACHMENT_ENTITY_ID)
243
+ .where('record_id', 'in', messageIds)
235
244
  .groupBy('record_id')
245
+ .execute()
236
246
  : []
237
247
 
238
248
  const attachmentCountByMessage = attachmentCounts.reduce((acc: Record<string, number>, row) => {
@@ -241,12 +251,13 @@ export async function GET(req: Request) {
241
251
  }, {})
242
252
 
243
253
  const recipientCounts: RecipientCountRow[] = messageIds.length > 0
244
- ? await getKnex(em)('message_recipients')
245
- .select('message_id')
246
- .count('* as count')
247
- .whereIn('message_id', messageIds)
248
- .whereNull('deleted_at')
254
+ ? await (getDb(em) as any)
255
+ .selectFrom('message_recipients')
256
+ .select(['message_id', sql<string>`count(*)`.as('count')])
257
+ .where('message_id', 'in', messageIds)
258
+ .where('deleted_at', 'is', null)
249
259
  .groupBy('message_id')
260
+ .execute()
250
261
  : []
251
262
 
252
263
  const recipientCountByMessage = recipientCounts.reduce((acc: Record<string, number>, row) => {
@@ -1,5 +1,5 @@
1
1
  import type { EntityManager } from '@mikro-orm/postgresql'
2
- import type { Knex } from 'knex'
2
+ import { type Kysely, sql } from 'kysely'
3
3
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'
4
4
  import { resolveMessageContext } from '../../lib/routeHelpers'
5
5
  import { unreadCountResponseSchema } from '../openapi'
@@ -8,31 +8,34 @@ export const metadata = {
8
8
  GET: { requireAuth: true, requireFeatures: ['messages.view'] },
9
9
  }
10
10
 
11
- function getKnex(em: EntityManager): Knex {
12
- return (em.getConnection() as unknown as { getKnex: () => Knex }).getKnex()
11
+ function getDb(em: EntityManager): Kysely<any> {
12
+ return em.getKysely<any>()
13
13
  }
14
14
 
15
15
  export async function GET(req: Request) {
16
16
  const { ctx, scope } = await resolveMessageContext(req)
17
17
  const em = ctx.container.resolve('em') as EntityManager
18
- const knex = getKnex(em)
19
-
20
- let query = knex('message_recipients as r')
21
- .join('messages as m', 'm.id', 'r.message_id')
22
- .where('r.recipient_user_id', scope.userId)
23
- .where('r.status', 'unread')
24
- .whereNull('r.deleted_at')
25
- .whereNull('r.archived_at')
26
- .where('m.tenant_id', scope.tenantId)
27
- .whereNull('m.deleted_at')
18
+ const db = getDb(em) as any
19
+
20
+ let query = db
21
+ .selectFrom('message_recipients as r')
22
+ .innerJoin('messages as m', 'm.id', 'r.message_id')
23
+ .where('r.recipient_user_id', '=', scope.userId)
24
+ .where('r.status', '=', 'unread')
25
+ .where('r.deleted_at', 'is', null)
26
+ .where('r.archived_at', 'is', null)
27
+ .where('m.tenant_id', '=', scope.tenantId)
28
+ .where('m.deleted_at', 'is', null)
28
29
 
29
30
  if (scope.organizationId) {
30
- query = query.where('m.organization_id', scope.organizationId)
31
+ query = query.where('m.organization_id', '=', scope.organizationId)
31
32
  } else {
32
- query = query.whereNull('m.organization_id')
33
+ query = query.where('m.organization_id', 'is', null)
33
34
  }
34
35
 
35
- const row = await query.count('* as count').first<{ count: string | number }>()
36
+ const row = await query
37
+ .select(sql<number>`count(*)`.as('count'))
38
+ .executeTakeFirst() as { count: string | number } | undefined
36
39
  const count = Number(row?.count ?? 0)
37
40
 
38
41
  return Response.json({ unreadCount: count })
@@ -102,7 +102,7 @@ const confirmMessageCommand: CommandHandler<unknown, ConfirmMessageResult> = {
102
102
  confirmation.confirmedByUserId = actorUserId
103
103
  confirmation.confirmedAt = input.confirmed ? new Date() : null
104
104
 
105
- await em.persistAndFlush(confirmation)
105
+ await em.persist(confirmation).flush()
106
106
 
107
107
  return {
108
108
  messageId: confirmation.messageId,