@open-mercato/core 0.5.1-develop.2663.2c29774b5b → 0.5.1-develop.2681.c559bb2bc3

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 (687) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/generated/entities/action_log/index.js +8 -0
  3. package/dist/generated/entities/action_log/index.js.map +2 -2
  4. package/dist/generated/entities/customer_company_billing/index.js +23 -0
  5. package/dist/generated/entities/customer_company_billing/index.js.map +7 -0
  6. package/dist/generated/entities/customer_deal/index.js +8 -0
  7. package/dist/generated/entities/customer_deal/index.js.map +2 -2
  8. package/dist/generated/entities/customer_deal_stage_transition/index.js +31 -0
  9. package/dist/generated/entities/customer_deal_stage_transition/index.js.map +7 -0
  10. package/dist/generated/entities/customer_dictionary_kind_setting/index.js +21 -0
  11. package/dist/generated/entities/customer_dictionary_kind_setting/index.js.map +7 -0
  12. package/dist/generated/entities/customer_entity/index.js +8 -0
  13. package/dist/generated/entities/customer_entity/index.js.map +2 -2
  14. package/dist/generated/entities/customer_entity_role/index.js +23 -0
  15. package/dist/generated/entities/customer_entity_role/index.js.map +7 -0
  16. package/dist/generated/entities/customer_interaction/index.js +23 -1
  17. package/dist/generated/entities/customer_interaction/index.js.map +2 -2
  18. package/dist/generated/entities/customer_label/index.js +19 -0
  19. package/dist/generated/entities/customer_label/index.js.map +7 -0
  20. package/dist/generated/entities/customer_label_assignment/index.js +17 -0
  21. package/dist/generated/entities/customer_label_assignment/index.js.map +7 -0
  22. package/dist/generated/entities/customer_person_company_link/index.js +21 -0
  23. package/dist/generated/entities/customer_person_company_link/index.js.map +7 -0
  24. package/dist/generated/entities/customer_person_company_role/index.js +17 -0
  25. package/dist/generated/entities/customer_person_company_role/index.js.map +7 -0
  26. package/dist/generated/entities/dictionary_entry/index.js +4 -0
  27. package/dist/generated/entities/dictionary_entry/index.js.map +2 -2
  28. package/dist/generated/entities.ids.generated.js +9 -1
  29. package/dist/generated/entities.ids.generated.js.map +2 -2
  30. package/dist/generated/entity-fields-registry.js +116 -1
  31. package/dist/generated/entity-fields-registry.js.map +2 -2
  32. package/dist/modules/attachments/api/route.js +46 -8
  33. package/dist/modules/attachments/api/route.js.map +2 -2
  34. package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js +208 -0
  35. package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js.map +7 -0
  36. package/dist/modules/audit_logs/api/audit-logs/actions/route.js +52 -6
  37. package/dist/modules/audit_logs/api/audit-logs/actions/route.js.map +2 -2
  38. package/dist/modules/audit_logs/cli.js +62 -0
  39. package/dist/modules/audit_logs/cli.js.map +7 -0
  40. package/dist/modules/audit_logs/data/entities.js +21 -1
  41. package/dist/modules/audit_logs/data/entities.js.map +2 -2
  42. package/dist/modules/audit_logs/data/validators.js +9 -1
  43. package/dist/modules/audit_logs/data/validators.js.map +2 -2
  44. package/dist/modules/audit_logs/lib/changeRows.js +34 -0
  45. package/dist/modules/audit_logs/lib/changeRows.js.map +7 -0
  46. package/dist/modules/audit_logs/lib/display-helpers.js +2 -20
  47. package/dist/modules/audit_logs/lib/display-helpers.js.map +3 -3
  48. package/dist/modules/audit_logs/lib/projections.js +58 -0
  49. package/dist/modules/audit_logs/lib/projections.js.map +7 -0
  50. package/dist/modules/audit_logs/migrations/Migration20260412160533.js +21 -0
  51. package/dist/modules/audit_logs/migrations/Migration20260412160533.js.map +7 -0
  52. package/dist/modules/audit_logs/services/actionLogService.js +313 -79
  53. package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
  54. package/dist/modules/customers/acl.js +3 -1
  55. package/dist/modules/customers/acl.js.map +2 -2
  56. package/dist/modules/customers/api/activities/route.js +4 -0
  57. package/dist/modules/customers/api/activities/route.js.map +2 -2
  58. package/dist/modules/customers/api/assignable-staff/route.js +208 -0
  59. package/dist/modules/customers/api/assignable-staff/route.js.map +7 -0
  60. package/dist/modules/customers/api/companies/[id]/people/route.js +205 -0
  61. package/dist/modules/customers/api/companies/[id]/people/route.js.map +7 -0
  62. package/dist/modules/customers/api/companies/[id]/roles/route.js +22 -0
  63. package/dist/modules/customers/api/companies/[id]/roles/route.js.map +7 -0
  64. package/dist/modules/customers/api/companies/[id]/route.js +374 -32
  65. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  66. package/dist/modules/customers/api/companies/route.js +82 -7
  67. package/dist/modules/customers/api/companies/route.js.map +2 -2
  68. package/dist/modules/customers/api/deals/[id]/companies/route.js +172 -0
  69. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +7 -0
  70. package/dist/modules/customers/api/deals/[id]/people/route.js +156 -0
  71. package/dist/modules/customers/api/deals/[id]/people/route.js.map +7 -0
  72. package/dist/modules/customers/api/deals/[id]/route.js +459 -53
  73. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  74. package/dist/modules/customers/api/deals/[id]/stats/route.js +195 -0
  75. package/dist/modules/customers/api/deals/[id]/stats/route.js.map +7 -0
  76. package/dist/modules/customers/api/deals/route.js +20 -10
  77. package/dist/modules/customers/api/deals/route.js.map +3 -3
  78. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +105 -4
  79. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
  80. package/dist/modules/customers/api/dictionaries/[kind]/route.js +118 -42
  81. package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
  82. package/dist/modules/customers/api/dictionaries/context.js +30 -6
  83. package/dist/modules/customers/api/dictionaries/context.js.map +2 -2
  84. package/dist/modules/customers/api/dictionaries/kind-settings/route.js +207 -0
  85. package/dist/modules/customers/api/dictionaries/kind-settings/route.js.map +7 -0
  86. package/dist/modules/customers/api/entity-roles-factory.js +471 -0
  87. package/dist/modules/customers/api/entity-roles-factory.js.map +7 -0
  88. package/dist/modules/customers/api/interactions/conflicts/route.js +158 -0
  89. package/dist/modules/customers/api/interactions/conflicts/route.js.map +7 -0
  90. package/dist/modules/customers/api/interactions/counts/route.js +92 -0
  91. package/dist/modules/customers/api/interactions/counts/route.js.map +7 -0
  92. package/dist/modules/customers/api/interactions/route.js +83 -4
  93. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  94. package/dist/modules/customers/api/labels/assign/route.js +189 -0
  95. package/dist/modules/customers/api/labels/assign/route.js.map +7 -0
  96. package/dist/modules/customers/api/labels/auth.js +17 -0
  97. package/dist/modules/customers/api/labels/auth.js.map +7 -0
  98. package/dist/modules/customers/api/labels/route.js +281 -0
  99. package/dist/modules/customers/api/labels/route.js.map +7 -0
  100. package/dist/modules/customers/api/labels/table-errors.js +38 -0
  101. package/dist/modules/customers/api/labels/table-errors.js.map +7 -0
  102. package/dist/modules/customers/api/labels/unassign/route.js +184 -0
  103. package/dist/modules/customers/api/labels/unassign/route.js.map +7 -0
  104. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +292 -0
  105. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +7 -0
  106. package/dist/modules/customers/api/people/[id]/companies/context.js +66 -0
  107. package/dist/modules/customers/api/people/[id]/companies/context.js.map +7 -0
  108. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +334 -0
  109. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +7 -0
  110. package/dist/modules/customers/api/people/[id]/companies/route.js +205 -0
  111. package/dist/modules/customers/api/people/[id]/companies/route.js.map +7 -0
  112. package/dist/modules/customers/api/people/[id]/roles/route.js +22 -0
  113. package/dist/modules/customers/api/people/[id]/roles/route.js.map +7 -0
  114. package/dist/modules/customers/api/people/[id]/route.js +134 -21
  115. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  116. package/dist/modules/customers/api/people/route.js +122 -23
  117. package/dist/modules/customers/api/people/route.js.map +2 -2
  118. package/dist/modules/customers/api/todos/route.js +4 -0
  119. package/dist/modules/customers/api/todos/route.js.map +2 -2
  120. package/dist/modules/customers/api/utils.js +22 -0
  121. package/dist/modules/customers/api/utils.js.map +2 -2
  122. package/dist/modules/customers/backend/config/customers/page.js +2 -6
  123. package/dist/modules/customers/backend/config/customers/page.js.map +2 -2
  124. package/dist/modules/customers/backend/customers/companies/page.js +37 -26
  125. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  126. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +265 -262
  127. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +3 -3
  128. package/dist/modules/customers/backend/customers/deals/[id]/hooks/formatters.js +23 -0
  129. package/dist/modules/customers/backend/customers/deals/[id]/hooks/formatters.js.map +7 -0
  130. package/dist/modules/customers/backend/customers/deals/[id]/hooks/types.js +1 -0
  131. package/dist/modules/customers/backend/customers/deals/[id]/hooks/types.js.map +7 -0
  132. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +43 -0
  133. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +7 -0
  134. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js +264 -0
  135. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js.map +7 -0
  136. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js +88 -0
  137. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js.map +7 -0
  138. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js +41 -0
  139. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js.map +7 -0
  140. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +66 -0
  141. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +7 -0
  142. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js +39 -0
  143. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js.map +7 -0
  144. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.js +49 -0
  145. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.js.map +7 -0
  146. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js +43 -0
  147. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js.map +7 -0
  148. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.js +28 -0
  149. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.js.map +7 -0
  150. package/dist/modules/customers/backend/customers/deals/[id]/page.js +556 -503
  151. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +3 -3
  152. package/dist/modules/customers/backend/customers/deals/page.js +66 -21
  153. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  154. package/dist/modules/customers/backend/customers/people/page.js +36 -28
  155. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  156. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +318 -203
  157. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +3 -3
  158. package/dist/modules/customers/cli.js +105 -13
  159. package/dist/modules/customers/cli.js.map +2 -2
  160. package/dist/modules/customers/commands/activities.js +6 -0
  161. package/dist/modules/customers/commands/activities.js.map +2 -2
  162. package/dist/modules/customers/commands/deals.js +315 -107
  163. package/dist/modules/customers/commands/deals.js.map +2 -2
  164. package/dist/modules/customers/commands/dictionaries.js +166 -32
  165. package/dist/modules/customers/commands/dictionaries.js.map +2 -2
  166. package/dist/modules/customers/commands/dictionaryKindSettings.js +208 -0
  167. package/dist/modules/customers/commands/dictionaryKindSettings.js.map +7 -0
  168. package/dist/modules/customers/commands/entity-roles.js +415 -0
  169. package/dist/modules/customers/commands/entity-roles.js.map +7 -0
  170. package/dist/modules/customers/commands/index.js +4 -0
  171. package/dist/modules/customers/commands/index.js.map +2 -2
  172. package/dist/modules/customers/commands/interactions.js +108 -21
  173. package/dist/modules/customers/commands/interactions.js.map +2 -2
  174. package/dist/modules/customers/commands/labels.js +539 -0
  175. package/dist/modules/customers/commands/labels.js.map +7 -0
  176. package/dist/modules/customers/commands/people.js +560 -463
  177. package/dist/modules/customers/commands/people.js.map +3 -3
  178. package/dist/modules/customers/commands/personCompanyLinks.js +568 -0
  179. package/dist/modules/customers/commands/personCompanyLinks.js.map +7 -0
  180. package/dist/modules/customers/commands/shared.js +12 -4
  181. package/dist/modules/customers/commands/shared.js.map +2 -2
  182. package/dist/modules/customers/commands/todos.js +10 -1
  183. package/dist/modules/customers/commands/todos.js.map +2 -2
  184. package/dist/modules/customers/components/AddressEditor.js +1 -1
  185. package/dist/modules/customers/components/AddressEditor.js.map +2 -2
  186. package/dist/modules/customers/components/CustomersConfigurationSections.js +31 -0
  187. package/dist/modules/customers/components/CustomersConfigurationSections.js.map +7 -0
  188. package/dist/modules/customers/components/DictionarySettings.js +37 -2
  189. package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
  190. package/dist/modules/customers/components/detail/ActiveDealCard.js +121 -0
  191. package/dist/modules/customers/components/detail/ActiveDealCard.js.map +7 -0
  192. package/dist/modules/customers/components/detail/ActivitiesSection.js +222 -331
  193. package/dist/modules/customers/components/detail/ActivitiesSection.js.map +3 -3
  194. package/dist/modules/customers/components/detail/ActivityAiActions.js +36 -0
  195. package/dist/modules/customers/components/detail/ActivityAiActions.js.map +7 -0
  196. package/dist/modules/customers/components/detail/ActivityCard.js +126 -0
  197. package/dist/modules/customers/components/detail/ActivityCard.js.map +7 -0
  198. package/dist/modules/customers/components/detail/ActivityHistorySection.js +340 -0
  199. package/dist/modules/customers/components/detail/ActivityHistorySection.js.map +7 -0
  200. package/dist/modules/customers/components/detail/ActivityLogTab.js +56 -0
  201. package/dist/modules/customers/components/detail/ActivityLogTab.js.map +7 -0
  202. package/dist/modules/customers/components/detail/ActivityTimeline.js +108 -0
  203. package/dist/modules/customers/components/detail/ActivityTimeline.js.map +7 -0
  204. package/dist/modules/customers/components/detail/ActivityTimelineFilters.js +139 -0
  205. package/dist/modules/customers/components/detail/ActivityTimelineFilters.js.map +7 -0
  206. package/dist/modules/customers/components/detail/ActivityTypeSelector.js +42 -0
  207. package/dist/modules/customers/components/detail/ActivityTypeSelector.js.map +7 -0
  208. package/dist/modules/customers/components/detail/AiActionChips.js +38 -0
  209. package/dist/modules/customers/components/detail/AiActionChips.js.map +7 -0
  210. package/dist/modules/customers/components/detail/AssignRoleDialog.js +534 -0
  211. package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +7 -0
  212. package/dist/modules/customers/components/detail/ChangelogEntryRow.js +79 -0
  213. package/dist/modules/customers/components/detail/ChangelogEntryRow.js.map +7 -0
  214. package/dist/modules/customers/components/detail/ChangelogFilters.js +176 -0
  215. package/dist/modules/customers/components/detail/ChangelogFilters.js.map +7 -0
  216. package/dist/modules/customers/components/detail/ChangelogKpiCards.js +88 -0
  217. package/dist/modules/customers/components/detail/ChangelogKpiCards.js.map +7 -0
  218. package/dist/modules/customers/components/detail/ChangelogTab.js +470 -0
  219. package/dist/modules/customers/components/detail/ChangelogTab.js.map +7 -0
  220. package/dist/modules/customers/components/detail/ComingSoonPlaceholder.js +16 -0
  221. package/dist/modules/customers/components/detail/ComingSoonPlaceholder.js.map +7 -0
  222. package/dist/modules/customers/components/detail/CompanyCard.js +283 -0
  223. package/dist/modules/customers/components/detail/CompanyCard.js.map +7 -0
  224. package/dist/modules/customers/components/detail/CompanyDashboardTab.js +133 -0
  225. package/dist/modules/customers/components/detail/CompanyDashboardTab.js.map +7 -0
  226. package/dist/modules/customers/components/detail/CompanyDetailHeader.js +191 -0
  227. package/dist/modules/customers/components/detail/CompanyDetailHeader.js.map +7 -0
  228. package/dist/modules/customers/components/detail/CompanyDetailTabs.js +123 -0
  229. package/dist/modules/customers/components/detail/CompanyDetailTabs.js.map +7 -0
  230. package/dist/modules/customers/components/detail/CompanyKpiBar.js +174 -0
  231. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +7 -0
  232. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +514 -230
  233. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  234. package/dist/modules/customers/components/detail/CompanyTagsDialog.js +22 -0
  235. package/dist/modules/customers/components/detail/CompanyTagsDialog.js.map +7 -0
  236. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +159 -0
  237. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +7 -0
  238. package/dist/modules/customers/components/detail/CreatePersonDialog.js +135 -0
  239. package/dist/modules/customers/components/detail/CreatePersonDialog.js.map +7 -0
  240. package/dist/modules/customers/components/detail/DealClosureActionBar.js +59 -0
  241. package/dist/modules/customers/components/detail/DealClosureActionBar.js.map +7 -0
  242. package/dist/modules/customers/components/detail/DealDetailHeader.js +237 -0
  243. package/dist/modules/customers/components/detail/DealDetailHeader.js.map +7 -0
  244. package/dist/modules/customers/components/detail/DealDetailTabs.js +109 -0
  245. package/dist/modules/customers/components/detail/DealDetailTabs.js.map +7 -0
  246. package/dist/modules/customers/components/detail/DealForm.js +219 -92
  247. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  248. package/dist/modules/customers/components/detail/DealLinkedEntitiesTab.js +295 -0
  249. package/dist/modules/customers/components/detail/DealLinkedEntitiesTab.js.map +7 -0
  250. package/dist/modules/customers/components/detail/DealLostSummaryDialog.js +107 -0
  251. package/dist/modules/customers/components/detail/DealLostSummaryDialog.js.map +7 -0
  252. package/dist/modules/customers/components/detail/DealWonPopup.js +113 -0
  253. package/dist/modules/customers/components/detail/DealWonPopup.js.map +7 -0
  254. package/dist/modules/customers/components/detail/DealsSection.js +206 -193
  255. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  256. package/dist/modules/customers/components/detail/DecisionMakersFooter.js +39 -0
  257. package/dist/modules/customers/components/detail/DecisionMakersFooter.js.map +7 -0
  258. package/dist/modules/customers/components/detail/EntityTagsDialog.js +1096 -0
  259. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +7 -0
  260. package/dist/modules/customers/components/detail/InlineActivityComposer.js +197 -0
  261. package/dist/modules/customers/components/detail/InlineActivityComposer.js.map +7 -0
  262. package/dist/modules/customers/components/detail/ManageTagsDialog.js +1091 -0
  263. package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +7 -0
  264. package/dist/modules/customers/components/detail/MiniWeekCalendar.js +272 -0
  265. package/dist/modules/customers/components/detail/MiniWeekCalendar.js.map +7 -0
  266. package/dist/modules/customers/components/detail/MobilePersonDetail.js +106 -0
  267. package/dist/modules/customers/components/detail/MobilePersonDetail.js.map +7 -0
  268. package/dist/modules/customers/components/detail/NextStepCard.js +72 -0
  269. package/dist/modules/customers/components/detail/NextStepCard.js.map +7 -0
  270. package/dist/modules/customers/components/detail/PersonCard.js +192 -0
  271. package/dist/modules/customers/components/detail/PersonCard.js.map +7 -0
  272. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +345 -0
  273. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +7 -0
  274. package/dist/modules/customers/components/detail/PersonDetailHeader.js +220 -0
  275. package/dist/modules/customers/components/detail/PersonDetailHeader.js.map +7 -0
  276. package/dist/modules/customers/components/detail/PersonDetailTabs.js +122 -0
  277. package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +7 -0
  278. package/dist/modules/customers/components/detail/PersonTagsDialog.js +24 -0
  279. package/dist/modules/customers/components/detail/PersonTagsDialog.js.map +7 -0
  280. package/dist/modules/customers/components/detail/PipelineStepper.js +191 -0
  281. package/dist/modules/customers/components/detail/PipelineStepper.js.map +7 -0
  282. package/dist/modules/customers/components/detail/PlannedActivitiesSection.js +222 -0
  283. package/dist/modules/customers/components/detail/PlannedActivitiesSection.js.map +7 -0
  284. package/dist/modules/customers/components/detail/RelationshipHealthCard.js +49 -0
  285. package/dist/modules/customers/components/detail/RelationshipHealthCard.js.map +7 -0
  286. package/dist/modules/customers/components/detail/RoleAssignmentRow.js +189 -0
  287. package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +7 -0
  288. package/dist/modules/customers/components/detail/RolesSection.js +234 -0
  289. package/dist/modules/customers/components/detail/RolesSection.js.map +7 -0
  290. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +410 -0
  291. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +7 -0
  292. package/dist/modules/customers/components/detail/aiActionCatalog.js +41 -0
  293. package/dist/modules/customers/components/detail/aiActionCatalog.js.map +7 -0
  294. package/dist/modules/customers/components/detail/assignableStaff.js +48 -0
  295. package/dist/modules/customers/components/detail/assignableStaff.js.map +7 -0
  296. package/dist/modules/customers/components/detail/dashboard/ActiveDealWidget.js +48 -0
  297. package/dist/modules/customers/components/detail/dashboard/ActiveDealWidget.js.map +7 -0
  298. package/dist/modules/customers/components/detail/dashboard/OpenTasksWidget.js +86 -0
  299. package/dist/modules/customers/components/detail/dashboard/OpenTasksWidget.js.map +7 -0
  300. package/dist/modules/customers/components/detail/dashboard/RecentActivityWidget.js +53 -0
  301. package/dist/modules/customers/components/detail/dashboard/RecentActivityWidget.js.map +7 -0
  302. package/dist/modules/customers/components/detail/dashboard/RelationshipHealthWidget.js +30 -0
  303. package/dist/modules/customers/components/detail/dashboard/RelationshipHealthWidget.js.map +7 -0
  304. package/dist/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.js +43 -0
  305. package/dist/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.js.map +7 -0
  306. package/dist/modules/customers/components/detail/dashboard/helpers.js +71 -0
  307. package/dist/modules/customers/components/detail/dashboard/helpers.js.map +7 -0
  308. package/dist/modules/customers/components/detail/healthScoreUtils.js +69 -0
  309. package/dist/modules/customers/components/detail/healthScoreUtils.js.map +7 -0
  310. package/dist/modules/customers/components/detail/hooks/useCurrencyDictionary.js +5 -5
  311. package/dist/modules/customers/components/detail/hooks/useCurrencyDictionary.js.map +2 -2
  312. package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js +9 -8
  313. package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js.map +3 -3
  314. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +65 -0
  315. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +7 -0
  316. package/dist/modules/customers/components/detail/notesAdapter.js +70 -30
  317. package/dist/modules/customers/components/detail/notesAdapter.js.map +2 -2
  318. package/dist/modules/customers/components/detail/pipelineStageUtils.js +26 -0
  319. package/dist/modules/customers/components/detail/pipelineStageUtils.js.map +7 -0
  320. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js +144 -0
  321. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js.map +7 -0
  322. package/dist/modules/customers/components/detail/schedule/FooterFields.js +60 -0
  323. package/dist/modules/customers/components/detail/schedule/FooterFields.js.map +7 -0
  324. package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js +216 -0
  325. package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js.map +7 -0
  326. package/dist/modules/customers/components/detail/schedule/LocationField.js +34 -0
  327. package/dist/modules/customers/components/detail/schedule/LocationField.js.map +7 -0
  328. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +226 -0
  329. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +7 -0
  330. package/dist/modules/customers/components/detail/schedule/fieldConfig.js +69 -0
  331. package/dist/modules/customers/components/detail/schedule/fieldConfig.js.map +7 -0
  332. package/dist/modules/customers/components/detail/schedule/index.js +21 -0
  333. package/dist/modules/customers/components/detail/schedule/index.js.map +7 -0
  334. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +172 -0
  335. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +7 -0
  336. package/dist/modules/customers/components/detail/utils.js +23 -0
  337. package/dist/modules/customers/components/detail/utils.js.map +2 -2
  338. package/dist/modules/customers/components/formConfig.js +144 -22
  339. package/dist/modules/customers/components/formConfig.js.map +2 -2
  340. package/dist/modules/customers/components/linking/LinkEntityDialog.js +661 -0
  341. package/dist/modules/customers/components/linking/LinkEntityDialog.js.map +7 -0
  342. package/dist/modules/customers/components/linking/adapters/companyAdapter.js +252 -0
  343. package/dist/modules/customers/components/linking/adapters/companyAdapter.js.map +7 -0
  344. package/dist/modules/customers/components/linking/adapters/dealAdapter.js +384 -0
  345. package/dist/modules/customers/components/linking/adapters/dealAdapter.js.map +7 -0
  346. package/dist/modules/customers/components/linking/adapters/personAdapter.js +324 -0
  347. package/dist/modules/customers/components/linking/adapters/personAdapter.js.map +7 -0
  348. package/dist/modules/customers/components/list/CollectionPreviewCell.js +53 -0
  349. package/dist/modules/customers/components/list/CollectionPreviewCell.js.map +7 -0
  350. package/dist/modules/customers/data/entities.js +407 -1
  351. package/dist/modules/customers/data/entities.js.map +2 -2
  352. package/dist/modules/customers/data/validators.js +139 -21
  353. package/dist/modules/customers/data/validators.js.map +2 -2
  354. package/dist/modules/customers/events.js +19 -1
  355. package/dist/modules/customers/events.js.map +2 -2
  356. package/dist/modules/customers/lib/customerRoleTypes.js +19 -0
  357. package/dist/modules/customers/lib/customerRoleTypes.js.map +7 -0
  358. package/dist/modules/customers/lib/dealClosureNotification.js +39 -0
  359. package/dist/modules/customers/lib/dealClosureNotification.js.map +7 -0
  360. package/dist/modules/customers/lib/dealStageTransitionTable.js +29 -0
  361. package/dist/modules/customers/lib/dealStageTransitionTable.js.map +7 -0
  362. package/dist/modules/customers/lib/dictionaries.js +25 -0
  363. package/dist/modules/customers/lib/dictionaries.js.map +2 -2
  364. package/dist/modules/customers/lib/interactionReadModel.js +10 -0
  365. package/dist/modules/customers/lib/interactionReadModel.js.map +2 -2
  366. package/dist/modules/customers/lib/personCompanies.js +235 -0
  367. package/dist/modules/customers/lib/personCompanies.js.map +7 -0
  368. package/dist/modules/customers/lib/personCompanyLinkTable.js +42 -0
  369. package/dist/modules/customers/lib/personCompanyLinkTable.js.map +7 -0
  370. package/dist/modules/customers/lib/roleTypeUsage.js +104 -0
  371. package/dist/modules/customers/lib/roleTypeUsage.js.map +7 -0
  372. package/dist/modules/customers/migrations/Migration20260406214502.js +18 -0
  373. package/dist/modules/customers/migrations/Migration20260406214502.js.map +7 -0
  374. package/dist/modules/customers/migrations/Migration20260408135736.js +17 -0
  375. package/dist/modules/customers/migrations/Migration20260408135736.js.map +7 -0
  376. package/dist/modules/customers/migrations/Migration20260408225345.js +21 -0
  377. package/dist/modules/customers/migrations/Migration20260408225345.js.map +7 -0
  378. package/dist/modules/customers/migrations/Migration20260411075533.js +27 -0
  379. package/dist/modules/customers/migrations/Migration20260411075533.js.map +7 -0
  380. package/dist/modules/customers/migrations/Migration20260411103551.js +13 -0
  381. package/dist/modules/customers/migrations/Migration20260411103551.js.map +7 -0
  382. package/dist/modules/customers/migrations/Migration20260411130944.js +26 -0
  383. package/dist/modules/customers/migrations/Migration20260411130944.js.map +7 -0
  384. package/dist/modules/customers/migrations/Migration20260415095203.js +13 -0
  385. package/dist/modules/customers/migrations/Migration20260415095203.js.map +7 -0
  386. package/dist/modules/customers/migrations/Migration20260415135056.js +20 -0
  387. package/dist/modules/customers/migrations/Migration20260415135056.js.map +7 -0
  388. package/dist/modules/customers/migrations/Migration20260417140000.js +15 -0
  389. package/dist/modules/customers/migrations/Migration20260417140000.js.map +7 -0
  390. package/dist/modules/customers/migrations/Migration20260417160000.js +17 -0
  391. package/dist/modules/customers/migrations/Migration20260417160000.js.map +7 -0
  392. package/dist/modules/customers/migrations/Migration20260417235407.js +13 -0
  393. package/dist/modules/customers/migrations/Migration20260417235407.js.map +7 -0
  394. package/dist/modules/customers/setup.js +16 -1
  395. package/dist/modules/customers/setup.js.map +2 -2
  396. package/dist/modules/customers/subscribers/deal-closure-notification.js +16 -0
  397. package/dist/modules/customers/subscribers/deal-closure-notification.js.map +7 -0
  398. package/dist/modules/customers/subscribers/deal-lost-notification.js +16 -0
  399. package/dist/modules/customers/subscribers/deal-lost-notification.js.map +7 -0
  400. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +2 -0
  401. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  402. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js +154 -0
  403. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js.map +7 -0
  404. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +6 -2
  405. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
  406. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js +154 -0
  407. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js.map +7 -0
  408. package/dist/modules/dictionaries/api/context.js +8 -1
  409. package/dist/modules/dictionaries/api/context.js.map +2 -2
  410. package/dist/modules/dictionaries/api/openapi.js +18 -1
  411. package/dist/modules/dictionaries/api/openapi.js.map +2 -2
  412. package/dist/modules/dictionaries/commands/entry-operations.js +388 -0
  413. package/dist/modules/dictionaries/commands/entry-operations.js.map +7 -0
  414. package/dist/modules/dictionaries/commands/factory.js +24 -3
  415. package/dist/modules/dictionaries/commands/factory.js.map +2 -2
  416. package/dist/modules/dictionaries/commands/index.js +1 -0
  417. package/dist/modules/dictionaries/commands/index.js.map +2 -2
  418. package/dist/modules/dictionaries/components/DictionaryTable.js +6 -3
  419. package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
  420. package/dist/modules/dictionaries/data/entities.js +11 -1
  421. package/dist/modules/dictionaries/data/entities.js.map +2 -2
  422. package/dist/modules/dictionaries/data/validators.js +28 -2
  423. package/dist/modules/dictionaries/data/validators.js.map +2 -2
  424. package/dist/modules/dictionaries/events.js +18 -0
  425. package/dist/modules/dictionaries/events.js.map +7 -0
  426. package/dist/modules/dictionaries/lib/clientEntries.js +43 -0
  427. package/dist/modules/dictionaries/lib/clientEntries.js.map +7 -0
  428. package/dist/modules/dictionaries/migrations/Migration20260410171544.js +45 -0
  429. package/dist/modules/dictionaries/migrations/Migration20260410171544.js.map +7 -0
  430. package/dist/modules/inbox_ops/api/proposals/[id]/route.js +4 -1
  431. package/dist/modules/inbox_ops/api/proposals/[id]/route.js.map +2 -2
  432. package/dist/modules/query_index/lib/engine.js +1 -1
  433. package/dist/modules/query_index/lib/engine.js.map +2 -2
  434. package/dist/modules/sales/components/documents/AddressesSection.js +82 -42
  435. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  436. package/dist/modules/sales/lib/dictionaries.js +16 -0
  437. package/dist/modules/sales/lib/dictionaries.js.map +2 -2
  438. package/dist/modules/sales/widgets/injection-table.js +5 -1
  439. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  440. package/generated/entities/action_log/index.ts +4 -0
  441. package/generated/entities/customer_company_billing/index.ts +10 -0
  442. package/generated/entities/customer_deal/index.ts +4 -0
  443. package/generated/entities/customer_deal_stage_transition/index.ts +14 -0
  444. package/generated/entities/customer_dictionary_kind_setting/index.ts +9 -0
  445. package/generated/entities/customer_entity/index.ts +4 -0
  446. package/generated/entities/customer_entity_role/index.ts +10 -0
  447. package/generated/entities/customer_interaction/index.ts +11 -0
  448. package/generated/entities/customer_label/index.ts +8 -0
  449. package/generated/entities/customer_label_assignment/index.ts +7 -0
  450. package/generated/entities/customer_person_company_link/index.ts +9 -0
  451. package/generated/entities/customer_person_company_role/index.ts +7 -0
  452. package/generated/entities/dictionary_entry/index.ts +2 -0
  453. package/generated/entities.ids.generated.ts +9 -1
  454. package/generated/entity-fields-registry.ts +116 -1
  455. package/package.json +3 -3
  456. package/src/modules/attachments/api/route.ts +48 -6
  457. package/src/modules/attachments/i18n/de.json +4 -0
  458. package/src/modules/attachments/i18n/en.json +4 -0
  459. package/src/modules/attachments/i18n/es.json +4 -0
  460. package/src/modules/attachments/i18n/pl.json +4 -0
  461. package/src/modules/audit_logs/api/audit-logs/actions/export/route.ts +260 -0
  462. package/src/modules/audit_logs/api/audit-logs/actions/route.ts +81 -6
  463. package/src/modules/audit_logs/cli.ts +79 -0
  464. package/src/modules/audit_logs/data/entities.ts +17 -0
  465. package/src/modules/audit_logs/data/validators.ts +9 -1
  466. package/src/modules/audit_logs/lib/changeRows.ts +47 -0
  467. package/src/modules/audit_logs/lib/display-helpers.tsx +4 -30
  468. package/src/modules/audit_logs/lib/projections.ts +110 -0
  469. package/src/modules/audit_logs/migrations/.snapshot-open-mercato.json +325 -2
  470. package/src/modules/audit_logs/migrations/Migration20260412160533.ts +21 -0
  471. package/src/modules/audit_logs/services/actionLogService.ts +455 -85
  472. package/src/modules/catalog/i18n/de.json +1 -0
  473. package/src/modules/catalog/i18n/en.json +1 -0
  474. package/src/modules/catalog/i18n/es.json +1 -0
  475. package/src/modules/catalog/i18n/pl.json +1 -0
  476. package/src/modules/customer_accounts/i18n/de.json +2 -0
  477. package/src/modules/customer_accounts/i18n/en.json +2 -0
  478. package/src/modules/customer_accounts/i18n/es.json +2 -0
  479. package/src/modules/customer_accounts/i18n/pl.json +2 -0
  480. package/src/modules/customers/acl.ts +2 -0
  481. package/src/modules/customers/api/activities/route.ts +4 -0
  482. package/src/modules/customers/api/assignable-staff/route.ts +250 -0
  483. package/src/modules/customers/api/companies/[id]/people/route.ts +244 -0
  484. package/src/modules/customers/api/companies/[id]/roles/route.ts +15 -0
  485. package/src/modules/customers/api/companies/[id]/route.ts +458 -40
  486. package/src/modules/customers/api/companies/route.ts +93 -15
  487. package/src/modules/customers/api/deals/[id]/companies/route.ts +203 -0
  488. package/src/modules/customers/api/deals/[id]/people/route.ts +182 -0
  489. package/src/modules/customers/api/deals/[id]/route.ts +554 -57
  490. package/src/modules/customers/api/deals/[id]/stats/route.ts +221 -0
  491. package/src/modules/customers/api/deals/route.ts +35 -46
  492. package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +105 -3
  493. package/src/modules/customers/api/dictionaries/[kind]/route.ts +143 -44
  494. package/src/modules/customers/api/dictionaries/context.ts +45 -16
  495. package/src/modules/customers/api/dictionaries/kind-settings/route.ts +232 -0
  496. package/src/modules/customers/api/entity-roles-factory.ts +520 -0
  497. package/src/modules/customers/api/interactions/conflicts/route.ts +196 -0
  498. package/src/modules/customers/api/interactions/counts/route.ts +112 -0
  499. package/src/modules/customers/api/interactions/route.ts +95 -2
  500. package/src/modules/customers/api/labels/assign/route.ts +202 -0
  501. package/src/modules/customers/api/labels/auth.ts +19 -0
  502. package/src/modules/customers/api/labels/route.ts +310 -0
  503. package/src/modules/customers/api/labels/table-errors.ts +36 -0
  504. package/src/modules/customers/api/labels/unassign/route.ts +197 -0
  505. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +331 -0
  506. package/src/modules/customers/api/people/[id]/companies/context.ts +70 -0
  507. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +384 -0
  508. package/src/modules/customers/api/people/[id]/companies/route.ts +215 -0
  509. package/src/modules/customers/api/people/[id]/roles/route.ts +15 -0
  510. package/src/modules/customers/api/people/[id]/route.ts +153 -26
  511. package/src/modules/customers/api/people/route.ts +134 -31
  512. package/src/modules/customers/api/todos/route.ts +4 -0
  513. package/src/modules/customers/api/utils.ts +36 -0
  514. package/src/modules/customers/backend/config/customers/page.tsx +2 -6
  515. package/src/modules/customers/backend/customers/companies/page.tsx +36 -26
  516. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +277 -262
  517. package/src/modules/customers/backend/customers/deals/[id]/hooks/formatters.ts +19 -0
  518. package/src/modules/customers/backend/customers/deals/[id]/hooks/types.ts +104 -0
  519. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +60 -0
  520. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.ts +362 -0
  521. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.ts +113 -0
  522. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealData.ts +52 -0
  523. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +86 -0
  524. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.tsx +60 -0
  525. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.ts +76 -0
  526. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.ts +56 -0
  527. package/src/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.ts +38 -0
  528. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +587 -624
  529. package/src/modules/customers/backend/customers/deals/page.tsx +71 -28
  530. package/src/modules/customers/backend/customers/people/page.tsx +35 -29
  531. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +343 -209
  532. package/src/modules/customers/cli.ts +107 -12
  533. package/src/modules/customers/commands/activities.ts +13 -0
  534. package/src/modules/customers/commands/deals.ts +386 -114
  535. package/src/modules/customers/commands/dictionaries.ts +175 -32
  536. package/src/modules/customers/commands/dictionaryKindSettings.ts +268 -0
  537. package/src/modules/customers/commands/entity-roles.ts +494 -0
  538. package/src/modules/customers/commands/index.ts +4 -0
  539. package/src/modules/customers/commands/interactions.ts +125 -21
  540. package/src/modules/customers/commands/labels.ts +626 -0
  541. package/src/modules/customers/commands/people.ts +373 -259
  542. package/src/modules/customers/commands/personCompanyLinks.ts +654 -0
  543. package/src/modules/customers/commands/shared.ts +16 -15
  544. package/src/modules/customers/commands/todos.ts +17 -1
  545. package/src/modules/customers/components/AddressEditor.tsx +1 -1
  546. package/src/modules/customers/components/CustomersConfigurationSections.tsx +36 -0
  547. package/src/modules/customers/components/DictionarySettings.tsx +43 -2
  548. package/src/modules/customers/components/detail/ActiveDealCard.tsx +175 -0
  549. package/src/modules/customers/components/detail/ActivitiesSection.tsx +267 -361
  550. package/src/modules/customers/components/detail/ActivityAiActions.tsx +49 -0
  551. package/src/modules/customers/components/detail/ActivityCard.tsx +154 -0
  552. package/src/modules/customers/components/detail/ActivityHistorySection.tsx +412 -0
  553. package/src/modules/customers/components/detail/ActivityLogTab.tsx +67 -0
  554. package/src/modules/customers/components/detail/ActivityTimeline.tsx +158 -0
  555. package/src/modules/customers/components/detail/ActivityTimelineFilters.tsx +163 -0
  556. package/src/modules/customers/components/detail/ActivityTypeSelector.tsx +53 -0
  557. package/src/modules/customers/components/detail/AiActionChips.tsx +48 -0
  558. package/src/modules/customers/components/detail/AssignRoleDialog.tsx +672 -0
  559. package/src/modules/customers/components/detail/ChangelogEntryRow.tsx +132 -0
  560. package/src/modules/customers/components/detail/ChangelogFilters.tsx +193 -0
  561. package/src/modules/customers/components/detail/ChangelogKpiCards.tsx +107 -0
  562. package/src/modules/customers/components/detail/ChangelogTab.tsx +629 -0
  563. package/src/modules/customers/components/detail/ComingSoonPlaceholder.tsx +21 -0
  564. package/src/modules/customers/components/detail/CompanyCard.tsx +419 -0
  565. package/src/modules/customers/components/detail/CompanyDashboardTab.tsx +161 -0
  566. package/src/modules/customers/components/detail/CompanyDetailHeader.tsx +243 -0
  567. package/src/modules/customers/components/detail/CompanyDetailTabs.tsx +172 -0
  568. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +206 -0
  569. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +582 -288
  570. package/src/modules/customers/components/detail/CompanyTagsDialog.tsx +23 -0
  571. package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +210 -0
  572. package/src/modules/customers/components/detail/CreatePersonDialog.tsx +178 -0
  573. package/src/modules/customers/components/detail/DealClosureActionBar.tsx +63 -0
  574. package/src/modules/customers/components/detail/DealDetailHeader.tsx +335 -0
  575. package/src/modules/customers/components/detail/DealDetailTabs.tsx +154 -0
  576. package/src/modules/customers/components/detail/DealForm.tsx +253 -101
  577. package/src/modules/customers/components/detail/DealLinkedEntitiesTab.tsx +349 -0
  578. package/src/modules/customers/components/detail/DealLostSummaryDialog.tsx +156 -0
  579. package/src/modules/customers/components/detail/DealWonPopup.tsx +164 -0
  580. package/src/modules/customers/components/detail/DealsSection.tsx +276 -221
  581. package/src/modules/customers/components/detail/DecisionMakersFooter.tsx +56 -0
  582. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +1372 -0
  583. package/src/modules/customers/components/detail/InlineActivityComposer.tsx +239 -0
  584. package/src/modules/customers/components/detail/ManageTagsDialog.tsx +1331 -0
  585. package/src/modules/customers/components/detail/MiniWeekCalendar.tsx +338 -0
  586. package/src/modules/customers/components/detail/MobilePersonDetail.tsx +124 -0
  587. package/src/modules/customers/components/detail/NextStepCard.tsx +104 -0
  588. package/src/modules/customers/components/detail/PersonCard.tsx +238 -0
  589. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +426 -0
  590. package/src/modules/customers/components/detail/PersonDetailHeader.tsx +294 -0
  591. package/src/modules/customers/components/detail/PersonDetailTabs.tsx +172 -0
  592. package/src/modules/customers/components/detail/PersonTagsDialog.tsx +26 -0
  593. package/src/modules/customers/components/detail/PipelineStepper.tsx +245 -0
  594. package/src/modules/customers/components/detail/PlannedActivitiesSection.tsx +255 -0
  595. package/src/modules/customers/components/detail/RelationshipHealthCard.tsx +63 -0
  596. package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +248 -0
  597. package/src/modules/customers/components/detail/RolesSection.tsx +311 -0
  598. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +481 -0
  599. package/src/modules/customers/components/detail/aiActionCatalog.ts +77 -0
  600. package/src/modules/customers/components/detail/assignableStaff.ts +124 -0
  601. package/src/modules/customers/components/detail/dashboard/ActiveDealWidget.tsx +63 -0
  602. package/src/modules/customers/components/detail/dashboard/OpenTasksWidget.tsx +114 -0
  603. package/src/modules/customers/components/detail/dashboard/RecentActivityWidget.tsx +69 -0
  604. package/src/modules/customers/components/detail/dashboard/RelationshipHealthWidget.tsx +40 -0
  605. package/src/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.tsx +64 -0
  606. package/src/modules/customers/components/detail/dashboard/helpers.ts +78 -0
  607. package/src/modules/customers/components/detail/healthScoreUtils.ts +91 -0
  608. package/src/modules/customers/components/detail/hooks/useCurrencyDictionary.ts +8 -8
  609. package/src/modules/customers/components/detail/hooks/useCustomerDictionary.ts +10 -6
  610. package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +91 -0
  611. package/src/modules/customers/components/detail/notesAdapter.ts +91 -30
  612. package/src/modules/customers/components/detail/pipelineStageUtils.ts +29 -0
  613. package/src/modules/customers/components/detail/schedule/DateTimeFields.tsx +187 -0
  614. package/src/modules/customers/components/detail/schedule/FooterFields.tsx +79 -0
  615. package/src/modules/customers/components/detail/schedule/LinkedEntitiesField.tsx +277 -0
  616. package/src/modules/customers/components/detail/schedule/LocationField.tsx +42 -0
  617. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +255 -0
  618. package/src/modules/customers/components/detail/schedule/fieldConfig.ts +70 -0
  619. package/src/modules/customers/components/detail/schedule/index.ts +9 -0
  620. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +221 -0
  621. package/src/modules/customers/components/detail/types.ts +16 -0
  622. package/src/modules/customers/components/detail/utils.ts +25 -0
  623. package/src/modules/customers/components/formConfig.tsx +223 -28
  624. package/src/modules/customers/components/linking/LinkEntityDialog.tsx +920 -0
  625. package/src/modules/customers/components/linking/adapters/companyAdapter.tsx +398 -0
  626. package/src/modules/customers/components/linking/adapters/dealAdapter.tsx +578 -0
  627. package/src/modules/customers/components/linking/adapters/personAdapter.tsx +512 -0
  628. package/src/modules/customers/components/list/CollectionPreviewCell.tsx +66 -0
  629. package/src/modules/customers/data/entities.ts +353 -1
  630. package/src/modules/customers/data/validators.ts +170 -19
  631. package/src/modules/customers/events.ts +22 -0
  632. package/src/modules/customers/i18n/de.json +841 -2
  633. package/src/modules/customers/i18n/en.json +841 -2
  634. package/src/modules/customers/i18n/es.json +840 -1
  635. package/src/modules/customers/i18n/pl.json +841 -2
  636. package/src/modules/customers/lib/customerRoleTypes.ts +24 -0
  637. package/src/modules/customers/lib/dealClosureNotification.ts +64 -0
  638. package/src/modules/customers/lib/dealStageTransitionTable.ts +32 -0
  639. package/src/modules/customers/lib/dictionaries.ts +26 -10
  640. package/src/modules/customers/lib/interactionReadModel.ts +10 -0
  641. package/src/modules/customers/lib/personCompanies.ts +317 -0
  642. package/src/modules/customers/lib/personCompanyLinkTable.ts +58 -0
  643. package/src/modules/customers/lib/roleTypeUsage.ts +146 -0
  644. package/src/modules/customers/migrations/.snapshot-open-mercato.json +2747 -798
  645. package/src/modules/customers/migrations/Migration20260406214502.ts +19 -0
  646. package/src/modules/customers/migrations/Migration20260408135736.ts +15 -0
  647. package/src/modules/customers/migrations/Migration20260408225345.ts +23 -0
  648. package/src/modules/customers/migrations/Migration20260411075533.ts +30 -0
  649. package/src/modules/customers/migrations/Migration20260411103551.ts +13 -0
  650. package/src/modules/customers/migrations/Migration20260411130944.ts +30 -0
  651. package/src/modules/customers/migrations/Migration20260415095203.ts +13 -0
  652. package/src/modules/customers/migrations/Migration20260415135056.ts +22 -0
  653. package/src/modules/customers/migrations/Migration20260417140000.ts +15 -0
  654. package/src/modules/customers/migrations/Migration20260417160000.ts +17 -0
  655. package/src/modules/customers/migrations/Migration20260417235407.ts +13 -0
  656. package/src/modules/customers/setup.ts +15 -0
  657. package/src/modules/customers/subscribers/deal-closure-notification.ts +22 -0
  658. package/src/modules/customers/subscribers/deal-lost-notification.ts +22 -0
  659. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +2 -0
  660. package/src/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.ts +162 -0
  661. package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +6 -2
  662. package/src/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.ts +162 -0
  663. package/src/modules/dictionaries/api/context.ts +9 -0
  664. package/src/modules/dictionaries/api/openapi.ts +17 -0
  665. package/src/modules/dictionaries/commands/entry-operations.ts +457 -0
  666. package/src/modules/dictionaries/commands/factory.ts +31 -3
  667. package/src/modules/dictionaries/commands/index.ts +1 -0
  668. package/src/modules/dictionaries/components/DictionaryTable.tsx +15 -6
  669. package/src/modules/dictionaries/data/entities.ts +9 -0
  670. package/src/modules/dictionaries/data/validators.ts +34 -0
  671. package/src/modules/dictionaries/events.ts +20 -0
  672. package/src/modules/dictionaries/i18n/de.json +2 -0
  673. package/src/modules/dictionaries/i18n/en.json +2 -0
  674. package/src/modules/dictionaries/i18n/es.json +2 -0
  675. package/src/modules/dictionaries/i18n/pl.json +2 -0
  676. package/src/modules/dictionaries/lib/clientEntries.ts +66 -0
  677. package/src/modules/dictionaries/migrations/.snapshot-open-mercato.json +185 -3
  678. package/src/modules/dictionaries/migrations/Migration20260410171544.ts +49 -0
  679. package/src/modules/inbox_ops/api/proposals/[id]/route.ts +4 -1
  680. package/src/modules/query_index/lib/engine.ts +9 -1
  681. package/src/modules/sales/components/documents/AddressesSection.tsx +92 -42
  682. package/src/modules/sales/i18n/de.json +28 -0
  683. package/src/modules/sales/i18n/en.json +28 -0
  684. package/src/modules/sales/i18n/es.json +28 -0
  685. package/src/modules/sales/i18n/pl.json +28 -0
  686. package/src/modules/sales/lib/dictionaries.ts +18 -0
  687. package/src/modules/sales/widgets/injection-table.ts +4 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/query_index/lib/engine.ts"],
4
- "sourcesContent": ["import type { QueryEngine, QueryOptions, QueryResult, FilterOp, Filter, QueryCustomFieldSource, PartialIndexWarning, QueryExtensionsConfig } from '@open-mercato/shared/lib/query/types'\nimport { SortDir } from '@open-mercato/shared/lib/query/types'\nimport type { EntityId } from '@open-mercato/shared/modules/entities'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { BasicQueryEngine, resolveEntityTableName } from '@open-mercato/shared/lib/query/engine'\nimport type { Knex } from 'knex'\nimport type { EventBus } from '@open-mercato/events'\nimport { readCoverageSnapshot, refreshCoverageSnapshot } from './coverage'\nimport { createProfiler, shouldEnableProfiler, type Profiler } from '@open-mercato/shared/lib/profiler'\nimport type { VectorIndexService } from '@open-mercato/search/vector'\nimport { decryptIndexDocCustomFields } from '@open-mercato/shared/lib/encryption/indexDoc'\nimport { parseBooleanToken, parseBooleanWithDefault } from '@open-mercato/shared/lib/boolean'\nimport {\n applyJoinFilters,\n normalizeFilters,\n partitionFilters,\n resolveJoins,\n type BaseFilter,\n type ResolvedJoin,\n} from '@open-mercato/shared/lib/query/join-utils'\nimport { resolveSearchConfig, type SearchConfig } from '@open-mercato/shared/lib/search/config'\nimport { tokenizeText } from '@open-mercato/shared/lib/search/tokenize'\nimport { runBeforeQueryPipeline, runAfterQueryPipeline, type QueryExtensionContext } from '@open-mercato/shared/lib/query/query-extension-runner'\n\nfunction buildFilterableCustomFieldJoins(\n sources: QueryCustomFieldSource[] | undefined,\n): Array<{\n alias: string\n table?: string\n entityId: EntityId\n from: { field: string }\n to: { field: string }\n type: 'left' | 'inner'\n}> {\n if (!sources || sources.length === 0) return []\n return sources.flatMap((source, index) => {\n if (!source.join) return []\n const alias = typeof source.alias === 'string' && source.alias.trim().length > 0\n ? source.alias.trim()\n : `cfs_${index}`\n return [{\n alias,\n table: source.table,\n entityId: source.entityId,\n from: { field: source.join.fromField },\n to: { field: source.join.toField },\n type: source.join.type === 'inner' ? 'inner' : 'left',\n }]\n })\n}\n\nfunction resolveBooleanEnv(names: readonly string[], defaultValue: boolean): boolean {\n for (const name of names) {\n const raw = process.env[name]\n if (raw !== undefined) return parseBooleanWithDefault(raw, defaultValue)\n }\n return defaultValue\n}\n\nfunction resolveDebugVerbosity(): boolean {\n // Check explicit OM_QUERY_INDEX_DEBUG flag first\n const queryIndexDebug = process.env.OM_QUERY_INDEX_DEBUG\n if (queryIndexDebug !== undefined) {\n return parseBooleanToken(queryIndexDebug) ?? false\n }\n // Fall back to log level or NODE_ENV\n const level = (process.env.LOG_VERBOSITY ?? process.env.LOG_LEVEL ?? '').toLowerCase()\n if (['debug', 'trace', 'silly'].includes(level)) return true\n // Default to false (don't spam logs in development)\n return false\n}\n\ntype ResultRow = Record<string, unknown>\ntype ResultBuilder<TResult = ResultRow[]> = Knex.QueryBuilder<ResultRow, TResult>\ntype NormalizedFilter = { field: string; op: FilterOp; value?: unknown }\ntype IndexDocSource = { alias: string; entityId: EntityId; recordIdColumn: string }\ntype PreparedCustomFieldSource = {\n alias: string\n indexAlias: string\n entityId: EntityId\n recordIdColumn: string\n organizationField?: string\n tenantField?: string\n table: string\n}\ntype SearchRuntime = {\n enabled: boolean\n config: SearchConfig\n organizationScope?: { ids: string[]; includeNull: boolean } | null\n tenantId?: string | null\n searchSources?: SearchTokenSource[]\n}\n\ntype EncryptionResolver = () => {\n decryptEntityPayload?: (entityId: EntityId, payload: Record<string, unknown>, tenantId?: string | null, organizationId?: string | null) => Promise<Record<string, unknown>>\n isEnabled?: () => boolean\n} | null\n\ntype SearchTokenSource = { entity: string; recordIdColumn: string }\n\nfunction createQueryProfiler(entity: string): Profiler {\n const enabled = shouldEnableProfiler(entity)\n return createProfiler({\n scope: 'query_engine',\n target: entity,\n label: `query_engine:${entity}`,\n loggerLabel: '[qe:profile]',\n enabled,\n })\n}\n\nexport class HybridQueryEngine implements QueryEngine {\n private coverageStatsTtlMs: number\n private customFieldKeysCache = new Map<string, { expiresAt: number; value: string[] }>()\n private customFieldKeysTtlMs: number\n private columnCache = new Map<string, boolean>()\n private debugVerbosity: boolean | null = null\n private sqlDebugEnabled: boolean | null = null\n private forcePartialIndexEnabled: boolean | null = null\n private autoReindexEnabled: boolean | null = null\n private coverageOptimizationEnabled: boolean | null = null\n private pendingCoverageRefreshKeys = new Set<string>()\n private searchAliasSeq = 0\n\n constructor(\n private em: EntityManager,\n private fallback: BasicQueryEngine,\n private eventBusResolver?: () => Pick<EventBus, 'emitEvent'> | null | undefined,\n private vectorServiceResolver?: () => VectorIndexService | null | undefined,\n private encryptionResolver?: EncryptionResolver,\n ) {\n const coverageTtl = Number.parseInt(process.env.QUERY_INDEX_COVERAGE_CACHE_MS ?? '', 10)\n this.coverageStatsTtlMs = Number.isFinite(coverageTtl) && coverageTtl >= 0 ? coverageTtl : 5 * 60 * 1000\n const cfTtl = Number.parseInt(process.env.QUERY_INDEX_CF_KEYS_CACHE_MS ?? '', 10)\n this.customFieldKeysTtlMs = Number.isFinite(cfTtl) && cfTtl >= 0 ? cfTtl : 5 * 60 * 1000\n }\n\n private getEncryptionService() {\n try {\n return this.encryptionResolver?.() ?? null\n } catch {\n return null\n }\n }\n\n async query<T = unknown>(entity: EntityId, opts: QueryOptions = {}): Promise<QueryResult<T>> {\n // --- UMES query extension: before-query pipeline ---\n const ext: QueryExtensionsConfig | undefined = opts.extensions\n let hybridExtCtx: QueryExtensionContext | null = null\n const noopDi = { resolve: <R = unknown>(_name: string): R => { throw new Error('No DI context') } }\n\n if (ext) {\n hybridExtCtx = {\n entity: String(entity),\n engine: 'hybrid',\n tenantId: opts.tenantId ?? '',\n organizationId: opts.organizationId,\n userId: ext.userId,\n em: this.em,\n container: ext.container,\n userFeatures: ext.userFeatures,\n }\n const diCtx = ext.resolve ? { resolve: ext.resolve } : noopDi\n const beforeResult = await runBeforeQueryPipeline(opts, hybridExtCtx, diCtx)\n if (beforeResult.blocked) {\n throw new Error(beforeResult.errorMessage ?? 'Query blocked by extension subscriber')\n }\n opts = beforeResult.query\n }\n // Strip extensions so fallback to BasicQueryEngine doesn't double-execute\n const { extensions: _stripExt, ...coreOpts } = opts\n opts = coreOpts\n\n const providedProfiler = opts.profiler\n const profiler = providedProfiler && providedProfiler.enabled\n ? providedProfiler\n : createQueryProfiler(String(entity))\n profiler.mark('query:init')\n let profileClosed = false\n const finishProfile = (meta?: Record<string, unknown>) => {\n if (!profiler.enabled || profileClosed) return\n profileClosed = true\n profiler.end(meta)\n }\n\n const applyAfterExtensions = async <R>(queryResult: QueryResult<R>): Promise<QueryResult<R>> => {\n if (!ext || !hybridExtCtx) return queryResult\n const diCtx = ext.resolve ? { resolve: ext.resolve } : noopDi\n return await runAfterQueryPipeline(\n queryResult as QueryResult<Record<string, unknown>>,\n opts,\n hybridExtCtx,\n diCtx,\n ) as QueryResult<R>\n }\n\n try {\n const debugEnabled = this.isDebugVerbosity()\n if (debugEnabled) this.debug('query:start', { entity })\n this.searchAliasSeq = 0\n\n const isCustom = await this.isCustomEntity(entity)\n if (isCustom) {\n if (debugEnabled) this.debug('query:custom-entity', { entity })\n const section = profiler.section('custom_entity')\n try {\n const result = await this.queryCustomEntity<T>(entity, opts)\n section.end({ mode: 'custom_entity' })\n finishProfile({\n result: 'custom_entity',\n total: Array.isArray(result.items) ? result.items.length : undefined,\n })\n return await applyAfterExtensions(result)\n } catch (err) {\n section.end({ error: err instanceof Error ? err.message : String(err) })\n throw err\n }\n }\n\n const knex = this.getKnex()\n profiler.mark('query:knex_ready')\n const baseTable = resolveEntityTableName(this.em, entity)\n profiler.mark('query:base_table_resolved')\n const searchConfig = resolveSearchConfig()\n const orgScope = this.resolveOrganizationScope(opts)\n const searchEnabled = searchConfig.enabled && await this.tableExists('search_tokens')\n\n const baseExists = await profiler.measure('base_table_exists', () => this.tableExists(baseTable))\n if (!baseExists) {\n if (debugEnabled) this.debug('query:fallback:missing-base', { entity, baseTable })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'missing_base' })\n return await applyAfterExtensions(fallbackResult)\n }\n\n if (opts.omitAutomaticTenantOrgScope === true) {\n if (debugEnabled) this.debug('query:fallback:omit-automatic-scope', { entity })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'omit_automatic_tenant_org_scope' })\n return await applyAfterExtensions(fallbackResult)\n }\n\n const normalizedFilters = normalizeFilters(opts.filters)\n const cfFilters = normalizedFilters.filter((filter) => filter.field.startsWith('cf:') || filter.field.startsWith('l10n:'))\n const coverageScope = this.resolveCoverageSnapshotScope(opts)\n const wantsCf = (\n (opts.fields || []).some((field) => typeof field === 'string' && (field.startsWith('cf:') || field.startsWith('l10n:'))) ||\n cfFilters.length > 0 ||\n (Array.isArray(opts.includeCustomFields) && opts.includeCustomFields.length > 0)\n )\n\n if (debugEnabled) {\n this.debug('query:config', {\n entity,\n wantsCustomFields: wantsCf,\n customFieldSources: Array.isArray(opts.customFieldSources) ? opts.customFieldSources.map((src) => src?.entityId) : undefined,\n fields: opts.fields,\n })\n }\n\n let partialIndexWarning: PartialIndexWarning | null = null\n let entityHasActiveCustomFields = true\n\n if (wantsCf) {\n entityHasActiveCustomFields = await this.entityHasActiveCustomFields(entity, opts.tenantId ?? null)\n const hasIndexRows = await profiler.measure(\n 'index_any_rows',\n () => this.indexAnyRows(entity),\n (value) => ({ hasIndexRows: value })\n )\n if (!hasIndexRows) {\n if (debugEnabled) this.debug('query:fallback:no-index', { entity })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'no_index_rows' })\n return await applyAfterExtensions(fallbackResult)\n }\n if (entityHasActiveCustomFields) {\n const gap = await profiler.measure(\n 'resolve_coverage_gap',\n () => this.resolveCoverageGap(entity, opts, coverageScope),\n (value) => (value\n ? {\n scope: value.scope,\n baseCount: value.stats?.baseCount ?? null,\n indexedCount: value.stats?.indexedCount ?? null,\n }\n : { scope: null })\n )\n if (gap) {\n if (!opts.skipAutoReindex) {\n this.scheduleAutoReindex(entity, opts, gap.stats, coverageScope?.organizationId ?? null)\n }\n const force = this.isForcePartialIndexEnabled()\n if (!force) {\n if (gap.stats) {\n console.warn('[HybridQueryEngine] Partial index coverage detected; falling back to basic engine:', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n if (debugEnabled) this.debug('query:fallback:partial-coverage', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n } else {\n console.warn('[HybridQueryEngine] Partial index coverage detected; falling back to basic engine:', { entity })\n if (debugEnabled) this.debug('query:fallback:partial-coverage', { entity })\n }\n const fallbackResult = await this.fallback.query(entity, opts)\n const resultWithWarning: QueryResult<T> = {\n ...fallbackResult,\n meta: {\n ...(fallbackResult.meta ?? {}),\n partialIndexWarning: {\n entity,\n entityLabel: this.resolveEntityLabel(entity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n },\n },\n }\n finishProfile({\n result: 'fallback',\n reason: 'partial_index',\n scope: gap.scope,\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n })\n return await applyAfterExtensions(resultWithWarning)\n }\n if (gap.stats) {\n console.warn('[HybridQueryEngine] Partial index coverage detected; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n if (debugEnabled) this.debug('query:partial-coverage:forced', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n } else {\n console.warn('[HybridQueryEngine] Partial index coverage detected; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity })\n if (debugEnabled) this.debug('query:partial-coverage:forced', { entity })\n }\n partialIndexWarning = {\n entity,\n entityLabel: this.resolveEntityLabel(entity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n }\n }\n } else if (debugEnabled) {\n this.debug('query:coverage:skip-no-custom-fields', { entity })\n }\n }\n\n const qualify = (col: string) => `b.${col}`\n let builder: ResultBuilder = knex({ b: baseTable })\n const hasCustomFieldFilters = cfFilters.length > 0\n const canOptimizeCount = !hasCustomFieldFilters\n let optimizedCountBuilder: ResultBuilder | null = canOptimizeCount ? knex({ b: baseTable }) : null\n\n const resolvedJoinsConfig = resolveJoins(\n baseTable,\n [...(opts.joins ?? []), ...buildFilterableCustomFieldJoins(opts.customFieldSources)],\n (entityId) => resolveEntityTableName(this.em, entityId as any),\n )\n const joinMap = new Map<string, ResolvedJoin>()\n const aliasTables = new Map<string, string>()\n aliasTables.set('b', baseTable)\n aliasTables.set('base', baseTable)\n aliasTables.set(baseTable, baseTable)\n for (const join of resolvedJoinsConfig) {\n joinMap.set(join.alias, join)\n aliasTables.set(join.alias, join.table)\n }\n const { baseFilters, joinFilters } = partitionFilters(baseTable, normalizedFilters, joinMap)\n\n if (!opts.tenantId) throw new Error('QueryEngine: tenantId is required')\n\n const hasOrganizationColumn = await this.columnExists(baseTable, 'organization_id')\n const hasTenantColumn = await this.columnExists(baseTable, 'tenant_id')\n const hasDeletedColumn = await this.columnExists(baseTable, 'deleted_at')\n const searchRuntimeBase = {\n enabled: false,\n config: searchConfig,\n organizationScope: orgScope,\n tenantId: opts.tenantId ?? null,\n }\n\n if (orgScope && hasOrganizationColumn) {\n builder = this.applyOrganizationScope(builder, qualify('organization_id'), orgScope)\n if (optimizedCountBuilder) optimizedCountBuilder = this.applyOrganizationScope(optimizedCountBuilder, qualify('organization_id'), orgScope)\n }\n if (hasTenantColumn) {\n builder = builder.where(qualify('tenant_id'), opts.tenantId)\n if (optimizedCountBuilder) optimizedCountBuilder = optimizedCountBuilder.where(qualify('tenant_id'), opts.tenantId)\n }\n if (!opts.withDeleted && hasDeletedColumn) {\n builder = builder.whereNull(qualify('deleted_at'))\n if (optimizedCountBuilder) optimizedCountBuilder = optimizedCountBuilder.whereNull(qualify('deleted_at'))\n }\n\n const baseJoinParts: string[] = []\n baseJoinParts.push(`ei.entity_type = ${knex.raw('?', [entity]).toString()}`)\n baseJoinParts.push(`ei.entity_id = (${qualify('id')}::text)`)\n if (hasOrganizationColumn) {\n baseJoinParts.push(`ei.organization_id = ${qualify('organization_id')}`)\n baseJoinParts.push('ei.organization_id is not null')\n }\n if (hasTenantColumn) {\n baseJoinParts.push(`ei.tenant_id = ${qualify('tenant_id')}`)\n baseJoinParts.push('ei.tenant_id is not null')\n }\n if (!opts.withDeleted) baseJoinParts.push(`ei.deleted_at is null`)\n builder = builder.leftJoin({ ei: 'entity_indexes' }, knex.raw(baseJoinParts.join(' AND ')))\n\n const columns = await this.getBaseColumnsForEntity(entity)\n const indexSources: IndexDocSource[] = [{ alias: 'ei', entityId: entity, recordIdColumn: 'b.id' }]\n\n const shouldAttachCustomSources = Array.isArray(opts.customFieldSources) && opts.customFieldSources.length > 0 && (wantsCf || searchEnabled)\n if (shouldAttachCustomSources) {\n const prepared = this.prepareCustomFieldSources(knex, builder, opts.customFieldSources ?? [], qualify)\n builder = prepared.builder\n for (const source of prepared.sources) {\n const fragments: string[] = []\n fragments.push(`${source.indexAlias}.entity_type = ${knex.raw('?', [source.entityId]).toString()}`)\n fragments.push(`${source.indexAlias}.entity_id = (${knex.raw('??::text', [`${source.alias}.${source.recordIdColumn}`]).toString()})`)\n const orgExpr = source.organizationField\n ? knex.raw('??', [`${source.alias}.${source.organizationField}`]).toString()\n : (columns.has('organization_id') ? qualify('organization_id') : null)\n if (orgExpr) {\n fragments.push(`${source.indexAlias}.organization_id = ${orgExpr}`)\n fragments.push(`${source.indexAlias}.organization_id is not null`)\n }\n const tenantExpr = source.tenantField\n ? knex.raw('??', [`${source.alias}.${source.tenantField}`]).toString()\n : (columns.has('tenant_id') ? qualify('tenant_id') : null)\n if (tenantExpr) {\n fragments.push(`${source.indexAlias}.tenant_id = ${tenantExpr}`)\n fragments.push(`${source.indexAlias}.tenant_id is not null`)\n }\n if (!opts.withDeleted) fragments.push(`${source.indexAlias}.deleted_at is null`)\n builder = builder.leftJoin({ [source.indexAlias]: 'entity_indexes' }, knex.raw(fragments.join(' AND ')))\n indexSources.push({ alias: source.indexAlias, entityId: source.entityId, recordIdColumn: `${source.alias}.${source.recordIdColumn}` })\n }\n }\n\n if (debugEnabled) {\n this.debug('query:index-sources', {\n entity,\n sources: indexSources.map((src) => ({ alias: src.alias, entity: src.entityId })),\n })\n }\n\n const searchSources: SearchTokenSource[] = indexSources\n .map((src) => ({\n entity: String(src.entityId),\n recordIdColumn: src.recordIdColumn,\n }))\n .filter((src) => src.recordIdColumn && src.entity)\n const hasSearchTokens = searchEnabled && searchSources.length\n ? await this.searchSourcesHaveTokens(searchSources, opts.tenantId ?? null, orgScope)\n : false\n const searchRuntime: SearchRuntime = { ...searchRuntimeBase, searchSources, enabled: searchEnabled && hasSearchTokens }\n const joinSearchAvailability = new Map<string, boolean>()\n const searchFilters = normalizeFilters(opts.filters).filter((filter) => filter.op === 'like' || filter.op === 'ilike')\n if (searchFilters.length) {\n this.logSearchDebug('search:init', {\n entity,\n baseTable,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n fields: searchFilters.map((filter) => String(filter.field)),\n searchEnabled,\n hasSearchTokens,\n searchSources,\n searchConfig: {\n enabled: searchConfig.enabled,\n minTokenLength: searchConfig.minTokenLength,\n enablePartials: searchConfig.enablePartials,\n hashAlgorithm: searchConfig.hashAlgorithm,\n blocklistedFields: searchConfig.blocklistedFields,\n },\n })\n if (!searchEnabled) {\n this.logSearchDebug('search:disabled', { entity, baseTable })\n } else if (!hasSearchTokens) {\n this.logSearchDebug('search:no-search-tokens', {\n entity,\n baseTable,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n searchSources,\n })\n }\n }\n const hasNonBaseSearchSource = searchSources.some(\n (src) => src.entity !== String(entity) || src.recordIdColumn !== 'b.id'\n )\n if (hasNonBaseSearchSource) {\n optimizedCountBuilder = null\n }\n\n if (!partialIndexWarning && Array.isArray(opts.customFieldSources) && opts.customFieldSources.length > 0 && this.isForcePartialIndexEnabled()) {\n const seen = new Set<string>([entity])\n for (const source of opts.customFieldSources) {\n const targetEntity = source?.entityId ? String(source.entityId) : null\n if (!targetEntity || seen.has(targetEntity)) continue\n seen.add(targetEntity)\n const sourceHasCustomFields = await this.entityHasActiveCustomFields(targetEntity, opts.tenantId ?? null)\n if (!sourceHasCustomFields) {\n if (debugEnabled) this.debug('query:coverage:skip-no-custom-fields', { entity: targetEntity })\n continue\n }\n const sourceTable = source.table ?? resolveEntityTableName(this.em, targetEntity)\n try {\n const gap = await profiler.measure(\n 'resolve_coverage_gap',\n () => this.resolveCoverageGap(targetEntity, opts, coverageScope, sourceTable),\n (value) => (value\n ? {\n entity: targetEntity,\n scope: value.scope,\n baseCount: value.stats?.baseCount ?? null,\n indexedCount: value.stats?.indexedCount ?? null,\n }\n : { entity: targetEntity, scope: null })\n )\n if (!gap) continue\n if (!opts.skipAutoReindex) {\n this.scheduleAutoReindex(targetEntity, opts, gap.stats, coverageScope?.organizationId ?? null)\n }\n partialIndexWarning = {\n entity: targetEntity,\n entityLabel: this.resolveEntityLabel(targetEntity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n }\n if (debugEnabled) {\n if (gap.stats) this.debug('query:partial-coverage:forced', { entity: targetEntity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n else this.debug('query:partial-coverage:forced', { entity: targetEntity })\n }\n break\n } catch (err) {\n if (debugEnabled) this.debug('query:partial-coverage:check-failed', { entity: targetEntity, error: err instanceof Error ? err.message : err })\n }\n }\n }\n\n if (\n !partialIndexWarning &&\n wantsCf &&\n entityHasActiveCustomFields &&\n this.isForcePartialIndexEnabled() &&\n opts.tenantId\n ) {\n try {\n await this.indexCoverageStats(entity, opts, coverageScope)\n const globalStats = await this.indexCoverageStats(entity, opts, coverageScope)\n if (globalStats) {\n const globalBase = globalStats.baseCount\n const globalIndexed = globalStats.indexedCount\n const globalGap = (globalBase > 0 && globalIndexed < globalBase) || globalIndexed > globalBase\n if (globalGap) {\n console.warn('[HybridQueryEngine] Partial index coverage detected at global scope; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity, baseCount: globalBase, indexedCount: globalIndexed, scope: 'global' })\n if (debugEnabled) {\n this.debug('query:partial-coverage:forced', {\n entity,\n baseCount: globalBase,\n indexedCount: globalIndexed,\n scope: 'global',\n })\n }\n partialIndexWarning = {\n entity,\n entityLabel: this.resolveEntityLabel(entity),\n baseCount: globalBase,\n indexedCount: globalIndexed,\n scope: 'global',\n }\n }\n }\n } catch (err) {\n if (debugEnabled) {\n this.debug('query:partial-coverage:global-check-failed', {\n entity,\n error: err instanceof Error ? err.message : err,\n })\n }\n }\n }\n\n const resolveBaseColumn = (field: string): string | null => {\n if (columns.has(field)) return field\n if (field === 'organization_id' && columns.has('id')) return 'id'\n return null\n }\n\n for (const filter of cfFilters) {\n builder = this.applyCfFilterAcrossSources(\n knex,\n builder,\n filter.field,\n filter.op,\n filter.value,\n indexSources,\n searchRuntime\n )\n }\n\n const regularBaseFilters = baseFilters.filter((filter) => !filter.orGroup)\n const orGroupFilters = baseFilters.filter((filter) => filter.orGroup)\n\n for (const filter of regularBaseFilters) {\n const fieldName = String(filter.field)\n const baseField = resolveBaseColumn(fieldName)\n if (!baseField) {\n builder = this.applyIndexDocFilterFromAlias(\n knex,\n builder,\n 'ei',\n entity,\n fieldName,\n filter.op,\n filter.value,\n 'b.id',\n searchRuntime,\n )\n if (optimizedCountBuilder) {\n optimizedCountBuilder = this.applyIndexDocFilterFromAlias(\n knex,\n optimizedCountBuilder,\n 'ei',\n entity,\n fieldName,\n filter.op,\n filter.value,\n 'b.id',\n searchRuntime,\n )\n }\n continue\n }\n const column = qualify(baseField)\n builder = this.applyColumnFilter(builder, column, filter, {\n ...searchRuntime,\n knex,\n entity,\n field: fieldName,\n recordIdColumn: 'b.id',\n })\n if (optimizedCountBuilder) {\n optimizedCountBuilder = this.applyColumnFilter(optimizedCountBuilder, column, filter, {\n ...searchRuntime,\n knex,\n entity,\n field: fieldName,\n recordIdColumn: 'b.id',\n })\n }\n }\n\n const applyOrGroupedBaseFilters = (target: ResultBuilder | null): ResultBuilder | null => {\n if (!target || orGroupFilters.length === 0) return target\n const groups = new Map<string, BaseFilter[]>()\n for (const filter of orGroupFilters) {\n if (!filter.orGroup) continue\n const existing = groups.get(filter.orGroup) ?? []\n existing.push(filter)\n groups.set(filter.orGroup, existing)\n }\n let next = target\n for (const [, groupFilters] of groups) {\n if (!groupFilters.length) continue\n next = next.where((groupBuilder) => {\n groupFilters.forEach((filter, index) => {\n const fieldName = String(filter.field)\n const baseField = resolveBaseColumn(fieldName)\n const applyCondition = (conditionBuilder: ResultBuilder) => {\n if (!baseField) {\n this.applyIndexDocFilterFromAlias(\n knex,\n conditionBuilder,\n 'ei',\n entity,\n fieldName,\n filter.op,\n filter.value,\n 'b.id',\n searchRuntime,\n )\n return\n }\n this.applyColumnFilter(conditionBuilder, qualify(baseField), filter, {\n ...searchRuntime,\n knex,\n entity,\n field: fieldName,\n recordIdColumn: 'b.id',\n })\n }\n if (index === 0) {\n applyCondition(groupBuilder as ResultBuilder)\n return\n }\n groupBuilder.orWhere((conditionBuilder) => {\n applyCondition(conditionBuilder as ResultBuilder)\n })\n })\n })\n }\n return next\n }\n\n builder = applyOrGroupedBaseFilters(builder) ?? builder\n optimizedCountBuilder = applyOrGroupedBaseFilters(optimizedCountBuilder)\n\n const applyAliasScopes = async (target: ResultBuilder, aliasName: string) => {\n const tableName = aliasTables.get(aliasName)\n if (!tableName) return\n if (orgScope && await this.columnExists(tableName, 'organization_id')) {\n this.applyOrganizationScope(target, `${aliasName}.organization_id`, orgScope)\n }\n if (opts.tenantId && await this.columnExists(tableName, 'tenant_id')) {\n target.where(`${aliasName}.tenant_id`, opts.tenantId)\n }\n if (!opts.withDeleted && await this.columnExists(tableName, 'deleted_at')) {\n target.whereNull(`${aliasName}.deleted_at`)\n }\n }\n\n const applyJoinFilterOp = (target: ResultBuilder, column: string, op: FilterOp, value?: unknown) => {\n switch (op) {\n case 'eq':\n target.where(column, value as Knex.Value)\n break\n case 'ne':\n target.whereNot(column, value as Knex.Value)\n break\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<='\n target.where(column, operator, value as Knex.Value)\n break\n }\n case 'in':\n target.whereIn(column, this.toArray(value) as readonly Knex.Value[])\n break\n case 'nin':\n target.whereNotIn(column, this.toArray(value) as readonly Knex.Value[])\n break\n case 'like':\n target.where(column, 'like', value as Knex.Value)\n break\n case 'ilike':\n target.where(column, 'ilike', value as Knex.Value)\n break\n case 'exists':\n value ? target.whereNotNull(column) : target.whereNull(column)\n break\n }\n }\n\n const applyJoinSearchFilterOp = async (\n target: ResultBuilder,\n filter: { column: string; op: FilterOp; value?: unknown },\n _qualified: string,\n join: ResolvedJoin,\n ): Promise<boolean> => {\n if (!searchEnabled || !join.entityId) return false\n if (!['like', 'ilike'].includes(filter.op)) return false\n if (typeof filter.value !== 'string' || filter.value.trim().length === 0) return false\n\n let searchAvailable = joinSearchAvailability.get(join.entityId)\n if (searchAvailable === undefined) {\n searchAvailable = await this.hasSearchTokens(String(join.entityId), opts.tenantId ?? null, orgScope)\n joinSearchAvailability.set(join.entityId, searchAvailable)\n }\n if (!searchAvailable) return false\n\n const tokens = tokenizeText(String(filter.value), searchConfig)\n if (!tokens.hashes.length) return false\n\n return this.applySearchTokens(target, {\n knex,\n entity: String(join.entityId),\n field: filter.column,\n hashes: tokens.hashes,\n recordIdColumn: `${join.alias}.id`,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n })\n }\n\n await applyJoinFilters({\n knex,\n baseTable,\n builder,\n joinMap,\n joinFilters,\n aliasTables,\n qualifyBase: (column) => qualify(column),\n applyAliasScope: (target, alias) => applyAliasScopes(target, alias),\n applyFilterOp: (target, column, op, value) => applyJoinFilterOp(target as ResultBuilder, column, op, value),\n applyJoinFilterOp: (target, filter, qualified, join) =>\n applyJoinSearchFilterOp(target as ResultBuilder, filter, qualified, join),\n columnExists: (tbl, column) => this.columnExists(tbl, column),\n }) as ResultBuilder\n\n if (optimizedCountBuilder) {\n await applyJoinFilters({\n knex,\n baseTable,\n builder: optimizedCountBuilder,\n joinMap,\n joinFilters,\n aliasTables,\n qualifyBase: (column) => qualify(column),\n applyAliasScope: (target, alias) => applyAliasScopes(target, alias),\n applyFilterOp: (target, column, op, value) => applyJoinFilterOp(target as ResultBuilder, column, op, value),\n applyJoinFilterOp: (target, filter, qualified, join) =>\n applyJoinSearchFilterOp(target as ResultBuilder, filter, qualified, join),\n columnExists: (tbl, column) => this.columnExists(tbl, column),\n })\n }\n\n // When no fields specified, select all base table columns (like BasicQueryEngine does)\n const selectFieldSet = new Set<string>((opts.fields && opts.fields.length) ? opts.fields.map(String) : Array.from(columns.keys()))\n if (opts.includeCustomFields === true) {\n const entityIds = Array.from(new Set(indexSources.map((src) => String(src.entityId))))\n try {\n const resolvedKeys = await this.resolveAvailableCustomFieldKeys(entityIds, opts.tenantId ?? null)\n resolvedKeys.forEach((key) => selectFieldSet.add(`cf:${key}`))\n if (this.isDebugVerbosity()) {\n this.debug('query:cf:resolved-keys', { entity, keys: resolvedKeys })\n }\n } catch (err) {\n console.warn('[HybridQueryEngine] Failed to resolve custom field keys for', entity, err)\n }\n } else if (Array.isArray(opts.includeCustomFields)) {\n opts.includeCustomFields\n .map((key) => String(key))\n .forEach((key) => selectFieldSet.add(`cf:${key}`))\n }\n const selectFields = Array.from(selectFieldSet)\n for (const field of selectFields) {\n const fieldName = String(field)\n if (fieldName.startsWith('cf:')) {\n const alias = this.sanitize(fieldName)\n const { jsonSql } = this.buildCfExpressions(knex, fieldName, indexSources)\n const exprSql = jsonSql === 'NULL' ? 'NULL::jsonb' : jsonSql\n builder = builder.select(knex.raw(`${exprSql} as ??`, [alias]))\n } else if (columns.has(fieldName)) {\n builder = builder.select(knex.raw('?? as ??', [qualify(fieldName), fieldName]))\n }\n }\n\n for (const sort of opts.sort || []) {\n const fieldName = String(sort.field)\n if (fieldName.startsWith('cf:')) {\n const { textSql } = this.buildCfExpressions(knex, fieldName, indexSources)\n if (textSql !== 'NULL') {\n const direction = sort.dir ?? SortDir.Asc\n builder = builder.orderByRaw(`${textSql} ${direction}`)\n }\n } else {\n const baseField = resolveBaseColumn(fieldName)\n if (!baseField) continue\n builder = builder.orderBy(qualify(baseField), sort.dir ?? SortDir.Asc)\n }\n }\n\n const page = opts.page?.page ?? 1\n const pageSize = opts.page?.pageSize ?? 20\n\n const sqlDebugEnabled = this.isSqlDebugEnabled()\n let total: number\n\n if (optimizedCountBuilder) {\n const countSource = optimizedCountBuilder.clone().clearSelect().clearOrder().select(knex.raw(`${qualify('id')} as id`)).groupBy(qualify('id'))\n const countQuery = knex.from(countSource.as('sq')).count({ count: knex.raw('*') })\n if (debugEnabled && sqlDebugEnabled) {\n const { sql, bindings } = countQuery.clone().toSQL()\n this.debug('query:sql:count', { entity, sql, bindings })\n }\n const countRow = await this.captureSqlTiming(\n 'query:sql:count',\n entity,\n () => countQuery.first(),\n { optimized: true },\n profiler\n )\n total = this.parseCount(countRow)\n } else {\n const countBuilder = builder.clone().clearSelect().clearOrder().countDistinct(`${qualify('id')} as count`)\n if (debugEnabled && sqlDebugEnabled) {\n const { sql, bindings } = countBuilder.clone().toSQL()\n this.debug('query:sql:count', { entity, sql, bindings })\n }\n const countRow = await this.captureSqlTiming(\n 'query:sql:count',\n entity,\n () => countBuilder.first(),\n { optimized: false },\n profiler\n )\n total = this.parseCount(countRow)\n }\n\n const dataBuilder = builder.clone().limit(pageSize).offset((page - 1) * pageSize)\n\n if (debugEnabled && sqlDebugEnabled) {\n const { sql, bindings } = dataBuilder.clone().toSQL()\n this.debug('query:sql:data', { entity, sql, bindings, page, pageSize })\n }\n const itemsRaw = await this.captureSqlTiming(\n 'query:sql:data',\n entity,\n () => dataBuilder,\n { page, pageSize },\n profiler\n )\n if (debugEnabled) this.debug('query:complete', { entity, total, items: Array.isArray(itemsRaw) ? itemsRaw.length : 0 })\n\n let items = itemsRaw as any[]\n const encSvc = this.getEncryptionService()\n const dekKeyCache = new Map<string | null, string | null>()\n if (encSvc?.decryptEntityPayload) {\n const decrypt = encSvc.decryptEntityPayload.bind(encSvc) as (\n entityId: EntityId,\n payload: Record<string, unknown>,\n tenantId: string | null,\n organizationId: string | null,\n ) => Promise<Record<string, unknown>>\n items = await Promise.all(\n items.map(async (item) => {\n try {\n const decrypted = await decrypt(\n entity,\n item,\n item?.tenant_id ?? item?.tenantId ?? opts.tenantId ?? null,\n item?.organization_id ?? item?.organizationId ?? null,\n )\n return { ...item, ...decrypted }\n } catch (err) {\n console.error('Error decrypting entity payload', err);\n return item\n }\n })\n )\n }\n if (encSvc) {\n items = await Promise.all(\n items.map(async (item) => {\n try {\n return await decryptIndexDocCustomFields(\n item,\n {\n tenantId: item?.tenant_id ?? item?.tenantId ?? opts.tenantId ?? null,\n organizationId: item?.organization_id ?? item?.organizationId ?? null,\n },\n encSvc as any,\n dekKeyCache,\n )\n } catch {\n return item\n }\n }),\n )\n }\n\n const typedItems = items as unknown as T[]\n let result: QueryResult<T> = { items: typedItems, page, pageSize, total }\n if (partialIndexWarning) {\n result.meta = { partialIndexWarning }\n }\n\n // --- UMES query extension: after-query pipeline ---\n result = await applyAfterExtensions(result)\n\n finishProfile({\n result: 'ok',\n total,\n page,\n pageSize,\n itemCount: Array.isArray(items) ? items.length : undefined,\n partialIndexWarning: partialIndexWarning ? true : false,\n })\n return result\n } catch (err) {\n finishProfile({ result: 'error', error: err instanceof Error ? err.message : String(err) })\n throw err\n }\n }\n\n private getKnex(): Knex {\n const connection = this.em.getConnection()\n const withKnex = connection as { getKnex?: () => Knex }\n if (typeof withKnex.getKnex === 'function') {\n return withKnex.getKnex()\n }\n throw new Error('HybridQueryEngine requires a SQL connection that exposes getKnex()')\n }\n\n private prepareCustomFieldSources(\n knex: Knex,\n builder: ResultBuilder,\n sources: QueryCustomFieldSource[],\n qualify: (column: string) => string\n ): { builder: ResultBuilder; sources: PreparedCustomFieldSource[] } {\n let current = builder\n const prepared: PreparedCustomFieldSource[] = []\n sources.forEach((source, index) => {\n if (!source) return\n const joinTable = source.table ?? resolveEntityTableName(this.em, source.entityId)\n const alias = source.alias ?? `cfs_${index}`\n const join = source.join\n if (!join) {\n throw new Error(`QueryEngine: customFieldSources entry for ${String(source.entityId)} requires a join configuration`)\n }\n const joinArgs = { [alias]: joinTable }\n const joinCallback = function (this: Knex.JoinClause) {\n this.on(`${alias}.${join.toField}`, '=', qualify(join.fromField))\n }\n current = (join.type ?? 'left') === 'inner'\n ? current.join(joinArgs, joinCallback)\n : current.leftJoin(joinArgs, joinCallback)\n prepared.push({\n alias,\n indexAlias: `ei_${alias}`,\n entityId: source.entityId,\n recordIdColumn: source.recordIdColumn ?? 'id',\n organizationField: source.organizationField,\n tenantField: source.tenantField,\n table: joinTable,\n })\n })\n return { builder: current, sources: prepared }\n }\n\n private async isCustomEntity(entity: string): Promise<boolean> {\n try {\n const knex = this.getKnex()\n const row = await knex('custom_entities').where({ entity_id: entity, is_active: true }).first()\n return !!row\n } catch {\n return false\n }\n }\n\n private applySearchTokens<TRecord extends ResultRow, TResult>(\n q: Knex.QueryBuilder<TRecord, TResult>,\n opts: {\n knex: Knex\n entity: string\n field: string\n hashes: string[]\n recordIdColumn: string\n tenantId?: string | null\n organizationScope?: { ids: string[]; includeNull: boolean } | null\n combineWith?: 'and' | 'or'\n }\n ): boolean {\n if (!opts.hashes.length) {\n this.logSearchDebug('search:skip-no-hashes', {\n entity: opts.entity,\n field: opts.field,\n tenantId: opts.tenantId ?? null,\n organizationScope: opts.organizationScope,\n })\n return false\n }\n const alias = `st_${this.searchAliasSeq++}`\n const combineWith = opts.combineWith === 'or' ? 'orWhereExists' : 'whereExists'\n const engine = this\n this.logSearchDebug('search:apply-search-tokens', {\n entity: opts.entity,\n field: opts.field,\n alias,\n tokenCount: opts.hashes.length,\n tenantId: opts.tenantId ?? null,\n organizationScope: opts.organizationScope,\n combineWith: opts.combineWith ?? 'and',\n })\n ;(q as any)[combineWith](function (this: Knex.QueryBuilder) {\n this.select(1)\n .from({ [alias]: 'search_tokens' })\n .where(`${alias}.entity_type`, opts.entity)\n .andWhere(`${alias}.field`, opts.field)\n .andWhereRaw('?? = ??::text', [`${alias}.entity_id`, opts.recordIdColumn])\n .whereIn(`${alias}.token_hash`, opts.hashes)\n .groupBy(`${alias}.entity_id`, `${alias}.field`)\n .havingRaw(`count(distinct ${alias}.token_hash) >= ?`, [opts.hashes.length])\n if (opts.tenantId !== undefined) {\n this.andWhereRaw(`${alias}.tenant_id is not distinct from ?`, [opts.tenantId ?? null])\n }\n if (opts.organizationScope) {\n engine.applyOrganizationScope(this as any, `${alias}.organization_id`, opts.organizationScope)\n }\n })\n return true\n }\n\n private jsonbRawAlias(knex: Knex, alias: string, key: string): Knex.Raw {\n // Prefer cf:<key> but fall back to bare <key> for legacy docs\n if (key.startsWith('cf:')) {\n const bare = key.slice(3)\n return knex.raw(`coalesce(${alias}.doc -> ?, ${alias}.doc -> ?)`, [key, bare])\n }\n return knex.raw(`${alias}.doc -> ?`, [key])\n }\n private cfTextExprAlias(knex: Knex, alias: string, key: string): Knex.Raw {\n if (key.startsWith('cf:')) {\n const bare = key.slice(3)\n return knex.raw(`coalesce((${alias}.doc ->> ?), (${alias}.doc ->> ?))`, [key, bare])\n }\n return knex.raw(`(${alias}.doc ->> ?)`, [key])\n }\n private buildCfExpressions(knex: Knex, key: string, sources: IndexDocSource[]): { jsonSql: string; textSql: string } {\n if (!sources.length) return { jsonSql: 'NULL', textSql: 'NULL' }\n const jsonFragments = sources.map((source) => this.jsonbRawAlias(knex, source.alias, key).toString())\n const textFragments = sources.map((source) => this.cfTextExprAlias(knex, source.alias, key).toString())\n const jsonSql = jsonFragments.length === 1 ? jsonFragments[0] : `coalesce(${jsonFragments.join(', ')})`\n const textSql = textFragments.length === 1 ? textFragments[0] : `coalesce(${textFragments.join(', ')})`\n return { jsonSql, textSql }\n }\n\n private applyCfFilterAcrossSources(\n knex: Knex,\n builder: ResultBuilder,\n key: string,\n op: FilterOp,\n value: unknown,\n sources: IndexDocSource[],\n search?: SearchRuntime\n ): ResultBuilder {\n if (!sources.length) return builder\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n let applied = false\n if (sources.length) {\n builder = builder.where((qb) => {\n sources.forEach((source, idx) => {\n const ok = this.applySearchTokens(qb as any, {\n knex,\n entity: source.entityId,\n field: key,\n hashes,\n recordIdColumn: `${source.alias}.entity_id`,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n combineWith: idx === 0 ? 'and' : 'or',\n })\n if (ok) applied = true\n })\n })\n }\n this.logSearchDebug('search:cf-filter-across', {\n entity: sources.map((src) => src.entityId),\n field: key,\n tokens: tokens.tokens,\n hashes,\n applied,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope,\n })\n if (applied) return builder\n } else {\n this.logSearchDebug('search:cf-skip-empty-hashes', {\n entity: sources.map((src) => src.entityId),\n field: key,\n value,\n })\n }\n return builder\n }\n const { jsonSql, textSql } = this.buildCfExpressions(knex, key, sources)\n if (jsonSql === 'NULL' || textSql === 'NULL') return builder\n const textExpr = knex.raw(textSql)\n const arrContains = (val: unknown) => knex.raw(`${jsonSql} @> ?::jsonb`, [JSON.stringify([val])])\n switch (op) {\n case 'eq':\n return builder.where((qb) => {\n qb.orWhere(textExpr, '=', value as Knex.Value)\n qb.orWhere(arrContains(value))\n })\n case 'ne':\n return builder.whereNot(textExpr, '=', value as Knex.Value)\n case 'in': {\n const values = this.toArray(value)\n return builder.where((qb) => {\n values.forEach((val) => {\n qb.orWhere(textExpr, '=', val as Knex.Value)\n qb.orWhere(arrContains(val))\n })\n })\n }\n case 'nin': {\n const values = this.toArray(value) as readonly Knex.Value[]\n return builder.whereNotIn(textExpr as any, values as any)\n }\n case 'like':\n return builder.where(textExpr, 'like', value as Knex.Value)\n case 'ilike':\n return builder.where(textExpr, 'ilike', value as Knex.Value)\n case 'exists':\n return value\n ? builder.whereRaw(`${textExpr.toString()} is not null`)\n : builder.whereRaw(`${textExpr.toString()} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<='\n return builder.where(textExpr, operator, value as Knex.Value)\n }\n default:\n return builder\n }\n }\n\n private applyCfFilterFromAlias(\n knex: Knex,\n q: ResultBuilder,\n alias: string,\n entityType: string,\n key: string,\n op: FilterOp,\n value: unknown,\n search?: SearchRuntime\n ): ResultBuilder {\n const text = this.cfTextExprAlias(knex, alias, key)\n const arrExpr = knex.raw(`(${alias}.doc -> ?)`, [key])\n const arrContains = (val: unknown) => knex.raw(`${arrExpr.toString()} @> ?::jsonb`, [JSON.stringify([val])])\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const applied = this.applySearchTokens(q, {\n knex,\n entity: entityType,\n field: key,\n hashes,\n recordIdColumn: `${alias}.entity_id`,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n })\n this.logSearchDebug('search:cf-filter', {\n entity: entityType,\n field: key,\n tokens: tokens.tokens,\n hashes,\n applied,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope,\n })\n if (applied) return q\n } else {\n this.logSearchDebug('search:cf-skip-empty-hashes', {\n entity: entityType,\n field: key,\n value,\n })\n }\n return q\n }\n switch (op) {\n case 'eq':\n return q.where((builder) => {\n builder.orWhere(text, '=', value as Knex.Value)\n builder.orWhere(arrContains(value))\n })\n case 'ne':\n return q.whereNot(text, '=', value as Knex.Value)\n case 'in': {\n const vals = this.toArray(value)\n return q.where((builder) => {\n vals.forEach((val) => {\n builder.orWhere(text, '=', val as Knex.Value)\n builder.orWhere(arrContains(val))\n })\n })\n }\n case 'nin': {\n const vals = this.toArray(value) as readonly Knex.Value[]\n return q.whereNotIn(text as any, vals as any)\n }\n case 'like':\n return q.where(text, 'like', value as Knex.Value)\n case 'ilike':\n return q.where(text, 'ilike', value as Knex.Value)\n case 'exists':\n return value\n ? q.whereRaw(`${text.toString()} is not null`)\n : q.whereRaw(`${text.toString()} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<='\n return q.where(text, operator, value as Knex.Value)\n }\n default:\n return q\n }\n }\n\n private applyIndexDocFilterFromAlias(\n knex: Knex,\n q: ResultBuilder,\n alias: string,\n entityType: string,\n key: string,\n op: FilterOp,\n value: unknown,\n recordIdColumn: string,\n search?: SearchRuntime,\n ): ResultBuilder {\n const text = knex.raw(`(${alias}.doc ->> ?)`, [key])\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const applied = this.applySearchTokens(q, {\n knex,\n entity: entityType,\n field: key,\n hashes,\n recordIdColumn,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n })\n this.logSearchDebug('search:index-doc-filter', {\n entity: entityType,\n field: key,\n tokens: tokens.tokens,\n hashes,\n applied,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope,\n })\n if (applied) return q\n } else {\n this.logSearchDebug('search:index-doc-skip-empty-hashes', {\n entity: entityType,\n field: key,\n value,\n })\n }\n return q\n }\n switch (op) {\n case 'eq':\n return q.where(text, '=', value as Knex.Value)\n case 'ne':\n return q.where(text, '!=', value as Knex.Value)\n case 'in':\n return q.whereIn(text as any, this.toArray(value) as readonly Knex.Value[])\n case 'nin':\n return q.whereNotIn(text as any, this.toArray(value) as readonly Knex.Value[])\n case 'like':\n return q.where(text, 'like', value as Knex.Value)\n case 'ilike':\n return q.where(text, 'ilike', value as Knex.Value)\n case 'exists':\n return value\n ? q.whereRaw(`${text.toString()} is not null`)\n : q.whereRaw(`${text.toString()} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<='\n return q.where(text, operator, value as Knex.Value)\n }\n default:\n return q\n }\n }\n\n private async queryCustomEntity<T = unknown>(entity: string, opts: QueryOptions = {}): Promise<QueryResult<T>> {\n const knex = this.getKnex()\n const alias = 'ce'\n let q = knex({ [alias]: 'custom_entities_storage' }).where(`${alias}.entity_type`, entity)\n\n const orgScope = this.resolveOrganizationScope(opts)\n\n // Require tenant scope; custom entities are tenant-scoped only\n if (!opts.tenantId) throw new Error('QueryEngine: tenantId is required')\n q = q.andWhere(`${alias}.tenant_id`, opts.tenantId)\n if (orgScope) {\n q = this.applyOrganizationScope(q, `${alias}.organization_id`, orgScope)\n }\n if (!opts.withDeleted) q = q.whereNull(`${alias}.deleted_at`)\n const searchConfig = resolveSearchConfig()\n const searchEnabled = searchConfig.enabled && await this.tableExists('search_tokens')\n const hasSearchTokens = searchEnabled\n ? await this.hasSearchTokens(entity, opts.tenantId ?? null, orgScope)\n : false\n const searchRuntime: SearchRuntime = {\n enabled: searchEnabled && hasSearchTokens,\n config: searchConfig,\n organizationScope: orgScope,\n tenantId: opts.tenantId ?? null,\n }\n\n const normalizedFilters = normalizeFilters(opts.filters)\n\n // Apply filters: cf:* via JSONB; other keys: special-case id/created_at/updated_at/deleted_at, otherwise from doc\n for (const filter of normalizedFilters) {\n if (filter.field.startsWith('cf:')) {\n q = this.applyCfFilterFromAlias(knex, q, alias, entity, filter.field, filter.op, filter.value, searchRuntime)\n continue\n }\n const column = this.resolveCustomEntityColumn(alias, String(filter.field))\n if (column) {\n q = this.applyColumnFilter(q, column, filter, {\n ...searchRuntime,\n knex,\n entity,\n field: String(filter.field),\n recordIdColumn: `${alias}.entity_id`,\n })\n continue\n }\n const docExpr = knex.raw(`(${alias}.doc ->> ?)`, [String(filter.field)])\n q = this.applyColumnFilter(q, docExpr, filter, {\n ...searchRuntime,\n knex,\n entity,\n field: String(filter.field),\n recordIdColumn: `${alias}.entity_id`,\n })\n }\n\n // Determine CFs and l10n keys to include\n const cfKeys = new Set<string>()\n for (const f of (opts.fields || [])) {\n if (typeof f === 'string' && f.startsWith('cf:')) cfKeys.add(f.slice(3))\n else if (typeof f === 'string' && f.startsWith('l10n:')) cfKeys.add(f)\n }\n for (const filter of normalizedFilters) {\n if (typeof filter.field === 'string' && filter.field.startsWith('cf:')) cfKeys.add(filter.field.slice(3))\n else if (typeof filter.field === 'string' && filter.field.startsWith('l10n:')) cfKeys.add(filter.field)\n }\n if (opts.includeCustomFields === true) {\n try {\n const rows = await knex('custom_field_defs')\n .select('key')\n .where({ entity_id: entity, is_active: true })\n .modify((qb) => {\n qb.andWhere({ tenant_id: opts.tenantId })\n // NOTE: organization-level scoping intentionally disabled for custom fields\n // if (opts.organizationId != null) qb.andWhere((b: any) => b.where({ organization_id: opts.organizationId }).orWhereNull('organization_id'))\n // else qb.whereNull('organization_id')\n })\n for (const row of rows) {\n const key = (row as Record<string, unknown>).key\n if (typeof key === 'string') {\n cfKeys.add(key)\n } else if (key != null) {\n cfKeys.add(String(key))\n }\n }\n } catch {\n // ignore and fall back to whatever keys we already have\n }\n } else if (Array.isArray(opts.includeCustomFields)) {\n for (const k of opts.includeCustomFields) cfKeys.add(k)\n }\n\n // Selection\n const requested = (opts.fields && opts.fields.length) ? opts.fields : ['id']\n for (const field of requested) {\n const f = String(field)\n if (f.startsWith('cf:')) {\n const aliasName = this.sanitize(f)\n const expr = this.jsonbRawAlias(knex, alias, f)\n q = q.select({ [aliasName]: expr })\n } else if (f === 'id') {\n q = q.select(knex.raw(`${alias}.entity_id as ??`, ['id']))\n } else if (f === 'created_at' || f === 'updated_at' || f === 'deleted_at') {\n q = q.select(knex.raw(`${alias}.?? as ??`, [f, f]))\n } else {\n // Non-cf from doc\n const expr = knex.raw(`(${alias}.doc ->> ?)`, [f])\n q = q.select({ [f]: expr })\n }\n }\n // Ensure CFs necessary for sort are selected\n const cfSelectedAliases: string[] = []\n for (const key of cfKeys) {\n const aliasName = this.sanitize(`cf:${key}`)\n const expr = this.jsonbRawAlias(knex, alias, `cf:${key}`)\n q = q.select({ [aliasName]: expr })\n cfSelectedAliases.push(aliasName)\n }\n\n // Sorting\n for (const s of opts.sort || []) {\n if (s.field.startsWith('cf:')) {\n const key = s.field.slice(3)\n const aliasName = this.sanitize(`cf:${key}`)\n if (!cfSelectedAliases.includes(aliasName)) {\n const expr = this.jsonbRawAlias(knex, alias, `cf:${key}`)\n q = q.select({ [aliasName]: expr })\n cfSelectedAliases.push(aliasName)\n }\n q = q.orderBy(aliasName, s.dir ?? SortDir.Asc)\n } else if (s.field === 'id') {\n q = q.orderBy(`${alias}.entity_id`, s.dir ?? SortDir.Asc)\n } else if (s.field === 'created_at' || s.field === 'updated_at' || s.field === 'deleted_at') {\n q = q.orderBy(`${alias}.${s.field}`, s.dir ?? SortDir.Asc)\n } else {\n const direction = s.dir ?? SortDir.Asc\n q = q.orderByRaw(`(${alias}.doc ->> ?) ${direction}`, [s.field])\n }\n }\n\n // Pagination + totals\n const page = opts.page?.page ?? 1\n const pageSize = opts.page?.pageSize ?? 20\n const countClone = q.clone()\n if (typeof countClone.clearSelect === 'function') countClone.clearSelect()\n if (typeof countClone.clearOrder === 'function') countClone.clearOrder()\n const countRow = await countClone.countDistinct(`${alias}.entity_id as count`).first()\n const total = this.parseCount(countRow)\n const items = await q.limit(pageSize).offset((page - 1) * pageSize)\n return { items, page, pageSize, total }\n }\n\n private async tableExists(table: string): Promise<boolean> {\n const knex = this.getKnex()\n const exists = await knex('information_schema.tables').where({ table_name: table }).first()\n return !!exists\n }\n\n private async hasSearchTokens(\n entity: string,\n tenantId: string | null,\n orgScope?: { ids: string[]; includeNull: boolean } | null\n ): Promise<boolean> {\n try {\n const knex = this.getKnex()\n const query = knex('search_tokens').select(1).where('entity_type', entity).limit(1)\n if (tenantId !== undefined) {\n query.andWhereRaw('tenant_id is not distinct from ?', [tenantId])\n }\n if (orgScope) {\n this.applyOrganizationScope(query as any, 'search_tokens.organization_id', orgScope)\n }\n const row = await query.first()\n return !!row\n } catch (err) {\n this.logSearchDebug('search:has-tokens-error', {\n entity,\n tenantId,\n organizationScope: orgScope,\n error: err instanceof Error ? err.message : String(err),\n })\n return false\n }\n }\n\n private async searchSourcesHaveTokens(\n sources: SearchTokenSource[],\n tenantId: string | null,\n orgScope?: { ids: string[]; includeNull: boolean } | null\n ): Promise<boolean> {\n for (const source of sources) {\n const ok = await this.hasSearchTokens(source.entity, tenantId, orgScope)\n this.logSearchDebug('search:source-has-tokens', {\n entity: source.entity,\n recordIdColumn: source.recordIdColumn,\n tenantId,\n organizationScope: orgScope,\n hasTokens: ok,\n })\n if (ok) return true\n }\n return false\n }\n\n private async resolveAvailableCustomFieldKeys(entityIds: string[], tenantId: string | null): Promise<string[]> {\n if (!entityIds.length) return []\n const cacheKey = this.customFieldKeysCacheKey(entityIds, tenantId)\n const now = Date.now()\n const cached = this.customFieldKeysCache.get(cacheKey)\n if (cached && cached.expiresAt > now) {\n return cached.value.slice()\n }\n\n const knex = this.getKnex()\n const rows = await knex('custom_field_defs')\n .select('key')\n .whereIn('entity_id', entityIds)\n .andWhere('is_active', true)\n .modify((qb: any) => {\n qb.andWhere((inner: any) => {\n inner.where({ tenant_id: tenantId }).orWhereNull('tenant_id')\n })\n })\n const keys = new Set<string>()\n for (const row of rows || []) {\n const key = (row as Record<string, unknown>).key\n if (typeof key === 'string' && key.trim().length) keys.add(key.trim())\n else if (key != null) keys.add(String(key))\n }\n const result = Array.from(keys)\n if (this.customFieldKeysTtlMs > 0) {\n this.customFieldKeysCache.set(cacheKey, { expiresAt: now + this.customFieldKeysTtlMs, value: result })\n }\n return result.slice()\n }\n\n private async entityHasActiveCustomFields(entityId: string, tenantId: string | null): Promise<boolean> {\n try {\n const keys = await this.resolveAvailableCustomFieldKeys([entityId], tenantId)\n return keys.length > 0\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('query:cf:check-error', {\n entity: entityId,\n tenantId: tenantId ?? null,\n error: err instanceof Error ? err.message : err,\n })\n }\n return true\n }\n }\n\n private customFieldKeysCacheKey(entityIds: string[], tenantId: string | null): string {\n const sorted = entityIds.slice().sort((a, b) => a.localeCompare(b)).join(',')\n return `${tenantId ?? '__none__'}|${sorted}`\n }\n\n private resolveVectorService(): VectorIndexService | null {\n if (!this.vectorServiceResolver) return null\n try {\n return this.vectorServiceResolver() ?? null\n } catch {\n return null\n }\n }\n\n private resolveEntityLabel(entity: string): string {\n return entity\n }\n\n private async indexAnyRows(entity: string): Promise<boolean> {\n const knex = this.getKnex()\n // Prefer coverage snapshots \u2013 cheap and already scoped by maintenance jobs.\n const coverage = await knex('entity_index_coverage')\n .select(1)\n .where('entity_type', entity)\n .where('indexed_count', '>', 0)\n .first()\n if (coverage) return true\n const exists = await knex('entity_indexes').select('entity_id').where({ entity_type: entity }).first()\n return !!exists\n }\n private async getStoredCoverageSnapshot(\n entity: string,\n tenantId: string | null,\n organizationId: string | null,\n withDeleted: boolean\n ): Promise<{ baseCount: number; indexedCount: number } | null> {\n try {\n if (!this.isCoverageOptimizationEnabled()) {\n await refreshCoverageSnapshot(\n this.em,\n {\n entityType: entity,\n tenantId,\n organizationId,\n withDeleted,\n },\n )\n }\n const knex = this.getKnex()\n const row = await readCoverageSnapshot(knex, {\n entityType: entity,\n tenantId,\n organizationId,\n withDeleted,\n })\n if (!row) return null\n return { baseCount: row.baseCount, indexedCount: row.indexedCount }\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('coverage:snapshot:read-error', {\n entity,\n tenantId,\n organizationId,\n withDeleted,\n error: err instanceof Error ? err.message : err,\n })\n }\n return null\n }\n }\n\n private scheduleAutoReindex(\n entity: string,\n opts: QueryOptions,\n stats?: { baseCount: number; indexedCount: number },\n organizationIdOverride?: string | null\n ) {\n if (!this.isAutoReindexEnabled()) return\n\n const bus = this.resolveEventBus()\n if (!bus) return\n const payload = {\n entityType: entity,\n tenantId: opts.tenantId ?? null,\n organizationId: organizationIdOverride ?? opts.organizationId ?? null,\n force: false,\n }\n const context = stats\n ? {\n entity,\n tenantId: payload.tenantId,\n organizationId: payload.organizationId,\n baseCount: stats.baseCount,\n indexedCount: stats.indexedCount,\n }\n : { entity, tenantId: payload.tenantId, organizationId: payload.organizationId }\n\n void Promise.resolve()\n .then(async () => {\n try {\n await bus.emitEvent('query_index.reindex', payload, { persistent: true })\n if (this.isDebugVerbosity()) this.debug('query:auto-reindex:scheduled', context)\n } catch (err) {\n console.warn('[HybridQueryEngine] Failed to schedule auto reindex:', {\n ...context,\n error: err instanceof Error ? err.message : err,\n })\n }\n })\n }\n\n private scheduleCoverageRefresh(\n entity: string,\n tenantId: string | null | undefined,\n organizationId: string | null | undefined,\n withDeleted: boolean\n ): void {\n const bus = this.resolveEventBus()\n if (!bus) return\n const key = [\n entity,\n tenantId ?? '__tenant__',\n organizationId ?? '__org__',\n withDeleted ? '1' : '0',\n ].join('|')\n if (this.pendingCoverageRefreshKeys.has(key)) return\n this.pendingCoverageRefreshKeys.add(key)\n void Promise.resolve()\n .then(async () => {\n try {\n await bus.emitEvent('query_index.coverage.refresh', {\n entityType: entity,\n tenantId: tenantId ?? null,\n organizationId: organizationId ?? null,\n withDeleted,\n delayMs: 0,\n })\n if (this.isDebugVerbosity()) {\n this.debug('coverage:refresh:scheduled', {\n entity,\n tenantId: tenantId ?? null,\n organizationId: organizationId ?? null,\n withDeleted,\n })\n }\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('coverage:refresh:failed', {\n entity,\n tenantId: tenantId ?? null,\n organizationId: organizationId ?? null,\n withDeleted,\n error: err instanceof Error ? err.message : err,\n })\n }\n }\n })\n .finally(() => {\n this.pendingCoverageRefreshKeys.delete(key)\n })\n }\n\n private resolveEventBus(): Pick<EventBus, 'emitEvent'> | null {\n if (!this.eventBusResolver) return null\n try {\n const bus = this.eventBusResolver()\n return bus ?? null\n } catch {\n return null\n }\n }\n\n private isAutoReindexEnabled(): boolean {\n if (this.autoReindexEnabled != null) return this.autoReindexEnabled\n const raw = (\n process.env.SCHEDULE_AUTO_REINDEX ??\n process.env.QUERY_INDEX_AUTO_REINDEX ??\n ''\n )\n .trim()\n .toLowerCase()\n if (!raw) {\n this.autoReindexEnabled = true\n return true\n }\n const parsed = parseBooleanToken(raw)\n this.autoReindexEnabled = parsed === null ? true : parsed\n return this.autoReindexEnabled\n }\n\n private isCoverageOptimizationEnabled(): boolean {\n if (this.coverageOptimizationEnabled != null) return this.coverageOptimizationEnabled\n const raw = (process.env.OPTIMIZE_INDEX_COVERAGE_STATS ?? '').trim().toLowerCase()\n if (!raw) {\n this.coverageOptimizationEnabled = false\n return false\n }\n this.coverageOptimizationEnabled = parseBooleanToken(raw) === true\n return this.coverageOptimizationEnabled\n }\n\n private async columnExists(table: string, column: string): Promise<boolean> {\n const key = `${table}.${column}`\n if (this.columnCache.has(key)) {\n const cached = this.columnCache.get(key)\n if (cached === true) return true\n this.columnCache.delete(key)\n }\n const knex = this.getKnex()\n const exists = await knex('information_schema.columns')\n .where({ table_name: table, column_name: column })\n .first()\n const present = !!exists\n if (present) this.columnCache.set(key, true)\n else this.columnCache.delete(key)\n return present\n }\n\n private async getBaseColumnsForEntity(entity: string): Promise<Map<string, string>> {\n const knex = this.getKnex()\n const table = resolveEntityTableName(this.em, entity)\n const rows = await knex('information_schema.columns')\n .select('column_name', 'data_type')\n .where({ table_name: table })\n const map = new Map<string, string>()\n for (const r of rows) map.set(r.column_name, r.data_type)\n return map\n }\n\n private resolveOrganizationScope(opts: QueryOptions): { ids: string[]; includeNull: boolean } | null {\n if (opts.organizationIds !== undefined) {\n const raw = (opts.organizationIds ?? []).map((id) => (typeof id === 'string' ? id.trim() : id))\n const includeNull = raw.some((id) => id == null || id === '')\n const ids = raw.filter((id): id is string => typeof id === 'string' && id.length > 0)\n const unique = Array.from(new Set(ids))\n return { ids: unique, includeNull }\n }\n if (typeof opts.organizationId === 'string' && opts.organizationId.trim().length > 0) {\n return { ids: [opts.organizationId], includeNull: false }\n }\n return null\n }\n\n private resolveCoverageSnapshotScope(\n opts: QueryOptions\n ): { tenantId: string | null; organizationId: string | null } | null {\n const tenantId = opts.tenantId ?? null\n const orgScope = this.resolveOrganizationScope(opts)\n if (!orgScope) return { tenantId, organizationId: null }\n if (orgScope.includeNull) {\n if (orgScope.ids.length === 0) return { tenantId, organizationId: null }\n return null\n }\n if (orgScope.ids.length === 1) return { tenantId, organizationId: orgScope.ids[0] }\n if (orgScope.ids.length === 0) return { tenantId, organizationId: null }\n return null\n }\n\n private applyOrganizationScope<TRecord extends ResultRow, TResult>(\n q: Knex.QueryBuilder<TRecord, TResult>,\n column: string,\n scope: { ids: string[]; includeNull: boolean }\n ): Knex.QueryBuilder<TRecord, TResult> {\n if (scope.ids.length === 0 && !scope.includeNull) {\n return q.whereRaw('1 = 0')\n }\n return q.where((builder) => {\n let applied = false\n if (scope.ids.length > 0) {\n builder.whereIn(column, scope.ids as readonly string[])\n applied = true\n }\n if (scope.includeNull) {\n if (applied) builder.orWhereNull(column)\n else builder.whereNull(column)\n } else if (!applied) {\n builder.whereRaw('1 = 0')\n }\n })\n }\n\n private normalizeFilters(filters?: QueryOptions['filters']): NormalizedFilter[] {\n if (!filters) return []\n const normalizeField = (k: string) => k.startsWith('cf_') ? `cf:${k.slice(3)}` : k\n if (Array.isArray(filters)) {\n return (filters as Filter[]).map((filter) => ({\n field: normalizeField(String(filter.field)),\n op: filter.op,\n value: filter.value,\n }))\n }\n const out: NormalizedFilter[] = []\n const obj = filters as Record<string, unknown>\n const add = (field: string, op: FilterOp, value?: unknown) => out.push({ field, op, value })\n for (const [rawKey, rawVal] of Object.entries(obj)) {\n const field = normalizeField(rawKey)\n if (rawVal !== null && typeof rawVal === 'object' && !Array.isArray(rawVal)) {\n for (const [opKey, opVal] of Object.entries(rawVal as Record<string, unknown>)) {\n switch (opKey) {\n case '$eq': add(field, 'eq', opVal); break\n case '$ne': add(field, 'ne', opVal); break\n case '$gt': add(field, 'gt', opVal); break\n case '$gte': add(field, 'gte', opVal); break\n case '$lt': add(field, 'lt', opVal); break\n case '$lte': add(field, 'lte', opVal); break\n case '$in': add(field, 'in', opVal); break\n case '$nin': add(field, 'nin', opVal); break\n case '$like': add(field, 'like', opVal); break\n case '$ilike': add(field, 'ilike', opVal); break\n case '$exists': add(field, 'exists', opVal); break\n }\n }\n } else {\n add(field, 'eq', rawVal)\n }\n }\n return out\n }\n\n private sanitize(s: string): string {\n return s.replace(/[^a-zA-Z0-9_]/g, '_')\n }\n\n private toArray(value: unknown): readonly unknown[] {\n if (Array.isArray(value)) {\n return value\n }\n if (value === undefined) {\n return []\n }\n return [value]\n }\n\n private parseCount(row: unknown): number {\n if (row && typeof row === 'object' && 'count' in row) {\n const value = (row as { count: unknown }).count\n if (typeof value === 'number') return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? 0 : parsed\n }\n }\n return 0\n }\n\n private logSearchDebug(event: string, payload: Record<string, unknown>) {\n if (!this.isDebugVerbosity()) return\n try {\n console.info('[query-index:search]', event, JSON.stringify(payload))\n } catch {\n console.info('[query-index:search]', event, payload)\n }\n }\n\n private applyColumnFilter<TRecord extends ResultRow, TResult>(\n q: Knex.QueryBuilder<TRecord, TResult>,\n column: string | Knex.Raw,\n filter: NormalizedFilter,\n search?: SearchRuntime & { knex: Knex; entity: string; field: string; recordIdColumn?: string }\n ): Knex.QueryBuilder<TRecord, TResult> {\n if (\n (filter.op === 'like' || filter.op === 'ilike') &&\n search?.enabled &&\n typeof filter.value === 'string'\n ) {\n const tokens = tokenizeText(String(filter.value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const sources: SearchTokenSource[] = (search.searchSources && search.searchSources.length\n ? search.searchSources\n : [{ entity: search.entity, recordIdColumn: search.recordIdColumn ?? '' }]\n ).filter((src) => src.recordIdColumn && src.entity)\n let applied = false\n if (sources.length) {\n q = q.where((qb) => {\n sources.forEach((src, idx) => {\n const ok = this.applySearchTokens(qb as any, {\n knex: search.knex,\n entity: src.entity,\n field: search.field,\n hashes,\n recordIdColumn: src.recordIdColumn,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n combineWith: idx === 0 ? 'and' : 'or',\n })\n if (ok) applied = true\n })\n })\n }\n this.logSearchDebug('search:filter', {\n entity: search.entity,\n field: search.field,\n tokens: tokens.tokens,\n hashes,\n applied,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope,\n sources: sources.map((src) => ({ entity: src.entity, recordIdColumn: src.recordIdColumn })),\n })\n if (applied) return q\n } else {\n this.logSearchDebug('search:skip-empty-hashes', {\n entity: search.entity,\n field: search.field,\n value: filter.value,\n })\n }\n return q\n }\n const col = column as any\n switch (filter.op) {\n case 'eq':\n return q.where(col, filter.value as Knex.Value)\n case 'ne':\n return q.whereNot(col, filter.value as Knex.Value)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = filter.op === 'gt' ? '>' : filter.op === 'gte' ? '>=' : filter.op === 'lt' ? '<' : '<='\n return q.where(col, operator, filter.value as Knex.Value)\n }\n case 'in': {\n const values = this.toArray(filter.value) as readonly Knex.Value[]\n return q.whereIn(col, values)\n }\n case 'nin': {\n const values = this.toArray(filter.value) as readonly Knex.Value[]\n return q.whereNotIn(col, values)\n }\n case 'like':\n return q.where(col, 'like', filter.value as Knex.Value)\n case 'ilike':\n return q.where(col, 'ilike', filter.value as Knex.Value)\n case 'exists':\n return filter.value ? q.whereNotNull(col) : q.whereNull(col)\n default:\n return q\n }\n }\n\n private resolveCustomEntityColumn(alias: string, field: string): string | null {\n if (field === 'id') return `${alias}.entity_id`\n if (field === 'organization_id' || field === 'organizationId') return `${alias}.organization_id`\n if (field === 'tenant_id' || field === 'tenantId') return `${alias}.tenant_id`\n if (field === 'created_at' || field === 'updated_at' || field === 'deleted_at') return `${alias}.${field}`\n return null\n }\n\n private isDebugVerbosity(): boolean {\n if (this.debugVerbosity != null) return this.debugVerbosity\n this.debugVerbosity = resolveDebugVerbosity()\n return this.debugVerbosity\n }\n\n private isSqlDebugEnabled(): boolean {\n if (this.sqlDebugEnabled != null) return this.sqlDebugEnabled\n this.sqlDebugEnabled = resolveBooleanEnv(['QUERY_ENGINE_DEBUG_SQL'], false)\n return this.sqlDebugEnabled\n }\n\n private isForcePartialIndexEnabled(): boolean {\n if (this.forcePartialIndexEnabled != null) return this.forcePartialIndexEnabled\n this.forcePartialIndexEnabled = resolveBooleanEnv(['FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES'], false)\n return this.forcePartialIndexEnabled\n }\n\n private async resolveCoverageGap(\n entity: string,\n opts: QueryOptions,\n coverageScope?: { tenantId: string | null; organizationId: string | null } | null,\n _sourceTable?: string\n ): Promise<{ stats?: { baseCount: number; indexedCount: number }; scope: 'scoped' | 'global' } | null> {\n const scope = coverageScope ?? this.resolveCoverageSnapshotScope(opts)\n if (!scope) return null\n const tenantId = scope.tenantId\n const organizationId = scope.organizationId\n const withDeleted = !!opts.withDeleted\n\n const snapshot = await this.getStoredCoverageSnapshot(entity, tenantId, organizationId, withDeleted)\n if (!snapshot) {\n this.scheduleCoverageRefresh(entity, tenantId, organizationId, withDeleted)\n return { stats: undefined, scope: 'scoped' }\n }\n\n const baseCount = snapshot.baseCount\n const indexCount = snapshot.indexedCount\n const hasGap = baseCount > 0 && indexCount < baseCount\n if (hasGap || indexCount > baseCount) {\n return { stats: snapshot, scope: 'scoped' }\n }\n\n return null\n }\n\n // Backward-compatible hook for tests that mock coverage stats\n private async indexCoverageStats(\n entity: string,\n opts: QueryOptions,\n coverageScope?: { tenantId: string | null; organizationId: string | null } | null,\n ): Promise<{ baseCount: number; indexedCount: number } | null> {\n const gap = await this.resolveCoverageGap(entity, opts, coverageScope)\n return gap?.stats ?? null\n }\n\n private async captureSqlTiming<TResult>(\n label: string,\n entity: EntityId,\n execute: () => Promise<TResult> | TResult,\n extra?: Record<string, unknown>,\n profiler?: Profiler\n ): Promise<TResult> {\n const shouldDebug = this.isSqlDebugEnabled() && this.isDebugVerbosity()\n const shouldProfile = profiler?.enabled === true\n if (!shouldDebug && !shouldProfile) {\n return Promise.resolve(execute())\n }\n const startedAt = process.hrtime.bigint()\n try {\n return await Promise.resolve(execute())\n } finally {\n const elapsedMs = Number(process.hrtime.bigint() - startedAt) / 1_000_000\n const context: Record<string, unknown> = {\n entity,\n durationMs: Math.round(elapsedMs * 1000) / 1000,\n }\n if (extra) Object.assign(context, extra)\n if (shouldProfile) profiler!.record(label, context.durationMs as number, extra)\n if (shouldDebug) this.debug(`${label}:timing`, context)\n }\n }\n\n private debug(message: string, context?: Record<string, unknown>): void {\n if (!this.isDebugVerbosity()) return\n if (!this.isSqlDebugEnabled()) return\n if (context) console.debug('[HybridQueryEngine]', message, context)\n else console.debug('[HybridQueryEngine]', message)\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { QueryEngine, QueryOptions, QueryResult, FilterOp, Filter, QueryCustomFieldSource, PartialIndexWarning, QueryExtensionsConfig } from '@open-mercato/shared/lib/query/types'\nimport { SortDir } from '@open-mercato/shared/lib/query/types'\nimport type { EntityId } from '@open-mercato/shared/modules/entities'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { BasicQueryEngine, resolveEntityTableName } from '@open-mercato/shared/lib/query/engine'\nimport type { Knex } from 'knex'\nimport type { EventBus } from '@open-mercato/events'\nimport { readCoverageSnapshot, refreshCoverageSnapshot } from './coverage'\nimport { createProfiler, shouldEnableProfiler, type Profiler } from '@open-mercato/shared/lib/profiler'\nimport type { VectorIndexService } from '@open-mercato/search/vector'\nimport { decryptIndexDocCustomFields } from '@open-mercato/shared/lib/encryption/indexDoc'\nimport { parseBooleanToken, parseBooleanWithDefault } from '@open-mercato/shared/lib/boolean'\nimport {\n applyJoinFilters,\n normalizeFilters,\n partitionFilters,\n resolveJoins,\n type BaseFilter,\n type ResolvedJoin,\n} from '@open-mercato/shared/lib/query/join-utils'\nimport { resolveSearchConfig, type SearchConfig } from '@open-mercato/shared/lib/search/config'\nimport { tokenizeText } from '@open-mercato/shared/lib/search/tokenize'\nimport { runBeforeQueryPipeline, runAfterQueryPipeline, type QueryExtensionContext } from '@open-mercato/shared/lib/query/query-extension-runner'\n\nfunction buildFilterableCustomFieldJoins(\n sources: QueryCustomFieldSource[] | undefined,\n): Array<{\n alias: string\n table?: string\n entityId: EntityId\n from: { field: string }\n to: { field: string }\n type: 'left' | 'inner'\n}> {\n if (!sources || sources.length === 0) return []\n return sources.flatMap((source, index) => {\n if (!source.join) return []\n const alias = typeof source.alias === 'string' && source.alias.trim().length > 0\n ? source.alias.trim()\n : `cfs_${index}`\n return [{\n alias,\n table: source.table,\n entityId: source.entityId,\n from: { field: source.join.fromField },\n to: { field: source.join.toField },\n type: source.join.type === 'inner' ? 'inner' : 'left',\n }]\n })\n}\n\nfunction resolveBooleanEnv(names: readonly string[], defaultValue: boolean): boolean {\n for (const name of names) {\n const raw = process.env[name]\n if (raw !== undefined) return parseBooleanWithDefault(raw, defaultValue)\n }\n return defaultValue\n}\n\nfunction resolveDebugVerbosity(): boolean {\n // Check explicit OM_QUERY_INDEX_DEBUG flag first\n const queryIndexDebug = process.env.OM_QUERY_INDEX_DEBUG\n if (queryIndexDebug !== undefined) {\n return parseBooleanToken(queryIndexDebug) ?? false\n }\n // Fall back to log level or NODE_ENV\n const level = (process.env.LOG_VERBOSITY ?? process.env.LOG_LEVEL ?? '').toLowerCase()\n if (['debug', 'trace', 'silly'].includes(level)) return true\n // Default to false (don't spam logs in development)\n return false\n}\n\ntype ResultRow = Record<string, unknown>\ntype ResultBuilder<TResult = ResultRow[]> = Knex.QueryBuilder<ResultRow, TResult>\ntype NormalizedFilter = { field: string; op: FilterOp; value?: unknown }\ntype IndexDocSource = { alias: string; entityId: EntityId; recordIdColumn: string }\ntype PreparedCustomFieldSource = {\n alias: string\n indexAlias: string\n entityId: EntityId\n recordIdColumn: string\n organizationField?: string\n tenantField?: string\n table: string\n}\ntype SearchRuntime = {\n enabled: boolean\n config: SearchConfig\n organizationScope?: { ids: string[]; includeNull: boolean } | null\n tenantId?: string | null\n searchSources?: SearchTokenSource[]\n}\n\ntype EncryptionResolver = () => {\n decryptEntityPayload?: (entityId: EntityId, payload: Record<string, unknown>, tenantId?: string | null, organizationId?: string | null) => Promise<Record<string, unknown>>\n isEnabled?: () => boolean\n} | null\n\ntype SearchTokenSource = { entity: string; recordIdColumn: string }\n\nfunction createQueryProfiler(entity: string): Profiler {\n const enabled = shouldEnableProfiler(entity)\n return createProfiler({\n scope: 'query_engine',\n target: entity,\n label: `query_engine:${entity}`,\n loggerLabel: '[qe:profile]',\n enabled,\n })\n}\n\nexport class HybridQueryEngine implements QueryEngine {\n private coverageStatsTtlMs: number\n private customFieldKeysCache = new Map<string, { expiresAt: number; value: string[] }>()\n private customFieldKeysTtlMs: number\n private columnCache = new Map<string, boolean>()\n private debugVerbosity: boolean | null = null\n private sqlDebugEnabled: boolean | null = null\n private forcePartialIndexEnabled: boolean | null = null\n private autoReindexEnabled: boolean | null = null\n private coverageOptimizationEnabled: boolean | null = null\n private pendingCoverageRefreshKeys = new Set<string>()\n private searchAliasSeq = 0\n\n constructor(\n private em: EntityManager,\n private fallback: BasicQueryEngine,\n private eventBusResolver?: () => Pick<EventBus, 'emitEvent'> | null | undefined,\n private vectorServiceResolver?: () => VectorIndexService | null | undefined,\n private encryptionResolver?: EncryptionResolver,\n ) {\n const coverageTtl = Number.parseInt(process.env.QUERY_INDEX_COVERAGE_CACHE_MS ?? '', 10)\n this.coverageStatsTtlMs = Number.isFinite(coverageTtl) && coverageTtl >= 0 ? coverageTtl : 5 * 60 * 1000\n const cfTtl = Number.parseInt(process.env.QUERY_INDEX_CF_KEYS_CACHE_MS ?? '', 10)\n this.customFieldKeysTtlMs = Number.isFinite(cfTtl) && cfTtl >= 0 ? cfTtl : 5 * 60 * 1000\n }\n\n private getEncryptionService() {\n try {\n return this.encryptionResolver?.() ?? null\n } catch {\n return null\n }\n }\n\n async query<T = unknown>(entity: EntityId, opts: QueryOptions = {}): Promise<QueryResult<T>> {\n // --- UMES query extension: before-query pipeline ---\n const ext: QueryExtensionsConfig | undefined = opts.extensions\n let hybridExtCtx: QueryExtensionContext | null = null\n const noopDi = { resolve: <R = unknown>(_name: string): R => { throw new Error('No DI context') } }\n\n if (ext) {\n hybridExtCtx = {\n entity: String(entity),\n engine: 'hybrid',\n tenantId: opts.tenantId ?? '',\n organizationId: opts.organizationId,\n userId: ext.userId,\n em: this.em,\n container: ext.container,\n userFeatures: ext.userFeatures,\n }\n const diCtx = ext.resolve ? { resolve: ext.resolve } : noopDi\n const beforeResult = await runBeforeQueryPipeline(opts, hybridExtCtx, diCtx)\n if (beforeResult.blocked) {\n throw new Error(beforeResult.errorMessage ?? 'Query blocked by extension subscriber')\n }\n opts = beforeResult.query\n }\n // Strip extensions so fallback to BasicQueryEngine doesn't double-execute\n const { extensions: _stripExt, ...coreOpts } = opts\n opts = coreOpts\n\n const providedProfiler = opts.profiler\n const profiler = providedProfiler && providedProfiler.enabled\n ? providedProfiler\n : createQueryProfiler(String(entity))\n profiler.mark('query:init')\n let profileClosed = false\n const finishProfile = (meta?: Record<string, unknown>) => {\n if (!profiler.enabled || profileClosed) return\n profileClosed = true\n profiler.end(meta)\n }\n\n const applyAfterExtensions = async <R>(queryResult: QueryResult<R>): Promise<QueryResult<R>> => {\n if (!ext || !hybridExtCtx) return queryResult\n const diCtx = ext.resolve ? { resolve: ext.resolve } : noopDi\n return await runAfterQueryPipeline(\n queryResult as QueryResult<Record<string, unknown>>,\n opts,\n hybridExtCtx,\n diCtx,\n ) as QueryResult<R>\n }\n\n try {\n const debugEnabled = this.isDebugVerbosity()\n if (debugEnabled) this.debug('query:start', { entity })\n this.searchAliasSeq = 0\n\n const isCustom = await this.isCustomEntity(entity)\n if (isCustom) {\n if (debugEnabled) this.debug('query:custom-entity', { entity })\n const section = profiler.section('custom_entity')\n try {\n const result = await this.queryCustomEntity<T>(entity, opts)\n section.end({ mode: 'custom_entity' })\n finishProfile({\n result: 'custom_entity',\n total: Array.isArray(result.items) ? result.items.length : undefined,\n })\n return await applyAfterExtensions(result)\n } catch (err) {\n section.end({ error: err instanceof Error ? err.message : String(err) })\n throw err\n }\n }\n\n const knex = this.getKnex()\n profiler.mark('query:knex_ready')\n const baseTable = resolveEntityTableName(this.em, entity)\n profiler.mark('query:base_table_resolved')\n const searchConfig = resolveSearchConfig()\n const orgScope = this.resolveOrganizationScope(opts)\n const searchEnabled = searchConfig.enabled && await this.tableExists('search_tokens')\n\n const baseExists = await profiler.measure('base_table_exists', () => this.tableExists(baseTable))\n if (!baseExists) {\n if (debugEnabled) this.debug('query:fallback:missing-base', { entity, baseTable })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'missing_base' })\n return await applyAfterExtensions(fallbackResult)\n }\n\n if (opts.omitAutomaticTenantOrgScope === true) {\n if (debugEnabled) this.debug('query:fallback:omit-automatic-scope', { entity })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'omit_automatic_tenant_org_scope' })\n return await applyAfterExtensions(fallbackResult)\n }\n\n const normalizedFilters = normalizeFilters(opts.filters)\n const cfFilters = normalizedFilters.filter((filter) => filter.field.startsWith('cf:') || filter.field.startsWith('l10n:'))\n const coverageScope = this.resolveCoverageSnapshotScope(opts)\n const wantsCf = (\n (opts.fields || []).some((field) => typeof field === 'string' && (field.startsWith('cf:') || field.startsWith('l10n:'))) ||\n cfFilters.length > 0 ||\n (Array.isArray(opts.includeCustomFields) && opts.includeCustomFields.length > 0)\n )\n\n if (debugEnabled) {\n this.debug('query:config', {\n entity,\n wantsCustomFields: wantsCf,\n customFieldSources: Array.isArray(opts.customFieldSources) ? opts.customFieldSources.map((src) => src?.entityId) : undefined,\n fields: opts.fields,\n })\n }\n\n let partialIndexWarning: PartialIndexWarning | null = null\n let entityHasActiveCustomFields = true\n\n if (wantsCf) {\n entityHasActiveCustomFields = await this.entityHasActiveCustomFields(entity, opts.tenantId ?? null)\n const hasIndexRows = await profiler.measure(\n 'index_any_rows',\n () => this.indexAnyRows(entity),\n (value) => ({ hasIndexRows: value })\n )\n if (!hasIndexRows) {\n if (debugEnabled) this.debug('query:fallback:no-index', { entity })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'no_index_rows' })\n return await applyAfterExtensions(fallbackResult)\n }\n if (entityHasActiveCustomFields) {\n const gap = await profiler.measure(\n 'resolve_coverage_gap',\n () => this.resolveCoverageGap(entity, opts, coverageScope),\n (value) => (value\n ? {\n scope: value.scope,\n baseCount: value.stats?.baseCount ?? null,\n indexedCount: value.stats?.indexedCount ?? null,\n }\n : { scope: null })\n )\n if (gap) {\n if (!opts.skipAutoReindex) {\n this.scheduleAutoReindex(entity, opts, gap.stats, coverageScope?.organizationId ?? null)\n }\n const force = this.isForcePartialIndexEnabled()\n if (!force) {\n if (gap.stats) {\n console.warn('[HybridQueryEngine] Partial index coverage detected; falling back to basic engine:', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n if (debugEnabled) this.debug('query:fallback:partial-coverage', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n } else {\n console.warn('[HybridQueryEngine] Partial index coverage detected; falling back to basic engine:', { entity })\n if (debugEnabled) this.debug('query:fallback:partial-coverage', { entity })\n }\n const fallbackResult = await this.fallback.query(entity, opts)\n const resultWithWarning: QueryResult<T> = {\n ...fallbackResult,\n meta: {\n ...(fallbackResult.meta ?? {}),\n partialIndexWarning: {\n entity,\n entityLabel: this.resolveEntityLabel(entity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n },\n },\n }\n finishProfile({\n result: 'fallback',\n reason: 'partial_index',\n scope: gap.scope,\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n })\n return await applyAfterExtensions(resultWithWarning)\n }\n if (gap.stats) {\n console.warn('[HybridQueryEngine] Partial index coverage detected; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n if (debugEnabled) this.debug('query:partial-coverage:forced', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n } else {\n console.warn('[HybridQueryEngine] Partial index coverage detected; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity })\n if (debugEnabled) this.debug('query:partial-coverage:forced', { entity })\n }\n partialIndexWarning = {\n entity,\n entityLabel: this.resolveEntityLabel(entity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n }\n }\n } else if (debugEnabled) {\n this.debug('query:coverage:skip-no-custom-fields', { entity })\n }\n }\n\n const qualify = (col: string) => `b.${col}`\n let builder: ResultBuilder = knex({ b: baseTable })\n const hasCustomFieldFilters = cfFilters.length > 0\n const canOptimizeCount = !hasCustomFieldFilters\n let optimizedCountBuilder: ResultBuilder | null = canOptimizeCount ? knex({ b: baseTable }) : null\n\n const resolvedJoinsConfig = resolveJoins(\n baseTable,\n [...(opts.joins ?? []), ...buildFilterableCustomFieldJoins(opts.customFieldSources)],\n (entityId) => resolveEntityTableName(this.em, entityId as any),\n )\n const joinMap = new Map<string, ResolvedJoin>()\n const aliasTables = new Map<string, string>()\n aliasTables.set('b', baseTable)\n aliasTables.set('base', baseTable)\n aliasTables.set(baseTable, baseTable)\n for (const join of resolvedJoinsConfig) {\n joinMap.set(join.alias, join)\n aliasTables.set(join.alias, join.table)\n }\n const { baseFilters, joinFilters } = partitionFilters(baseTable, normalizedFilters, joinMap)\n\n if (!opts.tenantId) throw new Error('QueryEngine: tenantId is required')\n\n const hasOrganizationColumn = await this.columnExists(baseTable, 'organization_id')\n const hasTenantColumn = await this.columnExists(baseTable, 'tenant_id')\n const hasDeletedColumn = await this.columnExists(baseTable, 'deleted_at')\n const searchRuntimeBase = {\n enabled: false,\n config: searchConfig,\n organizationScope: orgScope,\n tenantId: opts.tenantId ?? null,\n }\n\n if (orgScope && hasOrganizationColumn) {\n builder = this.applyOrganizationScope(builder, qualify('organization_id'), orgScope)\n if (optimizedCountBuilder) optimizedCountBuilder = this.applyOrganizationScope(optimizedCountBuilder, qualify('organization_id'), orgScope)\n }\n if (hasTenantColumn) {\n builder = builder.where(qualify('tenant_id'), opts.tenantId)\n if (optimizedCountBuilder) optimizedCountBuilder = optimizedCountBuilder.where(qualify('tenant_id'), opts.tenantId)\n }\n if (!opts.withDeleted && hasDeletedColumn) {\n builder = builder.whereNull(qualify('deleted_at'))\n if (optimizedCountBuilder) optimizedCountBuilder = optimizedCountBuilder.whereNull(qualify('deleted_at'))\n }\n\n const baseJoinParts: string[] = []\n baseJoinParts.push(`ei.entity_type = ${knex.raw('?', [entity]).toString()}`)\n baseJoinParts.push(`ei.entity_id = (${qualify('id')}::text)`)\n if (hasOrganizationColumn) {\n baseJoinParts.push(`ei.organization_id = ${qualify('organization_id')}`)\n baseJoinParts.push('ei.organization_id is not null')\n }\n if (hasTenantColumn) {\n baseJoinParts.push(`ei.tenant_id = ${qualify('tenant_id')}`)\n baseJoinParts.push('ei.tenant_id is not null')\n }\n if (!opts.withDeleted) baseJoinParts.push(`ei.deleted_at is null`)\n builder = builder.leftJoin({ ei: 'entity_indexes' }, knex.raw(baseJoinParts.join(' AND ')))\n\n const columns = await this.getBaseColumnsForEntity(entity)\n const indexSources: IndexDocSource[] = [{ alias: 'ei', entityId: entity, recordIdColumn: 'b.id' }]\n\n const shouldAttachCustomSources = Array.isArray(opts.customFieldSources) && opts.customFieldSources.length > 0 && (wantsCf || searchEnabled)\n if (shouldAttachCustomSources) {\n const prepared = this.prepareCustomFieldSources(knex, builder, opts.customFieldSources ?? [], qualify)\n builder = prepared.builder\n for (const source of prepared.sources) {\n const fragments: string[] = []\n fragments.push(`${source.indexAlias}.entity_type = ${knex.raw('?', [source.entityId]).toString()}`)\n fragments.push(`${source.indexAlias}.entity_id = (${knex.raw('??::text', [`${source.alias}.${source.recordIdColumn}`]).toString()})`)\n const orgExpr = source.organizationField\n ? knex.raw('??', [`${source.alias}.${source.organizationField}`]).toString()\n : (columns.has('organization_id') ? qualify('organization_id') : null)\n if (orgExpr) {\n fragments.push(`${source.indexAlias}.organization_id = ${orgExpr}`)\n fragments.push(`${source.indexAlias}.organization_id is not null`)\n }\n const tenantExpr = source.tenantField\n ? knex.raw('??', [`${source.alias}.${source.tenantField}`]).toString()\n : (columns.has('tenant_id') ? qualify('tenant_id') : null)\n if (tenantExpr) {\n fragments.push(`${source.indexAlias}.tenant_id = ${tenantExpr}`)\n fragments.push(`${source.indexAlias}.tenant_id is not null`)\n }\n if (!opts.withDeleted) fragments.push(`${source.indexAlias}.deleted_at is null`)\n builder = builder.leftJoin({ [source.indexAlias]: 'entity_indexes' }, knex.raw(fragments.join(' AND ')))\n indexSources.push({ alias: source.indexAlias, entityId: source.entityId, recordIdColumn: `${source.alias}.${source.recordIdColumn}` })\n }\n }\n\n if (debugEnabled) {\n this.debug('query:index-sources', {\n entity,\n sources: indexSources.map((src) => ({ alias: src.alias, entity: src.entityId })),\n })\n }\n\n const searchSources: SearchTokenSource[] = indexSources\n .map((src) => ({\n entity: String(src.entityId),\n recordIdColumn: src.recordIdColumn,\n }))\n .filter((src) => src.recordIdColumn && src.entity)\n const hasSearchTokens = searchEnabled && searchSources.length\n ? await this.searchSourcesHaveTokens(searchSources, opts.tenantId ?? null, orgScope)\n : false\n const searchRuntime: SearchRuntime = { ...searchRuntimeBase, searchSources, enabled: searchEnabled && hasSearchTokens }\n const joinSearchAvailability = new Map<string, boolean>()\n const searchFilters = normalizeFilters(opts.filters).filter((filter) => filter.op === 'like' || filter.op === 'ilike')\n if (searchFilters.length) {\n this.logSearchDebug('search:init', {\n entity,\n baseTable,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n fields: searchFilters.map((filter) => String(filter.field)),\n searchEnabled,\n hasSearchTokens,\n searchSources,\n searchConfig: {\n enabled: searchConfig.enabled,\n minTokenLength: searchConfig.minTokenLength,\n enablePartials: searchConfig.enablePartials,\n hashAlgorithm: searchConfig.hashAlgorithm,\n blocklistedFields: searchConfig.blocklistedFields,\n },\n })\n if (!searchEnabled) {\n this.logSearchDebug('search:disabled', { entity, baseTable })\n } else if (!hasSearchTokens) {\n this.logSearchDebug('search:no-search-tokens', {\n entity,\n baseTable,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n searchSources,\n })\n }\n }\n const hasNonBaseSearchSource = searchSources.some(\n (src) => src.entity !== String(entity) || src.recordIdColumn !== 'b.id'\n )\n if (hasNonBaseSearchSource) {\n optimizedCountBuilder = null\n }\n\n if (!partialIndexWarning && Array.isArray(opts.customFieldSources) && opts.customFieldSources.length > 0 && this.isForcePartialIndexEnabled()) {\n const seen = new Set<string>([entity])\n for (const source of opts.customFieldSources) {\n const targetEntity = source?.entityId ? String(source.entityId) : null\n if (!targetEntity || seen.has(targetEntity)) continue\n seen.add(targetEntity)\n const sourceHasCustomFields = await this.entityHasActiveCustomFields(targetEntity, opts.tenantId ?? null)\n if (!sourceHasCustomFields) {\n if (debugEnabled) this.debug('query:coverage:skip-no-custom-fields', { entity: targetEntity })\n continue\n }\n const sourceTable = source.table ?? resolveEntityTableName(this.em, targetEntity)\n try {\n const gap = await profiler.measure(\n 'resolve_coverage_gap',\n () => this.resolveCoverageGap(targetEntity, opts, coverageScope, sourceTable),\n (value) => (value\n ? {\n entity: targetEntity,\n scope: value.scope,\n baseCount: value.stats?.baseCount ?? null,\n indexedCount: value.stats?.indexedCount ?? null,\n }\n : { entity: targetEntity, scope: null })\n )\n if (!gap) continue\n if (!opts.skipAutoReindex) {\n this.scheduleAutoReindex(targetEntity, opts, gap.stats, coverageScope?.organizationId ?? null)\n }\n partialIndexWarning = {\n entity: targetEntity,\n entityLabel: this.resolveEntityLabel(targetEntity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n }\n if (debugEnabled) {\n if (gap.stats) this.debug('query:partial-coverage:forced', { entity: targetEntity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n else this.debug('query:partial-coverage:forced', { entity: targetEntity })\n }\n break\n } catch (err) {\n if (debugEnabled) this.debug('query:partial-coverage:check-failed', { entity: targetEntity, error: err instanceof Error ? err.message : err })\n }\n }\n }\n\n if (\n !partialIndexWarning &&\n wantsCf &&\n entityHasActiveCustomFields &&\n this.isForcePartialIndexEnabled() &&\n opts.tenantId\n ) {\n try {\n await this.indexCoverageStats(entity, opts, coverageScope)\n const globalStats = await this.indexCoverageStats(entity, opts, coverageScope)\n if (globalStats) {\n const globalBase = globalStats.baseCount\n const globalIndexed = globalStats.indexedCount\n const globalGap = (globalBase > 0 && globalIndexed < globalBase) || globalIndexed > globalBase\n if (globalGap) {\n console.warn('[HybridQueryEngine] Partial index coverage detected at global scope; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity, baseCount: globalBase, indexedCount: globalIndexed, scope: 'global' })\n if (debugEnabled) {\n this.debug('query:partial-coverage:forced', {\n entity,\n baseCount: globalBase,\n indexedCount: globalIndexed,\n scope: 'global',\n })\n }\n partialIndexWarning = {\n entity,\n entityLabel: this.resolveEntityLabel(entity),\n baseCount: globalBase,\n indexedCount: globalIndexed,\n scope: 'global',\n }\n }\n }\n } catch (err) {\n if (debugEnabled) {\n this.debug('query:partial-coverage:global-check-failed', {\n entity,\n error: err instanceof Error ? err.message : err,\n })\n }\n }\n }\n\n const resolveBaseColumn = (field: string): string | null => {\n if (columns.has(field)) return field\n if (field === 'organization_id' && columns.has('id')) return 'id'\n return null\n }\n\n for (const filter of cfFilters) {\n builder = this.applyCfFilterAcrossSources(\n knex,\n builder,\n filter.field,\n filter.op,\n filter.value,\n indexSources,\n searchRuntime\n )\n }\n\n const regularBaseFilters = baseFilters.filter((filter) => !filter.orGroup)\n const orGroupFilters = baseFilters.filter((filter) => filter.orGroup)\n\n for (const filter of regularBaseFilters) {\n const fieldName = String(filter.field)\n const baseField = resolveBaseColumn(fieldName)\n if (!baseField) {\n builder = this.applyIndexDocFilterFromAlias(\n knex,\n builder,\n 'ei',\n entity,\n fieldName,\n filter.op,\n filter.value,\n 'b.id',\n searchRuntime,\n )\n if (optimizedCountBuilder) {\n optimizedCountBuilder = this.applyIndexDocFilterFromAlias(\n knex,\n optimizedCountBuilder,\n 'ei',\n entity,\n fieldName,\n filter.op,\n filter.value,\n 'b.id',\n searchRuntime,\n )\n }\n continue\n }\n const column = qualify(baseField)\n builder = this.applyColumnFilter(builder, column, filter, {\n ...searchRuntime,\n knex,\n entity,\n field: fieldName,\n recordIdColumn: 'b.id',\n })\n if (optimizedCountBuilder) {\n optimizedCountBuilder = this.applyColumnFilter(optimizedCountBuilder, column, filter, {\n ...searchRuntime,\n knex,\n entity,\n field: fieldName,\n recordIdColumn: 'b.id',\n })\n }\n }\n\n const applyOrGroupedBaseFilters = (target: ResultBuilder | null): ResultBuilder | null => {\n if (!target || orGroupFilters.length === 0) return target\n const groups = new Map<string, BaseFilter[]>()\n for (const filter of orGroupFilters) {\n if (!filter.orGroup) continue\n const existing = groups.get(filter.orGroup) ?? []\n existing.push(filter)\n groups.set(filter.orGroup, existing)\n }\n let next = target\n for (const [, groupFilters] of groups) {\n if (!groupFilters.length) continue\n next = next.where((groupBuilder) => {\n groupFilters.forEach((filter, index) => {\n const fieldName = String(filter.field)\n const baseField = resolveBaseColumn(fieldName)\n const applyCondition = (conditionBuilder: ResultBuilder) => {\n if (!baseField) {\n this.applyIndexDocFilterFromAlias(\n knex,\n conditionBuilder,\n 'ei',\n entity,\n fieldName,\n filter.op,\n filter.value,\n 'b.id',\n searchRuntime,\n )\n return\n }\n this.applyColumnFilter(conditionBuilder, qualify(baseField), filter, {\n ...searchRuntime,\n knex,\n entity,\n field: fieldName,\n recordIdColumn: 'b.id',\n })\n }\n if (index === 0) {\n applyCondition(groupBuilder as ResultBuilder)\n return\n }\n groupBuilder.orWhere((conditionBuilder) => {\n applyCondition(conditionBuilder as ResultBuilder)\n })\n })\n })\n }\n return next\n }\n\n builder = applyOrGroupedBaseFilters(builder) ?? builder\n optimizedCountBuilder = applyOrGroupedBaseFilters(optimizedCountBuilder)\n\n const applyAliasScopes = async (target: ResultBuilder, aliasName: string) => {\n const tableName = aliasTables.get(aliasName)\n if (!tableName) return\n if (orgScope && await this.columnExists(tableName, 'organization_id')) {\n this.applyOrganizationScope(target, `${aliasName}.organization_id`, orgScope)\n }\n if (opts.tenantId && await this.columnExists(tableName, 'tenant_id')) {\n target.where(`${aliasName}.tenant_id`, opts.tenantId)\n }\n if (!opts.withDeleted && await this.columnExists(tableName, 'deleted_at')) {\n target.whereNull(`${aliasName}.deleted_at`)\n }\n }\n\n const applyJoinFilterOp = (target: ResultBuilder, column: string, op: FilterOp, value?: unknown) => {\n switch (op) {\n case 'eq':\n target.where(column, value as Knex.Value)\n break\n case 'ne':\n target.whereNot(column, value as Knex.Value)\n break\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<='\n target.where(column, operator, value as Knex.Value)\n break\n }\n case 'in':\n target.whereIn(column, this.toArray(value) as readonly Knex.Value[])\n break\n case 'nin':\n target.whereNotIn(column, this.toArray(value) as readonly Knex.Value[])\n break\n case 'like':\n target.where(column, 'like', value as Knex.Value)\n break\n case 'ilike':\n target.where(column, 'ilike', value as Knex.Value)\n break\n case 'exists':\n value ? target.whereNotNull(column) : target.whereNull(column)\n break\n }\n }\n\n // `eq` is accepted alongside `like`/`ilike` so that filters against\n // encrypted joined columns (whose ciphertext cannot be compared for\n // equality in SQL) can still resolve via tokenized search. Routing\n // only applies when `searchEnabled` is true AND the joined entity has\n // search tokens installed (`searchAvailable`); non-searchable columns\n // still fall through to exact SQL equality. Token match is approximate \u2014\n // callers needing strict equality on encrypted fields should filter on\n // the deterministic `*_hash` column instead.\n const applyJoinSearchFilterOp = async (\n target: ResultBuilder,\n filter: { column: string; op: FilterOp; value?: unknown },\n _qualified: string,\n join: ResolvedJoin,\n ): Promise<boolean> => {\n if (!searchEnabled || !join.entityId) return false\n if (!['eq', 'like', 'ilike'].includes(filter.op)) return false\n if (typeof filter.value !== 'string' || filter.value.trim().length === 0) return false\n\n let searchAvailable = joinSearchAvailability.get(join.entityId)\n if (searchAvailable === undefined) {\n searchAvailable = await this.hasSearchTokens(String(join.entityId), opts.tenantId ?? null, orgScope)\n joinSearchAvailability.set(join.entityId, searchAvailable)\n }\n if (!searchAvailable) return false\n\n const tokens = tokenizeText(String(filter.value), searchConfig)\n if (!tokens.hashes.length) return false\n\n return this.applySearchTokens(target, {\n knex,\n entity: String(join.entityId),\n field: filter.column,\n hashes: tokens.hashes,\n recordIdColumn: `${join.alias}.id`,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n })\n }\n\n await applyJoinFilters({\n knex,\n baseTable,\n builder,\n joinMap,\n joinFilters,\n aliasTables,\n qualifyBase: (column) => qualify(column),\n applyAliasScope: (target, alias) => applyAliasScopes(target, alias),\n applyFilterOp: (target, column, op, value) => applyJoinFilterOp(target as ResultBuilder, column, op, value),\n applyJoinFilterOp: (target, filter, qualified, join) =>\n applyJoinSearchFilterOp(target as ResultBuilder, filter, qualified, join),\n columnExists: (tbl, column) => this.columnExists(tbl, column),\n }) as ResultBuilder\n\n if (optimizedCountBuilder) {\n await applyJoinFilters({\n knex,\n baseTable,\n builder: optimizedCountBuilder,\n joinMap,\n joinFilters,\n aliasTables,\n qualifyBase: (column) => qualify(column),\n applyAliasScope: (target, alias) => applyAliasScopes(target, alias),\n applyFilterOp: (target, column, op, value) => applyJoinFilterOp(target as ResultBuilder, column, op, value),\n applyJoinFilterOp: (target, filter, qualified, join) =>\n applyJoinSearchFilterOp(target as ResultBuilder, filter, qualified, join),\n columnExists: (tbl, column) => this.columnExists(tbl, column),\n })\n }\n\n // When no fields specified, select all base table columns (like BasicQueryEngine does)\n const selectFieldSet = new Set<string>((opts.fields && opts.fields.length) ? opts.fields.map(String) : Array.from(columns.keys()))\n if (opts.includeCustomFields === true) {\n const entityIds = Array.from(new Set(indexSources.map((src) => String(src.entityId))))\n try {\n const resolvedKeys = await this.resolveAvailableCustomFieldKeys(entityIds, opts.tenantId ?? null)\n resolvedKeys.forEach((key) => selectFieldSet.add(`cf:${key}`))\n if (this.isDebugVerbosity()) {\n this.debug('query:cf:resolved-keys', { entity, keys: resolvedKeys })\n }\n } catch (err) {\n console.warn('[HybridQueryEngine] Failed to resolve custom field keys for', entity, err)\n }\n } else if (Array.isArray(opts.includeCustomFields)) {\n opts.includeCustomFields\n .map((key) => String(key))\n .forEach((key) => selectFieldSet.add(`cf:${key}`))\n }\n const selectFields = Array.from(selectFieldSet)\n for (const field of selectFields) {\n const fieldName = String(field)\n if (fieldName.startsWith('cf:')) {\n const alias = this.sanitize(fieldName)\n const { jsonSql } = this.buildCfExpressions(knex, fieldName, indexSources)\n const exprSql = jsonSql === 'NULL' ? 'NULL::jsonb' : jsonSql\n builder = builder.select(knex.raw(`${exprSql} as ??`, [alias]))\n } else if (columns.has(fieldName)) {\n builder = builder.select(knex.raw('?? as ??', [qualify(fieldName), fieldName]))\n }\n }\n\n for (const sort of opts.sort || []) {\n const fieldName = String(sort.field)\n if (fieldName.startsWith('cf:')) {\n const { textSql } = this.buildCfExpressions(knex, fieldName, indexSources)\n if (textSql !== 'NULL') {\n const direction = sort.dir ?? SortDir.Asc\n builder = builder.orderByRaw(`${textSql} ${direction}`)\n }\n } else {\n const baseField = resolveBaseColumn(fieldName)\n if (!baseField) continue\n builder = builder.orderBy(qualify(baseField), sort.dir ?? SortDir.Asc)\n }\n }\n\n const page = opts.page?.page ?? 1\n const pageSize = opts.page?.pageSize ?? 20\n\n const sqlDebugEnabled = this.isSqlDebugEnabled()\n let total: number\n\n if (optimizedCountBuilder) {\n const countSource = optimizedCountBuilder.clone().clearSelect().clearOrder().select(knex.raw(`${qualify('id')} as id`)).groupBy(qualify('id'))\n const countQuery = knex.from(countSource.as('sq')).count({ count: knex.raw('*') })\n if (debugEnabled && sqlDebugEnabled) {\n const { sql, bindings } = countQuery.clone().toSQL()\n this.debug('query:sql:count', { entity, sql, bindings })\n }\n const countRow = await this.captureSqlTiming(\n 'query:sql:count',\n entity,\n () => countQuery.first(),\n { optimized: true },\n profiler\n )\n total = this.parseCount(countRow)\n } else {\n const countBuilder = builder.clone().clearSelect().clearOrder().countDistinct(`${qualify('id')} as count`)\n if (debugEnabled && sqlDebugEnabled) {\n const { sql, bindings } = countBuilder.clone().toSQL()\n this.debug('query:sql:count', { entity, sql, bindings })\n }\n const countRow = await this.captureSqlTiming(\n 'query:sql:count',\n entity,\n () => countBuilder.first(),\n { optimized: false },\n profiler\n )\n total = this.parseCount(countRow)\n }\n\n const dataBuilder = builder.clone().limit(pageSize).offset((page - 1) * pageSize)\n\n if (debugEnabled && sqlDebugEnabled) {\n const { sql, bindings } = dataBuilder.clone().toSQL()\n this.debug('query:sql:data', { entity, sql, bindings, page, pageSize })\n }\n const itemsRaw = await this.captureSqlTiming(\n 'query:sql:data',\n entity,\n () => dataBuilder,\n { page, pageSize },\n profiler\n )\n if (debugEnabled) this.debug('query:complete', { entity, total, items: Array.isArray(itemsRaw) ? itemsRaw.length : 0 })\n\n let items = itemsRaw as any[]\n const encSvc = this.getEncryptionService()\n const dekKeyCache = new Map<string | null, string | null>()\n if (encSvc?.decryptEntityPayload) {\n const decrypt = encSvc.decryptEntityPayload.bind(encSvc) as (\n entityId: EntityId,\n payload: Record<string, unknown>,\n tenantId: string | null,\n organizationId: string | null,\n ) => Promise<Record<string, unknown>>\n items = await Promise.all(\n items.map(async (item) => {\n try {\n const decrypted = await decrypt(\n entity,\n item,\n item?.tenant_id ?? item?.tenantId ?? opts.tenantId ?? null,\n item?.organization_id ?? item?.organizationId ?? null,\n )\n return { ...item, ...decrypted }\n } catch (err) {\n console.error('Error decrypting entity payload', err);\n return item\n }\n })\n )\n }\n if (encSvc) {\n items = await Promise.all(\n items.map(async (item) => {\n try {\n return await decryptIndexDocCustomFields(\n item,\n {\n tenantId: item?.tenant_id ?? item?.tenantId ?? opts.tenantId ?? null,\n organizationId: item?.organization_id ?? item?.organizationId ?? null,\n },\n encSvc as any,\n dekKeyCache,\n )\n } catch {\n return item\n }\n }),\n )\n }\n\n const typedItems = items as unknown as T[]\n let result: QueryResult<T> = { items: typedItems, page, pageSize, total }\n if (partialIndexWarning) {\n result.meta = { partialIndexWarning }\n }\n\n // --- UMES query extension: after-query pipeline ---\n result = await applyAfterExtensions(result)\n\n finishProfile({\n result: 'ok',\n total,\n page,\n pageSize,\n itemCount: Array.isArray(items) ? items.length : undefined,\n partialIndexWarning: partialIndexWarning ? true : false,\n })\n return result\n } catch (err) {\n finishProfile({ result: 'error', error: err instanceof Error ? err.message : String(err) })\n throw err\n }\n }\n\n private getKnex(): Knex {\n const connection = this.em.getConnection()\n const withKnex = connection as { getKnex?: () => Knex }\n if (typeof withKnex.getKnex === 'function') {\n return withKnex.getKnex()\n }\n throw new Error('HybridQueryEngine requires a SQL connection that exposes getKnex()')\n }\n\n private prepareCustomFieldSources(\n knex: Knex,\n builder: ResultBuilder,\n sources: QueryCustomFieldSource[],\n qualify: (column: string) => string\n ): { builder: ResultBuilder; sources: PreparedCustomFieldSource[] } {\n let current = builder\n const prepared: PreparedCustomFieldSource[] = []\n sources.forEach((source, index) => {\n if (!source) return\n const joinTable = source.table ?? resolveEntityTableName(this.em, source.entityId)\n const alias = source.alias ?? `cfs_${index}`\n const join = source.join\n if (!join) {\n throw new Error(`QueryEngine: customFieldSources entry for ${String(source.entityId)} requires a join configuration`)\n }\n const joinArgs = { [alias]: joinTable }\n const joinCallback = function (this: Knex.JoinClause) {\n this.on(`${alias}.${join.toField}`, '=', qualify(join.fromField))\n }\n current = (join.type ?? 'left') === 'inner'\n ? current.join(joinArgs, joinCallback)\n : current.leftJoin(joinArgs, joinCallback)\n prepared.push({\n alias,\n indexAlias: `ei_${alias}`,\n entityId: source.entityId,\n recordIdColumn: source.recordIdColumn ?? 'id',\n organizationField: source.organizationField,\n tenantField: source.tenantField,\n table: joinTable,\n })\n })\n return { builder: current, sources: prepared }\n }\n\n private async isCustomEntity(entity: string): Promise<boolean> {\n try {\n const knex = this.getKnex()\n const row = await knex('custom_entities').where({ entity_id: entity, is_active: true }).first()\n return !!row\n } catch {\n return false\n }\n }\n\n private applySearchTokens<TRecord extends ResultRow, TResult>(\n q: Knex.QueryBuilder<TRecord, TResult>,\n opts: {\n knex: Knex\n entity: string\n field: string\n hashes: string[]\n recordIdColumn: string\n tenantId?: string | null\n organizationScope?: { ids: string[]; includeNull: boolean } | null\n combineWith?: 'and' | 'or'\n }\n ): boolean {\n if (!opts.hashes.length) {\n this.logSearchDebug('search:skip-no-hashes', {\n entity: opts.entity,\n field: opts.field,\n tenantId: opts.tenantId ?? null,\n organizationScope: opts.organizationScope,\n })\n return false\n }\n const alias = `st_${this.searchAliasSeq++}`\n const combineWith = opts.combineWith === 'or' ? 'orWhereExists' : 'whereExists'\n const engine = this\n this.logSearchDebug('search:apply-search-tokens', {\n entity: opts.entity,\n field: opts.field,\n alias,\n tokenCount: opts.hashes.length,\n tenantId: opts.tenantId ?? null,\n organizationScope: opts.organizationScope,\n combineWith: opts.combineWith ?? 'and',\n })\n ;(q as any)[combineWith](function (this: Knex.QueryBuilder) {\n this.select(1)\n .from({ [alias]: 'search_tokens' })\n .where(`${alias}.entity_type`, opts.entity)\n .andWhere(`${alias}.field`, opts.field)\n .andWhereRaw('?? = ??::text', [`${alias}.entity_id`, opts.recordIdColumn])\n .whereIn(`${alias}.token_hash`, opts.hashes)\n .groupBy(`${alias}.entity_id`, `${alias}.field`)\n .havingRaw(`count(distinct ${alias}.token_hash) >= ?`, [opts.hashes.length])\n if (opts.tenantId !== undefined) {\n this.andWhereRaw(`${alias}.tenant_id is not distinct from ?`, [opts.tenantId ?? null])\n }\n if (opts.organizationScope) {\n engine.applyOrganizationScope(this as any, `${alias}.organization_id`, opts.organizationScope)\n }\n })\n return true\n }\n\n private jsonbRawAlias(knex: Knex, alias: string, key: string): Knex.Raw {\n // Prefer cf:<key> but fall back to bare <key> for legacy docs\n if (key.startsWith('cf:')) {\n const bare = key.slice(3)\n return knex.raw(`coalesce(${alias}.doc -> ?, ${alias}.doc -> ?)`, [key, bare])\n }\n return knex.raw(`${alias}.doc -> ?`, [key])\n }\n private cfTextExprAlias(knex: Knex, alias: string, key: string): Knex.Raw {\n if (key.startsWith('cf:')) {\n const bare = key.slice(3)\n return knex.raw(`coalesce((${alias}.doc ->> ?), (${alias}.doc ->> ?))`, [key, bare])\n }\n return knex.raw(`(${alias}.doc ->> ?)`, [key])\n }\n private buildCfExpressions(knex: Knex, key: string, sources: IndexDocSource[]): { jsonSql: string; textSql: string } {\n if (!sources.length) return { jsonSql: 'NULL', textSql: 'NULL' }\n const jsonFragments = sources.map((source) => this.jsonbRawAlias(knex, source.alias, key).toString())\n const textFragments = sources.map((source) => this.cfTextExprAlias(knex, source.alias, key).toString())\n const jsonSql = jsonFragments.length === 1 ? jsonFragments[0] : `coalesce(${jsonFragments.join(', ')})`\n const textSql = textFragments.length === 1 ? textFragments[0] : `coalesce(${textFragments.join(', ')})`\n return { jsonSql, textSql }\n }\n\n private applyCfFilterAcrossSources(\n knex: Knex,\n builder: ResultBuilder,\n key: string,\n op: FilterOp,\n value: unknown,\n sources: IndexDocSource[],\n search?: SearchRuntime\n ): ResultBuilder {\n if (!sources.length) return builder\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n let applied = false\n if (sources.length) {\n builder = builder.where((qb) => {\n sources.forEach((source, idx) => {\n const ok = this.applySearchTokens(qb as any, {\n knex,\n entity: source.entityId,\n field: key,\n hashes,\n recordIdColumn: `${source.alias}.entity_id`,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n combineWith: idx === 0 ? 'and' : 'or',\n })\n if (ok) applied = true\n })\n })\n }\n this.logSearchDebug('search:cf-filter-across', {\n entity: sources.map((src) => src.entityId),\n field: key,\n tokens: tokens.tokens,\n hashes,\n applied,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope,\n })\n if (applied) return builder\n } else {\n this.logSearchDebug('search:cf-skip-empty-hashes', {\n entity: sources.map((src) => src.entityId),\n field: key,\n value,\n })\n }\n return builder\n }\n const { jsonSql, textSql } = this.buildCfExpressions(knex, key, sources)\n if (jsonSql === 'NULL' || textSql === 'NULL') return builder\n const textExpr = knex.raw(textSql)\n const arrContains = (val: unknown) => knex.raw(`${jsonSql} @> ?::jsonb`, [JSON.stringify([val])])\n switch (op) {\n case 'eq':\n return builder.where((qb) => {\n qb.orWhere(textExpr, '=', value as Knex.Value)\n qb.orWhere(arrContains(value))\n })\n case 'ne':\n return builder.whereNot(textExpr, '=', value as Knex.Value)\n case 'in': {\n const values = this.toArray(value)\n return builder.where((qb) => {\n values.forEach((val) => {\n qb.orWhere(textExpr, '=', val as Knex.Value)\n qb.orWhere(arrContains(val))\n })\n })\n }\n case 'nin': {\n const values = this.toArray(value) as readonly Knex.Value[]\n return builder.whereNotIn(textExpr as any, values as any)\n }\n case 'like':\n return builder.where(textExpr, 'like', value as Knex.Value)\n case 'ilike':\n return builder.where(textExpr, 'ilike', value as Knex.Value)\n case 'exists':\n return value\n ? builder.whereRaw(`${textExpr.toString()} is not null`)\n : builder.whereRaw(`${textExpr.toString()} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<='\n return builder.where(textExpr, operator, value as Knex.Value)\n }\n default:\n return builder\n }\n }\n\n private applyCfFilterFromAlias(\n knex: Knex,\n q: ResultBuilder,\n alias: string,\n entityType: string,\n key: string,\n op: FilterOp,\n value: unknown,\n search?: SearchRuntime\n ): ResultBuilder {\n const text = this.cfTextExprAlias(knex, alias, key)\n const arrExpr = knex.raw(`(${alias}.doc -> ?)`, [key])\n const arrContains = (val: unknown) => knex.raw(`${arrExpr.toString()} @> ?::jsonb`, [JSON.stringify([val])])\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const applied = this.applySearchTokens(q, {\n knex,\n entity: entityType,\n field: key,\n hashes,\n recordIdColumn: `${alias}.entity_id`,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n })\n this.logSearchDebug('search:cf-filter', {\n entity: entityType,\n field: key,\n tokens: tokens.tokens,\n hashes,\n applied,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope,\n })\n if (applied) return q\n } else {\n this.logSearchDebug('search:cf-skip-empty-hashes', {\n entity: entityType,\n field: key,\n value,\n })\n }\n return q\n }\n switch (op) {\n case 'eq':\n return q.where((builder) => {\n builder.orWhere(text, '=', value as Knex.Value)\n builder.orWhere(arrContains(value))\n })\n case 'ne':\n return q.whereNot(text, '=', value as Knex.Value)\n case 'in': {\n const vals = this.toArray(value)\n return q.where((builder) => {\n vals.forEach((val) => {\n builder.orWhere(text, '=', val as Knex.Value)\n builder.orWhere(arrContains(val))\n })\n })\n }\n case 'nin': {\n const vals = this.toArray(value) as readonly Knex.Value[]\n return q.whereNotIn(text as any, vals as any)\n }\n case 'like':\n return q.where(text, 'like', value as Knex.Value)\n case 'ilike':\n return q.where(text, 'ilike', value as Knex.Value)\n case 'exists':\n return value\n ? q.whereRaw(`${text.toString()} is not null`)\n : q.whereRaw(`${text.toString()} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<='\n return q.where(text, operator, value as Knex.Value)\n }\n default:\n return q\n }\n }\n\n private applyIndexDocFilterFromAlias(\n knex: Knex,\n q: ResultBuilder,\n alias: string,\n entityType: string,\n key: string,\n op: FilterOp,\n value: unknown,\n recordIdColumn: string,\n search?: SearchRuntime,\n ): ResultBuilder {\n const text = knex.raw(`(${alias}.doc ->> ?)`, [key])\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const applied = this.applySearchTokens(q, {\n knex,\n entity: entityType,\n field: key,\n hashes,\n recordIdColumn,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n })\n this.logSearchDebug('search:index-doc-filter', {\n entity: entityType,\n field: key,\n tokens: tokens.tokens,\n hashes,\n applied,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope,\n })\n if (applied) return q\n } else {\n this.logSearchDebug('search:index-doc-skip-empty-hashes', {\n entity: entityType,\n field: key,\n value,\n })\n }\n return q\n }\n switch (op) {\n case 'eq':\n return q.where(text, '=', value as Knex.Value)\n case 'ne':\n return q.where(text, '!=', value as Knex.Value)\n case 'in':\n return q.whereIn(text as any, this.toArray(value) as readonly Knex.Value[])\n case 'nin':\n return q.whereNotIn(text as any, this.toArray(value) as readonly Knex.Value[])\n case 'like':\n return q.where(text, 'like', value as Knex.Value)\n case 'ilike':\n return q.where(text, 'ilike', value as Knex.Value)\n case 'exists':\n return value\n ? q.whereRaw(`${text.toString()} is not null`)\n : q.whereRaw(`${text.toString()} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<='\n return q.where(text, operator, value as Knex.Value)\n }\n default:\n return q\n }\n }\n\n private async queryCustomEntity<T = unknown>(entity: string, opts: QueryOptions = {}): Promise<QueryResult<T>> {\n const knex = this.getKnex()\n const alias = 'ce'\n let q = knex({ [alias]: 'custom_entities_storage' }).where(`${alias}.entity_type`, entity)\n\n const orgScope = this.resolveOrganizationScope(opts)\n\n // Require tenant scope; custom entities are tenant-scoped only\n if (!opts.tenantId) throw new Error('QueryEngine: tenantId is required')\n q = q.andWhere(`${alias}.tenant_id`, opts.tenantId)\n if (orgScope) {\n q = this.applyOrganizationScope(q, `${alias}.organization_id`, orgScope)\n }\n if (!opts.withDeleted) q = q.whereNull(`${alias}.deleted_at`)\n const searchConfig = resolveSearchConfig()\n const searchEnabled = searchConfig.enabled && await this.tableExists('search_tokens')\n const hasSearchTokens = searchEnabled\n ? await this.hasSearchTokens(entity, opts.tenantId ?? null, orgScope)\n : false\n const searchRuntime: SearchRuntime = {\n enabled: searchEnabled && hasSearchTokens,\n config: searchConfig,\n organizationScope: orgScope,\n tenantId: opts.tenantId ?? null,\n }\n\n const normalizedFilters = normalizeFilters(opts.filters)\n\n // Apply filters: cf:* via JSONB; other keys: special-case id/created_at/updated_at/deleted_at, otherwise from doc\n for (const filter of normalizedFilters) {\n if (filter.field.startsWith('cf:')) {\n q = this.applyCfFilterFromAlias(knex, q, alias, entity, filter.field, filter.op, filter.value, searchRuntime)\n continue\n }\n const column = this.resolveCustomEntityColumn(alias, String(filter.field))\n if (column) {\n q = this.applyColumnFilter(q, column, filter, {\n ...searchRuntime,\n knex,\n entity,\n field: String(filter.field),\n recordIdColumn: `${alias}.entity_id`,\n })\n continue\n }\n const docExpr = knex.raw(`(${alias}.doc ->> ?)`, [String(filter.field)])\n q = this.applyColumnFilter(q, docExpr, filter, {\n ...searchRuntime,\n knex,\n entity,\n field: String(filter.field),\n recordIdColumn: `${alias}.entity_id`,\n })\n }\n\n // Determine CFs and l10n keys to include\n const cfKeys = new Set<string>()\n for (const f of (opts.fields || [])) {\n if (typeof f === 'string' && f.startsWith('cf:')) cfKeys.add(f.slice(3))\n else if (typeof f === 'string' && f.startsWith('l10n:')) cfKeys.add(f)\n }\n for (const filter of normalizedFilters) {\n if (typeof filter.field === 'string' && filter.field.startsWith('cf:')) cfKeys.add(filter.field.slice(3))\n else if (typeof filter.field === 'string' && filter.field.startsWith('l10n:')) cfKeys.add(filter.field)\n }\n if (opts.includeCustomFields === true) {\n try {\n const rows = await knex('custom_field_defs')\n .select('key')\n .where({ entity_id: entity, is_active: true })\n .modify((qb) => {\n qb.andWhere({ tenant_id: opts.tenantId })\n // NOTE: organization-level scoping intentionally disabled for custom fields\n // if (opts.organizationId != null) qb.andWhere((b: any) => b.where({ organization_id: opts.organizationId }).orWhereNull('organization_id'))\n // else qb.whereNull('organization_id')\n })\n for (const row of rows) {\n const key = (row as Record<string, unknown>).key\n if (typeof key === 'string') {\n cfKeys.add(key)\n } else if (key != null) {\n cfKeys.add(String(key))\n }\n }\n } catch {\n // ignore and fall back to whatever keys we already have\n }\n } else if (Array.isArray(opts.includeCustomFields)) {\n for (const k of opts.includeCustomFields) cfKeys.add(k)\n }\n\n // Selection\n const requested = (opts.fields && opts.fields.length) ? opts.fields : ['id']\n for (const field of requested) {\n const f = String(field)\n if (f.startsWith('cf:')) {\n const aliasName = this.sanitize(f)\n const expr = this.jsonbRawAlias(knex, alias, f)\n q = q.select({ [aliasName]: expr })\n } else if (f === 'id') {\n q = q.select(knex.raw(`${alias}.entity_id as ??`, ['id']))\n } else if (f === 'created_at' || f === 'updated_at' || f === 'deleted_at') {\n q = q.select(knex.raw(`${alias}.?? as ??`, [f, f]))\n } else {\n // Non-cf from doc\n const expr = knex.raw(`(${alias}.doc ->> ?)`, [f])\n q = q.select({ [f]: expr })\n }\n }\n // Ensure CFs necessary for sort are selected\n const cfSelectedAliases: string[] = []\n for (const key of cfKeys) {\n const aliasName = this.sanitize(`cf:${key}`)\n const expr = this.jsonbRawAlias(knex, alias, `cf:${key}`)\n q = q.select({ [aliasName]: expr })\n cfSelectedAliases.push(aliasName)\n }\n\n // Sorting\n for (const s of opts.sort || []) {\n if (s.field.startsWith('cf:')) {\n const key = s.field.slice(3)\n const aliasName = this.sanitize(`cf:${key}`)\n if (!cfSelectedAliases.includes(aliasName)) {\n const expr = this.jsonbRawAlias(knex, alias, `cf:${key}`)\n q = q.select({ [aliasName]: expr })\n cfSelectedAliases.push(aliasName)\n }\n q = q.orderBy(aliasName, s.dir ?? SortDir.Asc)\n } else if (s.field === 'id') {\n q = q.orderBy(`${alias}.entity_id`, s.dir ?? SortDir.Asc)\n } else if (s.field === 'created_at' || s.field === 'updated_at' || s.field === 'deleted_at') {\n q = q.orderBy(`${alias}.${s.field}`, s.dir ?? SortDir.Asc)\n } else {\n const direction = s.dir ?? SortDir.Asc\n q = q.orderByRaw(`(${alias}.doc ->> ?) ${direction}`, [s.field])\n }\n }\n\n // Pagination + totals\n const page = opts.page?.page ?? 1\n const pageSize = opts.page?.pageSize ?? 20\n const countClone = q.clone()\n if (typeof countClone.clearSelect === 'function') countClone.clearSelect()\n if (typeof countClone.clearOrder === 'function') countClone.clearOrder()\n const countRow = await countClone.countDistinct(`${alias}.entity_id as count`).first()\n const total = this.parseCount(countRow)\n const items = await q.limit(pageSize).offset((page - 1) * pageSize)\n return { items, page, pageSize, total }\n }\n\n private async tableExists(table: string): Promise<boolean> {\n const knex = this.getKnex()\n const exists = await knex('information_schema.tables').where({ table_name: table }).first()\n return !!exists\n }\n\n private async hasSearchTokens(\n entity: string,\n tenantId: string | null,\n orgScope?: { ids: string[]; includeNull: boolean } | null\n ): Promise<boolean> {\n try {\n const knex = this.getKnex()\n const query = knex('search_tokens').select(1).where('entity_type', entity).limit(1)\n if (tenantId !== undefined) {\n query.andWhereRaw('tenant_id is not distinct from ?', [tenantId])\n }\n if (orgScope) {\n this.applyOrganizationScope(query as any, 'search_tokens.organization_id', orgScope)\n }\n const row = await query.first()\n return !!row\n } catch (err) {\n this.logSearchDebug('search:has-tokens-error', {\n entity,\n tenantId,\n organizationScope: orgScope,\n error: err instanceof Error ? err.message : String(err),\n })\n return false\n }\n }\n\n private async searchSourcesHaveTokens(\n sources: SearchTokenSource[],\n tenantId: string | null,\n orgScope?: { ids: string[]; includeNull: boolean } | null\n ): Promise<boolean> {\n for (const source of sources) {\n const ok = await this.hasSearchTokens(source.entity, tenantId, orgScope)\n this.logSearchDebug('search:source-has-tokens', {\n entity: source.entity,\n recordIdColumn: source.recordIdColumn,\n tenantId,\n organizationScope: orgScope,\n hasTokens: ok,\n })\n if (ok) return true\n }\n return false\n }\n\n private async resolveAvailableCustomFieldKeys(entityIds: string[], tenantId: string | null): Promise<string[]> {\n if (!entityIds.length) return []\n const cacheKey = this.customFieldKeysCacheKey(entityIds, tenantId)\n const now = Date.now()\n const cached = this.customFieldKeysCache.get(cacheKey)\n if (cached && cached.expiresAt > now) {\n return cached.value.slice()\n }\n\n const knex = this.getKnex()\n const rows = await knex('custom_field_defs')\n .select('key')\n .whereIn('entity_id', entityIds)\n .andWhere('is_active', true)\n .modify((qb: any) => {\n qb.andWhere((inner: any) => {\n inner.where({ tenant_id: tenantId }).orWhereNull('tenant_id')\n })\n })\n const keys = new Set<string>()\n for (const row of rows || []) {\n const key = (row as Record<string, unknown>).key\n if (typeof key === 'string' && key.trim().length) keys.add(key.trim())\n else if (key != null) keys.add(String(key))\n }\n const result = Array.from(keys)\n if (this.customFieldKeysTtlMs > 0) {\n this.customFieldKeysCache.set(cacheKey, { expiresAt: now + this.customFieldKeysTtlMs, value: result })\n }\n return result.slice()\n }\n\n private async entityHasActiveCustomFields(entityId: string, tenantId: string | null): Promise<boolean> {\n try {\n const keys = await this.resolveAvailableCustomFieldKeys([entityId], tenantId)\n return keys.length > 0\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('query:cf:check-error', {\n entity: entityId,\n tenantId: tenantId ?? null,\n error: err instanceof Error ? err.message : err,\n })\n }\n return true\n }\n }\n\n private customFieldKeysCacheKey(entityIds: string[], tenantId: string | null): string {\n const sorted = entityIds.slice().sort((a, b) => a.localeCompare(b)).join(',')\n return `${tenantId ?? '__none__'}|${sorted}`\n }\n\n private resolveVectorService(): VectorIndexService | null {\n if (!this.vectorServiceResolver) return null\n try {\n return this.vectorServiceResolver() ?? null\n } catch {\n return null\n }\n }\n\n private resolveEntityLabel(entity: string): string {\n return entity\n }\n\n private async indexAnyRows(entity: string): Promise<boolean> {\n const knex = this.getKnex()\n // Prefer coverage snapshots \u2013 cheap and already scoped by maintenance jobs.\n const coverage = await knex('entity_index_coverage')\n .select(1)\n .where('entity_type', entity)\n .where('indexed_count', '>', 0)\n .first()\n if (coverage) return true\n const exists = await knex('entity_indexes').select('entity_id').where({ entity_type: entity }).first()\n return !!exists\n }\n private async getStoredCoverageSnapshot(\n entity: string,\n tenantId: string | null,\n organizationId: string | null,\n withDeleted: boolean\n ): Promise<{ baseCount: number; indexedCount: number } | null> {\n try {\n if (!this.isCoverageOptimizationEnabled()) {\n await refreshCoverageSnapshot(\n this.em,\n {\n entityType: entity,\n tenantId,\n organizationId,\n withDeleted,\n },\n )\n }\n const knex = this.getKnex()\n const row = await readCoverageSnapshot(knex, {\n entityType: entity,\n tenantId,\n organizationId,\n withDeleted,\n })\n if (!row) return null\n return { baseCount: row.baseCount, indexedCount: row.indexedCount }\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('coverage:snapshot:read-error', {\n entity,\n tenantId,\n organizationId,\n withDeleted,\n error: err instanceof Error ? err.message : err,\n })\n }\n return null\n }\n }\n\n private scheduleAutoReindex(\n entity: string,\n opts: QueryOptions,\n stats?: { baseCount: number; indexedCount: number },\n organizationIdOverride?: string | null\n ) {\n if (!this.isAutoReindexEnabled()) return\n\n const bus = this.resolveEventBus()\n if (!bus) return\n const payload = {\n entityType: entity,\n tenantId: opts.tenantId ?? null,\n organizationId: organizationIdOverride ?? opts.organizationId ?? null,\n force: false,\n }\n const context = stats\n ? {\n entity,\n tenantId: payload.tenantId,\n organizationId: payload.organizationId,\n baseCount: stats.baseCount,\n indexedCount: stats.indexedCount,\n }\n : { entity, tenantId: payload.tenantId, organizationId: payload.organizationId }\n\n void Promise.resolve()\n .then(async () => {\n try {\n await bus.emitEvent('query_index.reindex', payload, { persistent: true })\n if (this.isDebugVerbosity()) this.debug('query:auto-reindex:scheduled', context)\n } catch (err) {\n console.warn('[HybridQueryEngine] Failed to schedule auto reindex:', {\n ...context,\n error: err instanceof Error ? err.message : err,\n })\n }\n })\n }\n\n private scheduleCoverageRefresh(\n entity: string,\n tenantId: string | null | undefined,\n organizationId: string | null | undefined,\n withDeleted: boolean\n ): void {\n const bus = this.resolveEventBus()\n if (!bus) return\n const key = [\n entity,\n tenantId ?? '__tenant__',\n organizationId ?? '__org__',\n withDeleted ? '1' : '0',\n ].join('|')\n if (this.pendingCoverageRefreshKeys.has(key)) return\n this.pendingCoverageRefreshKeys.add(key)\n void Promise.resolve()\n .then(async () => {\n try {\n await bus.emitEvent('query_index.coverage.refresh', {\n entityType: entity,\n tenantId: tenantId ?? null,\n organizationId: organizationId ?? null,\n withDeleted,\n delayMs: 0,\n })\n if (this.isDebugVerbosity()) {\n this.debug('coverage:refresh:scheduled', {\n entity,\n tenantId: tenantId ?? null,\n organizationId: organizationId ?? null,\n withDeleted,\n })\n }\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('coverage:refresh:failed', {\n entity,\n tenantId: tenantId ?? null,\n organizationId: organizationId ?? null,\n withDeleted,\n error: err instanceof Error ? err.message : err,\n })\n }\n }\n })\n .finally(() => {\n this.pendingCoverageRefreshKeys.delete(key)\n })\n }\n\n private resolveEventBus(): Pick<EventBus, 'emitEvent'> | null {\n if (!this.eventBusResolver) return null\n try {\n const bus = this.eventBusResolver()\n return bus ?? null\n } catch {\n return null\n }\n }\n\n private isAutoReindexEnabled(): boolean {\n if (this.autoReindexEnabled != null) return this.autoReindexEnabled\n const raw = (\n process.env.SCHEDULE_AUTO_REINDEX ??\n process.env.QUERY_INDEX_AUTO_REINDEX ??\n ''\n )\n .trim()\n .toLowerCase()\n if (!raw) {\n this.autoReindexEnabled = true\n return true\n }\n const parsed = parseBooleanToken(raw)\n this.autoReindexEnabled = parsed === null ? true : parsed\n return this.autoReindexEnabled\n }\n\n private isCoverageOptimizationEnabled(): boolean {\n if (this.coverageOptimizationEnabled != null) return this.coverageOptimizationEnabled\n const raw = (process.env.OPTIMIZE_INDEX_COVERAGE_STATS ?? '').trim().toLowerCase()\n if (!raw) {\n this.coverageOptimizationEnabled = false\n return false\n }\n this.coverageOptimizationEnabled = parseBooleanToken(raw) === true\n return this.coverageOptimizationEnabled\n }\n\n private async columnExists(table: string, column: string): Promise<boolean> {\n const key = `${table}.${column}`\n if (this.columnCache.has(key)) {\n const cached = this.columnCache.get(key)\n if (cached === true) return true\n this.columnCache.delete(key)\n }\n const knex = this.getKnex()\n const exists = await knex('information_schema.columns')\n .where({ table_name: table, column_name: column })\n .first()\n const present = !!exists\n if (present) this.columnCache.set(key, true)\n else this.columnCache.delete(key)\n return present\n }\n\n private async getBaseColumnsForEntity(entity: string): Promise<Map<string, string>> {\n const knex = this.getKnex()\n const table = resolveEntityTableName(this.em, entity)\n const rows = await knex('information_schema.columns')\n .select('column_name', 'data_type')\n .where({ table_name: table })\n const map = new Map<string, string>()\n for (const r of rows) map.set(r.column_name, r.data_type)\n return map\n }\n\n private resolveOrganizationScope(opts: QueryOptions): { ids: string[]; includeNull: boolean } | null {\n if (opts.organizationIds !== undefined) {\n const raw = (opts.organizationIds ?? []).map((id) => (typeof id === 'string' ? id.trim() : id))\n const includeNull = raw.some((id) => id == null || id === '')\n const ids = raw.filter((id): id is string => typeof id === 'string' && id.length > 0)\n const unique = Array.from(new Set(ids))\n return { ids: unique, includeNull }\n }\n if (typeof opts.organizationId === 'string' && opts.organizationId.trim().length > 0) {\n return { ids: [opts.organizationId], includeNull: false }\n }\n return null\n }\n\n private resolveCoverageSnapshotScope(\n opts: QueryOptions\n ): { tenantId: string | null; organizationId: string | null } | null {\n const tenantId = opts.tenantId ?? null\n const orgScope = this.resolveOrganizationScope(opts)\n if (!orgScope) return { tenantId, organizationId: null }\n if (orgScope.includeNull) {\n if (orgScope.ids.length === 0) return { tenantId, organizationId: null }\n return null\n }\n if (orgScope.ids.length === 1) return { tenantId, organizationId: orgScope.ids[0] }\n if (orgScope.ids.length === 0) return { tenantId, organizationId: null }\n return null\n }\n\n private applyOrganizationScope<TRecord extends ResultRow, TResult>(\n q: Knex.QueryBuilder<TRecord, TResult>,\n column: string,\n scope: { ids: string[]; includeNull: boolean }\n ): Knex.QueryBuilder<TRecord, TResult> {\n if (scope.ids.length === 0 && !scope.includeNull) {\n return q.whereRaw('1 = 0')\n }\n return q.where((builder) => {\n let applied = false\n if (scope.ids.length > 0) {\n builder.whereIn(column, scope.ids as readonly string[])\n applied = true\n }\n if (scope.includeNull) {\n if (applied) builder.orWhereNull(column)\n else builder.whereNull(column)\n } else if (!applied) {\n builder.whereRaw('1 = 0')\n }\n })\n }\n\n private normalizeFilters(filters?: QueryOptions['filters']): NormalizedFilter[] {\n if (!filters) return []\n const normalizeField = (k: string) => k.startsWith('cf_') ? `cf:${k.slice(3)}` : k\n if (Array.isArray(filters)) {\n return (filters as Filter[]).map((filter) => ({\n field: normalizeField(String(filter.field)),\n op: filter.op,\n value: filter.value,\n }))\n }\n const out: NormalizedFilter[] = []\n const obj = filters as Record<string, unknown>\n const add = (field: string, op: FilterOp, value?: unknown) => out.push({ field, op, value })\n for (const [rawKey, rawVal] of Object.entries(obj)) {\n const field = normalizeField(rawKey)\n if (rawVal !== null && typeof rawVal === 'object' && !Array.isArray(rawVal)) {\n for (const [opKey, opVal] of Object.entries(rawVal as Record<string, unknown>)) {\n switch (opKey) {\n case '$eq': add(field, 'eq', opVal); break\n case '$ne': add(field, 'ne', opVal); break\n case '$gt': add(field, 'gt', opVal); break\n case '$gte': add(field, 'gte', opVal); break\n case '$lt': add(field, 'lt', opVal); break\n case '$lte': add(field, 'lte', opVal); break\n case '$in': add(field, 'in', opVal); break\n case '$nin': add(field, 'nin', opVal); break\n case '$like': add(field, 'like', opVal); break\n case '$ilike': add(field, 'ilike', opVal); break\n case '$exists': add(field, 'exists', opVal); break\n }\n }\n } else {\n add(field, 'eq', rawVal)\n }\n }\n return out\n }\n\n private sanitize(s: string): string {\n return s.replace(/[^a-zA-Z0-9_]/g, '_')\n }\n\n private toArray(value: unknown): readonly unknown[] {\n if (Array.isArray(value)) {\n return value\n }\n if (value === undefined) {\n return []\n }\n return [value]\n }\n\n private parseCount(row: unknown): number {\n if (row && typeof row === 'object' && 'count' in row) {\n const value = (row as { count: unknown }).count\n if (typeof value === 'number') return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? 0 : parsed\n }\n }\n return 0\n }\n\n private logSearchDebug(event: string, payload: Record<string, unknown>) {\n if (!this.isDebugVerbosity()) return\n try {\n console.info('[query-index:search]', event, JSON.stringify(payload))\n } catch {\n console.info('[query-index:search]', event, payload)\n }\n }\n\n private applyColumnFilter<TRecord extends ResultRow, TResult>(\n q: Knex.QueryBuilder<TRecord, TResult>,\n column: string | Knex.Raw,\n filter: NormalizedFilter,\n search?: SearchRuntime & { knex: Knex; entity: string; field: string; recordIdColumn?: string }\n ): Knex.QueryBuilder<TRecord, TResult> {\n if (\n (filter.op === 'like' || filter.op === 'ilike') &&\n search?.enabled &&\n typeof filter.value === 'string'\n ) {\n const tokens = tokenizeText(String(filter.value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const sources: SearchTokenSource[] = (search.searchSources && search.searchSources.length\n ? search.searchSources\n : [{ entity: search.entity, recordIdColumn: search.recordIdColumn ?? '' }]\n ).filter((src) => src.recordIdColumn && src.entity)\n let applied = false\n if (sources.length) {\n q = q.where((qb) => {\n sources.forEach((src, idx) => {\n const ok = this.applySearchTokens(qb as any, {\n knex: search.knex,\n entity: src.entity,\n field: search.field,\n hashes,\n recordIdColumn: src.recordIdColumn,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n combineWith: idx === 0 ? 'and' : 'or',\n })\n if (ok) applied = true\n })\n })\n }\n this.logSearchDebug('search:filter', {\n entity: search.entity,\n field: search.field,\n tokens: tokens.tokens,\n hashes,\n applied,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope,\n sources: sources.map((src) => ({ entity: src.entity, recordIdColumn: src.recordIdColumn })),\n })\n if (applied) return q\n } else {\n this.logSearchDebug('search:skip-empty-hashes', {\n entity: search.entity,\n field: search.field,\n value: filter.value,\n })\n }\n return q\n }\n const col = column as any\n switch (filter.op) {\n case 'eq':\n return q.where(col, filter.value as Knex.Value)\n case 'ne':\n return q.whereNot(col, filter.value as Knex.Value)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = filter.op === 'gt' ? '>' : filter.op === 'gte' ? '>=' : filter.op === 'lt' ? '<' : '<='\n return q.where(col, operator, filter.value as Knex.Value)\n }\n case 'in': {\n const values = this.toArray(filter.value) as readonly Knex.Value[]\n return q.whereIn(col, values)\n }\n case 'nin': {\n const values = this.toArray(filter.value) as readonly Knex.Value[]\n return q.whereNotIn(col, values)\n }\n case 'like':\n return q.where(col, 'like', filter.value as Knex.Value)\n case 'ilike':\n return q.where(col, 'ilike', filter.value as Knex.Value)\n case 'exists':\n return filter.value ? q.whereNotNull(col) : q.whereNull(col)\n default:\n return q\n }\n }\n\n private resolveCustomEntityColumn(alias: string, field: string): string | null {\n if (field === 'id') return `${alias}.entity_id`\n if (field === 'organization_id' || field === 'organizationId') return `${alias}.organization_id`\n if (field === 'tenant_id' || field === 'tenantId') return `${alias}.tenant_id`\n if (field === 'created_at' || field === 'updated_at' || field === 'deleted_at') return `${alias}.${field}`\n return null\n }\n\n private isDebugVerbosity(): boolean {\n if (this.debugVerbosity != null) return this.debugVerbosity\n this.debugVerbosity = resolveDebugVerbosity()\n return this.debugVerbosity\n }\n\n private isSqlDebugEnabled(): boolean {\n if (this.sqlDebugEnabled != null) return this.sqlDebugEnabled\n this.sqlDebugEnabled = resolveBooleanEnv(['QUERY_ENGINE_DEBUG_SQL'], false)\n return this.sqlDebugEnabled\n }\n\n private isForcePartialIndexEnabled(): boolean {\n if (this.forcePartialIndexEnabled != null) return this.forcePartialIndexEnabled\n this.forcePartialIndexEnabled = resolveBooleanEnv(['FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES'], false)\n return this.forcePartialIndexEnabled\n }\n\n private async resolveCoverageGap(\n entity: string,\n opts: QueryOptions,\n coverageScope?: { tenantId: string | null; organizationId: string | null } | null,\n _sourceTable?: string\n ): Promise<{ stats?: { baseCount: number; indexedCount: number }; scope: 'scoped' | 'global' } | null> {\n const scope = coverageScope ?? this.resolveCoverageSnapshotScope(opts)\n if (!scope) return null\n const tenantId = scope.tenantId\n const organizationId = scope.organizationId\n const withDeleted = !!opts.withDeleted\n\n const snapshot = await this.getStoredCoverageSnapshot(entity, tenantId, organizationId, withDeleted)\n if (!snapshot) {\n this.scheduleCoverageRefresh(entity, tenantId, organizationId, withDeleted)\n return { stats: undefined, scope: 'scoped' }\n }\n\n const baseCount = snapshot.baseCount\n const indexCount = snapshot.indexedCount\n const hasGap = baseCount > 0 && indexCount < baseCount\n if (hasGap || indexCount > baseCount) {\n return { stats: snapshot, scope: 'scoped' }\n }\n\n return null\n }\n\n // Backward-compatible hook for tests that mock coverage stats\n private async indexCoverageStats(\n entity: string,\n opts: QueryOptions,\n coverageScope?: { tenantId: string | null; organizationId: string | null } | null,\n ): Promise<{ baseCount: number; indexedCount: number } | null> {\n const gap = await this.resolveCoverageGap(entity, opts, coverageScope)\n return gap?.stats ?? null\n }\n\n private async captureSqlTiming<TResult>(\n label: string,\n entity: EntityId,\n execute: () => Promise<TResult> | TResult,\n extra?: Record<string, unknown>,\n profiler?: Profiler\n ): Promise<TResult> {\n const shouldDebug = this.isSqlDebugEnabled() && this.isDebugVerbosity()\n const shouldProfile = profiler?.enabled === true\n if (!shouldDebug && !shouldProfile) {\n return Promise.resolve(execute())\n }\n const startedAt = process.hrtime.bigint()\n try {\n return await Promise.resolve(execute())\n } finally {\n const elapsedMs = Number(process.hrtime.bigint() - startedAt) / 1_000_000\n const context: Record<string, unknown> = {\n entity,\n durationMs: Math.round(elapsedMs * 1000) / 1000,\n }\n if (extra) Object.assign(context, extra)\n if (shouldProfile) profiler!.record(label, context.durationMs as number, extra)\n if (shouldDebug) this.debug(`${label}:timing`, context)\n }\n }\n\n private debug(message: string, context?: Record<string, unknown>): void {\n if (!this.isDebugVerbosity()) return\n if (!this.isSqlDebugEnabled()) return\n if (context) console.debug('[HybridQueryEngine]', message, context)\n else console.debug('[HybridQueryEngine]', message)\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["result"]
7
7
  }