@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
@@ -1,3 +1,4 @@
1
+ import { sql } from "kysely";
1
2
  import { buildIndexDocument } from "./document.js";
2
3
  import { replaceSearchTokensForBatch, isSearchDebugEnabled } from "./search-tokens.js";
3
4
  function normalizeId(value) {
@@ -7,7 +8,7 @@ function normalizeScopedValue(value) {
7
8
  if (value === void 0 || value === null || value === "") return null;
8
9
  return String(value);
9
10
  }
10
- async function upsertIndexBatch(knex, entityType, rows, scope, options = {}) {
11
+ async function upsertIndexBatch(db, entityType, rows, scope, options = {}) {
11
12
  if (!rows.length) return;
12
13
  const recordIds = rows.map((row) => normalizeId(row.id));
13
14
  const shouldMergeCustomerEntity = entityType === "customers:customer_person_profile" || entityType === "customers:customer_company_profile";
@@ -19,11 +20,11 @@ async function upsertIndexBatch(knex, entityType, rows, scope, options = {}) {
19
20
  )
20
21
  );
21
22
  if (entityIds.length) {
22
- const entityRows = await knex("customer_entities").whereIn("id", entityIds);
23
+ const entityRows = await db.selectFrom("customer_entities").selectAll().where("id", "in", entityIds).execute();
23
24
  customerEntitiesById = new Map(entityRows.map((row) => [normalizeId(row.id), row]));
24
25
  }
25
26
  }
26
- const customFieldRows = await knex("custom_field_values").select([
27
+ const customFieldRows = await db.selectFrom("custom_field_values").select([
27
28
  "record_id",
28
29
  "field_key",
29
30
  "value_text",
@@ -33,7 +34,7 @@ async function upsertIndexBatch(knex, entityType, rows, scope, options = {}) {
33
34
  "value_bool",
34
35
  "organization_id",
35
36
  "tenant_id"
36
- ]).where("entity_id", entityType).whereIn("record_id", recordIds);
37
+ ]).where("entity_id", "=", entityType).where("record_id", "in", recordIds).execute();
37
38
  const customFieldMap = /* @__PURE__ */ new Map();
38
39
  for (const fieldRow of customFieldRows) {
39
40
  const key = normalizeId(fieldRow.record_id);
@@ -126,10 +127,10 @@ async function upsertIndexBatch(knex, entityType, rows, scope, options = {}) {
126
127
  entity_id: payload.entity_id,
127
128
  organization_id: payload.organization_id,
128
129
  tenant_id: payload.tenant_id,
129
- doc: payload.doc,
130
+ doc: sql`${JSON.stringify(payload.doc)}::jsonb`,
130
131
  index_version: payload.index_version,
131
- created_at: knex.fn.now(),
132
- updated_at: knex.fn.now(),
132
+ created_at: sql`now()`,
133
+ updated_at: sql`now()`,
133
134
  deleted_at: null
134
135
  }));
135
136
  const tokenPayloads = basePayloads.map((payload) => ({
@@ -140,16 +141,16 @@ async function upsertIndexBatch(knex, entityType, rows, scope, options = {}) {
140
141
  doc: payload.tokenDoc
141
142
  }));
142
143
  try {
143
- await knex("entity_indexes").insert(insertRows).onConflict(["entity_type", "entity_id", "organization_id_coalesced"]).merge({
144
- doc: knex.raw("excluded.doc"),
145
- index_version: knex.raw("excluded.index_version"),
146
- organization_id: knex.raw("excluded.organization_id"),
147
- tenant_id: knex.raw("excluded.tenant_id"),
148
- deleted_at: knex.raw("excluded.deleted_at"),
149
- updated_at: knex.fn.now()
150
- });
144
+ await db.insertInto("entity_indexes").values(insertRows).onConflict((oc) => oc.columns(["entity_type", "entity_id", "organization_id_coalesced"]).doUpdateSet({
145
+ doc: sql`excluded.doc`,
146
+ index_version: sql`excluded.index_version`,
147
+ organization_id: sql`excluded.organization_id`,
148
+ tenant_id: sql`excluded.tenant_id`,
149
+ deleted_at: sql`excluded.deleted_at`,
150
+ updated_at: sql`now()`
151
+ })).execute();
151
152
  try {
152
- await replaceSearchTokensForBatch(knex, tokenPayloads);
153
+ await replaceSearchTokensForBatch(db, tokenPayloads);
153
154
  } catch {
154
155
  }
155
156
  if (debugEnabled) {
@@ -162,41 +163,38 @@ async function upsertIndexBatch(knex, entityType, rows, scope, options = {}) {
162
163
  }
163
164
  return;
164
165
  } catch {
165
- await knex.transaction(async (trx) => {
166
- const now = trx.fn.now();
166
+ await db.transaction().execute(async (trx) => {
167
167
  for (const payload of basePayloads) {
168
- const updated = await trx("entity_indexes").where({
169
- entity_type: payload.entity_type,
170
- entity_id: payload.entity_id,
171
- organization_id: payload.organization_id ?? null
172
- }).update({
173
- doc: payload.doc,
168
+ let updateQuery = trx.updateTable("entity_indexes").set({
169
+ doc: sql`${JSON.stringify(payload.doc)}::jsonb`,
174
170
  index_version: payload.index_version,
175
171
  organization_id: payload.organization_id ?? null,
176
172
  tenant_id: payload.tenant_id ?? null,
177
- updated_at: now,
173
+ updated_at: sql`now()`,
178
174
  deleted_at: null
179
- });
180
- if (updated) continue;
175
+ }).where("entity_type", "=", payload.entity_type).where("entity_id", "=", payload.entity_id);
176
+ updateQuery = payload.organization_id == null ? updateQuery.where("organization_id", "is", null) : updateQuery.where("organization_id", "=", payload.organization_id);
177
+ const result = await updateQuery.executeTakeFirst();
178
+ if (result && Number(result.numUpdatedRows ?? 0) > 0) continue;
181
179
  try {
182
- await trx("entity_indexes").insert({
180
+ await trx.insertInto("entity_indexes").values({
183
181
  entity_type: payload.entity_type,
184
182
  entity_id: payload.entity_id,
185
183
  organization_id: payload.organization_id,
186
184
  tenant_id: payload.tenant_id,
187
- doc: payload.doc,
185
+ doc: sql`${JSON.stringify(payload.doc)}::jsonb`,
188
186
  index_version: payload.index_version,
189
- created_at: now,
190
- updated_at: now,
187
+ created_at: sql`now()`,
188
+ updated_at: sql`now()`,
191
189
  deleted_at: null
192
- });
190
+ }).execute();
193
191
  } catch {
194
192
  }
195
193
  }
196
194
  });
197
195
  }
198
196
  try {
199
- await replaceSearchTokensForBatch(knex, tokenPayloads);
197
+ await replaceSearchTokensForBatch(db, tokenPayloads);
200
198
  } catch {
201
199
  }
202
200
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/query_index/lib/batch.ts"],
4
- "sourcesContent": ["import type { Knex } from 'knex'\nimport { buildIndexDocument, type IndexCustomFieldValue } from './document'\nimport { replaceSearchTokensForBatch, isSearchDebugEnabled } from './search-tokens'\n\nexport type AnyRow = Record<string, any> & { id: string | number }\n\nexport type ScopeOverrides = {\n orgId?: string\n tenantId?: string\n}\n\ntype CustomFieldRow = {\n record_id: string\n field_key: string\n value_text: string | null\n value_multiline: string | null\n value_int: number | null\n value_float: number | null\n value_bool: boolean | null\n organization_id: string | null\n tenant_id: string | null\n}\n\nexport type IndexBatchOptions = {\n deriveOrganizationId?: (row: AnyRow) => string | null | undefined\n encryptDoc?: (\n entityType: string,\n doc: Record<string, unknown>,\n scope: { organizationId: string | null; tenantId: string | null },\n ) => Promise<Record<string, unknown> | null | undefined>\n decryptDoc?: (\n entityType: string,\n doc: Record<string, unknown>,\n scope: { organizationId: string | null; tenantId: string | null },\n ) => Promise<Record<string, unknown> | null | undefined>\n}\n\nfunction normalizeId(value: unknown): string {\n return String(value)\n}\n\nfunction normalizeScopedValue(value: unknown): string | null {\n if (value === undefined || value === null || value === '') return null\n return String(value)\n}\n\nexport async function upsertIndexBatch(\n knex: Knex,\n entityType: string,\n rows: AnyRow[],\n scope: ScopeOverrides,\n options: IndexBatchOptions = {},\n): Promise<void> {\n if (!rows.length) return\n const recordIds = rows.map((row) => normalizeId(row.id))\n\n const shouldMergeCustomerEntity =\n entityType === 'customers:customer_person_profile' || entityType === 'customers:customer_company_profile'\n\n let customerEntitiesById: Map<string, AnyRow> | null = null\n if (shouldMergeCustomerEntity) {\n const entityIds = Array.from(\n new Set(\n rows\n .map((row) => (row as AnyRow).entity_id || (row as AnyRow).entityId)\n .filter((value): value is string | number => value !== undefined && value !== null && `${value}` !== '')\n .map((value) => normalizeId(value)),\n ),\n )\n if (entityIds.length) {\n const entityRows = await knex<AnyRow>('customer_entities').whereIn('id', entityIds)\n customerEntitiesById = new Map(entityRows.map((row) => [normalizeId(row.id), row]))\n }\n }\n\n const customFieldRows = await knex<CustomFieldRow>('custom_field_values')\n .select([\n 'record_id',\n 'field_key',\n 'value_text',\n 'value_multiline',\n 'value_int',\n 'value_float',\n 'value_bool',\n 'organization_id',\n 'tenant_id',\n ])\n .where('entity_id', entityType)\n .whereIn('record_id', recordIds)\n\n const customFieldMap = new Map<string, CustomFieldRow[]>()\n for (const fieldRow of customFieldRows) {\n const key = normalizeId(fieldRow.record_id)\n const bucket = customFieldMap.get(key)\n if (bucket) bucket.push(fieldRow)\n else customFieldMap.set(key, [fieldRow])\n }\n\n const basePayloads: Array<{\n entity_type: string\n entity_id: string\n organization_id: string | null\n tenant_id: string | null\n doc: Record<string, unknown>\n tokenDoc: Record<string, unknown>\n index_version: number\n }> = []\n\n const debugEnabled = isSearchDebugEnabled()\n\n for (const row of rows) {\n const recordId = normalizeId(row.id)\n const baseOrg = normalizeScopedValue((row as AnyRow).organization_id)\n const baseTenant = normalizeScopedValue((row as AnyRow).tenant_id)\n const derivedOrg = options?.deriveOrganizationId\n ? normalizeScopedValue(options.deriveOrganizationId(row))\n : undefined\n const scopeOrg =\n scope.orgId !== undefined\n ? scope.orgId\n : derivedOrg !== undefined\n ? derivedOrg\n : baseOrg\n const scopeTenant = scope.tenantId !== undefined ? scope.tenantId : baseTenant\n const inputRows = customFieldMap.get(recordId) ?? []\n const values: IndexCustomFieldValue[] = inputRows.map((fieldRow) => ({\n key: fieldRow.field_key,\n value:\n fieldRow.value_bool ??\n fieldRow.value_int ??\n fieldRow.value_float ??\n fieldRow.value_text ??\n fieldRow.value_multiline ??\n null,\n organizationId: normalizeScopedValue(fieldRow.organization_id),\n tenantId: normalizeScopedValue(fieldRow.tenant_id),\n }))\n const mergedRow = (() => {\n if (!shouldMergeCustomerEntity || !customerEntitiesById) return row\n const entityId = (row as AnyRow).entity_id || (row as AnyRow).entityId\n if (!entityId) return row\n const entityRow = customerEntitiesById.get(normalizeId(entityId))\n if (!entityRow) return row\n return { ...entityRow, ...row }\n })()\n let doc = buildIndexDocument(mergedRow, values, {\n organizationId: scopeOrg ?? null,\n tenantId: scopeTenant ?? null,\n })\n let tokenDoc: Record<string, unknown> = doc\n if (typeof options.encryptDoc === 'function') {\n try {\n const encrypted = await options.encryptDoc(entityType, doc, {\n organizationId: scopeOrg ?? null,\n tenantId: scopeTenant ?? null,\n })\n if (encrypted && typeof encrypted === 'object') {\n doc = encrypted\n tokenDoc = encrypted\n }\n } catch {\n // best-effort; ignore encrypt errors during indexing\n }\n }\n if (typeof options.decryptDoc === 'function') {\n try {\n const decrypted = await options.decryptDoc(entityType, doc, {\n organizationId: scopeOrg ?? null,\n tenantId: scopeTenant ?? null,\n })\n if (decrypted && typeof decrypted === 'object') {\n tokenDoc = decrypted\n }\n } catch {\n // best-effort; ignore decrypt errors during indexing\n }\n }\n basePayloads.push({\n entity_type: entityType,\n entity_id: recordId,\n organization_id: scopeOrg ?? null,\n tenant_id: scopeTenant ?? null,\n doc,\n tokenDoc,\n index_version: 1,\n })\n if (debugEnabled) {\n const sample = {\n display_name: (tokenDoc as any).display_name,\n first_name: (tokenDoc as any).first_name,\n last_name: (tokenDoc as any).last_name,\n brand_name: (tokenDoc as any).brand_name,\n legal_name: (tokenDoc as any).legal_name,\n }\n console.info('[reindex:batch:doc]', {\n entityType,\n recordId,\n organizationId: scopeOrg ?? null,\n tenantId: scopeTenant ?? null,\n sample,\n })\n }\n }\n\n const insertRows = basePayloads.map((payload) => ({\n entity_type: payload.entity_type,\n entity_id: payload.entity_id,\n organization_id: payload.organization_id,\n tenant_id: payload.tenant_id,\n doc: payload.doc,\n index_version: payload.index_version,\n created_at: knex.fn.now(),\n updated_at: knex.fn.now(),\n deleted_at: null,\n }))\n\n const tokenPayloads = basePayloads.map((payload) => ({\n entityType: payload.entity_type,\n recordId: payload.entity_id,\n organizationId: payload.organization_id,\n tenantId: payload.tenant_id,\n doc: payload.tokenDoc,\n }))\n\n try {\n await knex('entity_indexes')\n .insert(insertRows)\n .onConflict(['entity_type', 'entity_id', 'organization_id_coalesced'])\n .merge({\n doc: knex.raw('excluded.doc'),\n index_version: knex.raw('excluded.index_version'),\n organization_id: knex.raw('excluded.organization_id'),\n tenant_id: knex.raw('excluded.tenant_id'),\n deleted_at: knex.raw('excluded.deleted_at'),\n updated_at: knex.fn.now(),\n })\n try {\n await replaceSearchTokensForBatch(knex, tokenPayloads)\n } catch {}\n if (debugEnabled) {\n console.info('[reindex:batch:tokens]', {\n entityType,\n records: basePayloads.length,\n scopeOrg: scope.orgId ?? null,\n scopeTenant: scope.tenantId ?? null,\n })\n }\n return\n } catch {\n await knex.transaction(async (trx) => {\n const now = trx.fn.now()\n for (const payload of basePayloads) {\n const updated = await trx('entity_indexes')\n .where({\n entity_type: payload.entity_type,\n entity_id: payload.entity_id,\n organization_id: payload.organization_id ?? null,\n })\n .update({\n doc: payload.doc,\n index_version: payload.index_version,\n organization_id: payload.organization_id ?? null,\n tenant_id: payload.tenant_id ?? null,\n updated_at: now,\n deleted_at: null,\n })\n if (updated) continue\n try {\n await trx('entity_indexes').insert({\n entity_type: payload.entity_type,\n entity_id: payload.entity_id,\n organization_id: payload.organization_id,\n tenant_id: payload.tenant_id,\n doc: payload.doc,\n index_version: payload.index_version,\n created_at: now,\n updated_at: now,\n deleted_at: null,\n })\n } catch {\n // ignore duplicate insert race; another concurrent worker updated the row\n }\n }\n })\n }\n try {\n await replaceSearchTokensForBatch(knex, tokenPayloads)\n } catch {}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { type Kysely, sql } from 'kysely'\nimport { buildIndexDocument, type IndexCustomFieldValue } from './document'\nimport { replaceSearchTokensForBatch, isSearchDebugEnabled } from './search-tokens'\n\nexport type AnyRow = Record<string, any> & { id: string | number }\n\nexport type ScopeOverrides = {\n orgId?: string\n tenantId?: string\n}\n\ntype CustomFieldRow = {\n record_id: string\n field_key: string\n value_text: string | null\n value_multiline: string | null\n value_int: number | null\n value_float: number | null\n value_bool: boolean | null\n organization_id: string | null\n tenant_id: string | null\n}\n\nexport type IndexBatchOptions = {\n deriveOrganizationId?: (row: AnyRow) => string | null | undefined\n encryptDoc?: (\n entityType: string,\n doc: Record<string, unknown>,\n scope: { organizationId: string | null; tenantId: string | null },\n ) => Promise<Record<string, unknown> | null | undefined>\n decryptDoc?: (\n entityType: string,\n doc: Record<string, unknown>,\n scope: { organizationId: string | null; tenantId: string | null },\n ) => Promise<Record<string, unknown> | null | undefined>\n}\n\nfunction normalizeId(value: unknown): string {\n return String(value)\n}\n\nfunction normalizeScopedValue(value: unknown): string | null {\n if (value === undefined || value === null || value === '') return null\n return String(value)\n}\n\nexport async function upsertIndexBatch(\n db: Kysely<any>,\n entityType: string,\n rows: AnyRow[],\n scope: ScopeOverrides,\n options: IndexBatchOptions = {},\n): Promise<void> {\n if (!rows.length) return\n const recordIds = rows.map((row) => normalizeId(row.id))\n\n const shouldMergeCustomerEntity =\n entityType === 'customers:customer_person_profile' || entityType === 'customers:customer_company_profile'\n\n let customerEntitiesById: Map<string, AnyRow> | null = null\n if (shouldMergeCustomerEntity) {\n const entityIds = Array.from(\n new Set(\n rows\n .map((row) => (row as AnyRow).entity_id || (row as AnyRow).entityId)\n .filter((value): value is string | number => value !== undefined && value !== null && `${value}` !== '')\n .map((value) => normalizeId(value)),\n ),\n )\n if (entityIds.length) {\n const entityRows = await db\n .selectFrom('customer_entities' as any)\n .selectAll()\n .where('id' as any, 'in', entityIds)\n .execute() as AnyRow[]\n customerEntitiesById = new Map(entityRows.map((row) => [normalizeId(row.id), row]))\n }\n }\n\n const customFieldRows = await db\n .selectFrom('custom_field_values' as any)\n .select([\n 'record_id' as any,\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 'organization_id' as any,\n 'tenant_id' as any,\n ])\n .where('entity_id' as any, '=', entityType)\n .where('record_id' as any, 'in', recordIds)\n .execute() as CustomFieldRow[]\n\n const customFieldMap = new Map<string, CustomFieldRow[]>()\n for (const fieldRow of customFieldRows) {\n const key = normalizeId(fieldRow.record_id)\n const bucket = customFieldMap.get(key)\n if (bucket) bucket.push(fieldRow)\n else customFieldMap.set(key, [fieldRow])\n }\n\n const basePayloads: Array<{\n entity_type: string\n entity_id: string\n organization_id: string | null\n tenant_id: string | null\n doc: Record<string, unknown>\n tokenDoc: Record<string, unknown>\n index_version: number\n }> = []\n\n const debugEnabled = isSearchDebugEnabled()\n\n for (const row of rows) {\n const recordId = normalizeId(row.id)\n const baseOrg = normalizeScopedValue((row as AnyRow).organization_id)\n const baseTenant = normalizeScopedValue((row as AnyRow).tenant_id)\n const derivedOrg = options?.deriveOrganizationId\n ? normalizeScopedValue(options.deriveOrganizationId(row))\n : undefined\n const scopeOrg =\n scope.orgId !== undefined\n ? scope.orgId\n : derivedOrg !== undefined\n ? derivedOrg\n : baseOrg\n const scopeTenant = scope.tenantId !== undefined ? scope.tenantId : baseTenant\n const inputRows = customFieldMap.get(recordId) ?? []\n const values: IndexCustomFieldValue[] = inputRows.map((fieldRow) => ({\n key: fieldRow.field_key,\n value:\n fieldRow.value_bool ??\n fieldRow.value_int ??\n fieldRow.value_float ??\n fieldRow.value_text ??\n fieldRow.value_multiline ??\n null,\n organizationId: normalizeScopedValue(fieldRow.organization_id),\n tenantId: normalizeScopedValue(fieldRow.tenant_id),\n }))\n const mergedRow = (() => {\n if (!shouldMergeCustomerEntity || !customerEntitiesById) return row\n const entityId = (row as AnyRow).entity_id || (row as AnyRow).entityId\n if (!entityId) return row\n const entityRow = customerEntitiesById.get(normalizeId(entityId))\n if (!entityRow) return row\n return { ...entityRow, ...row }\n })()\n let doc = buildIndexDocument(mergedRow, values, {\n organizationId: scopeOrg ?? null,\n tenantId: scopeTenant ?? null,\n })\n let tokenDoc: Record<string, unknown> = doc\n if (typeof options.encryptDoc === 'function') {\n try {\n const encrypted = await options.encryptDoc(entityType, doc, {\n organizationId: scopeOrg ?? null,\n tenantId: scopeTenant ?? null,\n })\n if (encrypted && typeof encrypted === 'object') {\n doc = encrypted\n tokenDoc = encrypted\n }\n } catch {\n // best-effort; ignore encrypt errors during indexing\n }\n }\n if (typeof options.decryptDoc === 'function') {\n try {\n const decrypted = await options.decryptDoc(entityType, doc, {\n organizationId: scopeOrg ?? null,\n tenantId: scopeTenant ?? null,\n })\n if (decrypted && typeof decrypted === 'object') {\n tokenDoc = decrypted\n }\n } catch {\n // best-effort; ignore decrypt errors during indexing\n }\n }\n basePayloads.push({\n entity_type: entityType,\n entity_id: recordId,\n organization_id: scopeOrg ?? null,\n tenant_id: scopeTenant ?? null,\n doc,\n tokenDoc,\n index_version: 1,\n })\n if (debugEnabled) {\n const sample = {\n display_name: (tokenDoc as any).display_name,\n first_name: (tokenDoc as any).first_name,\n last_name: (tokenDoc as any).last_name,\n brand_name: (tokenDoc as any).brand_name,\n legal_name: (tokenDoc as any).legal_name,\n }\n console.info('[reindex:batch:doc]', {\n entityType,\n recordId,\n organizationId: scopeOrg ?? null,\n tenantId: scopeTenant ?? null,\n sample,\n })\n }\n }\n\n const insertRows = basePayloads.map((payload) => ({\n entity_type: payload.entity_type,\n entity_id: payload.entity_id,\n organization_id: payload.organization_id,\n tenant_id: payload.tenant_id,\n doc: sql`${JSON.stringify(payload.doc)}::jsonb`,\n index_version: payload.index_version,\n created_at: sql`now()`,\n updated_at: sql`now()`,\n deleted_at: null,\n }))\n\n const tokenPayloads = basePayloads.map((payload) => ({\n entityType: payload.entity_type,\n recordId: payload.entity_id,\n organizationId: payload.organization_id,\n tenantId: payload.tenant_id,\n doc: payload.tokenDoc,\n }))\n\n try {\n await db\n .insertInto('entity_indexes' as any)\n .values(insertRows as any)\n .onConflict((oc: any) => oc\n .columns(['entity_type', 'entity_id', 'organization_id_coalesced'])\n .doUpdateSet({\n doc: sql`excluded.doc`,\n index_version: sql`excluded.index_version`,\n organization_id: sql`excluded.organization_id`,\n tenant_id: sql`excluded.tenant_id`,\n deleted_at: sql`excluded.deleted_at`,\n updated_at: sql`now()`,\n } as any))\n .execute()\n try {\n await replaceSearchTokensForBatch(db, tokenPayloads)\n } catch {}\n if (debugEnabled) {\n console.info('[reindex:batch:tokens]', {\n entityType,\n records: basePayloads.length,\n scopeOrg: scope.orgId ?? null,\n scopeTenant: scope.tenantId ?? null,\n })\n }\n return\n } catch {\n await db.transaction().execute(async (trx) => {\n for (const payload of basePayloads) {\n let updateQuery = trx\n .updateTable('entity_indexes' as any)\n .set({\n doc: sql`${JSON.stringify(payload.doc)}::jsonb`,\n index_version: payload.index_version,\n organization_id: payload.organization_id ?? null,\n tenant_id: payload.tenant_id ?? null,\n updated_at: sql`now()`,\n deleted_at: null,\n } as any)\n .where('entity_type' as any, '=', payload.entity_type)\n .where('entity_id' as any, '=', payload.entity_id)\n updateQuery = payload.organization_id == null\n ? updateQuery.where('organization_id' as any, 'is', null as any)\n : updateQuery.where('organization_id' as any, '=', payload.organization_id)\n const result = await updateQuery.executeTakeFirst() as { numUpdatedRows?: bigint | number } | undefined\n if (result && Number(result.numUpdatedRows ?? 0) > 0) continue\n try {\n await trx\n .insertInto('entity_indexes' as any)\n .values({\n entity_type: payload.entity_type,\n entity_id: payload.entity_id,\n organization_id: payload.organization_id,\n tenant_id: payload.tenant_id,\n doc: sql`${JSON.stringify(payload.doc)}::jsonb`,\n index_version: payload.index_version,\n created_at: sql`now()`,\n updated_at: sql`now()`,\n deleted_at: null,\n } as any)\n .execute()\n } catch {\n // ignore duplicate insert race; another concurrent worker updated the row\n }\n }\n })\n }\n try {\n await replaceSearchTokensForBatch(db, tokenPayloads)\n } catch {}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,3 +1,4 @@
1
+ import { sql } from "kysely";
1
2
  import { resolveEntityTableName } from "@open-mercato/shared/lib/query/engine";
2
3
  const COLUMN_CACHE = /* @__PURE__ */ new Map();
3
4
  const GLOBAL_ORGANIZATION_PLACEHOLDER = "00000000-0000-0000-0000-000000000000";
@@ -20,32 +21,44 @@ function normalizeOrganizationForStore(orgId) {
20
21
  function applyOrganizationCondition(qb, column, organizationId) {
21
22
  const stored = normalizeOrganizationForStore(organizationId ?? null);
22
23
  if (stored === GLOBAL_ORGANIZATION_PLACEHOLDER) {
23
- qb.andWhere((sub) => {
24
- sub.whereNull(column).orWhere(column, GLOBAL_ORGANIZATION_PLACEHOLDER);
25
- });
26
- } else {
27
- qb.andWhere(column, stored);
24
+ return qb.where((eb) => eb.or([
25
+ eb(column, "is", null),
26
+ eb(column, "=", GLOBAL_ORGANIZATION_PLACEHOLDER)
27
+ ]));
28
28
  }
29
+ return qb.where(column, "=", stored);
29
30
  }
30
- async function fetchCoverageRow(knex, scope) {
31
+ async function fetchCoverageRow(db, scope) {
31
32
  const { entityType, tenantId, organizationId, withDeleted } = scope;
32
- const row = await knex("entity_index_coverage").select(["base_count", "indexed_count", "vector_indexed_count", "refreshed_at", "organization_id"]).where("entity_type", entityType).where("tenant_id", tenantId ?? null).where("with_deleted", withDeleted === true).modify((qb) => applyOrganizationCondition(qb, "organization_id", organizationId ?? null)).orderBy("refreshed_at", "desc").first();
33
+ let query = db.selectFrom("entity_index_coverage").select([
34
+ "base_count",
35
+ "indexed_count",
36
+ "vector_indexed_count",
37
+ "refreshed_at",
38
+ "organization_id"
39
+ ]).where("entity_type", "=", entityType).where("with_deleted", "=", withDeleted === true).orderBy("refreshed_at", "desc");
40
+ query = tenantId == null ? query.where("tenant_id", "is", null) : query.where("tenant_id", "=", tenantId);
41
+ query = applyOrganizationCondition(query, "organization_id", organizationId ?? null);
42
+ const row = await query.executeTakeFirst();
33
43
  return row ?? null;
34
44
  }
35
- async function pruneDuplicateCoverageRows(knex, scope, keepId) {
36
- const query = knex("entity_index_coverage").where("entity_type", scope.entityType).where("tenant_id", scope.tenantId ?? null).where("with_deleted", scope.withDeleted === true).modify((qb) => applyOrganizationCondition(qb, "organization_id", scope.organizationId ?? null));
45
+ async function pruneDuplicateCoverageRows(db, scope, keepId) {
46
+ let query = db.deleteFrom("entity_index_coverage").where("entity_type", "=", scope.entityType).where("with_deleted", "=", scope.withDeleted === true);
47
+ query = scope.tenantId == null ? query.where("tenant_id", "is", null) : query.where("tenant_id", "=", scope.tenantId);
48
+ query = applyOrganizationCondition(query, "organization_id", scope.organizationId ?? null);
37
49
  if (keepId) {
38
- await query.andWhereNot("id", keepId).del();
39
- } else {
40
- await query.del();
50
+ query = query.where("id", "!=", keepId);
41
51
  }
52
+ await query.execute();
42
53
  }
43
- async function upsertCoverageRow(knex, scope, counts) {
54
+ async function upsertCoverageRow(db, scope, counts) {
44
55
  const storedOrgId = normalizeOrganizationForStore(scope.organizationId ?? null);
45
56
  if (scope.organizationId == null) {
46
- await knex("entity_index_coverage").where("entity_type", scope.entityType).where("tenant_id", scope.tenantId ?? null).where("with_deleted", scope.withDeleted === true).whereNull("organization_id").del();
57
+ let purge = db.deleteFrom("entity_index_coverage").where("entity_type", "=", scope.entityType).where("with_deleted", "=", scope.withDeleted === true).where("organization_id", "is", null);
58
+ purge = scope.tenantId == null ? purge.where("tenant_id", "is", null) : purge.where("tenant_id", "=", scope.tenantId);
59
+ await purge.execute();
47
60
  }
48
- const rows = await knex("entity_index_coverage").insert({
61
+ const rows = await db.insertInto("entity_index_coverage").values({
49
62
  entity_type: scope.entityType,
50
63
  tenant_id: scope.tenantId ?? null,
51
64
  organization_id: storedOrgId,
@@ -53,20 +66,20 @@ async function upsertCoverageRow(knex, scope, counts) {
53
66
  base_count: counts.baseCount,
54
67
  indexed_count: counts.indexedCount,
55
68
  vector_indexed_count: counts.vectorIndexedCount,
56
- refreshed_at: knex.fn.now()
57
- }).onConflict(["entity_type", "tenant_id", "organization_id", "with_deleted"]).merge({
69
+ refreshed_at: sql`now()`
70
+ }).onConflict((oc) => oc.columns(["entity_type", "tenant_id", "organization_id", "with_deleted"]).doUpdateSet({
58
71
  base_count: counts.baseCount,
59
72
  indexed_count: counts.indexedCount,
60
73
  vector_indexed_count: counts.vectorIndexedCount,
61
- refreshed_at: knex.fn.now()
62
- }).returning("id");
74
+ refreshed_at: sql`now()`
75
+ })).returning(["id"]).execute();
63
76
  const keepId = rows?.[0]?.id ?? null;
64
- await pruneDuplicateCoverageRows(knex, scope, keepId);
77
+ await pruneDuplicateCoverageRows(db, scope, keepId);
65
78
  }
66
- async function readCoverageSnapshot(knex, scope) {
79
+ async function readCoverageSnapshot(db, scope) {
67
80
  const entityType = String(scope.entityType || "");
68
81
  if (!entityType) return null;
69
- const row = await fetchCoverageRow(knex, {
82
+ const row = await fetchCoverageRow(db, {
70
83
  entityType,
71
84
  tenantId: scope.tenantId ?? null,
72
85
  organizationId: scope.organizationId ?? null,
@@ -86,32 +99,32 @@ async function readCoverageSnapshot(knex, scope) {
86
99
  }
87
100
  async function applyCoverageAdjustments(em, adjustments) {
88
101
  if (!adjustments.length) return;
89
- const knex = em.getConnection().getKnex();
102
+ const db = em.getKysely();
90
103
  const aggregated = aggregateAdjustments(adjustments);
91
104
  for (const entry of aggregated) {
92
105
  const scope = entry.scope;
93
- const existing = await fetchCoverageRow(knex, scope);
106
+ const existing = await fetchCoverageRow(db, scope);
94
107
  const currentBase = existing ? toCount(existing.base_count) : 0;
95
108
  const currentIndex = existing ? toCount(existing.indexed_count) : 0;
96
109
  const currentVector = existing ? toCount(existing.vector_indexed_count) : 0;
97
110
  const nextBase = Math.max(currentBase + entry.deltaBase, 0);
98
111
  const nextIndex = Math.max(currentIndex + entry.deltaIndex, 0);
99
112
  const nextVector = Math.max(currentVector + entry.deltaVector, 0);
100
- await upsertCoverageRow(knex, scope, {
113
+ await upsertCoverageRow(db, scope, {
101
114
  baseCount: nextBase,
102
115
  indexedCount: nextIndex,
103
116
  vectorIndexedCount: nextVector
104
117
  });
105
118
  }
106
119
  }
107
- async function deleteCoverageForEntity(knex, entityType) {
120
+ async function deleteCoverageForEntity(db, entityType) {
108
121
  if (!entityType) return;
109
- await knex("entity_index_coverage").where({ entity_type: entityType }).del();
122
+ await db.deleteFrom("entity_index_coverage").where("entity_type", "=", entityType).execute();
110
123
  }
111
- async function tableHasColumn(knex, table, column) {
124
+ async function tableHasColumn(db, table, column) {
112
125
  const key = `${table}.${column}`;
113
126
  if (COLUMN_CACHE.has(key)) return COLUMN_CACHE.get(key);
114
- const exists = await knex("information_schema.columns").whereRaw("table_schema = current_schema()").where({ table_name: table, column_name: column }).first();
127
+ const exists = await db.selectFrom("information_schema.columns").select(sql`1`.as("present")).where(sql`table_schema = current_schema()`).where("table_name", "=", table).where("column_name", "=", column).executeTakeFirst();
115
128
  const present = !!exists;
116
129
  COLUMN_CACHE.set(key, present);
117
130
  return present;
@@ -122,34 +135,34 @@ async function refreshCoverageSnapshot(em, scope) {
122
135
  const tenantId = scope.tenantId ?? null;
123
136
  const organizationId = scope.organizationId ?? null;
124
137
  const withDeleted = scope.withDeleted === true;
125
- const knex = em.getConnection().getKnex();
138
+ const db = em.getKysely();
126
139
  const baseTable = resolveEntityTableName(em, entityType);
127
- const hasOrg = await tableHasColumn(knex, baseTable, "organization_id");
128
- const hasTenant = await tableHasColumn(knex, baseTable, "tenant_id");
129
- const hasDeleted = await tableHasColumn(knex, baseTable, "deleted_at");
140
+ const hasOrg = await tableHasColumn(db, baseTable, "organization_id");
141
+ const hasTenant = await tableHasColumn(db, baseTable, "tenant_id");
142
+ const hasDeleted = await tableHasColumn(db, baseTable, "deleted_at");
130
143
  if (organizationId !== null && !hasOrg) return;
131
144
  if (tenantId !== null && !hasTenant) return;
132
- let baseQuery = knex({ b: baseTable }).count({ count: "*" });
133
- if (organizationId !== null && hasOrg) baseQuery = baseQuery.where("b.organization_id", organizationId);
134
- if (tenantId !== null && hasTenant) baseQuery = baseQuery.where("b.tenant_id", tenantId);
135
- if (!withDeleted && hasDeleted) baseQuery = baseQuery.whereNull("b.deleted_at");
136
- const baseRow = await baseQuery.first();
145
+ let baseQuery = db.selectFrom(`${baseTable} as b`).select(sql`count(*)`.as("count"));
146
+ if (organizationId !== null && hasOrg) baseQuery = baseQuery.where("b.organization_id", "=", organizationId);
147
+ if (tenantId !== null && hasTenant) baseQuery = baseQuery.where("b.tenant_id", "=", tenantId);
148
+ if (!withDeleted && hasDeleted) baseQuery = baseQuery.where("b.deleted_at", "is", null);
149
+ const baseRow = await baseQuery.executeTakeFirst();
137
150
  const baseCount = toCount(baseRow?.count);
138
- let indexQuery = knex({ ei: "entity_indexes" }).count({ count: "*" }).where("ei.entity_type", entityType);
139
- if (organizationId !== null) indexQuery = indexQuery.where("ei.organization_id", organizationId);
140
- if (tenantId !== null) indexQuery = indexQuery.where("ei.tenant_id", tenantId);
141
- if (!withDeleted) indexQuery = indexQuery.whereNull("ei.deleted_at");
142
- const indexRow = await indexQuery.first();
151
+ let indexQuery = db.selectFrom("entity_indexes as ei").select(sql`count(*)`.as("count")).where("ei.entity_type", "=", entityType);
152
+ if (organizationId !== null) indexQuery = indexQuery.where("ei.organization_id", "=", organizationId);
153
+ if (tenantId !== null) indexQuery = indexQuery.where("ei.tenant_id", "=", tenantId);
154
+ if (!withDeleted) indexQuery = indexQuery.where("ei.deleted_at", "is", null);
155
+ const indexRow = await indexQuery.executeTakeFirst();
143
156
  const indexCount = toCount(indexRow?.count);
144
157
  let vectorCount;
145
- const hasVectorTable = await tableHasColumn(knex, "vector_search", "entity_id");
158
+ const hasVectorTable = await tableHasColumn(db, "vector_search", "entity_id");
146
159
  if (hasVectorTable && typeof tenantId === "string" && tenantId.length > 0) {
147
160
  try {
148
- let vectorQuery = knex("vector_search").count({ count: 1 }).where("entity_id", entityType).where("tenant_id", tenantId);
161
+ let vectorQuery = db.selectFrom("vector_search").select(sql`count(*)`.as("count")).where("entity_id", "=", entityType).where("tenant_id", "=", tenantId);
149
162
  if (organizationId !== null) {
150
- vectorQuery = vectorQuery.where("organization_id", organizationId);
163
+ vectorQuery = vectorQuery.where("organization_id", "=", organizationId);
151
164
  }
152
- const vectorRow = await vectorQuery.first();
165
+ const vectorRow = await vectorQuery.executeTakeFirst();
153
166
  vectorCount = toCount(vectorRow?.count);
154
167
  } catch (err) {
155
168
  console.warn("[query_index] Failed to resolve vector count for coverage snapshot", {
@@ -170,11 +183,11 @@ async function refreshCoverageSnapshot(em, scope) {
170
183
  async function writeCoverageCounts(em, scope, counts) {
171
184
  const entityType = String(scope.entityType || "");
172
185
  if (!entityType) return;
173
- const knex = em.getConnection().getKnex();
186
+ const db = em.getKysely();
174
187
  const tenantId = scope.tenantId ?? null;
175
188
  const organizationId = scope.organizationId ?? null;
176
189
  const withDeleted = scope.withDeleted === true;
177
- const existing = await fetchCoverageRow(knex, {
190
+ const existing = await fetchCoverageRow(db, {
178
191
  entityType,
179
192
  tenantId,
180
193
  organizationId,
@@ -183,7 +196,7 @@ async function writeCoverageCounts(em, scope, counts) {
183
196
  const baseCount = counts.baseCount !== void 0 ? Math.max(0, Math.trunc(toCount(counts.baseCount))) : Math.max(0, Math.trunc(toCount(existing?.base_count)));
184
197
  const indexCount = counts.indexedCount !== void 0 ? Math.max(0, Math.trunc(toCount(counts.indexedCount))) : Math.max(0, Math.trunc(toCount(existing?.indexed_count)));
185
198
  const vectorCount = counts.vectorCount !== void 0 ? Math.max(0, Math.trunc(toCount(counts.vectorCount))) : Math.max(0, Math.trunc(toCount(existing?.vector_indexed_count)));
186
- await upsertCoverageRow(knex, { entityType, tenantId, organizationId, withDeleted }, {
199
+ await upsertCoverageRow(db, { entityType, tenantId, organizationId, withDeleted }, {
187
200
  baseCount,
188
201
  indexedCount: indexCount,
189
202
  vectorIndexedCount: vectorCount
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/query_index/lib/coverage.ts"],
4
- "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { Knex } from 'knex'\nimport { resolveEntityTableName } from '@open-mercato/shared/lib/query/engine'\n\nexport type CoverageScope = {\n entityType: string\n tenantId?: string | null\n organizationId?: string | null\n withDeleted?: boolean\n}\n\ntype CoverageRow = {\n base_count: unknown\n indexed_count: unknown\n vector_indexed_count: unknown\n refreshed_at: Date | string | null\n}\n\nexport type CoverageAdjustment = {\n entityType: string\n tenantId: string | null\n organizationId: string | null\n withDeleted?: boolean\n deltaBase: number\n deltaIndex: number\n deltaVector?: number\n}\n\nexport type CoverageDeltaInput = {\n entityType: string\n tenantId: string | null\n organizationId: string | null\n withDeleted?: boolean\n baseDelta: number\n indexDelta: number\n vectorDelta?: number\n}\n\nconst COLUMN_CACHE = new Map<string, boolean>()\nconst GLOBAL_ORGANIZATION_PLACEHOLDER = '00000000-0000-0000-0000-000000000000'\nexport const COVERAGE_ORG_PLACEHOLDER = GLOBAL_ORGANIZATION_PLACEHOLDER\n\nfunction toCount(value: unknown): number {\n if (typeof value === 'number') return Number.isFinite(value) ? value : 0\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isFinite(parsed) ? parsed : 0\n }\n if (value != null && typeof (value as { valueOf: () => number }).valueOf === 'function') {\n const parsed = Number((value as { valueOf: () => number }).valueOf())\n return Number.isFinite(parsed) ? parsed : 0\n }\n return 0\n}\n\nfunction normalizeOrganizationForStore(orgId: string | null | undefined): string {\n return orgId ?? GLOBAL_ORGANIZATION_PLACEHOLDER\n}\n\nfunction applyOrganizationCondition(\n qb: Knex.QueryBuilder<any, any>,\n column: string,\n organizationId: string | null | undefined\n) {\n const stored = normalizeOrganizationForStore(organizationId ?? null)\n if (stored === GLOBAL_ORGANIZATION_PLACEHOLDER) {\n qb.andWhere((sub) => {\n sub.whereNull(column).orWhere(column, GLOBAL_ORGANIZATION_PLACEHOLDER)\n })\n } else {\n qb.andWhere(column, stored)\n }\n}\n\nasync function fetchCoverageRow(\n knex: Knex,\n scope: CoverageScope\n): Promise<(CoverageRow & { organization_id: string | null }) | null> {\n const { entityType, tenantId, organizationId, withDeleted } = scope\n const row = await knex('entity_index_coverage')\n .select(['base_count', 'indexed_count', 'vector_indexed_count', 'refreshed_at', 'organization_id'])\n .where('entity_type', entityType)\n .where('tenant_id', tenantId ?? null)\n .where('with_deleted', withDeleted === true)\n .modify((qb) => applyOrganizationCondition(qb, 'organization_id', organizationId ?? null))\n .orderBy('refreshed_at', 'desc')\n .first<CoverageRow & { organization_id: string | null }>()\n return row ?? null\n}\n\nasync function pruneDuplicateCoverageRows(\n knex: Knex,\n scope: CoverageScope,\n keepId: string | null\n) {\n const query = knex('entity_index_coverage')\n .where('entity_type', scope.entityType)\n .where('tenant_id', scope.tenantId ?? null)\n .where('with_deleted', scope.withDeleted === true)\n .modify((qb) => applyOrganizationCondition(qb, 'organization_id', scope.organizationId ?? null))\n if (keepId) {\n await query.andWhereNot('id', keepId).del()\n } else {\n await query.del()\n }\n}\n\nasync function upsertCoverageRow(\n knex: Knex,\n scope: CoverageScope,\n counts: { baseCount: number; indexedCount: number; vectorIndexedCount: number }\n) {\n const storedOrgId = normalizeOrganizationForStore(scope.organizationId ?? null)\n if (scope.organizationId == null) {\n await knex('entity_index_coverage')\n .where('entity_type', scope.entityType)\n .where('tenant_id', scope.tenantId ?? null)\n .where('with_deleted', scope.withDeleted === true)\n .whereNull('organization_id')\n .del()\n }\n\n const rows = await knex('entity_index_coverage')\n .insert({\n entity_type: scope.entityType,\n tenant_id: scope.tenantId ?? null,\n organization_id: storedOrgId,\n with_deleted: scope.withDeleted === true,\n base_count: counts.baseCount,\n indexed_count: counts.indexedCount,\n vector_indexed_count: counts.vectorIndexedCount,\n refreshed_at: knex.fn.now(),\n })\n .onConflict(['entity_type', 'tenant_id', 'organization_id', 'with_deleted'])\n .merge({\n base_count: counts.baseCount,\n indexed_count: counts.indexedCount,\n vector_indexed_count: counts.vectorIndexedCount,\n refreshed_at: knex.fn.now(),\n })\n .returning<{ id: string }[]>('id')\n\n const keepId = rows?.[0]?.id ?? null\n await pruneDuplicateCoverageRows(knex, scope, keepId)\n}\n\nexport async function readCoverageSnapshot(\n knex: Knex,\n scope: CoverageScope\n): Promise<(CoverageRow & { baseCount: number; indexedCount: number; vectorIndexedCount: number }) | null> {\n const entityType = String(scope.entityType || '')\n if (!entityType) return null\n const row = await fetchCoverageRow(knex, {\n entityType,\n tenantId: scope.tenantId ?? null,\n organizationId: scope.organizationId ?? null,\n withDeleted: scope.withDeleted === true,\n })\n if (!row) return null\n const refreshedAt = row.refreshed_at instanceof Date ? row.refreshed_at : (row.refreshed_at ? new Date(row.refreshed_at) : null)\n return {\n base_count: row.base_count,\n indexed_count: row.indexed_count,\n vector_indexed_count: row.vector_indexed_count,\n refreshed_at: refreshedAt ?? null,\n baseCount: toCount(row.base_count),\n indexedCount: toCount(row.indexed_count),\n vectorIndexedCount: toCount(row.vector_indexed_count),\n }\n}\n\nexport async function applyCoverageAdjustments(\n em: EntityManager,\n adjustments: CoverageAdjustment[]\n): Promise<void> {\n if (!adjustments.length) return\n const knex = (em as any).getConnection().getKnex() as Knex\n const aggregated = aggregateAdjustments(adjustments)\n for (const entry of aggregated) {\n const scope = entry.scope\n const existing = await fetchCoverageRow(knex, scope)\n const currentBase = existing ? toCount(existing.base_count) : 0\n const currentIndex = existing ? toCount(existing.indexed_count) : 0\n const currentVector = existing ? toCount(existing.vector_indexed_count) : 0\n const nextBase = Math.max(currentBase + entry.deltaBase, 0)\n const nextIndex = Math.max(currentIndex + entry.deltaIndex, 0)\n const nextVector = Math.max(currentVector + entry.deltaVector, 0)\n\n await upsertCoverageRow(knex, scope, {\n baseCount: nextBase,\n indexedCount: nextIndex,\n vectorIndexedCount: nextVector,\n })\n }\n}\n\nexport async function deleteCoverageForEntity(knex: Knex, entityType: string): Promise<void> {\n if (!entityType) return\n await knex('entity_index_coverage').where({ entity_type: entityType }).del()\n}\n\nasync function tableHasColumn(knex: Knex, table: string, column: string): Promise<boolean> {\n const key = `${table}.${column}`\n if (COLUMN_CACHE.has(key)) return COLUMN_CACHE.get(key)!\n const exists = await knex('information_schema.columns')\n .whereRaw('table_schema = current_schema()')\n .where({ table_name: table, column_name: column })\n .first()\n const present = !!exists\n COLUMN_CACHE.set(key, present)\n return present\n}\n\nexport async function refreshCoverageSnapshot(\n em: EntityManager,\n scope: CoverageScope,\n): Promise<void> {\n const entityType = String(scope.entityType || '')\n if (!entityType) return\n const tenantId = scope.tenantId ?? null\n const organizationId = scope.organizationId ?? null\n const withDeleted = scope.withDeleted === true\n\n const knex = (em as any).getConnection().getKnex() as Knex\n const baseTable = resolveEntityTableName(em, entityType)\n\n const hasOrg = await tableHasColumn(knex, baseTable, 'organization_id')\n const hasTenant = await tableHasColumn(knex, baseTable, 'tenant_id')\n const hasDeleted = await tableHasColumn(knex, baseTable, 'deleted_at')\n\n if (organizationId !== null && !hasOrg) return\n if (tenantId !== null && !hasTenant) return\n\n let baseQuery = knex({ b: baseTable }).count({ count: '*' })\n if (organizationId !== null && hasOrg) baseQuery = baseQuery.where('b.organization_id', organizationId)\n if (tenantId !== null && hasTenant) baseQuery = baseQuery.where('b.tenant_id', tenantId)\n if (!withDeleted && hasDeleted) baseQuery = baseQuery.whereNull('b.deleted_at')\n\n const baseRow = await baseQuery.first()\n const baseCount = toCount(baseRow?.count)\n\n let indexQuery = knex({ ei: 'entity_indexes' })\n .count({ count: '*' })\n .where('ei.entity_type', entityType)\n if (organizationId !== null) indexQuery = indexQuery.where('ei.organization_id', organizationId)\n if (tenantId !== null) indexQuery = indexQuery.where('ei.tenant_id', tenantId)\n if (!withDeleted) indexQuery = indexQuery.whereNull('ei.deleted_at')\n\n const indexRow = await indexQuery.first()\n const indexCount = toCount(indexRow?.count)\n\n // Count vector entries directly from database\n let vectorCount: number | undefined\n const hasVectorTable = await tableHasColumn(knex, 'vector_search', 'entity_id')\n if (hasVectorTable && typeof tenantId === 'string' && tenantId.length > 0) {\n try {\n let vectorQuery = knex('vector_search')\n .count({ count: 1 })\n .where('entity_id', entityType)\n .where('tenant_id', tenantId)\n if (organizationId !== null) {\n vectorQuery = vectorQuery.where('organization_id', organizationId)\n }\n const vectorRow = await vectorQuery.first()\n vectorCount = toCount(vectorRow?.count)\n } catch (err) {\n console.warn('[query_index] Failed to resolve vector count for coverage snapshot', {\n entityType,\n tenantId,\n organizationId,\n error: err instanceof Error ? err.message : err,\n })\n vectorCount = undefined\n }\n }\n\n await writeCoverageCounts(em, { entityType, tenantId, organizationId, withDeleted }, {\n baseCount,\n indexedCount: indexCount,\n vectorCount,\n })\n}\n\nexport async function writeCoverageCounts(\n em: EntityManager,\n scope: CoverageScope,\n counts: { baseCount?: number; indexedCount?: number; vectorCount?: number }\n): Promise<void> {\n const entityType = String(scope.entityType || '')\n if (!entityType) return\n const knex = (em as any).getConnection().getKnex() as Knex\n const tenantId = scope.tenantId ?? null\n const organizationId = scope.organizationId ?? null\n const withDeleted = scope.withDeleted === true\n const existing = await fetchCoverageRow(knex, {\n entityType,\n tenantId,\n organizationId,\n withDeleted,\n })\n const baseCount = counts.baseCount !== undefined\n ? Math.max(0, Math.trunc(toCount(counts.baseCount)))\n : Math.max(0, Math.trunc(toCount(existing?.base_count)))\n const indexCount = counts.indexedCount !== undefined\n ? Math.max(0, Math.trunc(toCount(counts.indexedCount)))\n : Math.max(0, Math.trunc(toCount(existing?.indexed_count)))\n const vectorCount = counts.vectorCount !== undefined\n ? Math.max(0, Math.trunc(toCount(counts.vectorCount)))\n : Math.max(0, Math.trunc(toCount(existing?.vector_indexed_count)))\n await upsertCoverageRow(knex, { entityType, tenantId, organizationId, withDeleted }, {\n baseCount,\n indexedCount: indexCount,\n vectorIndexedCount: vectorCount,\n })\n}\n\ntype AggregatedAdjustment = {\n scope: CoverageScope\n deltaBase: number\n deltaIndex: number\n deltaVector: number\n}\n\nfunction aggregateAdjustments(adjustments: CoverageAdjustment[]): AggregatedAdjustment[] {\n const map = new Map<string, AggregatedAdjustment>()\n for (const adj of adjustments) {\n if (!adj?.entityType) continue\n const deltaBase = Number.isFinite(adj.deltaBase) ? adj.deltaBase : 0\n const deltaIndex = Number.isFinite(adj.deltaIndex) ? adj.deltaIndex : 0\n const deltaVector = Number.isFinite(adj.deltaVector) ? adj.deltaVector! : 0\n if (deltaBase === 0 && deltaIndex === 0 && deltaVector === 0) continue\n const scope: CoverageScope = {\n entityType: adj.entityType,\n tenantId: adj.tenantId ?? null,\n organizationId: adj.organizationId ?? null,\n withDeleted: adj.withDeleted === true,\n }\n const key = scopeKey(scope)\n const existing = map.get(key)\n if (existing) {\n existing.deltaBase += deltaBase\n existing.deltaIndex += deltaIndex\n existing.deltaVector += deltaVector\n } else {\n map.set(key, { scope, deltaBase, deltaIndex, deltaVector })\n }\n }\n return Array.from(map.values())\n}\n\nfunction scopeKey(scope: CoverageScope): string {\n const tenant = scope.tenantId ?? '__tenant_null__'\n const org = normalizeOrganizationForStore(scope.organizationId ?? null)\n const deleted = scope.withDeleted === true ? '1' : '0'\n return `${scope.entityType}|${tenant}|${org}|${deleted}`\n}\n\nexport function createCoverageAdjustments(input: CoverageDeltaInput): CoverageAdjustment[] {\n const entityType = String(input.entityType || '')\n if (!entityType) return []\n const baseDelta = Number.isFinite(input.baseDelta) ? input.baseDelta : 0\n const indexDelta = Number.isFinite(input.indexDelta) ? input.indexDelta : 0\n const vectorDelta = Number.isFinite(input.vectorDelta) ? input.vectorDelta! : 0\n if (baseDelta === 0 && indexDelta === 0 && vectorDelta === 0) return []\n const withDeleted = input.withDeleted === true\n const tenantId = input.tenantId ?? null\n const organizationId = input.organizationId ?? null\n return [\n {\n entityType,\n tenantId,\n organizationId,\n withDeleted,\n deltaBase: baseDelta,\n deltaIndex: indexDelta,\n deltaVector: vectorDelta,\n },\n ]\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { type Kysely, sql } from 'kysely'\nimport { resolveEntityTableName } from '@open-mercato/shared/lib/query/engine'\n\nexport type CoverageScope = {\n entityType: string\n tenantId?: string | null\n organizationId?: string | null\n withDeleted?: boolean\n}\n\ntype CoverageRow = {\n base_count: unknown\n indexed_count: unknown\n vector_indexed_count: unknown\n refreshed_at: Date | string | null\n}\n\nexport type CoverageAdjustment = {\n entityType: string\n tenantId: string | null\n organizationId: string | null\n withDeleted?: boolean\n deltaBase: number\n deltaIndex: number\n deltaVector?: number\n}\n\nexport type CoverageDeltaInput = {\n entityType: string\n tenantId: string | null\n organizationId: string | null\n withDeleted?: boolean\n baseDelta: number\n indexDelta: number\n vectorDelta?: number\n}\n\nconst COLUMN_CACHE = new Map<string, boolean>()\nconst GLOBAL_ORGANIZATION_PLACEHOLDER = '00000000-0000-0000-0000-000000000000'\nexport const COVERAGE_ORG_PLACEHOLDER = GLOBAL_ORGANIZATION_PLACEHOLDER\n\nfunction toCount(value: unknown): number {\n if (typeof value === 'number') return Number.isFinite(value) ? value : 0\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isFinite(parsed) ? parsed : 0\n }\n if (value != null && typeof (value as { valueOf: () => number }).valueOf === 'function') {\n const parsed = Number((value as { valueOf: () => number }).valueOf())\n return Number.isFinite(parsed) ? parsed : 0\n }\n return 0\n}\n\nfunction normalizeOrganizationForStore(orgId: string | null | undefined): string {\n return orgId ?? GLOBAL_ORGANIZATION_PLACEHOLDER\n}\n\nfunction applyOrganizationCondition<QB extends { where: (...args: any[]) => QB }>(\n qb: QB,\n column: string,\n organizationId: string | null | undefined,\n): QB {\n const stored = normalizeOrganizationForStore(organizationId ?? null)\n if (stored === GLOBAL_ORGANIZATION_PLACEHOLDER) {\n return qb.where((eb: any) => eb.or([\n eb(column as any, 'is', null),\n eb(column as any, '=', GLOBAL_ORGANIZATION_PLACEHOLDER),\n ]))\n }\n return qb.where(column as any, '=', stored)\n}\n\nasync function fetchCoverageRow(\n db: Kysely<any>,\n scope: CoverageScope\n): Promise<(CoverageRow & { organization_id: string | null }) | null> {\n const { entityType, tenantId, organizationId, withDeleted } = scope\n let query = db\n .selectFrom('entity_index_coverage' as any)\n .select([\n 'base_count' as any,\n 'indexed_count' as any,\n 'vector_indexed_count' as any,\n 'refreshed_at' as any,\n 'organization_id' as any,\n ])\n .where('entity_type' as any, '=', entityType)\n .where('with_deleted' as any, '=', withDeleted === true)\n .orderBy('refreshed_at' as any, 'desc')\n query = tenantId == null\n ? query.where('tenant_id' as any, 'is', null as any)\n : query.where('tenant_id' as any, '=', tenantId)\n query = applyOrganizationCondition(query as any, 'organization_id', organizationId ?? null)\n const row = await query.executeTakeFirst() as (CoverageRow & { organization_id: string | null }) | undefined\n return row ?? null\n}\n\nasync function pruneDuplicateCoverageRows(\n db: Kysely<any>,\n scope: CoverageScope,\n keepId: string | null\n): Promise<void> {\n let query = db\n .deleteFrom('entity_index_coverage' as any)\n .where('entity_type' as any, '=', scope.entityType)\n .where('with_deleted' as any, '=', scope.withDeleted === true)\n query = scope.tenantId == null\n ? query.where('tenant_id' as any, 'is', null as any)\n : query.where('tenant_id' as any, '=', scope.tenantId)\n query = applyOrganizationCondition(query as any, 'organization_id', scope.organizationId ?? null)\n if (keepId) {\n query = query.where('id' as any, '!=', keepId)\n }\n await query.execute()\n}\n\nasync function upsertCoverageRow(\n db: Kysely<any>,\n scope: CoverageScope,\n counts: { baseCount: number; indexedCount: number; vectorIndexedCount: number }\n): Promise<void> {\n const storedOrgId = normalizeOrganizationForStore(scope.organizationId ?? null)\n if (scope.organizationId == null) {\n let purge = db\n .deleteFrom('entity_index_coverage' as any)\n .where('entity_type' as any, '=', scope.entityType)\n .where('with_deleted' as any, '=', scope.withDeleted === true)\n .where('organization_id' as any, 'is', null as any)\n purge = scope.tenantId == null\n ? purge.where('tenant_id' as any, 'is', null as any)\n : purge.where('tenant_id' as any, '=', scope.tenantId)\n await purge.execute()\n }\n\n const rows = await db\n .insertInto('entity_index_coverage' as any)\n .values({\n entity_type: scope.entityType,\n tenant_id: scope.tenantId ?? null,\n organization_id: storedOrgId,\n with_deleted: scope.withDeleted === true,\n base_count: counts.baseCount,\n indexed_count: counts.indexedCount,\n vector_indexed_count: counts.vectorIndexedCount,\n refreshed_at: sql`now()`,\n } as any)\n .onConflict((oc: any) => oc\n .columns(['entity_type', 'tenant_id', 'organization_id', 'with_deleted'])\n .doUpdateSet({\n base_count: counts.baseCount,\n indexed_count: counts.indexedCount,\n vector_indexed_count: counts.vectorIndexedCount,\n refreshed_at: sql`now()`,\n } as any))\n .returning(['id' as any])\n .execute() as Array<{ id: string }>\n\n const keepId = rows?.[0]?.id ?? null\n await pruneDuplicateCoverageRows(db, scope, keepId)\n}\n\nexport async function readCoverageSnapshot(\n db: Kysely<any>,\n scope: CoverageScope\n): Promise<(CoverageRow & { baseCount: number; indexedCount: number; vectorIndexedCount: number }) | null> {\n const entityType = String(scope.entityType || '')\n if (!entityType) return null\n const row = await fetchCoverageRow(db, {\n entityType,\n tenantId: scope.tenantId ?? null,\n organizationId: scope.organizationId ?? null,\n withDeleted: scope.withDeleted === true,\n })\n if (!row) return null\n const refreshedAt = row.refreshed_at instanceof Date ? row.refreshed_at : (row.refreshed_at ? new Date(row.refreshed_at) : null)\n return {\n base_count: row.base_count,\n indexed_count: row.indexed_count,\n vector_indexed_count: row.vector_indexed_count,\n refreshed_at: refreshedAt ?? null,\n baseCount: toCount(row.base_count),\n indexedCount: toCount(row.indexed_count),\n vectorIndexedCount: toCount(row.vector_indexed_count),\n }\n}\n\nexport async function applyCoverageAdjustments(\n em: EntityManager,\n adjustments: CoverageAdjustment[]\n): Promise<void> {\n if (!adjustments.length) return\n const db = (em as any).getKysely() as Kysely<any>\n const aggregated = aggregateAdjustments(adjustments)\n for (const entry of aggregated) {\n const scope = entry.scope\n const existing = await fetchCoverageRow(db, scope)\n const currentBase = existing ? toCount(existing.base_count) : 0\n const currentIndex = existing ? toCount(existing.indexed_count) : 0\n const currentVector = existing ? toCount(existing.vector_indexed_count) : 0\n const nextBase = Math.max(currentBase + entry.deltaBase, 0)\n const nextIndex = Math.max(currentIndex + entry.deltaIndex, 0)\n const nextVector = Math.max(currentVector + entry.deltaVector, 0)\n\n await upsertCoverageRow(db, scope, {\n baseCount: nextBase,\n indexedCount: nextIndex,\n vectorIndexedCount: nextVector,\n })\n }\n}\n\nexport async function deleteCoverageForEntity(db: Kysely<any>, entityType: string): Promise<void> {\n if (!entityType) return\n await db\n .deleteFrom('entity_index_coverage' as any)\n .where('entity_type' as any, '=', entityType)\n .execute()\n}\n\nasync function tableHasColumn(db: Kysely<any>, table: string, column: string): Promise<boolean> {\n const key = `${table}.${column}`\n if (COLUMN_CACHE.has(key)) return COLUMN_CACHE.get(key)!\n const exists = await db\n .selectFrom('information_schema.columns' as any)\n .select(sql<number>`1`.as('present'))\n .where(sql<boolean>`table_schema = current_schema()`)\n .where('table_name' as any, '=', table)\n .where('column_name' as any, '=', column)\n .executeTakeFirst()\n const present = !!exists\n COLUMN_CACHE.set(key, present)\n return present\n}\n\nexport async function refreshCoverageSnapshot(\n em: EntityManager,\n scope: CoverageScope,\n): Promise<void> {\n const entityType = String(scope.entityType || '')\n if (!entityType) return\n const tenantId = scope.tenantId ?? null\n const organizationId = scope.organizationId ?? null\n const withDeleted = scope.withDeleted === true\n\n const db = (em as any).getKysely() as Kysely<any>\n const baseTable = resolveEntityTableName(em, entityType)\n\n const hasOrg = await tableHasColumn(db, baseTable, 'organization_id')\n const hasTenant = await tableHasColumn(db, baseTable, 'tenant_id')\n const hasDeleted = await tableHasColumn(db, baseTable, 'deleted_at')\n\n if (organizationId !== null && !hasOrg) return\n if (tenantId !== null && !hasTenant) return\n\n let baseQuery = db\n .selectFrom(`${baseTable} as b` as any)\n .select(sql`count(*)`.as('count'))\n if (organizationId !== null && hasOrg) baseQuery = baseQuery.where('b.organization_id' as any, '=', organizationId)\n if (tenantId !== null && hasTenant) baseQuery = baseQuery.where('b.tenant_id' as any, '=', tenantId)\n if (!withDeleted && hasDeleted) baseQuery = baseQuery.where('b.deleted_at' as any, 'is', null as any)\n\n const baseRow = await baseQuery.executeTakeFirst() as { count: unknown } | undefined\n const baseCount = toCount(baseRow?.count)\n\n let indexQuery = db\n .selectFrom('entity_indexes as ei' as any)\n .select(sql`count(*)`.as('count'))\n .where('ei.entity_type' as any, '=', entityType)\n if (organizationId !== null) indexQuery = indexQuery.where('ei.organization_id' as any, '=', organizationId)\n if (tenantId !== null) indexQuery = indexQuery.where('ei.tenant_id' as any, '=', tenantId)\n if (!withDeleted) indexQuery = indexQuery.where('ei.deleted_at' as any, 'is', null as any)\n\n const indexRow = await indexQuery.executeTakeFirst() as { count: unknown } | undefined\n const indexCount = toCount(indexRow?.count)\n\n // Count vector entries directly from database\n let vectorCount: number | undefined\n const hasVectorTable = await tableHasColumn(db, 'vector_search', 'entity_id')\n if (hasVectorTable && typeof tenantId === 'string' && tenantId.length > 0) {\n try {\n let vectorQuery = db\n .selectFrom('vector_search' as any)\n .select(sql`count(*)`.as('count'))\n .where('entity_id' as any, '=', entityType)\n .where('tenant_id' as any, '=', tenantId)\n if (organizationId !== null) {\n vectorQuery = vectorQuery.where('organization_id' as any, '=', organizationId)\n }\n const vectorRow = await vectorQuery.executeTakeFirst() as { count: unknown } | undefined\n vectorCount = toCount(vectorRow?.count)\n } catch (err) {\n console.warn('[query_index] Failed to resolve vector count for coverage snapshot', {\n entityType,\n tenantId,\n organizationId,\n error: err instanceof Error ? err.message : err,\n })\n vectorCount = undefined\n }\n }\n\n await writeCoverageCounts(em, { entityType, tenantId, organizationId, withDeleted }, {\n baseCount,\n indexedCount: indexCount,\n vectorCount,\n })\n}\n\nexport async function writeCoverageCounts(\n em: EntityManager,\n scope: CoverageScope,\n counts: { baseCount?: number; indexedCount?: number; vectorCount?: number }\n): Promise<void> {\n const entityType = String(scope.entityType || '')\n if (!entityType) return\n const db = (em as any).getKysely() as Kysely<any>\n const tenantId = scope.tenantId ?? null\n const organizationId = scope.organizationId ?? null\n const withDeleted = scope.withDeleted === true\n const existing = await fetchCoverageRow(db, {\n entityType,\n tenantId,\n organizationId,\n withDeleted,\n })\n const baseCount = counts.baseCount !== undefined\n ? Math.max(0, Math.trunc(toCount(counts.baseCount)))\n : Math.max(0, Math.trunc(toCount(existing?.base_count)))\n const indexCount = counts.indexedCount !== undefined\n ? Math.max(0, Math.trunc(toCount(counts.indexedCount)))\n : Math.max(0, Math.trunc(toCount(existing?.indexed_count)))\n const vectorCount = counts.vectorCount !== undefined\n ? Math.max(0, Math.trunc(toCount(counts.vectorCount)))\n : Math.max(0, Math.trunc(toCount(existing?.vector_indexed_count)))\n await upsertCoverageRow(db, { entityType, tenantId, organizationId, withDeleted }, {\n baseCount,\n indexedCount: indexCount,\n vectorIndexedCount: vectorCount,\n })\n}\n\ntype AggregatedAdjustment = {\n scope: CoverageScope\n deltaBase: number\n deltaIndex: number\n deltaVector: number\n}\n\nfunction aggregateAdjustments(adjustments: CoverageAdjustment[]): AggregatedAdjustment[] {\n const map = new Map<string, AggregatedAdjustment>()\n for (const adj of adjustments) {\n if (!adj?.entityType) continue\n const deltaBase = Number.isFinite(adj.deltaBase) ? adj.deltaBase : 0\n const deltaIndex = Number.isFinite(adj.deltaIndex) ? adj.deltaIndex : 0\n const deltaVector = Number.isFinite(adj.deltaVector) ? adj.deltaVector! : 0\n if (deltaBase === 0 && deltaIndex === 0 && deltaVector === 0) continue\n const scope: CoverageScope = {\n entityType: adj.entityType,\n tenantId: adj.tenantId ?? null,\n organizationId: adj.organizationId ?? null,\n withDeleted: adj.withDeleted === true,\n }\n const key = scopeKey(scope)\n const existing = map.get(key)\n if (existing) {\n existing.deltaBase += deltaBase\n existing.deltaIndex += deltaIndex\n existing.deltaVector += deltaVector\n } else {\n map.set(key, { scope, deltaBase, deltaIndex, deltaVector })\n }\n }\n return Array.from(map.values())\n}\n\nfunction scopeKey(scope: CoverageScope): string {\n const tenant = scope.tenantId ?? '__tenant_null__'\n const org = normalizeOrganizationForStore(scope.organizationId ?? null)\n const deleted = scope.withDeleted === true ? '1' : '0'\n return `${scope.entityType}|${tenant}|${org}|${deleted}`\n}\n\nexport function createCoverageAdjustments(input: CoverageDeltaInput): CoverageAdjustment[] {\n const entityType = String(input.entityType || '')\n if (!entityType) return []\n const baseDelta = Number.isFinite(input.baseDelta) ? input.baseDelta : 0\n const indexDelta = Number.isFinite(input.indexDelta) ? input.indexDelta : 0\n const vectorDelta = Number.isFinite(input.vectorDelta) ? input.vectorDelta! : 0\n if (baseDelta === 0 && indexDelta === 0 && vectorDelta === 0) return []\n const withDeleted = input.withDeleted === true\n const tenantId = input.tenantId ?? null\n const organizationId = input.organizationId ?? null\n return [\n {\n entityType,\n tenantId,\n organizationId,\n withDeleted,\n deltaBase: baseDelta,\n deltaIndex: indexDelta,\n deltaVector: vectorDelta,\n },\n ]\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }