@open-mercato/core 0.5.1-develop.2691.d8a0934b37 → 0.5.1-develop.2694.732417c5ec

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
@@ -1,36 +1,57 @@
1
1
  import { resolveEntityTableName } from "@open-mercato/shared/lib/query/engine";
2
2
  import { resolveTenantEncryptionService } from "@open-mercato/shared/lib/encryption/customFieldValues";
3
3
  import { decryptIndexDocForSearch, encryptIndexDocForStorage } from "@open-mercato/shared/lib/encryption/indexDoc";
4
+ import { sql } from "kysely";
4
5
  import { replaceSearchTokensForRecord, deleteSearchTokensForRecord } from "./search-tokens.js";
5
6
  import { attachAggregateSearchField } from "./document.js";
6
7
  async function buildIndexDoc(em, params) {
7
- const knex = em.getConnection().getKnex();
8
+ const db = em.getKysely();
8
9
  const baseTable = resolveEntityTableName(em, params.entityType);
9
- const baseRow = await knex(baseTable).where("id", params.recordId).first();
10
+ const baseRow = await db.selectFrom(baseTable).selectAll().where("id", "=", params.recordId).executeTakeFirst();
10
11
  if (!baseRow) return null;
11
12
  const docSources = [];
12
13
  let parentEntityRow = null;
13
14
  if (params.entityType === "customers:customer_person_profile" || params.entityType === "customers:customer_company_profile") {
14
15
  const entityId = baseRow.entity_id ?? baseRow.entityId;
15
16
  if (entityId) {
16
- const entityRow = await knex("customer_entities").where("id", entityId).first();
17
+ const entityRow = await db.selectFrom("customer_entities").selectAll().where("id", "=", entityId).executeTakeFirst();
17
18
  if (entityRow) {
18
19
  docSources.push(entityRow);
19
20
  parentEntityRow = entityRow;
20
21
  }
21
22
  }
22
23
  }
24
+ void parentEntityRow;
23
25
  let doc = {};
24
26
  docSources.push(baseRow);
25
27
  for (const source of docSources) {
26
28
  for (const [k, v] of Object.entries(source)) doc[k] = v;
27
29
  }
28
- const cfRows = await knex("custom_field_values").select(["field_key", "value_text", "value_multiline", "value_int", "value_float", "value_bool"]).where({ entity_id: params.entityType, record_id: String(params.recordId) }).modify((qb) => {
29
- if (params.organizationId != null) qb.andWhere((b) => b.where({ organization_id: params.organizationId }).orWhereNull("organization_id"));
30
- else qb.whereNull("organization_id");
31
- if (params.tenantId != null) qb.andWhere((b) => b.where({ tenant_id: params.tenantId }).orWhereNull("tenant_id"));
32
- else qb.whereNull("tenant_id");
33
- });
30
+ let cfQuery = db.selectFrom("custom_field_values").select([
31
+ "field_key",
32
+ "value_text",
33
+ "value_multiline",
34
+ "value_int",
35
+ "value_float",
36
+ "value_bool"
37
+ ]).where("entity_id", "=", params.entityType).where("record_id", "=", String(params.recordId));
38
+ if (params.organizationId != null) {
39
+ cfQuery = cfQuery.where((eb) => eb.or([
40
+ eb("organization_id", "=", params.organizationId),
41
+ eb("organization_id", "is", null)
42
+ ]));
43
+ } else {
44
+ cfQuery = cfQuery.where("organization_id", "is", null);
45
+ }
46
+ if (params.tenantId != null) {
47
+ cfQuery = cfQuery.where((eb) => eb.or([
48
+ eb("tenant_id", "=", params.tenantId),
49
+ eb("tenant_id", "is", null)
50
+ ]));
51
+ } else {
52
+ cfQuery = cfQuery.where("tenant_id", "is", null);
53
+ }
54
+ const cfRows = await cfQuery.execute();
34
55
  const cfMap = {};
35
56
  for (const r of cfRows) {
36
57
  const key = String(r.field_key);
@@ -43,7 +64,7 @@ async function buildIndexDoc(em, params) {
43
64
  doc[key] = arr.length <= 1 ? arr[0] : arr;
44
65
  }
45
66
  try {
46
- const translationRow = await knex("entity_translations").where({ entity_type: params.entityType, entity_id: String(params.recordId) }).andWhereRaw("tenant_id is not distinct from ?", [params.tenantId ?? null]).andWhereRaw("organization_id is not distinct from ?", [params.organizationId ?? null]).select(["translations"]).first();
67
+ const translationRow = await db.selectFrom("entity_translations").select(["translations"]).where("entity_type", "=", params.entityType).where("entity_id", "=", String(params.recordId)).where(sql`tenant_id is not distinct from ${params.tenantId ?? null}`).where(sql`organization_id is not distinct from ${params.organizationId ?? null}`).executeTakeFirst();
47
68
  if (translationRow?.translations && typeof translationRow.translations === "object") {
48
69
  for (const [locale, fields] of Object.entries(translationRow.translations)) {
49
70
  if (!fields || typeof fields !== "object") continue;
@@ -69,20 +90,25 @@ async function buildIndexDoc(em, params) {
69
90
  }
70
91
  return doc;
71
92
  }
93
+ function scopeEntityIndexes(q, args) {
94
+ let chain = q.where("entity_type", "=", args.entityType);
95
+ chain = chain.where("entity_id", "=", String(args.recordId));
96
+ chain = args.organizationId == null ? chain.where("organization_id", "is", null) : chain.where("organization_id", "=", args.organizationId);
97
+ chain = chain.where(sql`tenant_id is not distinct from ${args.tenantId ?? null}`);
98
+ return chain;
99
+ }
72
100
  async function upsertIndexRow(em, args) {
73
- const knex = em.getConnection().getKnex();
74
- const baseScopeQuery = knex("entity_indexes").select(["id", "deleted_at"]).where({
75
- entity_type: args.entityType,
76
- entity_id: String(args.recordId),
77
- organization_id: args.organizationId ?? null
78
- }).andWhereRaw("tenant_id is not distinct from ?", [args.tenantId ?? null]).first();
79
- const existing = await baseScopeQuery;
101
+ const db = em.getKysely();
102
+ const existing = await scopeEntityIndexes(
103
+ db.selectFrom("entity_indexes").select(["id", "deleted_at"]),
104
+ args
105
+ ).executeTakeFirst();
80
106
  const existed = !!existing;
81
107
  const wasDeleted = !!existing && existing.deleted_at != null;
82
108
  const doc = await buildIndexDoc(em, args);
83
109
  if (!doc) {
84
110
  try {
85
- await deleteSearchTokensForRecord(knex, {
111
+ await deleteSearchTokensForRecord(db, {
86
112
  entityType: args.entityType,
87
113
  recordId: args.recordId,
88
114
  organizationId: args.organizationId ?? null,
@@ -91,11 +117,10 @@ async function upsertIndexRow(em, args) {
91
117
  } catch {
92
118
  }
93
119
  if (existed) {
94
- await knex("entity_indexes").where({
95
- entity_type: args.entityType,
96
- entity_id: String(args.recordId),
97
- organization_id: args.organizationId ?? null
98
- }).andWhereRaw("tenant_id is not distinct from ?", [args.tenantId ?? null]).del();
120
+ await scopeEntityIndexes(
121
+ db.deleteFrom("entity_indexes"),
122
+ args
123
+ ).execute();
99
124
  }
100
125
  return { doc: null, existed, wasDeleted, created: false, revived: false };
101
126
  }
@@ -104,23 +129,27 @@ async function upsertIndexRow(em, args) {
104
129
  entity_id: String(args.recordId),
105
130
  organization_id: args.organizationId ?? null,
106
131
  tenant_id: args.tenantId ?? null,
107
- doc,
132
+ doc: sql`${JSON.stringify(doc)}::jsonb`,
108
133
  index_version: 1,
109
- updated_at: knex.fn.now(),
134
+ updated_at: sql`now()`,
110
135
  deleted_at: null
111
136
  };
112
137
  try {
113
- const insertQ = knex("entity_indexes").insert({ ...payload, created_at: knex.fn.now() });
114
- await insertQ.onConflict(["entity_type", "entity_id", "organization_id_coalesced"]).merge(payload);
138
+ await db.insertInto("entity_indexes").values({ ...payload, created_at: sql`now()` }).onConflict((oc) => oc.columns(["entity_type", "entity_id", "organization_id_coalesced"]).doUpdateSet({
139
+ tenant_id: args.tenantId ?? null,
140
+ doc: sql`${JSON.stringify(doc)}::jsonb`,
141
+ index_version: 1,
142
+ updated_at: sql`now()`,
143
+ deleted_at: null
144
+ })).execute();
115
145
  } catch {
116
- const updated = await knex("entity_indexes").where({
117
- entity_type: args.entityType,
118
- entity_id: String(args.recordId),
119
- organization_id: args.organizationId ?? null
120
- }).andWhereRaw("tenant_id is not distinct from ?", [args.tenantId ?? null]).update(payload);
121
- if (!updated) {
146
+ const updated = await scopeEntityIndexes(
147
+ db.updateTable("entity_indexes").set(payload),
148
+ args
149
+ ).executeTakeFirst();
150
+ if (!updated || Number(updated.numUpdatedRows ?? 0) === 0) {
122
151
  try {
123
- await knex("entity_indexes").insert({ ...payload, created_at: knex.fn.now() });
152
+ await db.insertInto("entity_indexes").values({ ...payload, created_at: sql`now()` }).execute();
124
153
  } catch {
125
154
  }
126
155
  }
@@ -137,7 +166,7 @@ async function upsertIndexRow(em, args) {
137
166
  encryption,
138
167
  dekKeyCache
139
168
  );
140
- await replaceSearchTokensForRecord(knex, {
169
+ await replaceSearchTokensForRecord(db, {
141
170
  entityType: args.entityType,
142
171
  recordId: args.recordId,
143
172
  organizationId: args.organizationId ?? null,
@@ -149,16 +178,15 @@ async function upsertIndexRow(em, args) {
149
178
  return { doc, existed, wasDeleted, created, revived };
150
179
  }
151
180
  async function markDeleted(em, args) {
152
- const knex = em.getConnection().getKnex();
153
- const existing = await knex("entity_indexes").select(["deleted_at"]).where({
154
- entity_type: args.entityType,
155
- entity_id: String(args.recordId),
156
- organization_id: args.organizationId ?? null
157
- }).andWhereRaw("tenant_id is not distinct from ?", [args.tenantId ?? null]).first();
181
+ const db = em.getKysely();
182
+ const existing = await scopeEntityIndexes(
183
+ db.selectFrom("entity_indexes").select(["deleted_at"]),
184
+ args
185
+ ).executeTakeFirst();
158
186
  const wasActive = !!existing && existing.deleted_at == null;
159
187
  if (existing) {
160
188
  try {
161
- await deleteSearchTokensForRecord(knex, {
189
+ await deleteSearchTokensForRecord(db, {
162
190
  entityType: args.entityType,
163
191
  recordId: args.recordId,
164
192
  organizationId: args.organizationId ?? null,
@@ -166,11 +194,10 @@ async function markDeleted(em, args) {
166
194
  });
167
195
  } catch {
168
196
  }
169
- await knex("entity_indexes").where({
170
- entity_type: args.entityType,
171
- entity_id: String(args.recordId),
172
- organization_id: args.organizationId ?? null
173
- }).andWhereRaw("tenant_id is not distinct from ?", [args.tenantId ?? null]).del();
197
+ await scopeEntityIndexes(
198
+ db.deleteFrom("entity_indexes"),
199
+ args
200
+ ).execute();
174
201
  }
175
202
  return { wasActive };
176
203
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/query_index/lib/indexer.ts"],
4
- "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { resolveEntityTableName } from '@open-mercato/shared/lib/query/engine'\nimport { resolveTenantEncryptionService } from '@open-mercato/shared/lib/encryption/customFieldValues'\nimport { decryptIndexDocForSearch, encryptIndexDocForStorage } from '@open-mercato/shared/lib/encryption/indexDoc'\nimport type { Knex } from 'knex'\nimport { replaceSearchTokensForRecord, deleteSearchTokensForRecord } from './search-tokens'\nimport { attachAggregateSearchField } from './document'\n\ntype BuildDocParams = {\n entityType: string // '<module>:<entity>'\n recordId: string\n organizationId?: string | null\n tenantId?: string | null\n}\n\nexport async function buildIndexDoc(em: EntityManager, params: BuildDocParams): Promise<Record<string, any> | null> {\n const knex = (em as any).getConnection().getKnex() as Knex\n const baseTable = resolveEntityTableName(em, params.entityType)\n\n // Fetch base row\n const baseRow = await knex(baseTable)\n .where('id', params.recordId)\n .first()\n if (!baseRow) return null\n const docSources: Array<Record<string, any>> = []\n\n // Attach the core customer entity when indexing customer profiles so search tokens see the combined row\n let parentEntityRow: Record<string, any> | null = null\n if (params.entityType === 'customers:customer_person_profile' || params.entityType === 'customers:customer_company_profile') {\n const entityId = (baseRow as any).entity_id ?? (baseRow as any).entityId\n if (entityId) {\n const entityRow = await knex('customer_entities')\n .where('id', entityId)\n .first()\n if (entityRow) {\n docSources.push(entityRow)\n parentEntityRow = entityRow\n }\n }\n }\n\n // Build base document (snake_case keys as in DB)\n let doc: Record<string, any> = {}\n docSources.push(baseRow)\n for (const source of docSources) {\n for (const [k, v] of Object.entries(source)) doc[k] = v\n }\n\n // Attach custom fields under flat keys 'cf:<key>'\n const cfRows = await knex('custom_field_values')\n .select(['field_key', 'value_text', 'value_multiline', 'value_int', 'value_float', 'value_bool'])\n .where({ entity_id: params.entityType, record_id: String(params.recordId) })\n .modify((qb: any) => {\n if (params.organizationId != null) qb.andWhere((b: any) => b.where({ organization_id: params.organizationId }).orWhereNull('organization_id'))\n else qb.whereNull('organization_id')\n if (params.tenantId != null) qb.andWhere((b: any) => b.where({ tenant_id: params.tenantId }).orWhereNull('tenant_id'))\n else qb.whereNull('tenant_id')\n })\n\n const cfMap: Record<string, any[]> = {}\n for (const r of cfRows) {\n const key = String(r.field_key)\n const cfKey = `cf:${key}`\n const val = r.value_bool ?? r.value_int ?? r.value_float ?? r.value_text ?? r.value_multiline ?? null\n if (!cfMap[cfKey]) cfMap[cfKey] = []\n cfMap[cfKey].push(val)\n }\n for (const [key, arr] of Object.entries(cfMap)) {\n // Store singletons as simple value; multis as array\n doc[key] = arr.length <= 1 ? arr[0] : arr\n }\n\n // Attach translations under flat keys 'l10n:{locale}:{field}'\n try {\n const translationRow = await knex('entity_translations')\n .where({ entity_type: params.entityType, entity_id: String(params.recordId) })\n .andWhereRaw('tenant_id is not distinct from ?', [params.tenantId ?? null])\n .andWhereRaw('organization_id is not distinct from ?', [params.organizationId ?? null])\n .select(['translations'])\n .first()\n\n if (translationRow?.translations && typeof translationRow.translations === 'object') {\n for (const [locale, fields] of Object.entries(translationRow.translations)) {\n if (!fields || typeof fields !== 'object') continue\n for (const [field, value] of Object.entries(fields as Record<string, unknown>)) {\n if (typeof value === 'string' && value.length > 0) {\n doc[`l10n:${locale}:${field}`] = value\n }\n }\n }\n }\n } catch {}\n\n try {\n doc = attachAggregateSearchField(doc)\n const encryption = resolveTenantEncryptionService(em as any)\n doc = await encryptIndexDocForStorage(\n params.entityType,\n doc,\n { tenantId: params.tenantId ?? null, organizationId: params.organizationId ?? null },\n encryption,\n )\n } catch {}\n\n return doc\n}\n\nexport type UpsertIndexResult = {\n doc: Record<string, any> | null\n existed: boolean\n wasDeleted: boolean\n created: boolean\n revived: boolean\n}\n\nexport async function upsertIndexRow(\n em: EntityManager,\n args: { entityType: string; recordId: string; organizationId?: string | null; tenantId?: string | null }\n): Promise<UpsertIndexResult> {\n const knex = (em as any).getConnection().getKnex() as Knex\n const baseScopeQuery = knex('entity_indexes')\n .select(['id', 'deleted_at'])\n .where({\n entity_type: args.entityType,\n entity_id: String(args.recordId),\n organization_id: args.organizationId ?? null,\n })\n .andWhereRaw('tenant_id is not distinct from ?', [args.tenantId ?? null])\n .first<{ id: string; deleted_at: Date | null } | undefined>()\n\n const existing = await baseScopeQuery\n const existed = !!existing\n const wasDeleted = !!existing && existing.deleted_at != null\n\n const doc = await buildIndexDoc(em, args)\n if (!doc) {\n try {\n await deleteSearchTokensForRecord(knex, {\n entityType: args.entityType,\n recordId: args.recordId,\n organizationId: args.organizationId ?? null,\n tenantId: args.tenantId ?? null,\n })\n } catch {}\n if (existed) {\n await knex('entity_indexes')\n .where({\n entity_type: args.entityType,\n entity_id: String(args.recordId),\n organization_id: args.organizationId ?? null,\n })\n .andWhereRaw('tenant_id is not distinct from ?', [args.tenantId ?? null])\n .del()\n }\n return { doc: null, existed, wasDeleted, created: false, revived: false }\n }\n\n const payload = {\n entity_type: args.entityType,\n entity_id: String(args.recordId),\n organization_id: args.organizationId ?? null,\n tenant_id: args.tenantId ?? null,\n doc,\n index_version: 1,\n updated_at: knex.fn.now(),\n deleted_at: null,\n }\n // Prefer modern upsert keyed by coalesced org id when available; fallback to update-then-insert\n try {\n const insertQ = knex('entity_indexes').insert({ ...payload, created_at: knex.fn.now() })\n await insertQ\n .onConflict(['entity_type', 'entity_id', 'organization_id_coalesced'])\n .merge(payload)\n } catch {\n // Fallback for schemas without organization_id_coalesced column/index\n const updated = await knex('entity_indexes')\n .where({\n entity_type: args.entityType,\n entity_id: String(args.recordId),\n organization_id: args.organizationId ?? null,\n })\n .andWhereRaw('tenant_id is not distinct from ?', [args.tenantId ?? null])\n .update(payload)\n if (!updated) {\n try { await knex('entity_indexes').insert({ ...payload, created_at: knex.fn.now() }) } catch {}\n }\n }\n\n const created = !existed\n const revived = existed && wasDeleted\n try {\n const encryption = resolveTenantEncryptionService(em as any)\n const dekKeyCache = new Map<string | null, string | null>()\n const tokenDoc = await decryptIndexDocForSearch(\n args.entityType,\n doc,\n { tenantId: args.tenantId ?? null, organizationId: args.organizationId ?? null },\n encryption,\n dekKeyCache,\n )\n await replaceSearchTokensForRecord(knex, {\n entityType: args.entityType,\n recordId: args.recordId,\n organizationId: args.organizationId ?? null,\n tenantId: args.tenantId ?? null,\n doc: tokenDoc,\n })\n } catch {}\n return { doc, existed, wasDeleted, created, revived }\n}\n\nexport async function markDeleted(\n em: EntityManager,\n args: { entityType: string; recordId: string; organizationId?: string | null; tenantId?: string | null }\n): Promise<{ wasActive: boolean }> {\n const knex = (em as any).getConnection().getKnex() as Knex\n const existing = await knex('entity_indexes')\n .select(['deleted_at'])\n .where({\n entity_type: args.entityType,\n entity_id: String(args.recordId),\n organization_id: args.organizationId ?? null,\n })\n .andWhereRaw('tenant_id is not distinct from ?', [args.tenantId ?? null])\n .first<{ deleted_at: Date | null } | undefined>()\n\n const wasActive = !!existing && existing.deleted_at == null\n\n if (existing) {\n try {\n await deleteSearchTokensForRecord(knex, {\n entityType: args.entityType,\n recordId: args.recordId,\n organizationId: args.organizationId ?? null,\n tenantId: args.tenantId ?? null,\n })\n } catch {}\n await knex('entity_indexes')\n .where({\n entity_type: args.entityType,\n entity_id: String(args.recordId),\n organization_id: args.organizationId ?? null,\n })\n .andWhereRaw('tenant_id is not distinct from ?', [args.tenantId ?? null])\n .del()\n }\n\n return { wasActive }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { resolveEntityTableName } from '@open-mercato/shared/lib/query/engine'\nimport { resolveTenantEncryptionService } from '@open-mercato/shared/lib/encryption/customFieldValues'\nimport { decryptIndexDocForSearch, encryptIndexDocForStorage } from '@open-mercato/shared/lib/encryption/indexDoc'\nimport { sql } from 'kysely'\nimport { replaceSearchTokensForRecord, deleteSearchTokensForRecord } from './search-tokens'\nimport { attachAggregateSearchField } from './document'\n\ntype BuildDocParams = {\n entityType: string // '<module>:<entity>'\n recordId: string\n organizationId?: string | null\n tenantId?: string | null\n}\n\nexport async function buildIndexDoc(em: EntityManager, params: BuildDocParams): Promise<Record<string, any> | null> {\n const db = (em as any).getKysely()\n const baseTable = resolveEntityTableName(em, params.entityType)\n\n // Fetch base row\n const baseRow = await db\n .selectFrom(baseTable as any)\n .selectAll()\n .where('id' as any, '=', params.recordId)\n .executeTakeFirst() as Record<string, any> | undefined\n if (!baseRow) return null\n const docSources: Array<Record<string, any>> = []\n\n // Attach the core customer entity when indexing customer profiles so search tokens see the combined row\n let parentEntityRow: Record<string, any> | null = null\n if (params.entityType === 'customers:customer_person_profile' || params.entityType === 'customers:customer_company_profile') {\n const entityId = (baseRow as any).entity_id ?? (baseRow as any).entityId\n if (entityId) {\n const entityRow = await db\n .selectFrom('customer_entities' as any)\n .selectAll()\n .where('id' as any, '=', entityId)\n .executeTakeFirst() as Record<string, any> | undefined\n if (entityRow) {\n docSources.push(entityRow)\n parentEntityRow = entityRow\n }\n }\n }\n void parentEntityRow\n\n // Build base document (snake_case keys as in DB)\n let doc: Record<string, any> = {}\n docSources.push(baseRow)\n for (const source of docSources) {\n for (const [k, v] of Object.entries(source)) doc[k] = v\n }\n\n // Attach custom fields under flat keys 'cf:<key>'\n let cfQuery = db\n .selectFrom('custom_field_values' as any)\n .select([\n 'field_key' as any,\n 'value_text' as any,\n 'value_multiline' as any,\n 'value_int' as any,\n 'value_float' as any,\n 'value_bool' as any,\n ])\n .where('entity_id' as any, '=', params.entityType)\n .where('record_id' as any, '=', String(params.recordId))\n\n if (params.organizationId != null) {\n cfQuery = cfQuery.where((eb: any) => eb.or([\n eb('organization_id' as any, '=', params.organizationId),\n eb('organization_id' as any, 'is', null),\n ]))\n } else {\n cfQuery = cfQuery.where('organization_id' as any, 'is', null)\n }\n\n if (params.tenantId != null) {\n cfQuery = cfQuery.where((eb: any) => eb.or([\n eb('tenant_id' as any, '=', params.tenantId),\n eb('tenant_id' as any, 'is', null),\n ]))\n } else {\n cfQuery = cfQuery.where('tenant_id' as any, 'is', null)\n }\n\n const cfRows = await cfQuery.execute() as Array<Record<string, any>>\n\n const cfMap: Record<string, any[]> = {}\n for (const r of cfRows) {\n const key = String(r.field_key)\n const cfKey = `cf:${key}`\n const val = r.value_bool ?? r.value_int ?? r.value_float ?? r.value_text ?? r.value_multiline ?? null\n if (!cfMap[cfKey]) cfMap[cfKey] = []\n cfMap[cfKey].push(val)\n }\n for (const [key, arr] of Object.entries(cfMap)) {\n // Store singletons as simple value; multis as array\n doc[key] = arr.length <= 1 ? arr[0] : arr\n }\n\n // Attach translations under flat keys 'l10n:{locale}:{field}'\n try {\n const translationRow = await db\n .selectFrom('entity_translations' as any)\n .select(['translations' as any])\n .where('entity_type' as any, '=', params.entityType)\n .where('entity_id' as any, '=', String(params.recordId))\n .where(sql`tenant_id is not distinct from ${params.tenantId ?? null}`)\n .where(sql`organization_id is not distinct from ${params.organizationId ?? null}`)\n .executeTakeFirst() as { translations: Record<string, Record<string, unknown>> | null } | undefined\n\n if (translationRow?.translations && typeof translationRow.translations === 'object') {\n for (const [locale, fields] of Object.entries(translationRow.translations)) {\n if (!fields || typeof fields !== 'object') continue\n for (const [field, value] of Object.entries(fields as Record<string, unknown>)) {\n if (typeof value === 'string' && value.length > 0) {\n doc[`l10n:${locale}:${field}`] = value\n }\n }\n }\n }\n } catch {}\n\n try {\n doc = attachAggregateSearchField(doc)\n const encryption = resolveTenantEncryptionService(em as any)\n doc = await encryptIndexDocForStorage(\n params.entityType,\n doc,\n { tenantId: params.tenantId ?? null, organizationId: params.organizationId ?? null },\n encryption,\n )\n } catch {}\n\n return doc\n}\n\nexport type UpsertIndexResult = {\n doc: Record<string, any> | null\n existed: boolean\n wasDeleted: boolean\n created: boolean\n revived: boolean\n}\n\nfunction scopeEntityIndexes<QB extends { where: (...args: any[]) => QB }>(\n q: QB,\n args: { entityType: string; recordId: string; organizationId?: string | null; tenantId?: string | null },\n): QB {\n let chain = q.where('entity_type' as any, '=', args.entityType)\n chain = chain.where('entity_id' as any, '=', String(args.recordId))\n chain = args.organizationId == null\n ? chain.where('organization_id' as any, 'is', null as any)\n : chain.where('organization_id' as any, '=', args.organizationId)\n chain = chain.where(sql`tenant_id is not distinct from ${args.tenantId ?? null}`)\n return chain\n}\n\nexport async function upsertIndexRow(\n em: EntityManager,\n args: { entityType: string; recordId: string; organizationId?: string | null; tenantId?: string | null }\n): Promise<UpsertIndexResult> {\n const db = (em as any).getKysely()\n\n const existing = await scopeEntityIndexes(\n db.selectFrom('entity_indexes' as any).select(['id' as any, 'deleted_at' as any]),\n args,\n ).executeTakeFirst() as { id: string; deleted_at: Date | null } | undefined\n\n const existed = !!existing\n const wasDeleted = !!existing && existing.deleted_at != null\n\n const doc = await buildIndexDoc(em, args)\n if (!doc) {\n try {\n await deleteSearchTokensForRecord(db, {\n entityType: args.entityType,\n recordId: args.recordId,\n organizationId: args.organizationId ?? null,\n tenantId: args.tenantId ?? null,\n })\n } catch {}\n if (existed) {\n await scopeEntityIndexes(\n db.deleteFrom('entity_indexes' as any) as any,\n args,\n ).execute()\n }\n return { doc: null, existed, wasDeleted, created: false, revived: false }\n }\n\n const payload = {\n entity_type: args.entityType,\n entity_id: String(args.recordId),\n organization_id: args.organizationId ?? null,\n tenant_id: args.tenantId ?? null,\n doc: sql`${JSON.stringify(doc)}::jsonb`,\n index_version: 1,\n updated_at: sql`now()`,\n deleted_at: null,\n }\n\n // Prefer modern upsert keyed by coalesced org id when available; fallback to update-then-insert\n try {\n await db\n .insertInto('entity_indexes' as any)\n .values({ ...payload, created_at: sql`now()` } as any)\n .onConflict((oc: any) => oc\n .columns(['entity_type', 'entity_id', 'organization_id_coalesced'])\n .doUpdateSet({\n tenant_id: args.tenantId ?? null,\n doc: sql`${JSON.stringify(doc)}::jsonb`,\n index_version: 1,\n updated_at: sql`now()`,\n deleted_at: null,\n } as any))\n .execute()\n } catch {\n // Fallback for schemas without organization_id_coalesced column/index\n const updated = await scopeEntityIndexes(\n db.updateTable('entity_indexes' as any).set(payload as any) as any,\n args,\n ).executeTakeFirst() as { numUpdatedRows?: bigint | number } | undefined\n if (!updated || Number(updated.numUpdatedRows ?? 0) === 0) {\n try {\n await db\n .insertInto('entity_indexes' as any)\n .values({ ...payload, created_at: sql`now()` } as any)\n .execute()\n } catch {}\n }\n }\n\n const created = !existed\n const revived = existed && wasDeleted\n try {\n const encryption = resolveTenantEncryptionService(em as any)\n const dekKeyCache = new Map<string | null, string | null>()\n const tokenDoc = await decryptIndexDocForSearch(\n args.entityType,\n doc,\n { tenantId: args.tenantId ?? null, organizationId: args.organizationId ?? null },\n encryption,\n dekKeyCache,\n )\n await replaceSearchTokensForRecord(db, {\n entityType: args.entityType,\n recordId: args.recordId,\n organizationId: args.organizationId ?? null,\n tenantId: args.tenantId ?? null,\n doc: tokenDoc,\n })\n } catch {}\n return { doc, existed, wasDeleted, created, revived }\n}\n\nexport async function markDeleted(\n em: EntityManager,\n args: { entityType: string; recordId: string; organizationId?: string | null; tenantId?: string | null }\n): Promise<{ wasActive: boolean }> {\n const db = (em as any).getKysely()\n const existing = await scopeEntityIndexes(\n db.selectFrom('entity_indexes' as any).select(['deleted_at' as any]),\n args,\n ).executeTakeFirst() as { deleted_at: Date | null } | undefined\n\n const wasActive = !!existing && existing.deleted_at == null\n\n if (existing) {\n try {\n await deleteSearchTokensForRecord(db, {\n entityType: args.entityType,\n recordId: args.recordId,\n organizationId: args.organizationId ?? null,\n tenantId: args.tenantId ?? null,\n })\n } catch {}\n await scopeEntityIndexes(\n db.deleteFrom('entity_indexes' as any) as any,\n args,\n ).execute()\n }\n\n return { wasActive }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,46 +1,59 @@
1
- function scopeQuery(knex, scope) {
2
- let query = knex("entity_index_jobs").where("entity_type", scope.entityType);
3
- query = query.andWhereRaw("organization_id is not distinct from ?", [scope.organizationId ?? null]);
4
- query = query.andWhereRaw("tenant_id is not distinct from ?", [scope.tenantId ?? null]);
5
- query = query.andWhereRaw("partition_index is not distinct from ?", [scope.partitionIndex ?? null]);
6
- query = query.andWhereRaw("partition_count is not distinct from ?", [scope.partitionCount ?? null]);
7
- return query;
1
+ import { sql } from "kysely";
2
+ function applyScopeWhere(builder, scope) {
3
+ let q = builder.where("entity_type", "=", scope.entityType);
4
+ q = q.where(sql`organization_id is not distinct from ${scope.organizationId ?? null}`);
5
+ q = q.where(sql`tenant_id is not distinct from ${scope.tenantId ?? null}`);
6
+ q = q.where(sql`partition_index is not distinct from ${scope.partitionIndex ?? null}`);
7
+ q = q.where(sql`partition_count is not distinct from ${scope.partitionCount ?? null}`);
8
+ return q;
8
9
  }
9
- async function prepareJob(knex, scope, status, options = {}) {
10
+ async function prepareJob(db, scope, status, options = {}) {
10
11
  const base = {
11
12
  organization_id: scope.organizationId ?? null,
12
13
  tenant_id: scope.tenantId ?? null,
13
14
  partition_index: scope.partitionIndex ?? null,
14
15
  partition_count: scope.partitionCount ?? null,
15
16
  status,
16
- started_at: knex.fn.now(),
17
+ started_at: sql`now()`,
17
18
  finished_at: null,
18
- heartbeat_at: knex.fn.now(),
19
+ heartbeat_at: sql`now()`,
19
20
  processed_count: 0,
20
21
  total_count: options.totalCount ?? null
21
22
  };
22
- const existing = await scopeQuery(knex, scope).first();
23
+ const existing = await applyScopeWhere(
24
+ db.selectFrom("entity_index_jobs").select(["id"]),
25
+ scope
26
+ ).executeTakeFirst();
23
27
  if (existing) {
24
- await scopeQuery(knex, scope).update(base);
28
+ await applyScopeWhere(
29
+ db.updateTable("entity_index_jobs").set(base),
30
+ scope
31
+ ).execute();
25
32
  return existing.id;
26
33
  }
27
- const inserted = await knex("entity_index_jobs").insert({
34
+ const inserted = await db.insertInto("entity_index_jobs").values({
28
35
  entity_type: scope.entityType,
29
36
  ...base
30
- }).returning("id");
37
+ }).returning(["id"]).execute();
31
38
  return inserted?.[0]?.id ?? null;
32
39
  }
33
- async function updateJobProgress(knex, scope, processedDelta) {
34
- await scopeQuery(knex, scope).update({
35
- processed_count: knex.raw("coalesce(processed_count, 0) + ?", [Math.max(0, processedDelta)]),
36
- heartbeat_at: knex.fn.now()
37
- });
40
+ async function updateJobProgress(db, scope, processedDelta) {
41
+ await applyScopeWhere(
42
+ db.updateTable("entity_index_jobs").set({
43
+ processed_count: sql`coalesce(processed_count, 0) + ${Math.max(0, processedDelta)}`,
44
+ heartbeat_at: sql`now()`
45
+ }),
46
+ scope
47
+ ).execute();
38
48
  }
39
- async function finalizeJob(knex, scope) {
40
- await scopeQuery(knex, scope).update({
41
- finished_at: knex.fn.now(),
42
- heartbeat_at: knex.fn.now()
43
- });
49
+ async function finalizeJob(db, scope) {
50
+ await applyScopeWhere(
51
+ db.updateTable("entity_index_jobs").set({
52
+ finished_at: sql`now()`,
53
+ heartbeat_at: sql`now()`
54
+ }),
55
+ scope
56
+ ).execute();
44
57
  }
45
58
  export {
46
59
  finalizeJob,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/query_index/lib/jobs.ts"],
4
- "sourcesContent": ["import type { Knex } from 'knex'\n\nexport type JobScope = {\n entityType: string\n organizationId?: string | null\n tenantId?: string | null\n partitionIndex?: number | null\n partitionCount?: number | null\n}\n\nfunction scopeQuery(knex: Knex, scope: JobScope) {\n let query = knex('entity_index_jobs').where('entity_type', scope.entityType)\n query = query.andWhereRaw('organization_id is not distinct from ?', [scope.organizationId ?? null])\n query = query.andWhereRaw('tenant_id is not distinct from ?', [scope.tenantId ?? null])\n query = query.andWhereRaw('partition_index is not distinct from ?', [scope.partitionIndex ?? null])\n query = query.andWhereRaw('partition_count is not distinct from ?', [scope.partitionCount ?? null])\n return query\n}\n\nexport async function prepareJob(\n knex: Knex,\n scope: JobScope,\n status: 'reindexing' | 'purging',\n options: { totalCount?: number | null } = {},\n) {\n const base = {\n organization_id: scope.organizationId ?? null,\n tenant_id: scope.tenantId ?? null,\n partition_index: scope.partitionIndex ?? null,\n partition_count: scope.partitionCount ?? null,\n status,\n started_at: knex.fn.now(),\n finished_at: null,\n heartbeat_at: knex.fn.now(),\n processed_count: 0,\n total_count: options.totalCount ?? null,\n }\n const existing = await scopeQuery(knex, scope).first<{ id: string }>()\n if (existing) {\n await scopeQuery(knex, scope).update(base)\n return existing.id\n }\n const inserted = await knex('entity_index_jobs')\n .insert({\n entity_type: scope.entityType,\n ...base,\n })\n .returning<{ id: string }[]>('id')\n return inserted?.[0]?.id ?? null\n}\n\nexport async function updateJobProgress(\n knex: Knex,\n scope: JobScope,\n processedDelta: number,\n) {\n await scopeQuery(knex, scope).update({\n processed_count: knex.raw('coalesce(processed_count, 0) + ?', [Math.max(0, processedDelta)]),\n heartbeat_at: knex.fn.now(),\n })\n}\n\nexport async function finalizeJob(\n knex: Knex,\n scope: JobScope,\n) {\n await scopeQuery(knex, scope).update({\n finished_at: knex.fn.now(),\n heartbeat_at: knex.fn.now(),\n })\n}\n\n"],
5
- "mappings": "AAUA,SAAS,WAAW,MAAY,OAAiB;AAC/C,MAAI,QAAQ,KAAK,mBAAmB,EAAE,MAAM,eAAe,MAAM,UAAU;AAC3E,UAAQ,MAAM,YAAY,0CAA0C,CAAC,MAAM,kBAAkB,IAAI,CAAC;AAClG,UAAQ,MAAM,YAAY,oCAAoC,CAAC,MAAM,YAAY,IAAI,CAAC;AACtF,UAAQ,MAAM,YAAY,0CAA0C,CAAC,MAAM,kBAAkB,IAAI,CAAC;AAClG,UAAQ,MAAM,YAAY,0CAA0C,CAAC,MAAM,kBAAkB,IAAI,CAAC;AAClG,SAAO;AACT;AAEA,eAAsB,WACpB,MACA,OACA,QACA,UAA0C,CAAC,GAC3C;AACA,QAAM,OAAO;AAAA,IACX,iBAAiB,MAAM,kBAAkB;AAAA,IACzC,WAAW,MAAM,YAAY;AAAA,IAC7B,iBAAiB,MAAM,kBAAkB;AAAA,IACzC,iBAAiB,MAAM,kBAAkB;AAAA,IACzC;AAAA,IACA,YAAY,KAAK,GAAG,IAAI;AAAA,IACxB,aAAa;AAAA,IACb,cAAc,KAAK,GAAG,IAAI;AAAA,IAC1B,iBAAiB;AAAA,IACjB,aAAa,QAAQ,cAAc;AAAA,EACrC;AACA,QAAM,WAAW,MAAM,WAAW,MAAM,KAAK,EAAE,MAAsB;AACrE,MAAI,UAAU;AACZ,UAAM,WAAW,MAAM,KAAK,EAAE,OAAO,IAAI;AACzC,WAAO,SAAS;AAAA,EAClB;AACA,QAAM,WAAW,MAAM,KAAK,mBAAmB,EAC5C,OAAO;AAAA,IACN,aAAa,MAAM;AAAA,IACnB,GAAG;AAAA,EACL,CAAC,EACA,UAA4B,IAAI;AACnC,SAAO,WAAW,CAAC,GAAG,MAAM;AAC9B;AAEA,eAAsB,kBACpB,MACA,OACA,gBACA;AACA,QAAM,WAAW,MAAM,KAAK,EAAE,OAAO;AAAA,IACnC,iBAAiB,KAAK,IAAI,oCAAoC,CAAC,KAAK,IAAI,GAAG,cAAc,CAAC,CAAC;AAAA,IAC3F,cAAc,KAAK,GAAG,IAAI;AAAA,EAC5B,CAAC;AACH;AAEA,eAAsB,YACpB,MACA,OACA;AACA,QAAM,WAAW,MAAM,KAAK,EAAE,OAAO;AAAA,IACnC,aAAa,KAAK,GAAG,IAAI;AAAA,IACzB,cAAc,KAAK,GAAG,IAAI;AAAA,EAC5B,CAAC;AACH;",
4
+ "sourcesContent": ["import { type Kysely, sql } from 'kysely'\n\nexport type JobScope = {\n entityType: string\n organizationId?: string | null\n tenantId?: string | null\n partitionIndex?: number | null\n partitionCount?: number | null\n}\n\nfunction applyScopeWhere<QB extends { where: (...args: any[]) => QB }>(\n builder: QB,\n scope: JobScope,\n): QB {\n let q = builder.where('entity_type' as any, '=', scope.entityType)\n q = q.where(sql`organization_id is not distinct from ${scope.organizationId ?? null}`)\n q = q.where(sql`tenant_id is not distinct from ${scope.tenantId ?? null}`)\n q = q.where(sql`partition_index is not distinct from ${scope.partitionIndex ?? null}`)\n q = q.where(sql`partition_count is not distinct from ${scope.partitionCount ?? null}`)\n return q\n}\n\nexport async function prepareJob(\n db: Kysely<any>,\n scope: JobScope,\n status: 'reindexing' | 'purging',\n options: { totalCount?: number | null } = {},\n): Promise<string | null> {\n const base = {\n organization_id: scope.organizationId ?? null,\n tenant_id: scope.tenantId ?? null,\n partition_index: scope.partitionIndex ?? null,\n partition_count: scope.partitionCount ?? null,\n status,\n started_at: sql`now()`,\n finished_at: null,\n heartbeat_at: sql`now()`,\n processed_count: 0,\n total_count: options.totalCount ?? null,\n }\n\n const existing = await applyScopeWhere(\n db.selectFrom('entity_index_jobs' as any).select(['id' as any]),\n scope,\n ).executeTakeFirst() as { id: string } | undefined\n\n if (existing) {\n await applyScopeWhere(\n db.updateTable('entity_index_jobs' as any).set(base as any) as any,\n scope,\n ).execute()\n return existing.id\n }\n\n const inserted = await db\n .insertInto('entity_index_jobs' as any)\n .values({\n entity_type: scope.entityType,\n ...base,\n } as any)\n .returning(['id' as any])\n .execute() as Array<{ id: string }>\n\n return inserted?.[0]?.id ?? null\n}\n\nexport async function updateJobProgress(\n db: Kysely<any>,\n scope: JobScope,\n processedDelta: number,\n): Promise<void> {\n await applyScopeWhere(\n db.updateTable('entity_index_jobs' as any).set({\n processed_count: sql`coalesce(processed_count, 0) + ${Math.max(0, processedDelta)}`,\n heartbeat_at: sql`now()`,\n } as any) as any,\n scope,\n ).execute()\n}\n\nexport async function finalizeJob(\n db: Kysely<any>,\n scope: JobScope,\n): Promise<void> {\n await applyScopeWhere(\n db.updateTable('entity_index_jobs' as any).set({\n finished_at: sql`now()`,\n heartbeat_at: sql`now()`,\n } as any) as any,\n scope,\n ).execute()\n}\n"],
5
+ "mappings": "AAAA,SAAsB,WAAW;AAUjC,SAAS,gBACP,SACA,OACI;AACJ,MAAI,IAAI,QAAQ,MAAM,eAAsB,KAAK,MAAM,UAAU;AACjE,MAAI,EAAE,MAAM,2CAA2C,MAAM,kBAAkB,IAAI,EAAE;AACrF,MAAI,EAAE,MAAM,qCAAqC,MAAM,YAAY,IAAI,EAAE;AACzE,MAAI,EAAE,MAAM,2CAA2C,MAAM,kBAAkB,IAAI,EAAE;AACrF,MAAI,EAAE,MAAM,2CAA2C,MAAM,kBAAkB,IAAI,EAAE;AACrF,SAAO;AACT;AAEA,eAAsB,WACpB,IACA,OACA,QACA,UAA0C,CAAC,GACnB;AACxB,QAAM,OAAO;AAAA,IACX,iBAAiB,MAAM,kBAAkB;AAAA,IACzC,WAAW,MAAM,YAAY;AAAA,IAC7B,iBAAiB,MAAM,kBAAkB;AAAA,IACzC,iBAAiB,MAAM,kBAAkB;AAAA,IACzC;AAAA,IACA,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,aAAa,QAAQ,cAAc;AAAA,EACrC;AAEA,QAAM,WAAW,MAAM;AAAA,IACrB,GAAG,WAAW,mBAA0B,EAAE,OAAO,CAAC,IAAW,CAAC;AAAA,IAC9D;AAAA,EACF,EAAE,iBAAiB;AAEnB,MAAI,UAAU;AACZ,UAAM;AAAA,MACJ,GAAG,YAAY,mBAA0B,EAAE,IAAI,IAAW;AAAA,MAC1D;AAAA,IACF,EAAE,QAAQ;AACV,WAAO,SAAS;AAAA,EAClB;AAEA,QAAM,WAAW,MAAM,GACpB,WAAW,mBAA0B,EACrC,OAAO;AAAA,IACN,aAAa,MAAM;AAAA,IACnB,GAAG;AAAA,EACL,CAAQ,EACP,UAAU,CAAC,IAAW,CAAC,EACvB,QAAQ;AAEX,SAAO,WAAW,CAAC,GAAG,MAAM;AAC9B;AAEA,eAAsB,kBACpB,IACA,OACA,gBACe;AACf,QAAM;AAAA,IACJ,GAAG,YAAY,mBAA0B,EAAE,IAAI;AAAA,MAC7C,iBAAiB,qCAAqC,KAAK,IAAI,GAAG,cAAc,CAAC;AAAA,MACjF,cAAc;AAAA,IAChB,CAAQ;AAAA,IACR;AAAA,EACF,EAAE,QAAQ;AACZ;AAEA,eAAsB,YACpB,IACA,OACe;AACf,QAAM;AAAA,IACJ,GAAG,YAAY,mBAA0B,EAAE,IAAI;AAAA,MAC7C,aAAa;AAAA,MACb,cAAc;AAAA,IAChB,CAAQ;AAAA,IACR;AAAA,EACF,EAAE,QAAQ;AACZ;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,7 @@
1
+ import { sql } from "kysely";
1
2
  import { prepareJob, updateJobProgress, finalizeJob } from "./jobs.js";
2
3
  async function purgeIndexScope(em, options) {
3
- const knex = em.getConnection().getKnex();
4
+ const db = em.getKysely();
4
5
  const scope = {
5
6
  entityType: options.entityType,
6
7
  organizationId: options.organizationId ?? null,
@@ -8,24 +9,31 @@ async function purgeIndexScope(em, options) {
8
9
  partitionIndex: null,
9
10
  partitionCount: null
10
11
  };
11
- const countQuery = knex("entity_indexes").where({ entity_type: options.entityType }).modify((qb) => {
12
+ const applyScope = (q) => {
13
+ let chain = q.where("entity_type", "=", options.entityType);
12
14
  if (options.organizationId !== void 0) {
13
- qb.andWhereRaw("organization_id is not distinct from ?", [options.organizationId ?? null]);
15
+ chain = chain.where(sql`organization_id is not distinct from ${options.organizationId ?? null}`);
14
16
  }
15
17
  if (options.tenantId !== void 0) {
16
- qb.andWhereRaw("tenant_id is not distinct from ?", [options.tenantId ?? null]);
18
+ chain = chain.where(sql`tenant_id is not distinct from ${options.tenantId ?? null}`);
17
19
  }
18
- });
19
- const totalRow = await countQuery.clone().count({ count: "*" }).first();
20
+ return chain;
21
+ };
22
+ const totalRow = await applyScope(
23
+ db.selectFrom("entity_indexes").select(sql`count(*)`.as("count"))
24
+ ).executeTakeFirst();
20
25
  const total = totalRow ? Number(totalRow.count) || 0 : 0;
21
- await prepareJob(knex, scope, "purging", { totalCount: total });
26
+ await prepareJob(db, scope, "purging", { totalCount: total });
22
27
  if (total > 0) {
23
- const removed = await countQuery.clone().del();
24
- await updateJobProgress(knex, scope, typeof removed === "number" ? removed : total);
28
+ const result = await applyScope(
29
+ db.deleteFrom("entity_indexes")
30
+ ).executeTakeFirst();
31
+ const removed = Number(result?.numDeletedRows ?? 0);
32
+ await updateJobProgress(db, scope, removed || total);
25
33
  } else {
26
- await updateJobProgress(knex, scope, 0);
34
+ await updateJobProgress(db, scope, 0);
27
35
  }
28
- await finalizeJob(knex, scope);
36
+ await finalizeJob(db, scope);
29
37
  }
30
38
  export {
31
39
  purgeIndexScope
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/query_index/lib/purge.ts"],
4
- "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { Knex } from 'knex'\nimport { prepareJob, updateJobProgress, finalizeJob, type JobScope } from './jobs'\n\nexport type PurgeOptions = {\n entityType: string\n organizationId?: string | null\n tenantId?: string | null\n}\n\nexport async function purgeIndexScope(\n em: EntityManager,\n options: PurgeOptions,\n): Promise<void> {\n const knex = (em as any).getConnection().getKnex() as Knex\n const scope: JobScope = {\n entityType: options.entityType,\n organizationId: options.organizationId ?? null,\n tenantId: options.tenantId ?? null,\n partitionIndex: null,\n partitionCount: null,\n }\n\n const countQuery = knex('entity_indexes')\n .where({ entity_type: options.entityType })\n .modify((qb) => {\n if (options.organizationId !== undefined) {\n qb.andWhereRaw('organization_id is not distinct from ?', [options.organizationId ?? null])\n }\n if (options.tenantId !== undefined) {\n qb.andWhereRaw('tenant_id is not distinct from ?', [options.tenantId ?? null])\n }\n })\n\n const totalRow = await countQuery.clone().count<{ count: unknown }>({ count: '*' }).first()\n const total = totalRow ? Number(totalRow.count) || 0 : 0\n\n await prepareJob(knex, scope, 'purging', { totalCount: total })\n\n if (total > 0) {\n const removed = await countQuery.clone().del()\n await updateJobProgress(knex, scope, typeof removed === 'number' ? removed : total)\n } else {\n await updateJobProgress(knex, scope, 0)\n }\n\n await finalizeJob(knex, scope)\n}\n"],
5
- "mappings": "AAEA,SAAS,YAAY,mBAAmB,mBAAkC;AAQ1E,eAAsB,gBACpB,IACA,SACe;AACf,QAAM,OAAQ,GAAW,cAAc,EAAE,QAAQ;AACjD,QAAM,QAAkB;AAAA,IACtB,YAAY,QAAQ;AAAA,IACpB,gBAAgB,QAAQ,kBAAkB;AAAA,IAC1C,UAAU,QAAQ,YAAY;AAAA,IAC9B,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,EAClB;AAEA,QAAM,aAAa,KAAK,gBAAgB,EACrC,MAAM,EAAE,aAAa,QAAQ,WAAW,CAAC,EACzC,OAAO,CAAC,OAAO;AACd,QAAI,QAAQ,mBAAmB,QAAW;AACxC,SAAG,YAAY,0CAA0C,CAAC,QAAQ,kBAAkB,IAAI,CAAC;AAAA,IAC3F;AACA,QAAI,QAAQ,aAAa,QAAW;AAClC,SAAG,YAAY,oCAAoC,CAAC,QAAQ,YAAY,IAAI,CAAC;AAAA,IAC/E;AAAA,EACF,CAAC;AAEH,QAAM,WAAW,MAAM,WAAW,MAAM,EAAE,MAA0B,EAAE,OAAO,IAAI,CAAC,EAAE,MAAM;AAC1F,QAAM,QAAQ,WAAW,OAAO,SAAS,KAAK,KAAK,IAAI;AAEvD,QAAM,WAAW,MAAM,OAAO,WAAW,EAAE,YAAY,MAAM,CAAC;AAE9D,MAAI,QAAQ,GAAG;AACb,UAAM,UAAU,MAAM,WAAW,MAAM,EAAE,IAAI;AAC7C,UAAM,kBAAkB,MAAM,OAAO,OAAO,YAAY,WAAW,UAAU,KAAK;AAAA,EACpF,OAAO;AACL,UAAM,kBAAkB,MAAM,OAAO,CAAC;AAAA,EACxC;AAEA,QAAM,YAAY,MAAM,KAAK;AAC/B;",
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { sql } from 'kysely'\nimport { prepareJob, updateJobProgress, finalizeJob, type JobScope } from './jobs'\n\nexport type PurgeOptions = {\n entityType: string\n organizationId?: string | null\n tenantId?: string | null\n}\n\nexport async function purgeIndexScope(\n em: EntityManager,\n options: PurgeOptions,\n): Promise<void> {\n const db = em.getKysely<any>()\n const scope: JobScope = {\n entityType: options.entityType,\n organizationId: options.organizationId ?? null,\n tenantId: options.tenantId ?? null,\n partitionIndex: null,\n partitionCount: null,\n }\n\n const applyScope = <QB extends { where: (...args: any[]) => QB }>(q: QB): QB => {\n let chain = q.where('entity_type' as any, '=', options.entityType)\n if (options.organizationId !== undefined) {\n chain = chain.where(sql`organization_id is not distinct from ${options.organizationId ?? null}`)\n }\n if (options.tenantId !== undefined) {\n chain = chain.where(sql`tenant_id is not distinct from ${options.tenantId ?? null}`)\n }\n return chain\n }\n\n const totalRow = await applyScope(\n db.selectFrom('entity_indexes' as any).select(sql`count(*)`.as('count')),\n ).executeTakeFirst() as { count: unknown } | undefined\n\n const total = totalRow ? Number(totalRow.count) || 0 : 0\n\n await prepareJob(db, scope, 'purging', { totalCount: total })\n\n if (total > 0) {\n const result = await applyScope(\n db.deleteFrom('entity_indexes' as any) as any,\n ).executeTakeFirst() as { numDeletedRows?: bigint | number } | undefined\n const removed = Number(result?.numDeletedRows ?? 0)\n await updateJobProgress(db, scope, removed || total)\n } else {\n await updateJobProgress(db, scope, 0)\n }\n\n await finalizeJob(db, scope)\n}\n"],
5
+ "mappings": "AACA,SAAS,WAAW;AACpB,SAAS,YAAY,mBAAmB,mBAAkC;AAQ1E,eAAsB,gBACpB,IACA,SACe;AACf,QAAM,KAAK,GAAG,UAAe;AAC7B,QAAM,QAAkB;AAAA,IACtB,YAAY,QAAQ;AAAA,IACpB,gBAAgB,QAAQ,kBAAkB;AAAA,IAC1C,UAAU,QAAQ,YAAY;AAAA,IAC9B,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,EAClB;AAEA,QAAM,aAAa,CAA+C,MAAc;AAC9E,QAAI,QAAQ,EAAE,MAAM,eAAsB,KAAK,QAAQ,UAAU;AACjE,QAAI,QAAQ,mBAAmB,QAAW;AACxC,cAAQ,MAAM,MAAM,2CAA2C,QAAQ,kBAAkB,IAAI,EAAE;AAAA,IACjG;AACA,QAAI,QAAQ,aAAa,QAAW;AAClC,cAAQ,MAAM,MAAM,qCAAqC,QAAQ,YAAY,IAAI,EAAE;AAAA,IACrF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,MAAM;AAAA,IACrB,GAAG,WAAW,gBAAuB,EAAE,OAAO,cAAc,GAAG,OAAO,CAAC;AAAA,EACzE,EAAE,iBAAiB;AAEnB,QAAM,QAAQ,WAAW,OAAO,SAAS,KAAK,KAAK,IAAI;AAEvD,QAAM,WAAW,IAAI,OAAO,WAAW,EAAE,YAAY,MAAM,CAAC;AAE5D,MAAI,QAAQ,GAAG;AACb,UAAM,SAAS,MAAM;AAAA,MACnB,GAAG,WAAW,gBAAuB;AAAA,IACvC,EAAE,iBAAiB;AACnB,UAAM,UAAU,OAAO,QAAQ,kBAAkB,CAAC;AAClD,UAAM,kBAAkB,IAAI,OAAO,WAAW,KAAK;AAAA,EACrD,OAAO;AACL,UAAM,kBAAkB,IAAI,OAAO,CAAC;AAAA,EACtC;AAEA,QAAM,YAAY,IAAI,KAAK;AAC7B;",
6
6
  "names": []
7
7
  }