@resolveio/server-lib 22.3.219 → 22.3.221

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 (745) hide show
  1. package/.nodemon.json +5 -0
  2. package/.vscode/settings.json +21 -0
  3. package/AGENTS.md +195 -0
  4. package/README.md +22 -0
  5. package/build_package.sh +5 -0
  6. package/compileDTS.pl +64 -0
  7. package/docs/ai-assistant-nightly-eval.md +65 -0
  8. package/docs/ai-assistant-preflight-checklist.md +23 -0
  9. package/docs/ai-assistant-report-builder-bridge-playbook.md +115 -0
  10. package/eslint-plugin-custom/index.js +7 -0
  11. package/eslint-plugin-custom/rules/no-filter-zero-index.js +44 -0
  12. package/eslint.config.js +103 -0
  13. package/gulpfile.js +216 -0
  14. package/methodAndPublicationListGenerator.py +375 -0
  15. package/mongodbensurers.js +2 -0
  16. package/mongostop.js +3 -0
  17. package/package.json +1 -1
  18. package/scripts/cleanup-bypassed-callmethod-logs.js +616 -0
  19. package/settings.development.json +25 -0
  20. package/settings.development.redacted.json +25 -0
  21. package/src/.env +12 -0
  22. package/src/ai/assistant-core-heuristics.ts +379 -0
  23. package/src/ai/resolveio-platform-intelligence-memory-corpus.ts +185 -0
  24. package/src/ai/resolveio-platform-intelligence-memory.ts +325 -0
  25. package/{ai/resolveio-platform-intelligence-types.d.ts → src/ai/resolveio-platform-intelligence-types.ts} +20 -15
  26. package/src/ai/resolveio-platform-intelligence.ts +462 -0
  27. package/src/client-server-app.ts +12 -0
  28. package/src/collections/ai-run.collection.ts +117 -0
  29. package/src/collections/ai-terminal-conversation.collection.ts +91 -0
  30. package/src/collections/ai-terminal-issue-report.collection.ts +99 -0
  31. package/src/collections/ai-terminal-message.collection.ts +77 -0
  32. package/src/collections/app-setting.collection.ts +104 -0
  33. package/src/collections/app-status.collection.ts +58 -0
  34. package/src/collections/communication-metric.collection.ts +84 -0
  35. package/src/collections/counter.collection.ts +56 -0
  36. package/src/collections/cron-job-history.collection.ts +94 -0
  37. package/src/collections/cron-job.collection.ts +92 -0
  38. package/src/collections/customer-notification.collection.ts +131 -0
  39. package/src/collections/customer-portal-password.collection.ts +76 -0
  40. package/src/collections/email-history.collection.ts +134 -0
  41. package/src/collections/email-verified.collection.ts +62 -0
  42. package/src/collections/file.collection.ts +74 -0
  43. package/src/collections/flag-update.collection.ts +57 -0
  44. package/src/collections/flag.collection.ts +57 -0
  45. package/src/collections/log-method-latency.collection.ts +77 -0
  46. package/src/collections/log-subscription.collection.ts +80 -0
  47. package/src/collections/log.collection.ts +93 -0
  48. package/src/collections/logged-in-users.collection.ts +67 -0
  49. package/src/collections/monitor-cpu.collection.ts +65 -0
  50. package/src/collections/monitor-function.collection.ts +74 -0
  51. package/src/collections/monitor-memory.collection.ts +77 -0
  52. package/src/collections/monitor-mongo.collection.ts +71 -0
  53. package/src/collections/notification.collection.ts +57 -0
  54. package/src/collections/openai-usage-ledger.collection.ts +131 -0
  55. package/src/collections/report-builder-dashboard-builder.collection.ts +109 -0
  56. package/src/collections/report-builder-library.collection.ts +89 -0
  57. package/src/collections/report-builder-report.collection.ts +184 -0
  58. package/src/collections/user-group.collection.ts +89 -0
  59. package/src/collections/user-guide.collection.ts +57 -0
  60. package/src/collections/user.collection.ts +181 -0
  61. package/src/cron/cron.ts +117 -0
  62. package/src/fixtures/cron-jobs.ts +95 -0
  63. package/src/fixtures/init.ts +35 -0
  64. package/src/http/auth.ts +818 -0
  65. package/src/http/health.ts +7 -0
  66. package/src/http/home.ts +90 -0
  67. package/src/http/slow-query-publication.ts +49 -0
  68. package/src/index.ts +1 -0
  69. package/src/managers/ai-assistant-codex-manager.manager.ts +1131 -0
  70. package/src/managers/ai-run-evidence.manager.ts +264 -0
  71. package/src/managers/communication-metric.manager.ts +82 -0
  72. package/src/managers/cron.manager.ts +333 -0
  73. package/src/managers/customer-notification-content.manager.ts +236 -0
  74. package/src/managers/diagnostic-manager-bootstrap.ts +165 -0
  75. package/src/managers/error-auto-fix.manager.ts +2767 -0
  76. package/src/managers/local-log.manager.ts +113 -0
  77. package/src/managers/method.manager.ts +1857 -0
  78. package/src/managers/mongo.manager.ts +4575 -0
  79. package/src/managers/monitor.manager.ts +507 -0
  80. package/src/managers/openai-usage-ledger.manager.ts +112 -0
  81. package/src/managers/slow-query-verifier.manager.ts +3590 -0
  82. package/src/managers/slow-query.manager.ts +519 -0
  83. package/src/managers/subscription.manager.ts +3128 -0
  84. package/src/managers/websocket.manager.ts +746 -0
  85. package/src/managers/worker-dispatcher.manager.ts +1360 -0
  86. package/src/managers/worker-server.manager.ts +536 -0
  87. package/src/methods/accounts.ts +532 -0
  88. package/src/methods/ai-terminal.ts +29070 -0
  89. package/src/methods/app-settings.ts +114 -0
  90. package/src/methods/aws.ts +649 -0
  91. package/src/methods/collections.ts +641 -0
  92. package/src/methods/counters.ts +69 -0
  93. package/src/methods/cron-jobs.ts +2614 -0
  94. package/src/methods/customer-notifications.ts +458 -0
  95. package/src/methods/diagnostics.ts +616 -0
  96. package/src/methods/flag-updates.ts +7 -0
  97. package/src/methods/flags.ts +7 -0
  98. package/src/methods/logs.ts +657 -0
  99. package/src/methods/mongo-explorer.ts +1880 -0
  100. package/src/methods/monitor.ts +540 -0
  101. package/src/methods/pdf.ts +1236 -0
  102. package/src/methods/publications.ts +129 -0
  103. package/src/methods/report-builder.ts +3300 -0
  104. package/src/methods/support.ts +335 -0
  105. package/src/models/ai-run.model.ts +27 -0
  106. package/src/models/ai-terminal-conversation.model.ts +19 -0
  107. package/src/models/ai-terminal-issue-report.model.ts +21 -0
  108. package/src/models/ai-terminal-message.model.ts +24 -0
  109. package/src/models/app-setting.model.ts +17 -0
  110. package/{models/app-status.model.d.ts → src/models/app-status.model.ts} +3 -2
  111. package/{models/billing-logged-in-users.model.d.ts → src/models/billing-logged-in-users.model.ts} +5 -4
  112. package/src/models/collection-document.model.ts +24 -0
  113. package/src/models/communication-metric.model.ts +23 -0
  114. package/{models/counter.model.d.ts → src/models/counter.model.ts} +4 -3
  115. package/src/models/cron-job-history.model.ts +16 -0
  116. package/src/models/cron-job.model.ts +15 -0
  117. package/src/models/customer-notification.model.ts +28 -0
  118. package/src/models/customer-portal-password.model.ts +12 -0
  119. package/src/models/dialog.model.ts +25 -0
  120. package/{models/email-history.model.js → src/models/email-history.model.ts} +36 -4
  121. package/{models/email-verified.model.d.ts → src/models/email-verified.model.ts} +6 -5
  122. package/{models/file.model.d.ts → src/models/file.model.ts} +8 -7
  123. package/{models/flag-update.model.d.ts → src/models/flag-update.model.ts} +4 -3
  124. package/{models/flag.model.d.ts → src/models/flag.model.ts} +4 -3
  125. package/src/models/log-method-latency.model.ts +11 -0
  126. package/{models/log-subscription.model.d.ts → src/models/log-subscription.model.ts} +11 -9
  127. package/src/models/log.model.ts +19 -0
  128. package/{models/logged-in-users.model.d.ts → src/models/logged-in-users.model.ts} +6 -5
  129. package/{models/method-response.model.d.ts → src/models/method-response.model.ts} +7 -6
  130. package/src/models/method.model.ts +25 -0
  131. package/{models/monitor-cpu.model.d.ts → src/models/monitor-cpu.model.ts} +9 -7
  132. package/src/models/monitor-function.model.ts +16 -0
  133. package/src/models/monitor-memory.model.ts +17 -0
  134. package/src/models/monitor-mongo.model.ts +15 -0
  135. package/{models/notification.model.d.ts → src/models/notification.model.ts} +6 -4
  136. package/src/models/openai-usage-ledger.model.ts +56 -0
  137. package/src/models/pagination.model.ts +35 -0
  138. package/src/models/permission.model.ts +14 -0
  139. package/src/models/report-builder-dashboard-builder.model.ts +29 -0
  140. package/src/models/report-builder-library.model.ts +20 -0
  141. package/src/models/report-builder-report.model.ts +136 -0
  142. package/src/models/report-builder.model.ts +68 -0
  143. package/src/models/select-data-label.model.ts +9 -0
  144. package/src/models/server-message.model.ts +31 -0
  145. package/src/models/slow-query-report.model.ts +23 -0
  146. package/src/models/subscription.model.ts +73 -0
  147. package/src/models/support-ticket.model.ts +104 -0
  148. package/src/models/user-group.model.ts +24 -0
  149. package/{models/user-guide.model.d.ts → src/models/user-guide.model.ts} +5 -4
  150. package/src/models/user.model.ts +96 -0
  151. package/src/private/images/ResolveIO.png +0 -0
  152. package/src/publications/ai-terminal.ts +73 -0
  153. package/src/publications/app-settings.ts +25 -0
  154. package/src/publications/app-status.ts +13 -0
  155. package/src/publications/cron-jobs.ts +40 -0
  156. package/src/publications/customer-notifications.ts +101 -0
  157. package/src/publications/files.ts +33 -0
  158. package/src/publications/flags-update.ts +19 -0
  159. package/src/publications/flags.ts +19 -0
  160. package/src/publications/logs.ts +163 -0
  161. package/src/publications/notifications.ts +13 -0
  162. package/src/publications/report-builder-dashboard-builders.ts +39 -0
  163. package/src/publications/report-builder-libraries.ts +41 -0
  164. package/src/publications/report-builder-reports.ts +47 -0
  165. package/src/publications/super-admin.ts +13 -0
  166. package/src/publications/user-groups.ts +12 -0
  167. package/src/publications/user-guides.ts +12 -0
  168. package/src/resolveio-server-app.ts +617 -0
  169. package/src/server-app.ts +3354 -0
  170. package/src/services/codex-client.ts +1231 -0
  171. package/src/services/openai-client.ts +265 -0
  172. package/src/types/error-report.ts +26 -0
  173. package/src/types/js-tiktoken.d.ts +11 -0
  174. package/src/types/slow-query-report.ts +28 -0
  175. package/src/util/ai-qa-policy.ts +925 -0
  176. package/src/util/ai-run-evidence-adapters.ts +8347 -0
  177. package/src/util/ai-run-evidence-dashboard.ts +323 -0
  178. package/src/util/ai-run-evidence-eval.ts +1057 -0
  179. package/src/util/ai-run-evidence.ts +1430 -0
  180. package/src/util/ai-runner-artifacts.ts +586 -0
  181. package/src/util/ai-runner-manager-autopilot.ts +961 -0
  182. package/src/util/ai-runner-manager-policy.ts +5011 -0
  183. package/src/util/ai-runner-qa-auth.ts +838 -0
  184. package/src/util/ai-runner-qa-tools.ts +3536 -0
  185. package/src/util/aicoder-runner-v6.ts +3121 -0
  186. package/src/util/common.ts +649 -0
  187. package/src/util/customer-portal-password.ts +183 -0
  188. package/src/util/error-reporter.ts +332 -0
  189. package/src/util/error-tracking.ts +79 -0
  190. package/src/util/openai-usage-cost.ts +114 -0
  191. package/src/util/report-builder-unwinds.ts +180 -0
  192. package/src/util/runner-process-janitor.ts +219 -0
  193. package/src/util/schema-report-builder.ts +448 -0
  194. package/src/util/slow-query-reporter.ts +216 -0
  195. package/src/util/subscription-dependency-context.ts +1096 -0
  196. package/src/util/support-runner-v5.ts +10040 -0
  197. package/src/util/tokenizer.ts +38 -0
  198. package/src/workers/codex-runner.worker.ts +142 -0
  199. package/start_server.sh +5 -0
  200. package/tests/ai-assistant-corpus-build.ts +484 -0
  201. package/tests/ai-assistant-corpus-replay-e2e.ts +774 -0
  202. package/tests/ai-assistant-data-parity-e2e.ts +1989 -0
  203. package/tests/ai-assistant-eval-triage.ts +831 -0
  204. package/tests/ai-assistant-openai-e2e.ts +1061 -0
  205. package/tests/ai-assistant-openai-git-e2e.ts +155 -0
  206. package/tests/ai-assistant-preflight-matrix.ts +215 -0
  207. package/tests/ai-assistant-routing-eval.test.ts +585 -0
  208. package/tests/ai-assistant-snf-live-eval.ts +975 -0
  209. package/tests/ai-assistant-utils.test.ts +4834 -0
  210. package/tests/ai-manager-autopilot-snapshot.test.ts +193 -0
  211. package/tests/ai-manager-recovery-checkpoint.test.ts +1383 -0
  212. package/tests/ai-run-eval.test.ts +132 -0
  213. package/tests/ai-run-evidence.test.ts +3773 -0
  214. package/tests/ai-runner-contract.test.ts +515 -0
  215. package/tests/aicoder-runner-v6.test.ts +822 -0
  216. package/tests/error-reporter.test.ts +145 -0
  217. package/tests/method-publication-generator.test.ts +46 -0
  218. package/tests/report-builder-linking.test.ts +79 -0
  219. package/tests/resolveio-platform-intelligence.test.ts +352 -0
  220. package/tests/server-app-cron-owner.test.ts +127 -0
  221. package/tests/subscription-connect-race.test.ts +158 -0
  222. package/tests/subscription-dependency-context.test.ts +324 -0
  223. package/tests/subscription-manager-collection-tracking.test.ts +86 -0
  224. package/tests/subscription-manager-invalidation.test.ts +86 -0
  225. package/tests/support-runner-v5.test.ts +3201 -0
  226. package/tsconfig.json +34 -0
  227. package/ai/assistant-core-heuristics.d.ts +0 -11
  228. package/ai/assistant-core-heuristics.js +0 -356
  229. package/ai/assistant-core-heuristics.js.map +0 -1
  230. package/ai/resolveio-platform-intelligence-memory-corpus.d.ts +0 -3
  231. package/ai/resolveio-platform-intelligence-memory-corpus.js +0 -214
  232. package/ai/resolveio-platform-intelligence-memory-corpus.js.map +0 -1
  233. package/ai/resolveio-platform-intelligence-memory.d.ts +0 -20
  234. package/ai/resolveio-platform-intelligence-memory.js +0 -341
  235. package/ai/resolveio-platform-intelligence-memory.js.map +0 -1
  236. package/ai/resolveio-platform-intelligence-types.js +0 -4
  237. package/ai/resolveio-platform-intelligence-types.js.map +0 -1
  238. package/ai/resolveio-platform-intelligence.d.ts +0 -6
  239. package/ai/resolveio-platform-intelligence.js +0 -463
  240. package/ai/resolveio-platform-intelligence.js.map +0 -1
  241. package/client-server-app.d.ts +0 -1
  242. package/client-server-app.js +0 -68
  243. package/client-server-app.js.map +0 -1
  244. package/collections/ai-run.collection.d.ts +0 -3
  245. package/collections/ai-run.collection.js +0 -170
  246. package/collections/ai-run.collection.js.map +0 -1
  247. package/collections/ai-terminal-conversation.collection.d.ts +0 -2
  248. package/collections/ai-terminal-conversation.collection.js +0 -140
  249. package/collections/ai-terminal-conversation.collection.js.map +0 -1
  250. package/collections/ai-terminal-issue-report.collection.d.ts +0 -2
  251. package/collections/ai-terminal-issue-report.collection.js +0 -148
  252. package/collections/ai-terminal-issue-report.collection.js.map +0 -1
  253. package/collections/ai-terminal-message.collection.d.ts +0 -2
  254. package/collections/ai-terminal-message.collection.js +0 -121
  255. package/collections/ai-terminal-message.collection.js.map +0 -1
  256. package/collections/app-setting.collection.d.ts +0 -3
  257. package/collections/app-setting.collection.js +0 -103
  258. package/collections/app-setting.collection.js.map +0 -1
  259. package/collections/app-status.collection.d.ts +0 -3
  260. package/collections/app-status.collection.js +0 -57
  261. package/collections/app-status.collection.js.map +0 -1
  262. package/collections/communication-metric.collection.d.ts +0 -2
  263. package/collections/communication-metric.collection.js +0 -133
  264. package/collections/communication-metric.collection.js.map +0 -1
  265. package/collections/counter.collection.d.ts +0 -3
  266. package/collections/counter.collection.js +0 -56
  267. package/collections/counter.collection.js.map +0 -1
  268. package/collections/cron-job-history.collection.d.ts +0 -3
  269. package/collections/cron-job-history.collection.js +0 -137
  270. package/collections/cron-job-history.collection.js.map +0 -1
  271. package/collections/cron-job.collection.d.ts +0 -3
  272. package/collections/cron-job.collection.js +0 -92
  273. package/collections/cron-job.collection.js.map +0 -1
  274. package/collections/customer-notification.collection.d.ts +0 -3
  275. package/collections/customer-notification.collection.js +0 -130
  276. package/collections/customer-notification.collection.js.map +0 -1
  277. package/collections/customer-portal-password.collection.d.ts +0 -3
  278. package/collections/customer-portal-password.collection.js +0 -75
  279. package/collections/customer-portal-password.collection.js.map +0 -1
  280. package/collections/email-history.collection.d.ts +0 -3
  281. package/collections/email-history.collection.js +0 -134
  282. package/collections/email-history.collection.js.map +0 -1
  283. package/collections/email-verified.collection.d.ts +0 -3
  284. package/collections/email-verified.collection.js +0 -62
  285. package/collections/email-verified.collection.js.map +0 -1
  286. package/collections/file.collection.d.ts +0 -3
  287. package/collections/file.collection.js +0 -74
  288. package/collections/file.collection.js.map +0 -1
  289. package/collections/flag-update.collection.d.ts +0 -3
  290. package/collections/flag-update.collection.js +0 -57
  291. package/collections/flag-update.collection.js.map +0 -1
  292. package/collections/flag.collection.d.ts +0 -3
  293. package/collections/flag.collection.js +0 -57
  294. package/collections/flag.collection.js.map +0 -1
  295. package/collections/log-method-latency.collection.d.ts +0 -3
  296. package/collections/log-method-latency.collection.js +0 -77
  297. package/collections/log-method-latency.collection.js.map +0 -1
  298. package/collections/log-subscription.collection.d.ts +0 -3
  299. package/collections/log-subscription.collection.js +0 -80
  300. package/collections/log-subscription.collection.js.map +0 -1
  301. package/collections/log.collection.d.ts +0 -3
  302. package/collections/log.collection.js +0 -93
  303. package/collections/log.collection.js.map +0 -1
  304. package/collections/logged-in-users.collection.d.ts +0 -3
  305. package/collections/logged-in-users.collection.js +0 -67
  306. package/collections/logged-in-users.collection.js.map +0 -1
  307. package/collections/monitor-cpu.collection.d.ts +0 -3
  308. package/collections/monitor-cpu.collection.js +0 -65
  309. package/collections/monitor-cpu.collection.js.map +0 -1
  310. package/collections/monitor-function.collection.d.ts +0 -3
  311. package/collections/monitor-function.collection.js +0 -74
  312. package/collections/monitor-function.collection.js.map +0 -1
  313. package/collections/monitor-memory.collection.d.ts +0 -3
  314. package/collections/monitor-memory.collection.js +0 -77
  315. package/collections/monitor-memory.collection.js.map +0 -1
  316. package/collections/monitor-mongo.collection.d.ts +0 -3
  317. package/collections/monitor-mongo.collection.js +0 -71
  318. package/collections/monitor-mongo.collection.js.map +0 -1
  319. package/collections/notification.collection.d.ts +0 -3
  320. package/collections/notification.collection.js +0 -57
  321. package/collections/notification.collection.js.map +0 -1
  322. package/collections/openai-usage-ledger.collection.d.ts +0 -2
  323. package/collections/openai-usage-ledger.collection.js +0 -188
  324. package/collections/openai-usage-ledger.collection.js.map +0 -1
  325. package/collections/report-builder-dashboard-builder.collection.d.ts +0 -3
  326. package/collections/report-builder-dashboard-builder.collection.js +0 -109
  327. package/collections/report-builder-dashboard-builder.collection.js.map +0 -1
  328. package/collections/report-builder-library.collection.d.ts +0 -3
  329. package/collections/report-builder-library.collection.js +0 -87
  330. package/collections/report-builder-library.collection.js.map +0 -1
  331. package/collections/report-builder-report.collection.d.ts +0 -4
  332. package/collections/report-builder-report.collection.js +0 -184
  333. package/collections/report-builder-report.collection.js.map +0 -1
  334. package/collections/user-group.collection.d.ts +0 -4
  335. package/collections/user-group.collection.js +0 -89
  336. package/collections/user-group.collection.js.map +0 -1
  337. package/collections/user-guide.collection.d.ts +0 -3
  338. package/collections/user-guide.collection.js +0 -57
  339. package/collections/user-guide.collection.js.map +0 -1
  340. package/collections/user.collection.d.ts +0 -4
  341. package/collections/user.collection.js +0 -180
  342. package/collections/user.collection.js.map +0 -1
  343. package/cron/cron.d.ts +0 -14
  344. package/cron/cron.js +0 -216
  345. package/cron/cron.js.map +0 -1
  346. package/fixtures/cron-jobs.d.ts +0 -1
  347. package/fixtures/cron-jobs.js +0 -150
  348. package/fixtures/cron-jobs.js.map +0 -1
  349. package/fixtures/init.d.ts +0 -1
  350. package/fixtures/init.js +0 -91
  351. package/fixtures/init.js.map +0 -1
  352. package/http/auth.d.ts +0 -2
  353. package/http/auth.js +0 -951
  354. package/http/auth.js.map +0 -1
  355. package/http/health.d.ts +0 -1
  356. package/http/health.js +0 -11
  357. package/http/health.js.map +0 -1
  358. package/http/home.d.ts +0 -1
  359. package/http/home.js +0 -134
  360. package/http/home.js.map +0 -1
  361. package/http/slow-query-publication.d.ts +0 -2
  362. package/http/slow-query-publication.js +0 -99
  363. package/http/slow-query-publication.js.map +0 -1
  364. package/index.d.ts +0 -1
  365. package/index.js +0 -19
  366. package/index.js.map +0 -1
  367. package/managers/ai-assistant-codex-manager.manager.d.ts +0 -67
  368. package/managers/ai-assistant-codex-manager.manager.js +0 -1113
  369. package/managers/ai-assistant-codex-manager.manager.js.map +0 -1
  370. package/managers/ai-run-evidence.manager.d.ts +0 -36
  371. package/managers/ai-run-evidence.manager.js +0 -377
  372. package/managers/ai-run-evidence.manager.js.map +0 -1
  373. package/managers/communication-metric.manager.d.ts +0 -16
  374. package/managers/communication-metric.manager.js +0 -134
  375. package/managers/communication-metric.manager.js.map +0 -1
  376. package/managers/cron.manager.d.ts +0 -20
  377. package/managers/cron.manager.js +0 -534
  378. package/managers/cron.manager.js.map +0 -1
  379. package/managers/customer-notification-content.manager.d.ts +0 -55
  380. package/managers/customer-notification-content.manager.js +0 -158
  381. package/managers/customer-notification-content.manager.js.map +0 -1
  382. package/managers/diagnostic-manager-bootstrap.d.ts +0 -9
  383. package/managers/diagnostic-manager-bootstrap.js +0 -260
  384. package/managers/diagnostic-manager-bootstrap.js.map +0 -1
  385. package/managers/error-auto-fix.manager.d.ts +0 -149
  386. package/managers/error-auto-fix.manager.js +0 -3064
  387. package/managers/error-auto-fix.manager.js.map +0 -1
  388. package/managers/local-log.manager.d.ts +0 -18
  389. package/managers/local-log.manager.js +0 -88
  390. package/managers/local-log.manager.js.map +0 -1
  391. package/managers/method.manager.d.ts +0 -84
  392. package/managers/method.manager.js +0 -1964
  393. package/managers/method.manager.js.map +0 -1
  394. package/managers/mongo.manager.d.ts +0 -224
  395. package/managers/mongo.manager.js +0 -5000
  396. package/managers/mongo.manager.js.map +0 -1
  397. package/managers/monitor.manager.d.ts +0 -70
  398. package/managers/monitor.manager.js +0 -550
  399. package/managers/monitor.manager.js.map +0 -1
  400. package/managers/openai-usage-ledger.manager.d.ts +0 -30
  401. package/managers/openai-usage-ledger.manager.js +0 -142
  402. package/managers/openai-usage-ledger.manager.js.map +0 -1
  403. package/managers/slow-query-verifier.manager.d.ts +0 -144
  404. package/managers/slow-query-verifier.manager.js +0 -3857
  405. package/managers/slow-query-verifier.manager.js.map +0 -1
  406. package/managers/slow-query.manager.d.ts +0 -28
  407. package/managers/slow-query.manager.js +0 -468
  408. package/managers/slow-query.manager.js.map +0 -1
  409. package/managers/subscription.manager.d.ts +0 -169
  410. package/managers/subscription.manager.js +0 -3434
  411. package/managers/subscription.manager.js.map +0 -1
  412. package/managers/websocket.manager.d.ts +0 -73
  413. package/managers/websocket.manager.js +0 -673
  414. package/managers/websocket.manager.js.map +0 -1
  415. package/managers/worker-dispatcher.manager.d.ts +0 -120
  416. package/managers/worker-dispatcher.manager.js +0 -1266
  417. package/managers/worker-dispatcher.manager.js.map +0 -1
  418. package/managers/worker-server.manager.d.ts +0 -35
  419. package/managers/worker-server.manager.js +0 -582
  420. package/managers/worker-server.manager.js.map +0 -1
  421. package/methods/accounts.d.ts +0 -2
  422. package/methods/accounts.js +0 -624
  423. package/methods/accounts.js.map +0 -1
  424. package/methods/ai-terminal.d.ts +0 -458
  425. package/methods/ai-terminal.js +0 -27991
  426. package/methods/ai-terminal.js.map +0 -1
  427. package/methods/app-settings.d.ts +0 -2
  428. package/methods/app-settings.js +0 -169
  429. package/methods/app-settings.js.map +0 -1
  430. package/methods/aws.d.ts +0 -2
  431. package/methods/aws.js +0 -877
  432. package/methods/aws.js.map +0 -1
  433. package/methods/collections.d.ts +0 -2
  434. package/methods/collections.js +0 -719
  435. package/methods/collections.js.map +0 -1
  436. package/methods/counters.d.ts +0 -2
  437. package/methods/counters.js +0 -113
  438. package/methods/counters.js.map +0 -1
  439. package/methods/cron-jobs.d.ts +0 -2
  440. package/methods/cron-jobs.js +0 -2475
  441. package/methods/cron-jobs.js.map +0 -1
  442. package/methods/customer-notifications.d.ts +0 -2
  443. package/methods/customer-notifications.js +0 -528
  444. package/methods/customer-notifications.js.map +0 -1
  445. package/methods/diagnostics.d.ts +0 -2
  446. package/methods/diagnostics.js +0 -703
  447. package/methods/diagnostics.js.map +0 -1
  448. package/methods/flag-updates.d.ts +0 -2
  449. package/methods/flag-updates.js +0 -8
  450. package/methods/flag-updates.js.map +0 -1
  451. package/methods/flags.d.ts +0 -2
  452. package/methods/flags.js +0 -8
  453. package/methods/flags.js.map +0 -1
  454. package/methods/logs.d.ts +0 -2
  455. package/methods/logs.js +0 -751
  456. package/methods/logs.js.map +0 -1
  457. package/methods/mongo-explorer.d.ts +0 -2
  458. package/methods/mongo-explorer.js +0 -1808
  459. package/methods/mongo-explorer.js.map +0 -1
  460. package/methods/monitor.d.ts +0 -2
  461. package/methods/monitor.js +0 -543
  462. package/methods/monitor.js.map +0 -1
  463. package/methods/pdf.d.ts +0 -2
  464. package/methods/pdf.js +0 -1216
  465. package/methods/pdf.js.map +0 -1
  466. package/methods/publications.d.ts +0 -1
  467. package/methods/publications.js +0 -183
  468. package/methods/publications.js.map +0 -1
  469. package/methods/report-builder.d.ts +0 -2
  470. package/methods/report-builder.js +0 -3094
  471. package/methods/report-builder.js.map +0 -1
  472. package/methods/support.d.ts +0 -2
  473. package/methods/support.js +0 -430
  474. package/methods/support.js.map +0 -1
  475. package/models/ai-run.model.d.ts +0 -19
  476. package/models/ai-run.model.js +0 -4
  477. package/models/ai-run.model.js.map +0 -1
  478. package/models/ai-terminal-conversation.model.d.ts +0 -17
  479. package/models/ai-terminal-conversation.model.js +0 -4
  480. package/models/ai-terminal-conversation.model.js.map +0 -1
  481. package/models/ai-terminal-issue-report.model.d.ts +0 -19
  482. package/models/ai-terminal-issue-report.model.js +0 -4
  483. package/models/ai-terminal-issue-report.model.js.map +0 -1
  484. package/models/ai-terminal-message.model.d.ts +0 -22
  485. package/models/ai-terminal-message.model.js +0 -4
  486. package/models/ai-terminal-message.model.js.map +0 -1
  487. package/models/app-setting.model.d.ts +0 -16
  488. package/models/app-setting.model.js +0 -4
  489. package/models/app-setting.model.js.map +0 -1
  490. package/models/app-status.model.js +0 -4
  491. package/models/app-status.model.js.map +0 -1
  492. package/models/billing-logged-in-users.model.js +0 -4
  493. package/models/billing-logged-in-users.model.js.map +0 -1
  494. package/models/collection-document.model.d.ts +0 -21
  495. package/models/collection-document.model.js +0 -4
  496. package/models/collection-document.model.js.map +0 -1
  497. package/models/communication-metric.model.d.ts +0 -20
  498. package/models/communication-metric.model.js +0 -4
  499. package/models/communication-metric.model.js.map +0 -1
  500. package/models/counter.model.js +0 -4
  501. package/models/counter.model.js.map +0 -1
  502. package/models/cron-job-history.model.d.ts +0 -15
  503. package/models/cron-job-history.model.js +0 -4
  504. package/models/cron-job-history.model.js.map +0 -1
  505. package/models/cron-job.model.d.ts +0 -14
  506. package/models/cron-job.model.js +0 -4
  507. package/models/cron-job.model.js.map +0 -1
  508. package/models/customer-notification.model.d.ts +0 -26
  509. package/models/customer-notification.model.js +0 -4
  510. package/models/customer-notification.model.js.map +0 -1
  511. package/models/customer-portal-password.model.d.ts +0 -11
  512. package/models/customer-portal-password.model.js +0 -4
  513. package/models/customer-portal-password.model.js.map +0 -1
  514. package/models/dialog.model.d.ts +0 -23
  515. package/models/dialog.model.js +0 -4
  516. package/models/dialog.model.js.map +0 -1
  517. package/models/email-history.model.d.ts +0 -32
  518. package/models/email-history.model.js.map +0 -1
  519. package/models/email-verified.model.js +0 -4
  520. package/models/email-verified.model.js.map +0 -1
  521. package/models/file.model.js +0 -4
  522. package/models/file.model.js.map +0 -1
  523. package/models/flag-update.model.js +0 -4
  524. package/models/flag-update.model.js.map +0 -1
  525. package/models/flag.model.js +0 -4
  526. package/models/flag.model.js.map +0 -1
  527. package/models/log-method-latency.model.d.ts +0 -10
  528. package/models/log-method-latency.model.js +0 -4
  529. package/models/log-method-latency.model.js.map +0 -1
  530. package/models/log-subscription.model.js +0 -4
  531. package/models/log-subscription.model.js.map +0 -1
  532. package/models/log.model.d.ts +0 -17
  533. package/models/log.model.js +0 -4
  534. package/models/log.model.js.map +0 -1
  535. package/models/logged-in-users.model.js +0 -4
  536. package/models/logged-in-users.model.js.map +0 -1
  537. package/models/method-response.model.js +0 -4
  538. package/models/method-response.model.js.map +0 -1
  539. package/models/method.model.d.ts +0 -26
  540. package/models/method.model.js +0 -4
  541. package/models/method.model.js.map +0 -1
  542. package/models/monitor-cpu.model.js +0 -4
  543. package/models/monitor-cpu.model.js.map +0 -1
  544. package/models/monitor-function.model.d.ts +0 -14
  545. package/models/monitor-function.model.js +0 -4
  546. package/models/monitor-function.model.js.map +0 -1
  547. package/models/monitor-memory.model.d.ts +0 -15
  548. package/models/monitor-memory.model.js +0 -4
  549. package/models/monitor-memory.model.js.map +0 -1
  550. package/models/monitor-mongo.model.d.ts +0 -13
  551. package/models/monitor-mongo.model.js +0 -4
  552. package/models/monitor-mongo.model.js.map +0 -1
  553. package/models/notification.model.js +0 -4
  554. package/models/notification.model.js.map +0 -1
  555. package/models/openai-usage-ledger.model.d.ts +0 -30
  556. package/models/openai-usage-ledger.model.js +0 -4
  557. package/models/openai-usage-ledger.model.js.map +0 -1
  558. package/models/pagination.model.d.ts +0 -11
  559. package/models/pagination.model.js +0 -28
  560. package/models/pagination.model.js.map +0 -1
  561. package/models/permission.model.d.ts +0 -12
  562. package/models/permission.model.js +0 -4
  563. package/models/permission.model.js.map +0 -1
  564. package/models/report-builder-dashboard-builder.model.d.ts +0 -25
  565. package/models/report-builder-dashboard-builder.model.js +0 -4
  566. package/models/report-builder-dashboard-builder.model.js.map +0 -1
  567. package/models/report-builder-library.model.d.ts +0 -17
  568. package/models/report-builder-library.model.js +0 -4
  569. package/models/report-builder-library.model.js.map +0 -1
  570. package/models/report-builder-report.model.d.ts +0 -121
  571. package/models/report-builder-report.model.js +0 -4
  572. package/models/report-builder-report.model.js.map +0 -1
  573. package/models/report-builder.model.d.ts +0 -61
  574. package/models/report-builder.model.js +0 -4
  575. package/models/report-builder.model.js.map +0 -1
  576. package/models/select-data-label.model.d.ts +0 -9
  577. package/models/select-data-label.model.js +0 -4
  578. package/models/select-data-label.model.js.map +0 -1
  579. package/models/server-message.model.d.ts +0 -32
  580. package/models/server-message.model.js +0 -4
  581. package/models/server-message.model.js.map +0 -1
  582. package/models/slow-query-report.model.d.ts +0 -23
  583. package/models/slow-query-report.model.js +0 -4
  584. package/models/slow-query-report.model.js.map +0 -1
  585. package/models/subscription.model.d.ts +0 -31
  586. package/models/subscription.model.js +0 -4
  587. package/models/subscription.model.js.map +0 -1
  588. package/models/support-ticket.model.d.ts +0 -87
  589. package/models/support-ticket.model.js +0 -4
  590. package/models/support-ticket.model.js.map +0 -1
  591. package/models/user-group.model.d.ts +0 -20
  592. package/models/user-group.model.js +0 -4
  593. package/models/user-group.model.js.map +0 -1
  594. package/models/user-guide.model.js +0 -4
  595. package/models/user-guide.model.js.map +0 -1
  596. package/models/user.model.d.ts +0 -84
  597. package/models/user.model.js +0 -4
  598. package/models/user.model.js.map +0 -1
  599. package/private/images/ResolveIO.png +0 -0
  600. package/public_api.js +0 -127
  601. package/public_api.js.map +0 -1
  602. package/publications/ai-terminal.d.ts +0 -1
  603. package/publications/ai-terminal.js +0 -122
  604. package/publications/ai-terminal.js.map +0 -1
  605. package/publications/app-settings.d.ts +0 -2
  606. package/publications/app-settings.js +0 -28
  607. package/publications/app-settings.js.map +0 -1
  608. package/publications/app-status.d.ts +0 -2
  609. package/publications/app-status.js +0 -16
  610. package/publications/app-status.js.map +0 -1
  611. package/publications/cron-jobs.d.ts +0 -2
  612. package/publications/cron-jobs.js +0 -88
  613. package/publications/cron-jobs.js.map +0 -1
  614. package/publications/customer-notifications.d.ts +0 -2
  615. package/publications/customer-notifications.js +0 -161
  616. package/publications/customer-notifications.js.map +0 -1
  617. package/publications/files.d.ts +0 -2
  618. package/publications/files.js +0 -36
  619. package/publications/files.js.map +0 -1
  620. package/publications/flags-update.d.ts +0 -2
  621. package/publications/flags-update.js +0 -22
  622. package/publications/flags-update.js.map +0 -1
  623. package/publications/flags.d.ts +0 -2
  624. package/publications/flags.js +0 -22
  625. package/publications/flags.js.map +0 -1
  626. package/publications/logs.d.ts +0 -2
  627. package/publications/logs.js +0 -164
  628. package/publications/logs.js.map +0 -1
  629. package/publications/notifications.d.ts +0 -2
  630. package/publications/notifications.js +0 -16
  631. package/publications/notifications.js.map +0 -1
  632. package/publications/report-builder-dashboard-builders.d.ts +0 -2
  633. package/publications/report-builder-dashboard-builders.js +0 -42
  634. package/publications/report-builder-dashboard-builders.js.map +0 -1
  635. package/publications/report-builder-libraries.d.ts +0 -2
  636. package/publications/report-builder-libraries.js +0 -90
  637. package/publications/report-builder-libraries.js.map +0 -1
  638. package/publications/report-builder-reports.d.ts +0 -2
  639. package/publications/report-builder-reports.js +0 -50
  640. package/publications/report-builder-reports.js.map +0 -1
  641. package/publications/super-admin.d.ts +0 -2
  642. package/publications/super-admin.js +0 -16
  643. package/publications/super-admin.js.map +0 -1
  644. package/publications/user-groups.d.ts +0 -1
  645. package/publications/user-groups.js +0 -16
  646. package/publications/user-groups.js.map +0 -1
  647. package/publications/user-guides.d.ts +0 -1
  648. package/publications/user-guides.js +0 -16
  649. package/publications/user-guides.js.map +0 -1
  650. package/resolveio-server-app.d.ts +0 -70
  651. package/resolveio-server-app.js +0 -801
  652. package/resolveio-server-app.js.map +0 -1
  653. package/server-app.d.ts +0 -228
  654. package/server-app.js +0 -3566
  655. package/server-app.js.map +0 -1
  656. package/services/codex-client.d.ts +0 -128
  657. package/services/codex-client.js +0 -1629
  658. package/services/codex-client.js.map +0 -1
  659. package/services/openai-client.d.ts +0 -46
  660. package/services/openai-client.js +0 -318
  661. package/services/openai-client.js.map +0 -1
  662. package/types/error-report.d.ts +0 -25
  663. package/types/error-report.js +0 -4
  664. package/types/error-report.js.map +0 -1
  665. package/types/slow-query-report.d.ts +0 -27
  666. package/types/slow-query-report.js +0 -6
  667. package/types/slow-query-report.js.map +0 -1
  668. package/util/ai-qa-policy.d.ts +0 -124
  669. package/util/ai-qa-policy.js +0 -736
  670. package/util/ai-qa-policy.js.map +0 -1
  671. package/util/ai-run-evidence-adapters.d.ts +0 -109
  672. package/util/ai-run-evidence-adapters.js +0 -7234
  673. package/util/ai-run-evidence-adapters.js.map +0 -1
  674. package/util/ai-run-evidence-dashboard.d.ts +0 -88
  675. package/util/ai-run-evidence-dashboard.js +0 -343
  676. package/util/ai-run-evidence-dashboard.js.map +0 -1
  677. package/util/ai-run-evidence-eval.d.ts +0 -86
  678. package/util/ai-run-evidence-eval.js +0 -1018
  679. package/util/ai-run-evidence-eval.js.map +0 -1
  680. package/util/ai-run-evidence.d.ts +0 -244
  681. package/util/ai-run-evidence.js +0 -1096
  682. package/util/ai-run-evidence.js.map +0 -1
  683. package/util/ai-runner-artifacts.d.ts +0 -82
  684. package/util/ai-runner-artifacts.js +0 -713
  685. package/util/ai-runner-artifacts.js.map +0 -1
  686. package/util/ai-runner-manager-autopilot.d.ts +0 -210
  687. package/util/ai-runner-manager-autopilot.js +0 -642
  688. package/util/ai-runner-manager-autopilot.js.map +0 -1
  689. package/util/ai-runner-manager-policy.d.ts +0 -807
  690. package/util/ai-runner-manager-policy.js +0 -3501
  691. package/util/ai-runner-manager-policy.js.map +0 -1
  692. package/util/ai-runner-qa-auth.d.ts +0 -5
  693. package/util/ai-runner-qa-auth.js +0 -839
  694. package/util/ai-runner-qa-auth.js.map +0 -1
  695. package/util/ai-runner-qa-tools.d.ts +0 -26
  696. package/util/ai-runner-qa-tools.js +0 -3520
  697. package/util/ai-runner-qa-tools.js.map +0 -1
  698. package/util/aicoder-runner-v6.d.ts +0 -426
  699. package/util/aicoder-runner-v6.js +0 -2464
  700. package/util/aicoder-runner-v6.js.map +0 -1
  701. package/util/common.d.ts +0 -31
  702. package/util/common.js +0 -683
  703. package/util/common.js.map +0 -1
  704. package/util/customer-portal-password.d.ts +0 -13
  705. package/util/customer-portal-password.js +0 -209
  706. package/util/customer-portal-password.js.map +0 -1
  707. package/util/error-reporter.d.ts +0 -52
  708. package/util/error-reporter.js +0 -326
  709. package/util/error-reporter.js.map +0 -1
  710. package/util/error-tracking.d.ts +0 -13
  711. package/util/error-tracking.js +0 -120
  712. package/util/error-tracking.js.map +0 -1
  713. package/util/openai-usage-cost.d.ts +0 -6
  714. package/util/openai-usage-cost.js +0 -103
  715. package/util/openai-usage-cost.js.map +0 -1
  716. package/util/report-builder-unwinds.d.ts +0 -15
  717. package/util/report-builder-unwinds.js +0 -156
  718. package/util/report-builder-unwinds.js.map +0 -1
  719. package/util/runner-process-janitor.d.ts +0 -27
  720. package/util/runner-process-janitor.js +0 -208
  721. package/util/runner-process-janitor.js.map +0 -1
  722. package/util/schema-report-builder.d.ts +0 -6
  723. package/util/schema-report-builder.js +0 -481
  724. package/util/schema-report-builder.js.map +0 -1
  725. package/util/slow-query-reporter.d.ts +0 -28
  726. package/util/slow-query-reporter.js +0 -226
  727. package/util/slow-query-reporter.js.map +0 -1
  728. package/util/subscription-dependency-context.d.ts +0 -34
  729. package/util/subscription-dependency-context.js +0 -1283
  730. package/util/subscription-dependency-context.js.map +0 -1
  731. package/util/support-runner-v5.d.ts +0 -1426
  732. package/util/support-runner-v5.js +0 -7624
  733. package/util/support-runner-v5.js.map +0 -1
  734. package/util/tokenizer.d.ts +0 -5
  735. package/util/tokenizer.js +0 -41
  736. package/util/tokenizer.js.map +0 -1
  737. package/workers/codex-runner.worker.d.ts +0 -1
  738. package/workers/codex-runner.worker.js +0 -192
  739. package/workers/codex-runner.worker.js.map +0 -1
  740. /package/{private → src/private}/email-templates/enrollment.html +0 -0
  741. /package/{private → src/private}/email-templates/forgot-password.html +0 -0
  742. /package/{private → src/private}/email-templates/support-ticket-deleted.html +0 -0
  743. /package/{private → src/private}/email-templates/support-ticket-modified.html +0 -0
  744. /package/{private → src/private}/email-templates/support-ticket.html +0 -0
  745. /package/{public_api.d.ts → src/public_api.ts} +0 -0
@@ -1,3857 +0,0 @@
1
- "use strict";
2
- var __extends = (this && this.__extends) || (function () {
3
- var extendStatics = function (d, b) {
4
- extendStatics = Object.setPrototypeOf ||
5
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
- return extendStatics(d, b);
8
- };
9
- return function (d, b) {
10
- if (typeof b !== "function" && b !== null)
11
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
- extendStatics(d, b);
13
- function __() { this.constructor = d; }
14
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
- };
16
- })();
17
- var __assign = (this && this.__assign) || function () {
18
- __assign = Object.assign || function(t) {
19
- for (var s, i = 1, n = arguments.length; i < n; i++) {
20
- s = arguments[i];
21
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
22
- t[p] = s[p];
23
- }
24
- return t;
25
- };
26
- return __assign.apply(this, arguments);
27
- };
28
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
29
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
30
- return new (P || (P = Promise))(function (resolve, reject) {
31
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
32
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
33
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
34
- step((generator = generator.apply(thisArg, _arguments || [])).next());
35
- });
36
- };
37
- var __generator = (this && this.__generator) || function (thisArg, body) {
38
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
39
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
40
- function verb(n) { return function (v) { return step([n, v]); }; }
41
- function step(op) {
42
- if (f) throw new TypeError("Generator is already executing.");
43
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
44
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
45
- if (y = 0, t) op = [op[0] & 2, t.value];
46
- switch (op[0]) {
47
- case 0: case 1: t = op; break;
48
- case 4: _.label++; return { value: op[1], done: false };
49
- case 5: _.label++; y = op[1]; op = [0]; continue;
50
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
51
- default:
52
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
53
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
54
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
55
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
56
- if (t[2]) _.ops.pop();
57
- _.trys.pop(); continue;
58
- }
59
- op = body.call(thisArg, _);
60
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
61
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
62
- }
63
- };
64
- var __asyncValues = (this && this.__asyncValues) || function (o) {
65
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
66
- var m = o[Symbol.asyncIterator], i;
67
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
68
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
69
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
70
- };
71
- var __values = (this && this.__values) || function(o) {
72
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
73
- if (m) return m.call(o);
74
- if (o && typeof o.length === "number") return {
75
- next: function () {
76
- if (o && i >= o.length) o = void 0;
77
- return { value: o && o[i++], done: !o };
78
- }
79
- };
80
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
81
- };
82
- var __read = (this && this.__read) || function (o, n) {
83
- var m = typeof Symbol === "function" && o[Symbol.iterator];
84
- if (!m) return o;
85
- var i = m.call(o), r, ar = [], e;
86
- try {
87
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
88
- }
89
- catch (error) { e = { error: error }; }
90
- finally {
91
- try {
92
- if (r && !r.done && (m = i["return"])) m.call(i);
93
- }
94
- finally { if (e) throw e.error; }
95
- }
96
- return ar;
97
- };
98
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
99
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
100
- if (ar || !(i in from)) {
101
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
102
- ar[i] = from[i];
103
- }
104
- }
105
- return to.concat(ar || Array.prototype.slice.call(from));
106
- };
107
- Object.defineProperty(exports, "__esModule", { value: true });
108
- exports.SlowQueryVerifier = void 0;
109
- exports.registerSlowQueryVerifierDependencies = registerSlowQueryVerifierDependencies;
110
- exports.ensureSlowQueryVerifier = ensureSlowQueryVerifier;
111
- var crypto_1 = require("crypto");
112
- var resolveio_server_app_1 = require("../resolveio-server-app");
113
- var common_1 = require("../util/common");
114
- var mongodb_1 = require("mongodb");
115
- var user_collection_1 = require("../collections/user.collection");
116
- var app_setting_collection_1 = require("../collections/app-setting.collection");
117
- var customer_notification_content_manager_1 = require("./customer-notification-content.manager");
118
- var OPTIONAL_COLLECTION = {
119
- findOne: function () { return Promise.resolve(null); },
120
- find: function () { return Promise.resolve([]); }
121
- };
122
- var AICoderApps = OPTIONAL_COLLECTION;
123
- var AIDashboardJobs = OPTIONAL_COLLECTION;
124
- var ClientDBs = OPTIONAL_COLLECTION;
125
- var Clients = OPTIONAL_COLLECTION;
126
- var SlowQueryLogs = null;
127
- var DEFAULT_CHECK_AICODER_TOKEN_ELIGIBILITY = function () {
128
- return Promise.resolve({
129
- eligible: true
130
- });
131
- };
132
- var checkAICoderTokenEligibility = DEFAULT_CHECK_AICODER_TOKEN_ELIGIBILITY;
133
- var configuredSlowQueryVerifierDependencies = null;
134
- function resolveSlowQueryVerifierDependencies(overrides) {
135
- var resolved = __assign(__assign({}, (configuredSlowQueryVerifierDependencies || {})), (overrides || {}));
136
- if (!resolved.SlowQueryLogs) {
137
- throw new Error('SlowQueryVerifier dependencies are not configured.');
138
- }
139
- return resolved;
140
- }
141
- function applySlowQueryVerifierDependencies(dependencies) {
142
- configuredSlowQueryVerifierDependencies = dependencies;
143
- ClientDBs = dependencies.ClientDBs || OPTIONAL_COLLECTION;
144
- Clients = dependencies.Clients || OPTIONAL_COLLECTION;
145
- SlowQueryLogs = dependencies.SlowQueryLogs;
146
- AICoderApps = dependencies.AICoderApps || OPTIONAL_COLLECTION;
147
- AIDashboardJobs = dependencies.AIDashboardJobs || OPTIONAL_COLLECTION;
148
- checkAICoderTokenEligibility = dependencies.checkAICoderTokenEligibility || DEFAULT_CHECK_AICODER_TOKEN_ELIGIBILITY;
149
- }
150
- function registerSlowQueryVerifierDependencies(dependencies) {
151
- applySlowQueryVerifierDependencies(dependencies);
152
- ensureSlowQueryVerifier();
153
- }
154
- var VERIFICATION_CHECK_INTERVAL_MS = 60 * 1000;
155
- var VERIFICATION_INTERVAL_MS = 5 * 60 * 1000;
156
- var VERIFICATION_ATTEMPTS = 3;
157
- var VERIFICATION_THRESHOLD_MS = 2000;
158
- var AUTO_OPTIMIZE_DEFAULT_IMPROVEMENT_RATIO = 0.7;
159
- var AUTO_OPTIMIZE_DEFAULT_RETURNED_DOC_TOLERANCE = 0.15;
160
- var AUTO_OPTIMIZE_DEFAULT_MAX_ATTEMPTS_PER_QUERY = 3;
161
- var AUTO_OPTIMIZE_DEFAULT_COOLDOWN_MINUTES = 120;
162
- var AUTO_OPTIMIZE_DEFAULT_MAX_ATTEMPTS_PER_FINGERPRINT = 4;
163
- var AUTO_OPTIMIZE_DEFAULT_FINGERPRINT_WINDOW_HOURS = 24;
164
- var AUTO_OPTIMIZE_DEFAULT_OUTPUT_COMPARE_MAX_DOCS = 10000;
165
- var DEFAULT_ERROR_ALERT_EMAIL = 'dev@resolveio.com';
166
- var MAX_LOCAL_NOTIFICATION_USERS = 5000;
167
- function ensureSlowQueryVerifier(serverConfig) {
168
- var existing = resolveio_server_app_1.ResolveIOServer['SlowQueryVerifier'];
169
- if (existing) {
170
- return existing;
171
- }
172
- if (!configuredSlowQueryVerifierDependencies) {
173
- return null;
174
- }
175
- var resolvedServerConfig = serverConfig || resolveio_server_app_1.ResolveIOServer.getServerConfig();
176
- if (!resolvedServerConfig) {
177
- return null;
178
- }
179
- var verifier = new SlowQueryVerifier(resolvedServerConfig);
180
- resolveio_server_app_1.ResolveIOServer['SlowQueryVerifier'] = verifier;
181
- return verifier;
182
- }
183
- var SlowQueryVerifierError = /** @class */ (function (_super) {
184
- __extends(SlowQueryVerifierError, _super);
185
- function SlowQueryVerifierError(code, message) {
186
- var _this = _super.call(this, message) || this;
187
- _this.code = code;
188
- return _this;
189
- }
190
- return SlowQueryVerifierError;
191
- }(Error));
192
- var SlowQueryVerifier = /** @class */ (function () {
193
- function SlowQueryVerifier(serverConfig, dependencies) {
194
- var _this = this;
195
- this.autoOptimizeInFlight = new Set();
196
- this.appSettingsAutoOptimizeCacheExpiresAt = 0;
197
- this.appSettingsAutoOptimizeCacheValue = null;
198
- var resolvedDependencies = resolveSlowQueryVerifierDependencies(dependencies);
199
- applySlowQueryVerifierDependencies(resolvedDependencies);
200
- this.config = SlowQueryVerifier.resolveConfig(serverConfig);
201
- this.autoOptimizeDependenciesAvailable = !!(resolvedDependencies.AICoderApps && resolvedDependencies.AIDashboardJobs);
202
- if (this.config.enabled) {
203
- this._timer = setInterval(function () {
204
- // eslint-disable-next-line no-restricted-syntax
205
- _this.poll().catch(function (err) {
206
- console.error('Slow query verifier poll failed', err);
207
- });
208
- }, VERIFICATION_CHECK_INTERVAL_MS);
209
- // eslint-disable-next-line no-restricted-syntax
210
- this.poll().catch(function (err) {
211
- console.error('Slow query verifier failed to start', err);
212
- });
213
- }
214
- }
215
- SlowQueryVerifier.resolveConfig = function (serverConfig) {
216
- var slowQueryConfig = (serverConfig && (serverConfig.slowQuery || serverConfig.SLOW_QUERY)) || {};
217
- var verifierConfig = (slowQueryConfig && (slowQueryConfig.verifier || slowQueryConfig.slowQueryVerifier)) || {};
218
- var autofixConfig = (serverConfig && (serverConfig.autofix || serverConfig.AUTOFIX)) || {};
219
- var getBoolean = function (envKey, configKey, fallback) {
220
- if (fallback === void 0) { fallback = true; }
221
- if (typeof process.env[envKey] !== 'undefined') {
222
- return process.env[envKey] === 'true';
223
- }
224
- if (typeof verifierConfig[configKey] !== 'undefined') {
225
- return !!verifierConfig[configKey];
226
- }
227
- return fallback;
228
- };
229
- var getNumber = function (envKey, configKey, fallback) {
230
- if (typeof process.env[envKey] !== 'undefined') {
231
- var parsedEnv = Number(process.env[envKey]);
232
- if (Number.isFinite(parsedEnv)) {
233
- return parsedEnv;
234
- }
235
- }
236
- if (typeof verifierConfig[configKey] !== 'undefined') {
237
- var parsedConfig = Number(verifierConfig[configKey]);
238
- if (Number.isFinite(parsedConfig)) {
239
- return parsedConfig;
240
- }
241
- }
242
- return fallback;
243
- };
244
- var getString = function (envKey, configKey, fallback) {
245
- if (fallback === void 0) { fallback = ''; }
246
- if (typeof process.env[envKey] !== 'undefined') {
247
- return String(process.env[envKey] || '').trim();
248
- }
249
- if (typeof verifierConfig[configKey] !== 'undefined') {
250
- return String(verifierConfig[configKey] || '').trim();
251
- }
252
- if (typeof slowQueryConfig[configKey] !== 'undefined') {
253
- return String(slowQueryConfig[configKey] || '').trim();
254
- }
255
- if (typeof autofixConfig[configKey] !== 'undefined') {
256
- return String(autofixConfig[configKey] || '').trim();
257
- }
258
- return fallback;
259
- };
260
- var parseEmails = function (value) {
261
- if (Array.isArray(value)) {
262
- return value.map(function (item) { return "".concat(item || '').trim().toLowerCase(); }).filter(Boolean);
263
- }
264
- if (typeof value === 'string') {
265
- return value.split(',').map(function (item) { return item.trim().toLowerCase(); }).filter(Boolean);
266
- }
267
- return [];
268
- };
269
- var clampRatio = function (value, fallback) {
270
- if (!Number.isFinite(value)) {
271
- return fallback;
272
- }
273
- if (value <= 0 || value >= 1) {
274
- return fallback;
275
- }
276
- return value;
277
- };
278
- var normalizePositiveInt = function (value, fallback) {
279
- if (!Number.isFinite(value) || value <= 0) {
280
- return fallback;
281
- }
282
- return Math.floor(value);
283
- };
284
- var normalizeNonNegativeInt = function (value, fallback) {
285
- if (fallback === void 0) { fallback = 0; }
286
- if (!Number.isFinite(value) || value < 0) {
287
- return fallback;
288
- }
289
- return Math.floor(value);
290
- };
291
- var escalationEmails = parseEmails(process.env.SLOW_QUERY_ESCALATION_EMAILS
292
- || verifierConfig.escalationEmails
293
- || slowQueryConfig.escalationEmails
294
- || slowQueryConfig.notifyEmails);
295
- return {
296
- enabled: true,
297
- fallbackToMainDB: getBoolean('SLOW_QUERY_VERIFIER_FALLBACK_MAIN_DB', 'fallbackToMainDB', true),
298
- debugLogging: getBoolean('SLOW_QUERY_VERIFIER_DEBUG_LOGS', 'debugLogging', false),
299
- configSource: Object.keys(verifierConfig).length ? 'serverConfig' : 'defaults',
300
- autofixRepoRoot: getString('AUTOFIX_REPO_ROOT', 'repoRoot', '/var/app/current'),
301
- autofixGithubOwner: getString('AUTOFIX_GITHUB_OWNER', 'githubOwner', 'resolveio'),
302
- autofixGithubRepo: getString('AUTOFIX_GITHUB_REPO', 'githubRepo', ''),
303
- autoOptimizeEnabled: getBoolean('SLOW_QUERY_AUTO_OPTIMIZE_ENABLED', 'autoOptimizeEnabled', false),
304
- autoOptimizeWaitTimeoutMs: getNumber('SLOW_QUERY_AUTO_OPTIMIZE_WAIT_TIMEOUT_MS', 'autoOptimizeWaitTimeoutMs', 45 * 60 * 1000),
305
- autoOptimizeDurationRatioTarget: clampRatio(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_DURATION_RATIO', 'autoOptimizeDurationRatioTarget', AUTO_OPTIMIZE_DEFAULT_IMPROVEMENT_RATIO), AUTO_OPTIMIZE_DEFAULT_IMPROVEMENT_RATIO),
306
- autoOptimizeDocsRatioTarget: clampRatio(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_DOCS_RATIO', 'autoOptimizeDocsRatioTarget', AUTO_OPTIMIZE_DEFAULT_IMPROVEMENT_RATIO), AUTO_OPTIMIZE_DEFAULT_IMPROVEMENT_RATIO),
307
- autoOptimizeReturnedDocsTolerance: clampRatio(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_RETURNED_DOCS_TOLERANCE', 'autoOptimizeReturnedDocsTolerance', AUTO_OPTIMIZE_DEFAULT_RETURNED_DOC_TOLERANCE), AUTO_OPTIMIZE_DEFAULT_RETURNED_DOC_TOLERANCE),
308
- autoOptimizeMaxAttemptsPerQuery: normalizePositiveInt(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_MAX_ATTEMPTS_PER_QUERY', 'autoOptimizeMaxAttemptsPerQuery', AUTO_OPTIMIZE_DEFAULT_MAX_ATTEMPTS_PER_QUERY), AUTO_OPTIMIZE_DEFAULT_MAX_ATTEMPTS_PER_QUERY),
309
- autoOptimizeCooldownMinutes: normalizeNonNegativeInt(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_COOLDOWN_MINUTES', 'autoOptimizeCooldownMinutes', AUTO_OPTIMIZE_DEFAULT_COOLDOWN_MINUTES), AUTO_OPTIMIZE_DEFAULT_COOLDOWN_MINUTES),
310
- autoOptimizeMaxAttemptsPerFingerprint: normalizePositiveInt(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_MAX_ATTEMPTS_PER_FINGERPRINT', 'autoOptimizeMaxAttemptsPerFingerprint', AUTO_OPTIMIZE_DEFAULT_MAX_ATTEMPTS_PER_FINGERPRINT), AUTO_OPTIMIZE_DEFAULT_MAX_ATTEMPTS_PER_FINGERPRINT),
311
- autoOptimizeFingerprintWindowHours: normalizePositiveInt(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_FINGERPRINT_WINDOW_HOURS', 'autoOptimizeFingerprintWindowHours', AUTO_OPTIMIZE_DEFAULT_FINGERPRINT_WINDOW_HOURS), AUTO_OPTIMIZE_DEFAULT_FINGERPRINT_WINDOW_HOURS),
312
- autoOptimizeRequiredTokens: normalizeNonNegativeInt(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_REQUIRED_TOKENS', 'autoOptimizeRequiredTokens', 0), 0),
313
- autoOptimizeOutputCompareEnabled: getBoolean('SLOW_QUERY_AUTO_OPTIMIZE_OUTPUT_COMPARE_ENABLED', 'autoOptimizeOutputCompareEnabled', true),
314
- autoOptimizeRequireExactOutput: getBoolean('SLOW_QUERY_AUTO_OPTIMIZE_REQUIRE_EXACT_OUTPUT', 'autoOptimizeRequireExactOutput', true),
315
- autoOptimizeOutputMismatchRetryCount: normalizeNonNegativeInt(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_OUTPUT_MISMATCH_RETRY_COUNT', 'autoOptimizeOutputMismatchRetryCount', 2), 2),
316
- autoOptimizeOutputCompareMaxDocs: normalizePositiveInt(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_OUTPUT_COMPARE_MAX_DOCS', 'autoOptimizeOutputCompareMaxDocs', AUTO_OPTIMIZE_DEFAULT_OUTPUT_COMPARE_MAX_DOCS), AUTO_OPTIMIZE_DEFAULT_OUTPUT_COMPARE_MAX_DOCS),
317
- escalationEmails: escalationEmails
318
- };
319
- };
320
- SlowQueryVerifier.prototype.parseBooleanEnv = function (envKey) {
321
- if (typeof process.env[envKey] === 'undefined') {
322
- return null;
323
- }
324
- return process.env[envKey] === 'true';
325
- };
326
- SlowQueryVerifier.prototype.resolveAutoOptimizeEnabled = function () {
327
- return __awaiter(this, void 0, void 0, function () {
328
- var now, envValue, enabled, activeSetting, _a, error_1;
329
- var _b;
330
- return __generator(this, function (_c) {
331
- switch (_c.label) {
332
- case 0:
333
- if (!this.autoOptimizeDependenciesAvailable) {
334
- return [2 /*return*/, false];
335
- }
336
- now = Date.now();
337
- if (this.appSettingsAutoOptimizeCacheValue !== null && now < this.appSettingsAutoOptimizeCacheExpiresAt) {
338
- return [2 /*return*/, this.appSettingsAutoOptimizeCacheValue];
339
- }
340
- envValue = this.parseBooleanEnv('SLOW_QUERY_AUTO_OPTIMIZE_ENABLED');
341
- enabled = envValue !== null ? envValue : !!this.config.autoOptimizeEnabled;
342
- _c.label = 1;
343
- case 1:
344
- _c.trys.push([1, 6, , 7]);
345
- if (!(app_setting_collection_1.AppSettings && typeof app_setting_collection_1.AppSettings.findOne === 'function')) return [3 /*break*/, 5];
346
- return [4 /*yield*/, app_setting_collection_1.AppSettings.findOne({
347
- is_active: {
348
- $ne: false
349
- }
350
- }, {
351
- sort: {
352
- updatedAt: -1,
353
- createdAt: -1
354
- }
355
- })];
356
- case 2:
357
- _a = (_c.sent());
358
- if (_a) return [3 /*break*/, 4];
359
- return [4 /*yield*/, app_setting_collection_1.AppSettings.findOne({}, {
360
- sort: {
361
- updatedAt: -1,
362
- createdAt: -1
363
- }
364
- })];
365
- case 3:
366
- _a = (_c.sent());
367
- _c.label = 4;
368
- case 4:
369
- activeSetting = _a;
370
- if (activeSetting && typeof activeSetting.enable_slow_query_optimizer === 'boolean') {
371
- enabled = !!activeSetting.enable_slow_query_optimizer;
372
- }
373
- _c.label = 5;
374
- case 5: return [3 /*break*/, 7];
375
- case 6:
376
- error_1 = _c.sent();
377
- if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debugLogging) {
378
- console.warn('SlowQueryVerifier failed to read app settings slow-query optimizer toggle', error_1);
379
- }
380
- return [3 /*break*/, 7];
381
- case 7:
382
- this.appSettingsAutoOptimizeCacheValue = enabled;
383
- this.appSettingsAutoOptimizeCacheExpiresAt = now + SlowQueryVerifier.APP_SETTINGS_CACHE_TTL_MS;
384
- return [2 /*return*/, enabled];
385
- }
386
- });
387
- });
388
- };
389
- SlowQueryVerifier.prototype.poll = function () {
390
- return __awaiter(this, void 0, void 0, function () {
391
- var autoOptimizeEnabled, now, candidates, candidates_1, candidates_1_1, candidate, e_1_1;
392
- var e_1, _a;
393
- return __generator(this, function (_b) {
394
- switch (_b.label) {
395
- case 0: return [4 /*yield*/, this.resolveAutoOptimizeEnabled()];
396
- case 1:
397
- autoOptimizeEnabled = _b.sent();
398
- if (!autoOptimizeEnabled) {
399
- return [2 /*return*/];
400
- }
401
- now = new Date();
402
- return [4 /*yield*/, SlowQueryLogs.find({
403
- ignored: {
404
- $ne: true
405
- },
406
- verification_status: {
407
- $in: [null, 'pending']
408
- },
409
- $or: [
410
- {
411
- verification_next_run_at: {
412
- $exists: false
413
- }
414
- },
415
- {
416
- verification_next_run_at: {
417
- $lte: now
418
- }
419
- }
420
- ]
421
- }, {
422
- sort: {
423
- verification_next_run_at: 1,
424
- last_seen_at: -1
425
- },
426
- limit: 5
427
- })];
428
- case 2:
429
- candidates = _b.sent();
430
- _b.label = 3;
431
- case 3:
432
- _b.trys.push([3, 8, 9, 10]);
433
- candidates_1 = __values(candidates), candidates_1_1 = candidates_1.next();
434
- _b.label = 4;
435
- case 4:
436
- if (!!candidates_1_1.done) return [3 /*break*/, 7];
437
- candidate = candidates_1_1.value;
438
- return [4 /*yield*/, this.processCandidate(candidate)];
439
- case 5:
440
- _b.sent();
441
- _b.label = 6;
442
- case 6:
443
- candidates_1_1 = candidates_1.next();
444
- return [3 /*break*/, 4];
445
- case 7: return [3 /*break*/, 10];
446
- case 8:
447
- e_1_1 = _b.sent();
448
- e_1 = { error: e_1_1 };
449
- return [3 /*break*/, 10];
450
- case 9:
451
- try {
452
- if (candidates_1_1 && !candidates_1_1.done && (_a = candidates_1.return)) _a.call(candidates_1);
453
- }
454
- finally { if (e_1) throw e_1.error; }
455
- return [7 /*endfinally*/];
456
- case 10: return [2 /*return*/];
457
- }
458
- });
459
- });
460
- };
461
- SlowQueryVerifier.prototype.processCandidate = function (candidate) {
462
- return __awaiter(this, void 0, void 0, function () {
463
- var claimAt, result, err_1;
464
- return __generator(this, function (_a) {
465
- switch (_a.label) {
466
- case 0:
467
- if (!candidate || !candidate._id) {
468
- return [2 /*return*/];
469
- }
470
- claimAt = new Date(Date.now() + VERIFICATION_INTERVAL_MS);
471
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: candidate._id }, {
472
- $set: {
473
- verification_next_run_at: claimAt
474
- }
475
- })];
476
- case 1:
477
- _a.sent();
478
- _a.label = 2;
479
- case 2:
480
- _a.trys.push([2, 5, , 7]);
481
- return [4 /*yield*/, this.runExplain(candidate)];
482
- case 3:
483
- result = _a.sent();
484
- return [4 /*yield*/, this.handleExplainResult(candidate, result)];
485
- case 4:
486
- _a.sent();
487
- return [3 /*break*/, 7];
488
- case 5:
489
- err_1 = _a.sent();
490
- return [4 /*yield*/, this.handleExplainError(candidate, err_1)];
491
- case 6:
492
- _a.sent();
493
- return [3 /*break*/, 7];
494
- case 7: return [2 /*return*/];
495
- }
496
- });
497
- });
498
- };
499
- SlowQueryVerifier.prototype.generateExplainForLog = function (logId) {
500
- return __awaiter(this, void 0, void 0, function () {
501
- var log, result, err_2;
502
- return __generator(this, function (_a) {
503
- switch (_a.label) {
504
- case 0:
505
- if (!logId) {
506
- throw new Error('Slow query log ID is required.');
507
- }
508
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
509
- case 1:
510
- log = _a.sent();
511
- if (!log) {
512
- throw new Error('Slow query log not found.');
513
- }
514
- _a.label = 2;
515
- case 2:
516
- _a.trys.push([2, 5, , 7]);
517
- return [4 /*yield*/, this.runExplain(log)];
518
- case 3:
519
- result = _a.sent();
520
- return [4 /*yield*/, this.handleExplainResult(log, result)];
521
- case 4:
522
- _a.sent();
523
- return [3 /*break*/, 7];
524
- case 5:
525
- err_2 = _a.sent();
526
- return [4 /*yield*/, this.handleExplainError(log, err_2)];
527
- case 6:
528
- _a.sent();
529
- throw err_2;
530
- case 7: return [2 /*return*/];
531
- }
532
- });
533
- });
534
- };
535
- SlowQueryVerifier.prototype.runLog = function (logId, options) {
536
- return __awaiter(this, void 0, void 0, function () {
537
- var existing, updated;
538
- return __generator(this, function (_a) {
539
- switch (_a.label) {
540
- case 0:
541
- if (!logId) {
542
- throw new Error('Slow query log ID is required.');
543
- }
544
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
545
- case 1:
546
- existing = _a.sent();
547
- if (!existing) {
548
- return [2 /*return*/, {
549
- status: 'not_found',
550
- reason: 'Slow query log not found.'
551
- }];
552
- }
553
- if (existing.ignored) {
554
- throw new Error('Slow query log is ignored.');
555
- }
556
- if (this.autoOptimizeInFlight.has(logId) || existing.auto_fix_status === 'running' || existing.status === 'queued') {
557
- return [2 /*return*/, {
558
- status: 'in_progress',
559
- reason: 'Slow query optimization is already running.',
560
- log: existing
561
- }];
562
- }
563
- this.autoOptimizeInFlight.add(logId);
564
- _a.label = 2;
565
- case 2:
566
- _a.trys.push([2, , 4, 5]);
567
- return [4 /*yield*/, this.runLogWithRetries(logId, {
568
- force: !!(options === null || options === void 0 ? void 0 : options.force),
569
- retryOutputMismatch: true
570
- })];
571
- case 3:
572
- _a.sent();
573
- return [3 /*break*/, 5];
574
- case 4:
575
- this.autoOptimizeInFlight.delete(logId);
576
- return [7 /*endfinally*/];
577
- case 5: return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
578
- case 6:
579
- updated = _a.sent();
580
- if (!updated) {
581
- return [2 /*return*/, {
582
- status: 'not_found',
583
- reason: 'Slow query log no longer exists.'
584
- }];
585
- }
586
- if (updated.auto_fix_status === 'running' || updated.status === 'queued') {
587
- return [2 /*return*/, {
588
- status: 'in_progress',
589
- reason: 'Slow query optimization queued.',
590
- log: updated
591
- }];
592
- }
593
- if (updated.auto_fix_status === 'completed' || updated.status === 'optimized') {
594
- return [2 /*return*/, {
595
- status: 'success',
596
- reason: 'Slow query optimization completed.',
597
- log: updated
598
- }];
599
- }
600
- if (updated.auto_fix_status === 'failed') {
601
- return [2 /*return*/, {
602
- status: 'failed',
603
- reason: updated.verification_notes || updated.auto_fix_disabled_reason || 'Slow query optimization failed.',
604
- log: updated
605
- }];
606
- }
607
- return [2 /*return*/, {
608
- status: 'updated',
609
- reason: updated.verification_notes || '',
610
- log: updated
611
- }];
612
- }
613
- });
614
- });
615
- };
616
- SlowQueryVerifier.prototype.queueLogRun = function (logId, options) {
617
- return __awaiter(this, void 0, void 0, function () {
618
- var existing, queuedAt, queuedLog;
619
- var _this = this;
620
- return __generator(this, function (_a) {
621
- switch (_a.label) {
622
- case 0:
623
- if (!logId) {
624
- throw new Error('Slow query log ID is required.');
625
- }
626
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
627
- case 1:
628
- existing = _a.sent();
629
- if (!existing) {
630
- return [2 /*return*/, {
631
- status: 'not_found',
632
- reason: 'Slow query log not found.'
633
- }];
634
- }
635
- if (existing.ignored) {
636
- throw new Error('Slow query log is ignored.');
637
- }
638
- if (this.autoOptimizeInFlight.has(logId) || existing.auto_fix_status === 'running' || existing.status === 'queued') {
639
- return [2 /*return*/, {
640
- status: 'in_progress',
641
- reason: 'Slow query optimization is already running.',
642
- log: existing
643
- }];
644
- }
645
- queuedAt = new Date();
646
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
647
- $set: {
648
- status: 'queued',
649
- auto_fix_status: 'queued',
650
- verification_notes: 'Slow query optimization queued from super-admin.',
651
- last_triaged_by: 'super-admin',
652
- last_triaged_at: queuedAt
653
- }
654
- })];
655
- case 2:
656
- _a.sent();
657
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
658
- case 3:
659
- queuedLog = (_a.sent()) || existing;
660
- this.autoOptimizeInFlight.add(logId);
661
- setImmediate(function () { return __awaiter(_this, void 0, void 0, function () {
662
- var error_2;
663
- return __generator(this, function (_a) {
664
- switch (_a.label) {
665
- case 0:
666
- _a.trys.push([0, 2, 3, 4]);
667
- return [4 /*yield*/, this.runLogWithRetries(logId, {
668
- force: !!(options === null || options === void 0 ? void 0 : options.force),
669
- retryOutputMismatch: true
670
- })];
671
- case 1:
672
- _a.sent();
673
- return [3 /*break*/, 4];
674
- case 2:
675
- error_2 = _a.sent();
676
- console.error('Slow query queued run failed', { logId: logId, error: (error_2 === null || error_2 === void 0 ? void 0 : error_2.message) || error_2 });
677
- return [3 /*break*/, 4];
678
- case 3:
679
- this.autoOptimizeInFlight.delete(logId);
680
- return [7 /*endfinally*/];
681
- case 4: return [2 /*return*/];
682
- }
683
- });
684
- }); });
685
- return [2 /*return*/, {
686
- status: 'in_progress',
687
- reason: 'Slow query optimization queued.',
688
- log: queuedLog
689
- }];
690
- }
691
- });
692
- });
693
- };
694
- SlowQueryVerifier.prototype.deployLog = function (logId) {
695
- return __awaiter(this, void 0, void 0, function () {
696
- var log, jobId, job, publishOutcome, now, existingResult, refreshed, error_3, message, refreshed;
697
- return __generator(this, function (_a) {
698
- switch (_a.label) {
699
- case 0:
700
- if (!logId) {
701
- throw new Error('Slow query log ID is required.');
702
- }
703
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
704
- case 1:
705
- log = _a.sent();
706
- if (!log) {
707
- return [2 /*return*/, {
708
- status: 'not_found',
709
- reason: 'Slow query log not found.'
710
- }];
711
- }
712
- jobId = String(log.openai_task_id || '').trim();
713
- if (!jobId) {
714
- throw new Error('Slow query log does not have a dashboard job id to deploy.');
715
- }
716
- _a.label = 2;
717
- case 2:
718
- _a.trys.push([2, 6, , 9]);
719
- return [4 /*yield*/, this.publishDashboardJob(jobId)];
720
- case 3:
721
- job = _a.sent();
722
- publishOutcome = this.evaluateDashboardPublishOutcome(job);
723
- now = new Date();
724
- existingResult = (log.auto_fix_result && typeof log.auto_fix_result === 'object')
725
- ? __assign({}, log.auto_fix_result) : {};
726
- existingResult.manual_deploy = {
727
- job_id: jobId,
728
- requested_at: now,
729
- success: publishOutcome.success,
730
- message: publishOutcome.message,
731
- branch_name: publishOutcome.branchName || existingResult.publish_branch || ''
732
- };
733
- if (publishOutcome.branchName) {
734
- existingResult.publish_branch = publishOutcome.branchName;
735
- }
736
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
737
- $set: {
738
- auto_fix_result: existingResult,
739
- verification_notes: publishOutcome.success
740
- ? "Manual deploy completed: ".concat(publishOutcome.message)
741
- : "Manual deploy failed: ".concat(publishOutcome.message),
742
- last_triaged_by: 'super-admin',
743
- last_triaged_at: now
744
- }
745
- })];
746
- case 4:
747
- _a.sent();
748
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
749
- case 5:
750
- refreshed = (_a.sent()) || log;
751
- return [2 /*return*/, {
752
- status: publishOutcome.success ? 'success' : 'failed',
753
- reason: publishOutcome.message,
754
- log: refreshed
755
- }];
756
- case 6:
757
- error_3 = _a.sent();
758
- message = (error_3 === null || error_3 === void 0 ? void 0 : error_3.message) || 'Manual deploy failed.';
759
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
760
- $set: {
761
- verification_notes: "Manual deploy failed: ".concat(message),
762
- last_triaged_by: 'super-admin',
763
- last_triaged_at: new Date()
764
- }
765
- })];
766
- case 7:
767
- _a.sent();
768
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
769
- case 8:
770
- refreshed = _a.sent();
771
- return [2 /*return*/, {
772
- status: 'failed',
773
- reason: message,
774
- log: refreshed || log
775
- }];
776
- case 9: return [2 /*return*/];
777
- }
778
- });
779
- });
780
- };
781
- SlowQueryVerifier.prototype.runLogWithRetries = function (logId, options) {
782
- return __awaiter(this, void 0, void 0, function () {
783
- var retryBudget, retriesUsed, latest, maxAttempts, attemptsUsed;
784
- return __generator(this, function (_a) {
785
- switch (_a.label) {
786
- case 0:
787
- retryBudget = options.retryOutputMismatch
788
- ? (Number.isFinite(Number(this.config.autoOptimizeOutputMismatchRetryCount))
789
- ? Number(this.config.autoOptimizeOutputMismatchRetryCount)
790
- : 0)
791
- : 0;
792
- retriesUsed = 0;
793
- _a.label = 1;
794
- case 1:
795
- if (!true) return [3 /*break*/, 5];
796
- return [4 /*yield*/, this.runAutoOptimization(logId, options.force)];
797
- case 2:
798
- _a.sent();
799
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
800
- case 3:
801
- latest = _a.sent();
802
- if (!latest) {
803
- return [2 /*return*/, null];
804
- }
805
- if (!options.retryOutputMismatch
806
- || !this.shouldRetryForOutputMismatch(latest)
807
- || retriesUsed >= retryBudget) {
808
- return [2 /*return*/, latest];
809
- }
810
- maxAttempts = Number.isFinite(Number(this.config.autoOptimizeMaxAttemptsPerQuery))
811
- ? Number(this.config.autoOptimizeMaxAttemptsPerQuery)
812
- : 0;
813
- attemptsUsed = Number.isFinite(Number(latest.auto_fix_attempt_count))
814
- ? Number(latest.auto_fix_attempt_count)
815
- : 0;
816
- if (maxAttempts > 0 && attemptsUsed >= maxAttempts) {
817
- return [2 /*return*/, latest];
818
- }
819
- retriesUsed += 1;
820
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
821
- $set: {
822
- verification_notes: "Output equivalence mismatch detected. Retrying (".concat(retriesUsed, "/").concat(retryBudget, ")."),
823
- last_triaged_by: 'auto-slow-query',
824
- last_triaged_at: new Date()
825
- }
826
- })];
827
- case 4:
828
- _a.sent();
829
- return [3 /*break*/, 1];
830
- case 5: return [2 /*return*/];
831
- }
832
- });
833
- });
834
- };
835
- SlowQueryVerifier.prototype.shouldRetryForOutputMismatch = function (log) {
836
- if (!log || log.ignored || log.auto_fix_status !== 'failed') {
837
- return false;
838
- }
839
- var result = (log.auto_fix_result && typeof log.auto_fix_result === 'object')
840
- ? log.auto_fix_result
841
- : {};
842
- var validation = (result.validation && typeof result.validation === 'object')
843
- ? result.validation
844
- : {};
845
- var outputEquivalence = result.output_equivalence;
846
- var validationReason = String(validation.reason || '').toLowerCase();
847
- var notes = String(log.verification_notes || '').toLowerCase();
848
- if (outputEquivalence && outputEquivalence.passed === false) {
849
- return true;
850
- }
851
- return validationReason.includes('output equivalence')
852
- || notes.includes('output equivalence');
853
- };
854
- SlowQueryVerifier.prototype.runExplain = function (log, overrides) {
855
- return __awaiter(this, void 0, void 0, function () {
856
- var collectionName, target, client, db, effectiveLog, pipeline_1, filter, findOptions, aggregateOptions_1, explainResponse, usedVerbosity, explainAggregate, cursor, err_3, code, codeName, message, fallbackErr_1, durationMs_1, cursor, _a, durationMs_2, durationMs, explainPlanRaw, explainStatsRaw, stageSummaries, explainPlan, explainStats;
857
- var _this = this;
858
- var _b, _c, _d, _e;
859
- return __generator(this, function (_f) {
860
- switch (_f.label) {
861
- case 0:
862
- collectionName = log.collection;
863
- if (!collectionName) {
864
- throw new Error('Slow query missing collection name.');
865
- }
866
- return [4 /*yield*/, this.resolveExplainTarget(log)];
867
- case 1:
868
- target = _f.sent();
869
- _f.label = 2;
870
- case 2:
871
- _f.trys.push([2, , 31, 34]);
872
- if (!(target.type === 'client')) return [3 /*break*/, 4];
873
- if (!target.uri) {
874
- throw new SlowQueryVerifierError('client_db_missing_uri', 'Client DB missing uri.');
875
- }
876
- return [4 /*yield*/, mongodb_1.MongoClient.connect(target.uri, {
877
- connectTimeoutMS: 10000,
878
- serverSelectionTimeoutMS: 10000,
879
- readPreference: 'secondaryPreferred'
880
- })];
881
- case 3:
882
- client = _f.sent();
883
- db = client.db(target.dbName);
884
- return [3 /*break*/, 5];
885
- case 4:
886
- db = resolveio_server_app_1.ResolveIOServer.getMainDB();
887
- _f.label = 5;
888
- case 5:
889
- if (!db) {
890
- throw new SlowQueryVerifierError('main_db_unavailable', 'Main server DB is not available.');
891
- }
892
- effectiveLog = SlowQueryVerifier.applyQueryOverrides(log, overrides);
893
- pipeline_1 = SlowQueryVerifier.extractPipelineFromLog(effectiveLog);
894
- filter = (_b = effectiveLog.filter) !== null && _b !== void 0 ? _b : {};
895
- findOptions = SlowQueryVerifier.extractFindOptions(effectiveLog.options);
896
- aggregateOptions_1 = SlowQueryVerifier.extractAggregateOptions(effectiveLog.options);
897
- explainResponse = void 0;
898
- usedVerbosity = 'executionStats';
899
- explainAggregate = function (verbosity) { return __awaiter(_this, void 0, void 0, function () {
900
- var err_4;
901
- return __generator(this, function (_a) {
902
- switch (_a.label) {
903
- case 0:
904
- if (SlowQueryVerifier.pipelineHasWriteStage(pipeline_1)) {
905
- throw new SlowQueryVerifierError('aggregate_write_stage', 'Aggregate pipeline includes a write stage; verification skipped.');
906
- }
907
- _a.label = 1;
908
- case 1:
909
- _a.trys.push([1, 3, , 6]);
910
- return [4 /*yield*/, db.collection(collectionName)
911
- .aggregate(pipeline_1, __assign(__assign({}, (aggregateOptions_1 || {})), { readPreference: 'secondaryPreferred' }))
912
- .explain(verbosity)];
913
- case 2: return [2 /*return*/, _a.sent()];
914
- case 3:
915
- err_4 = _a.sent();
916
- if (!SlowQueryVerifier.isAggregateExplainWriteConcernError(err_4)) return [3 /*break*/, 5];
917
- return [4 /*yield*/, db.command(SlowQueryVerifier.buildAggregateExplainCommand(collectionName, pipeline_1, aggregateOptions_1, verbosity), { readPreference: 'secondaryPreferred' })];
918
- case 4: return [2 /*return*/, _a.sent()];
919
- case 5: throw err_4;
920
- case 6: return [2 /*return*/];
921
- }
922
- });
923
- }); };
924
- _f.label = 6;
925
- case 6:
926
- _f.trys.push([6, 11, , 28]);
927
- if (!pipeline_1) return [3 /*break*/, 8];
928
- return [4 /*yield*/, explainAggregate('executionStats')];
929
- case 7:
930
- explainResponse = _f.sent();
931
- return [3 /*break*/, 10];
932
- case 8:
933
- cursor = SlowQueryVerifier.buildFindCursor(db.collection(collectionName), filter, findOptions);
934
- return [4 /*yield*/, cursor.explain('executionStats')];
935
- case 9:
936
- explainResponse = _f.sent();
937
- _f.label = 10;
938
- case 10: return [3 /*break*/, 28];
939
- case 11:
940
- err_3 = _f.sent();
941
- code = err_3 === null || err_3 === void 0 ? void 0 : err_3.code;
942
- codeName = "".concat((err_3 === null || err_3 === void 0 ? void 0 : err_3.codeName) || '').trim();
943
- message = "".concat((err_3 === null || err_3 === void 0 ? void 0 : err_3.message) || '').toLowerCase();
944
- if (code === 26 || codeName === 'NamespaceNotFound' || message.includes('ns does not exist')) {
945
- throw new SlowQueryVerifierError('collection_missing', "Collection '".concat(collectionName, "' not found in ").concat(target.type, " DB."));
946
- }
947
- if (!pipeline_1) return [3 /*break*/, 20];
948
- if (!SlowQueryVerifier.isBsonObjectTooLargeError(err_3)) return [3 /*break*/, 18];
949
- _f.label = 12;
950
- case 12:
951
- _f.trys.push([12, 14, , 17]);
952
- return [4 /*yield*/, explainAggregate('queryPlanner')];
953
- case 13:
954
- explainResponse = _f.sent();
955
- usedVerbosity = 'queryPlanner';
956
- return [3 /*break*/, 17];
957
- case 14:
958
- fallbackErr_1 = _f.sent();
959
- if (!SlowQueryVerifier.isBsonObjectTooLargeError(fallbackErr_1)) return [3 /*break*/, 16];
960
- return [4 /*yield*/, SlowQueryVerifier.measureExecution(db, collectionName, pipeline_1, filter, findOptions, aggregateOptions_1)];
961
- case 15:
962
- durationMs_1 = _f.sent();
963
- if (!SlowQueryVerifier.isValidDuration(durationMs_1)) {
964
- throw new SlowQueryVerifierError('bson_too_large', 'Explain/query payload too large to verify.');
965
- }
966
- return [2 /*return*/, {
967
- durationMs: durationMs_1,
968
- explainPlan: {},
969
- explainStats: {},
970
- stageSummaries: []
971
- }];
972
- case 16: throw fallbackErr_1;
973
- case 17: return [3 /*break*/, 19];
974
- case 18: throw err_3;
975
- case 19: return [3 /*break*/, 27];
976
- case 20:
977
- if (!SlowQueryVerifier.isBsonObjectTooLargeError(err_3)) return [3 /*break*/, 26];
978
- _f.label = 21;
979
- case 21:
980
- _f.trys.push([21, 23, , 25]);
981
- cursor = SlowQueryVerifier.buildFindCursor(db.collection(collectionName), filter, findOptions);
982
- return [4 /*yield*/, cursor.explain('queryPlanner')];
983
- case 22:
984
- explainResponse = _f.sent();
985
- usedVerbosity = 'queryPlanner';
986
- return [3 /*break*/, 25];
987
- case 23:
988
- _a = _f.sent();
989
- return [4 /*yield*/, SlowQueryVerifier.measureExecution(db, collectionName, pipeline_1, filter, findOptions, aggregateOptions_1)];
990
- case 24:
991
- durationMs_2 = _f.sent();
992
- if (!SlowQueryVerifier.isValidDuration(durationMs_2)) {
993
- throw new SlowQueryVerifierError('bson_too_large', 'Explain/query payload too large to verify.');
994
- }
995
- return [2 /*return*/, {
996
- durationMs: durationMs_2,
997
- explainPlan: {},
998
- explainStats: {},
999
- stageSummaries: []
1000
- }];
1001
- case 25: return [3 /*break*/, 27];
1002
- case 26: throw err_3;
1003
- case 27: return [3 /*break*/, 28];
1004
- case 28:
1005
- durationMs = SlowQueryVerifier.resolveDurationMs(explainResponse);
1006
- if (!!SlowQueryVerifier.isValidDuration(durationMs)) return [3 /*break*/, 30];
1007
- return [4 /*yield*/, SlowQueryVerifier.measureExecution(db, collectionName, pipeline_1, filter, findOptions, aggregateOptions_1)];
1008
- case 29:
1009
- durationMs = _f.sent();
1010
- _f.label = 30;
1011
- case 30:
1012
- explainPlanRaw = (_d = (_c = explainResponse === null || explainResponse === void 0 ? void 0 : explainResponse.queryPlanner) !== null && _c !== void 0 ? _c : explainResponse) !== null && _d !== void 0 ? _d : {};
1013
- explainStatsRaw = usedVerbosity === 'queryPlanner' ? {} : ((_e = explainResponse === null || explainResponse === void 0 ? void 0 : explainResponse.executionStats) !== null && _e !== void 0 ? _e : {});
1014
- stageSummaries = SlowQueryVerifier.extractStageSummaries(explainResponse, explainStatsRaw);
1015
- explainPlan = SlowQueryVerifier.sanitizeExplainPayload(SlowQueryVerifier.normalizeExplainPayload(explainPlanRaw));
1016
- explainStats = SlowQueryVerifier.sanitizeExplainPayload(SlowQueryVerifier.normalizeExplainPayload(explainStatsRaw));
1017
- return [2 /*return*/, {
1018
- durationMs: durationMs,
1019
- explainPlan: explainPlan,
1020
- explainStats: explainStats,
1021
- stageSummaries: stageSummaries
1022
- }];
1023
- case 31:
1024
- if (!client) return [3 /*break*/, 33];
1025
- return [4 /*yield*/, client.close()];
1026
- case 32:
1027
- _f.sent();
1028
- _f.label = 33;
1029
- case 33: return [7 /*endfinally*/];
1030
- case 34: return [2 /*return*/];
1031
- }
1032
- });
1033
- });
1034
- };
1035
- SlowQueryVerifier.prototype.measureQuery = function (log, overrides) {
1036
- return __awaiter(this, void 0, void 0, function () {
1037
- return __generator(this, function (_a) {
1038
- return [2 /*return*/, this.runExplain(log, overrides)];
1039
- });
1040
- });
1041
- };
1042
- SlowQueryVerifier.prototype.handleExplainResult = function (log, result) {
1043
- return __awaiter(this, void 0, void 0, function () {
1044
- var existingRuns, durationValid, previousInvalidAttempts, invalidAttempts, shouldFail, nextRunAt_1, updateOps_1, runs, hasFastRun, hasEnoughRuns, status, nextRunAt, updateOps;
1045
- return __generator(this, function (_a) {
1046
- switch (_a.label) {
1047
- case 0:
1048
- if (!log._id) {
1049
- return [2 /*return*/];
1050
- }
1051
- existingRuns = (Array.isArray(log.verification_runs) ? log.verification_runs : [])
1052
- .filter(function (run) { return SlowQueryVerifier.isValidDuration(run.duration_ms); });
1053
- durationValid = SlowQueryVerifier.isValidDuration(result.durationMs);
1054
- if (!!durationValid) return [3 /*break*/, 2];
1055
- if (this.config.debugLogging) {
1056
- console.warn('Slow query verification reported invalid duration; keeping log pending.', log.collection, result.durationMs);
1057
- }
1058
- previousInvalidAttempts = typeof log.verification_invalid_attempts === 'number'
1059
- ? log.verification_invalid_attempts
1060
- : 0;
1061
- invalidAttempts = previousInvalidAttempts + 1;
1062
- shouldFail = invalidAttempts >= VERIFICATION_ATTEMPTS;
1063
- nextRunAt_1 = new Date(Date.now() + VERIFICATION_INTERVAL_MS);
1064
- updateOps_1 = {
1065
- $set: {
1066
- verification_runs: existingRuns,
1067
- verification_status: shouldFail ? 'failed' : 'pending',
1068
- verification_invalid_attempts: invalidAttempts,
1069
- explain_plan: result.explainPlan,
1070
- explain_execution_stats: result.explainStats,
1071
- explain_generated_at: new Date(),
1072
- verification_notes: shouldFail ? 'Verification failed: invalid duration' : 'Explain returned invalid duration'
1073
- }
1074
- };
1075
- if (shouldFail) {
1076
- updateOps_1.$unset = {
1077
- verification_next_run_at: ''
1078
- };
1079
- }
1080
- else {
1081
- updateOps_1.$set.verification_next_run_at = nextRunAt_1;
1082
- }
1083
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: log._id }, updateOps_1)];
1084
- case 1:
1085
- _a.sent();
1086
- return [2 /*return*/];
1087
- case 2:
1088
- runs = existingRuns
1089
- .concat([
1090
- {
1091
- timestamp: new Date(),
1092
- duration_ms: result.durationMs
1093
- }
1094
- ])
1095
- .slice(-VERIFICATION_ATTEMPTS);
1096
- hasFastRun = runs.some(function (run) { return run.duration_ms < VERIFICATION_THRESHOLD_MS; });
1097
- if (!hasFastRun) return [3 /*break*/, 4];
1098
- // const durations = runs.map(run => `${run.duration_ms}ms`).join(', ');
1099
- // console.info('Removing slow query log; not consistently slow.', log.collection, durations);
1100
- return [4 /*yield*/, SlowQueryLogs.deleteOne({ _id: log._id })];
1101
- case 3:
1102
- // const durations = runs.map(run => `${run.duration_ms}ms`).join(', ');
1103
- // console.info('Removing slow query log; not consistently slow.', log.collection, durations);
1104
- _a.sent();
1105
- return [2 /*return*/];
1106
- case 4:
1107
- hasEnoughRuns = runs.length >= VERIFICATION_ATTEMPTS;
1108
- status = hasEnoughRuns ? 'passed' : 'pending';
1109
- if (!hasEnoughRuns) {
1110
- nextRunAt = new Date(Date.now() + VERIFICATION_INTERVAL_MS);
1111
- }
1112
- updateOps = {
1113
- $set: {
1114
- verification_runs: runs,
1115
- verification_status: status,
1116
- verification_invalid_attempts: 0,
1117
- explain_plan: result.explainPlan,
1118
- explain_execution_stats: result.explainStats,
1119
- explain_generated_at: new Date()
1120
- }
1121
- };
1122
- if (nextRunAt) {
1123
- updateOps.$set.verification_next_run_at = nextRunAt;
1124
- }
1125
- else {
1126
- updateOps.$unset = updateOps.$unset || {};
1127
- updateOps.$unset.verification_next_run_at = '';
1128
- }
1129
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: log._id }, updateOps)];
1130
- case 5:
1131
- _a.sent();
1132
- if (!(status === 'passed')) return [3 /*break*/, 7];
1133
- return [4 /*yield*/, this.assignSlowQueryCounter(log._id)];
1134
- case 6:
1135
- _a.sent();
1136
- this.scheduleAutoOptimization(log._id);
1137
- _a.label = 7;
1138
- case 7: return [2 /*return*/];
1139
- }
1140
- });
1141
- });
1142
- };
1143
- SlowQueryVerifier.prototype.handleExplainError = function (log, err) {
1144
- return __awaiter(this, void 0, void 0, function () {
1145
- var message, code, permanentFailure, nextRunAt;
1146
- return __generator(this, function (_a) {
1147
- switch (_a.label) {
1148
- case 0:
1149
- if (!log._id) {
1150
- return [2 /*return*/];
1151
- }
1152
- message = typeof err === 'string' ? err : (err === null || err === void 0 ? void 0 : err.message) || 'Unknown error';
1153
- code = err instanceof SlowQueryVerifierError ? err.code : null;
1154
- permanentFailure = !!code && ['client_db_not_found', 'client_db_missing_uri', 'client_db_missing_database', 'main_db_unavailable', 'aggregate_write_stage', 'bson_too_large', 'collection_missing'].includes(code);
1155
- if (this.config.debugLogging) {
1156
- console.error('Slow query verification error for', log.collection, message);
1157
- }
1158
- else if (!permanentFailure) {
1159
- console.warn('Slow query verification error for', log.collection, message);
1160
- }
1161
- if (!permanentFailure) return [3 /*break*/, 2];
1162
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: log._id }, {
1163
- $set: {
1164
- verification_status: 'failed',
1165
- verification_notes: "Verification failed: ".concat(message)
1166
- },
1167
- $unset: {
1168
- verification_next_run_at: ''
1169
- }
1170
- })];
1171
- case 1:
1172
- _a.sent();
1173
- return [2 /*return*/];
1174
- case 2:
1175
- nextRunAt = new Date(Date.now() + VERIFICATION_INTERVAL_MS);
1176
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: log._id }, {
1177
- $set: {
1178
- verification_next_run_at: nextRunAt,
1179
- verification_notes: "Verification error: ".concat(message)
1180
- }
1181
- })];
1182
- case 3:
1183
- _a.sent();
1184
- return [2 /*return*/];
1185
- }
1186
- });
1187
- });
1188
- };
1189
- SlowQueryVerifier.prototype.assignSlowQueryCounter = function (logId) {
1190
- return __awaiter(this, void 0, void 0, function () {
1191
- var latest, hasNumber, counterValue, counterString;
1192
- return __generator(this, function (_a) {
1193
- switch (_a.label) {
1194
- case 0:
1195
- if (!logId) {
1196
- return [2 /*return*/];
1197
- }
1198
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
1199
- case 1:
1200
- latest = _a.sent();
1201
- if (!latest) {
1202
- return [2 /*return*/];
1203
- }
1204
- hasNumber = typeof latest.slow_query_count === 'number' && latest.slow_query_count > 0;
1205
- if (hasNumber) {
1206
- return [2 /*return*/];
1207
- }
1208
- return [4 /*yield*/, resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager().callMethod('incCounter', 'slow_query')];
1209
- case 2:
1210
- counterValue = _a.sent();
1211
- counterString = (0, common_1.pad)(counterValue, 6);
1212
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
1213
- $set: {
1214
- slow_query_count: counterValue,
1215
- slow_query_count_string: counterString
1216
- }
1217
- })];
1218
- case 3:
1219
- _a.sent();
1220
- return [2 /*return*/];
1221
- }
1222
- });
1223
- });
1224
- };
1225
- SlowQueryVerifier.prototype.scheduleAutoOptimization = function (logId) {
1226
- if (!logId) {
1227
- return;
1228
- }
1229
- if (this.autoOptimizeInFlight.has(logId)) {
1230
- return;
1231
- }
1232
- this.autoOptimizeInFlight.add(logId);
1233
- this.runAutoOptimizationInBackground(logId);
1234
- };
1235
- SlowQueryVerifier.prototype.runAutoOptimizationInBackground = function (logId) {
1236
- var _this = this;
1237
- setImmediate(function () { return __awaiter(_this, void 0, void 0, function () {
1238
- var error_4;
1239
- return __generator(this, function (_a) {
1240
- switch (_a.label) {
1241
- case 0:
1242
- _a.trys.push([0, 2, 3, 4]);
1243
- return [4 /*yield*/, this.runAutoOptimization(logId)];
1244
- case 1:
1245
- _a.sent();
1246
- return [3 /*break*/, 4];
1247
- case 2:
1248
- error_4 = _a.sent();
1249
- console.error('Slow query auto optimization failed', { logId: logId, error: (error_4 === null || error_4 === void 0 ? void 0 : error_4.message) || error_4 });
1250
- return [3 /*break*/, 4];
1251
- case 3:
1252
- this.autoOptimizeInFlight.delete(logId);
1253
- return [7 /*endfinally*/];
1254
- case 4: return [2 /*return*/];
1255
- }
1256
- });
1257
- }); });
1258
- };
1259
- SlowQueryVerifier.prototype.escapeRegex = function (value) {
1260
- return String(value || '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1261
- };
1262
- SlowQueryVerifier.prototype.getEscalationRecipients = function () {
1263
- var unique = new Set();
1264
- (this.config.escalationEmails || []).forEach(function (entry) {
1265
- var normalized = String(entry || '').trim().toLowerCase();
1266
- if (normalized) {
1267
- unique.add(normalized);
1268
- }
1269
- });
1270
- if (!unique.size) {
1271
- unique.add(DEFAULT_ERROR_ALERT_EMAIL);
1272
- }
1273
- return Array.from(unique);
1274
- };
1275
- SlowQueryVerifier.prototype.sendSlowQueryEscalationNotice = function (log, reason) {
1276
- return __awaiter(this, void 0, void 0, function () {
1277
- var recipients, subject, body, methodManager, recipients_1, recipients_1_1, recipient, error_5, e_2_1;
1278
- var e_2, _a;
1279
- return __generator(this, function (_b) {
1280
- switch (_b.label) {
1281
- case 0:
1282
- recipients = this.getEscalationRecipients();
1283
- if (!recipients.length || !(log === null || log === void 0 ? void 0 : log._id)) {
1284
- return [2 /*return*/];
1285
- }
1286
- subject = "ResolveIO Slow Query Escalation: ".concat(log.slow_query_count_string || log._id);
1287
- body = [
1288
- 'Slow-query auto optimization budget was exhausted and additional autonomous attempts were stopped.',
1289
- '',
1290
- "Reason: ".concat(reason),
1291
- "Slow Query Log ID: ".concat(log._id),
1292
- "Slow Query Counter: ".concat(log.slow_query_count_string || 'n/a'),
1293
- "Collection: ".concat(log.collection || 'unknown'),
1294
- "Query Hash: ".concat(log.query_hash || 'n/a'),
1295
- "Client: ".concat(log.client_name || log.client_slug || 'unknown'),
1296
- "Environment: ".concat(log.environment || 'unknown'),
1297
- "Attempts: ".concat(log.auto_fix_attempt_count || 0, "/").concat(this.config.autoOptimizeMaxAttemptsPerQuery),
1298
- '',
1299
- 'The query has been marked ignored to protect customer AI credits. Manual tuning or explicit allow-list override is required.'
1300
- ].join('\n');
1301
- methodManager = resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager();
1302
- _b.label = 1;
1303
- case 1:
1304
- _b.trys.push([1, 8, 9, 10]);
1305
- recipients_1 = __values(recipients), recipients_1_1 = recipients_1.next();
1306
- _b.label = 2;
1307
- case 2:
1308
- if (!!recipients_1_1.done) return [3 /*break*/, 7];
1309
- recipient = recipients_1_1.value;
1310
- _b.label = 3;
1311
- case 3:
1312
- _b.trys.push([3, 5, , 6]);
1313
- return [4 /*yield*/, methodManager.sendEmail(recipient, subject, body)];
1314
- case 4:
1315
- _b.sent();
1316
- return [3 /*break*/, 6];
1317
- case 5:
1318
- error_5 = _b.sent();
1319
- console.error('Failed sending slow-query escalation email', { recipient: recipient, logId: log._id, error: error_5 });
1320
- return [3 /*break*/, 6];
1321
- case 6:
1322
- recipients_1_1 = recipients_1.next();
1323
- return [3 /*break*/, 2];
1324
- case 7: return [3 /*break*/, 10];
1325
- case 8:
1326
- e_2_1 = _b.sent();
1327
- e_2 = { error: e_2_1 };
1328
- return [3 /*break*/, 10];
1329
- case 9:
1330
- try {
1331
- if (recipients_1_1 && !recipients_1_1.done && (_a = recipients_1.return)) _a.call(recipients_1);
1332
- }
1333
- finally { if (e_2) throw e_2.error; }
1334
- return [7 /*endfinally*/];
1335
- case 10: return [2 /*return*/];
1336
- }
1337
- });
1338
- });
1339
- };
1340
- SlowQueryVerifier.prototype.resolveSlowQueryClientTarget = function (log) {
1341
- return __awaiter(this, void 0, void 0, function () {
1342
- var directId, candidates, candidates_2, candidates_2_1, candidate, escaped, match, e_3_1;
1343
- var e_3, _a;
1344
- return __generator(this, function (_b) {
1345
- switch (_b.label) {
1346
- case 0:
1347
- directId = String((log === null || log === void 0 ? void 0 : log.id_client) || '').trim();
1348
- if (directId) {
1349
- return [2 /*return*/, {
1350
- idClient: directId,
1351
- clientName: String((log === null || log === void 0 ? void 0 : log.client_name) || '').trim()
1352
- }];
1353
- }
1354
- candidates = [
1355
- String((log === null || log === void 0 ? void 0 : log.client_slug) || '').trim(),
1356
- String((log === null || log === void 0 ? void 0 : log.client_name) || '').trim(),
1357
- String((log === null || log === void 0 ? void 0 : log.source_app) || '').trim()
1358
- ].filter(Boolean);
1359
- _b.label = 1;
1360
- case 1:
1361
- _b.trys.push([1, 6, 7, 8]);
1362
- candidates_2 = __values(candidates), candidates_2_1 = candidates_2.next();
1363
- _b.label = 2;
1364
- case 2:
1365
- if (!!candidates_2_1.done) return [3 /*break*/, 5];
1366
- candidate = candidates_2_1.value;
1367
- escaped = this.escapeRegex(candidate);
1368
- return [4 /*yield*/, Clients.findOne({
1369
- $or: [
1370
- { name: { $regex: "^".concat(escaped, "$"), $options: 'i' } },
1371
- { demo_name: { $regex: "^".concat(escaped, "$"), $options: 'i' } },
1372
- { project: { $regex: "^".concat(escaped, "$"), $options: 'i' } },
1373
- { repo: { $regex: "^".concat(escaped, "$"), $options: 'i' } }
1374
- ]
1375
- }, {
1376
- projection: {
1377
- _id: 1,
1378
- name: 1
1379
- }
1380
- })];
1381
- case 3:
1382
- match = _b.sent();
1383
- if (match === null || match === void 0 ? void 0 : match._id) {
1384
- return [2 /*return*/, {
1385
- idClient: String(match._id || '').trim(),
1386
- clientName: String(match.name || (log === null || log === void 0 ? void 0 : log.client_name) || candidate || '').trim()
1387
- }];
1388
- }
1389
- _b.label = 4;
1390
- case 4:
1391
- candidates_2_1 = candidates_2.next();
1392
- return [3 /*break*/, 2];
1393
- case 5: return [3 /*break*/, 8];
1394
- case 6:
1395
- e_3_1 = _b.sent();
1396
- e_3 = { error: e_3_1 };
1397
- return [3 /*break*/, 8];
1398
- case 7:
1399
- try {
1400
- if (candidates_2_1 && !candidates_2_1.done && (_a = candidates_2.return)) _a.call(candidates_2);
1401
- }
1402
- finally { if (e_3) throw e_3.error; }
1403
- return [7 /*endfinally*/];
1404
- case 8: return [2 /*return*/, {
1405
- idClient: '',
1406
- clientName: String((log === null || log === void 0 ? void 0 : log.client_name) || '').trim()
1407
- }];
1408
- }
1409
- });
1410
- });
1411
- };
1412
- SlowQueryVerifier.prototype.buildLocalInternalUserCriteria = function () {
1413
- return {
1414
- $and: [
1415
- {
1416
- is_customer: {
1417
- $ne: true
1418
- }
1419
- },
1420
- {
1421
- $nor: [
1422
- {
1423
- 'other.id_customer': {
1424
- $exists: true,
1425
- $nin: ['', null]
1426
- }
1427
- },
1428
- {
1429
- id_customer: {
1430
- $exists: true,
1431
- $nin: ['', null]
1432
- }
1433
- }
1434
- ]
1435
- }
1436
- ]
1437
- };
1438
- };
1439
- SlowQueryVerifier.prototype.buildLocalAdminUserCriteria = function () {
1440
- return {
1441
- $or: [
1442
- {
1443
- 'roles.super_admin': true
1444
- },
1445
- {
1446
- 'roles.groups.name': {
1447
- $regex: 'admin',
1448
- $options: 'i'
1449
- }
1450
- },
1451
- {
1452
- 'roles.groups.views': {
1453
- $regex: '^/manage'
1454
- }
1455
- },
1456
- {
1457
- 'roles.groups.views': '/manage'
1458
- }
1459
- ]
1460
- };
1461
- };
1462
- SlowQueryVerifier.prototype.resolveLocalNotificationUserIds = function (isGeneratedApp) {
1463
- return __awaiter(this, void 0, void 0, function () {
1464
- var andClauses, users, unique, users_1, users_1_1, user, idUser;
1465
- var e_4, _a;
1466
- return __generator(this, function (_b) {
1467
- switch (_b.label) {
1468
- case 0:
1469
- andClauses = [
1470
- {
1471
- active: true
1472
- },
1473
- {
1474
- username: {
1475
- $exists: true
1476
- }
1477
- }
1478
- ];
1479
- if (isGeneratedApp) {
1480
- andClauses.push(this.buildLocalInternalUserCriteria());
1481
- }
1482
- else {
1483
- andClauses.push(this.buildLocalAdminUserCriteria());
1484
- }
1485
- return [4 /*yield*/, user_collection_1.Users.find({
1486
- $and: andClauses
1487
- }, {
1488
- projection: {
1489
- _id: 1
1490
- },
1491
- limit: MAX_LOCAL_NOTIFICATION_USERS
1492
- })];
1493
- case 1:
1494
- users = _b.sent();
1495
- if (!Array.isArray(users) || !users.length) {
1496
- return [2 /*return*/, []];
1497
- }
1498
- unique = new Set();
1499
- try {
1500
- for (users_1 = __values(users), users_1_1 = users_1.next(); !users_1_1.done; users_1_1 = users_1.next()) {
1501
- user = users_1_1.value;
1502
- idUser = String((user === null || user === void 0 ? void 0 : user._id) || '').trim();
1503
- if (idUser) {
1504
- unique.add(idUser);
1505
- }
1506
- if (unique.size >= MAX_LOCAL_NOTIFICATION_USERS) {
1507
- break;
1508
- }
1509
- }
1510
- }
1511
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
1512
- finally {
1513
- try {
1514
- if (users_1_1 && !users_1_1.done && (_a = users_1.return)) _a.call(users_1);
1515
- }
1516
- finally { if (e_4) throw e_4.error; }
1517
- }
1518
- return [2 /*return*/, Array.from(unique)];
1519
- }
1520
- });
1521
- });
1522
- };
1523
- SlowQueryVerifier.prototype.isGeneratedAICoderClient = function (idClient) {
1524
- return __awaiter(this, void 0, void 0, function () {
1525
- var normalizedClientId, match;
1526
- return __generator(this, function (_a) {
1527
- switch (_a.label) {
1528
- case 0:
1529
- normalizedClientId = String(idClient || '').trim();
1530
- if (!normalizedClientId) {
1531
- return [2 /*return*/, false];
1532
- }
1533
- return [4 /*yield*/, AICoderApps.findOne({
1534
- client_id: normalizedClientId
1535
- }, {
1536
- projection: {
1537
- _id: 1
1538
- }
1539
- })];
1540
- case 1:
1541
- match = _a.sent();
1542
- return [2 /*return*/, !!(match === null || match === void 0 ? void 0 : match._id)];
1543
- }
1544
- });
1545
- });
1546
- };
1547
- SlowQueryVerifier.prototype.buildAICoderSlowQuerySummary = function (stage, log, extra) {
1548
- var _a, _b, _c, _d;
1549
- return (0, customer_notification_content_manager_1.buildGeneratedSlowQuerySummary)(stage, {
1550
- collection: String((log === null || log === void 0 ? void 0 : log.collection) || '').trim(),
1551
- source_app: String((log === null || log === void 0 ? void 0 : log.source_app) || '').trim(),
1552
- environment: String((log === null || log === void 0 ? void 0 : log.environment) || '').trim(),
1553
- baseline_duration_ms: Number((_b = (_a = log === null || log === void 0 ? void 0 : log.auto_fix_result) === null || _a === void 0 ? void 0 : _a.baseline) === null || _b === void 0 ? void 0 : _b.durationMs),
1554
- after_duration_ms: Number((_d = (_c = log === null || log === void 0 ? void 0 : log.auto_fix_result) === null || _c === void 0 ? void 0 : _c.after) === null || _d === void 0 ? void 0 : _d.durationMs),
1555
- reason: extra === null || extra === void 0 ? void 0 : extra.reason,
1556
- notes: extra === null || extra === void 0 ? void 0 : extra.notes
1557
- }, extra);
1558
- };
1559
- SlowQueryVerifier.prototype.buildResolveIOProjectSlowQueryDetails = function (log, extra) {
1560
- var _a, _b, _c, _d;
1561
- var runDurations = Array.isArray(log === null || log === void 0 ? void 0 : log.verification_runs)
1562
- ? log.verification_runs
1563
- .map(function (run) { return Number(run === null || run === void 0 ? void 0 : run.duration_ms); })
1564
- .filter(function (duration) { return Number.isFinite(duration) && duration >= 0; })
1565
- : [];
1566
- return (0, customer_notification_content_manager_1.buildResolveIOProjectSlowQueryDetails)({
1567
- collection: log.collection || '',
1568
- client_name: log.client_name || log.client_slug || '',
1569
- source_app: log.source_app || '',
1570
- environment: log.environment || '',
1571
- query_hash: log.query_hash || '',
1572
- baseline_duration_ms: Number((_b = (_a = log === null || log === void 0 ? void 0 : log.auto_fix_result) === null || _a === void 0 ? void 0 : _a.baseline) === null || _b === void 0 ? void 0 : _b.durationMs),
1573
- after_duration_ms: Number((_d = (_c = log === null || log === void 0 ? void 0 : log.auto_fix_result) === null || _c === void 0 ? void 0 : _c.after) === null || _d === void 0 ? void 0 : _d.durationMs),
1574
- verification_run_durations_ms: runDurations,
1575
- log_id: log._id || '',
1576
- reason: extra === null || extra === void 0 ? void 0 : extra.reason,
1577
- notes: extra === null || extra === void 0 ? void 0 : extra.notes
1578
- });
1579
- };
1580
- SlowQueryVerifier.prototype.notifyCustomerSlowQueryStatus = function (stage, log, extra) {
1581
- return __awaiter(this, void 0, void 0, function () {
1582
- var target, isGeneratedApp, generatedApp, issueKey, dedupeKey, metadata, targetPayload, idUsers, payload, error_6;
1583
- return __generator(this, function (_a) {
1584
- switch (_a.label) {
1585
- case 0:
1586
- if (!(log === null || log === void 0 ? void 0 : log._id)) {
1587
- return [2 /*return*/];
1588
- }
1589
- return [4 /*yield*/, this.resolveSlowQueryClientTarget(log)];
1590
- case 1:
1591
- target = _a.sent();
1592
- isGeneratedApp = false;
1593
- if (!target.idClient) return [3 /*break*/, 3];
1594
- return [4 /*yield*/, this.isGeneratedAICoderClient(target.idClient)];
1595
- case 2:
1596
- isGeneratedApp = _a.sent();
1597
- return [3 /*break*/, 5];
1598
- case 3: return [4 /*yield*/, this.resolveAutoOptimizeApp(log)];
1599
- case 4:
1600
- generatedApp = _a.sent();
1601
- isGeneratedApp = !!generatedApp;
1602
- _a.label = 5;
1603
- case 5:
1604
- if (!isGeneratedApp && stage !== 'completed_success') {
1605
- return [2 /*return*/];
1606
- }
1607
- issueKey = String(log.query_hash || log._id || '').trim();
1608
- dedupeKey = "slow-query:".concat(issueKey, ":").concat(stage);
1609
- metadata = {
1610
- log_id: log._id,
1611
- query_hash: log.query_hash || '',
1612
- collection: log.collection || '',
1613
- environment: log.environment || '',
1614
- source_app: log.source_app || '',
1615
- reason: (extra === null || extra === void 0 ? void 0 : extra.reason) || '',
1616
- notes: (extra === null || extra === void 0 ? void 0 : extra.notes) || ''
1617
- };
1618
- targetPayload = {};
1619
- if (!target.idClient) return [3 /*break*/, 6];
1620
- targetPayload.target_type = isGeneratedApp ? 'client_internal' : 'client_admins';
1621
- targetPayload.id_client = target.idClient;
1622
- targetPayload.client_name = target.clientName || undefined;
1623
- return [3 /*break*/, 8];
1624
- case 6: return [4 /*yield*/, this.resolveLocalNotificationUserIds(isGeneratedApp)];
1625
- case 7:
1626
- idUsers = _a.sent();
1627
- if (!idUsers.length) {
1628
- return [2 /*return*/];
1629
- }
1630
- targetPayload.target_type = 'users';
1631
- targetPayload.id_users = idUsers;
1632
- targetPayload.client_name = target.clientName || undefined;
1633
- _a.label = 8;
1634
- case 8:
1635
- payload = {};
1636
- if (isGeneratedApp) {
1637
- if (stage === 'detected_auto_optimize_enabled') {
1638
- payload = {
1639
- title: 'Slow query detected. Auto-optimization is running.',
1640
- message: 'We detected a slow query and started an automatic optimization workflow. We will notify you when it is complete.',
1641
- severity: 'info',
1642
- details: this.buildAICoderSlowQuerySummary(stage, log, extra)
1643
- };
1644
- }
1645
- else if (stage === 'completed_success') {
1646
- payload = {
1647
- title: 'Slow query optimization completed.',
1648
- message: "We optimized slow performance for ".concat(log.collection || 'a collection', " and published the improvement."),
1649
- severity: 'success',
1650
- details: this.buildAICoderSlowQuerySummary(stage, log, extra)
1651
- };
1652
- }
1653
- else {
1654
- payload = {
1655
- title: 'Slow query needs manual review.',
1656
- message: 'We could not complete automatic optimization for a slow query. Manual tuning is required.',
1657
- severity: 'warning',
1658
- details: this.buildAICoderSlowQuerySummary(stage, log, extra)
1659
- };
1660
- }
1661
- }
1662
- else {
1663
- payload = {
1664
- title: 'ResolveIO project slow query optimized',
1665
- message: "Slow-query optimization completed for ".concat(log.collection || 'a collection', "."),
1666
- severity: 'success',
1667
- details: this.buildResolveIOProjectSlowQueryDetails(log, extra)
1668
- };
1669
- }
1670
- _a.label = 9;
1671
- case 9:
1672
- _a.trys.push([9, 11, , 12]);
1673
- return [4 /*yield*/, resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager().callMethod('createCustomerNotification', __assign(__assign(__assign({}, targetPayload), { category: 'slow-query', source: 'slow-query-auto-optimize', source_id: String(log._id || '').trim() || undefined, dedupe_key: dedupeKey, metadata: metadata }), payload))];
1674
- case 10:
1675
- _a.sent();
1676
- return [3 /*break*/, 12];
1677
- case 11:
1678
- error_6 = _a.sent();
1679
- if (this.config.debugLogging) {
1680
- console.warn('Slow query customer notification failed', {
1681
- logId: log._id,
1682
- stage: stage,
1683
- error: (error_6 === null || error_6 === void 0 ? void 0 : error_6.message) || error_6
1684
- });
1685
- }
1686
- return [3 /*break*/, 12];
1687
- case 12: return [2 /*return*/];
1688
- }
1689
- });
1690
- });
1691
- };
1692
- SlowQueryVerifier.prototype.parseDate = function (value) {
1693
- if (!value) {
1694
- return null;
1695
- }
1696
- if (value instanceof Date && !Number.isNaN(value.getTime())) {
1697
- return value;
1698
- }
1699
- var parsed = new Date(value);
1700
- return Number.isNaN(parsed.getTime()) ? null : parsed;
1701
- };
1702
- SlowQueryVerifier.prototype.resolveFingerprintScopeKey = function (log) {
1703
- var explicit = String((log === null || log === void 0 ? void 0 : log.fingerprint_scope_key) || '').trim();
1704
- if (explicit) {
1705
- return explicit;
1706
- }
1707
- var normalize = function (value) {
1708
- var normalized = String(value || '')
1709
- .trim()
1710
- .toLowerCase()
1711
- .replace(/\s+/g, ' ');
1712
- return normalized || '_';
1713
- };
1714
- var clientKey = normalize((log === null || log === void 0 ? void 0 : log.client_slug) || (log === null || log === void 0 ? void 0 : log.client_name) || '');
1715
- var sourceApp = normalize((log === null || log === void 0 ? void 0 : log.source_app) || '');
1716
- var environment = normalize((log === null || log === void 0 ? void 0 : log.environment) || '');
1717
- var publication = normalize((log === null || log === void 0 ? void 0 : log.publication) || '');
1718
- var serverUrl = normalize((log === null || log === void 0 ? void 0 : log.server_url) || '');
1719
- return [clientKey, sourceApp, environment, publication, serverUrl].join('|');
1720
- };
1721
- SlowQueryVerifier.prototype.buildFingerprintMatchQuery = function (log) {
1722
- var conditions = [];
1723
- var collection = String((log === null || log === void 0 ? void 0 : log.collection) || '').trim();
1724
- if (collection) {
1725
- conditions.push({ collection: collection });
1726
- }
1727
- var explicitScopeKey = String((log === null || log === void 0 ? void 0 : log.fingerprint_scope_key) || '').trim();
1728
- var scopeKey = this.resolveFingerprintScopeKey(log);
1729
- if (scopeKey) {
1730
- var legacyScopeQuery = {};
1731
- if (String((log === null || log === void 0 ? void 0 : log.client_slug) || '').trim()) {
1732
- legacyScopeQuery.client_slug = log.client_slug;
1733
- }
1734
- if (String((log === null || log === void 0 ? void 0 : log.environment) || '').trim()) {
1735
- legacyScopeQuery.environment = log.environment;
1736
- }
1737
- if (String((log === null || log === void 0 ? void 0 : log.source_app) || '').trim()) {
1738
- legacyScopeQuery.source_app = log.source_app;
1739
- }
1740
- if (String((log === null || log === void 0 ? void 0 : log.publication) || '').trim()) {
1741
- legacyScopeQuery.publication = log.publication;
1742
- }
1743
- if (String((log === null || log === void 0 ? void 0 : log.server_url) || '').trim()) {
1744
- legacyScopeQuery.server_url = log.server_url;
1745
- }
1746
- if (explicitScopeKey) {
1747
- conditions.push({ fingerprint_scope_key: scopeKey });
1748
- }
1749
- else {
1750
- var scopeCandidates = [{ _id: (log === null || log === void 0 ? void 0 : log._id) || '' }, { fingerprint_scope_key: scopeKey }];
1751
- if (Object.keys(legacyScopeQuery).length) {
1752
- scopeCandidates.push(legacyScopeQuery);
1753
- }
1754
- conditions.push({ $or: scopeCandidates });
1755
- }
1756
- }
1757
- var canonicalHash = String((log === null || log === void 0 ? void 0 : log.canonical_fingerprint_hash) || '').trim();
1758
- var queryHash = String((log === null || log === void 0 ? void 0 : log.query_hash) || '').trim();
1759
- if (canonicalHash && queryHash && canonicalHash !== queryHash) {
1760
- conditions.push({
1761
- $or: [
1762
- { canonical_fingerprint_hash: canonicalHash },
1763
- {
1764
- canonical_fingerprint_hash: { $exists: false },
1765
- query_hash: queryHash
1766
- }
1767
- ]
1768
- });
1769
- }
1770
- else if (canonicalHash) {
1771
- conditions.push({ canonical_fingerprint_hash: canonicalHash });
1772
- }
1773
- else if (queryHash) {
1774
- conditions.push({ query_hash: queryHash });
1775
- }
1776
- else if (log === null || log === void 0 ? void 0 : log._id) {
1777
- conditions.push({ _id: log._id });
1778
- }
1779
- if (!conditions.length) {
1780
- return { _id: (log === null || log === void 0 ? void 0 : log._id) || '' };
1781
- }
1782
- if (conditions.length === 1) {
1783
- return conditions[0];
1784
- }
1785
- return { $and: conditions };
1786
- };
1787
- SlowQueryVerifier.prototype.countAttemptsWithinWindow = function (log, windowStart) {
1788
- var _this = this;
1789
- var history = Array.isArray(log === null || log === void 0 ? void 0 : log.auto_fix_attempt_history)
1790
- ? log.auto_fix_attempt_history
1791
- : [];
1792
- var attemptsInWindow = 0;
1793
- history.forEach(function (entry) {
1794
- var attemptAt = _this.parseDate(entry);
1795
- if (attemptAt && attemptAt.getTime() >= windowStart.getTime()) {
1796
- attemptsInWindow += 1;
1797
- }
1798
- });
1799
- if (attemptsInWindow > 0) {
1800
- return attemptsInWindow;
1801
- }
1802
- var lastAttemptAt = this.parseDate(log === null || log === void 0 ? void 0 : log.auto_fix_last_attempt_at);
1803
- var attemptsUsed = Number.isFinite(Number(log === null || log === void 0 ? void 0 : log.auto_fix_attempt_count))
1804
- ? Number(log.auto_fix_attempt_count)
1805
- : 0;
1806
- if (lastAttemptAt && lastAttemptAt.getTime() >= windowStart.getTime() && attemptsUsed > 0) {
1807
- return 1;
1808
- }
1809
- return 0;
1810
- };
1811
- SlowQueryVerifier.prototype.resolveFingerprintAttemptsInWindow = function (log, windowStart) {
1812
- return __awaiter(this, void 0, void 0, function () {
1813
- var matchQuery, matches, attempts;
1814
- var _this = this;
1815
- return __generator(this, function (_a) {
1816
- switch (_a.label) {
1817
- case 0:
1818
- matchQuery = this.buildFingerprintMatchQuery(log);
1819
- return [4 /*yield*/, SlowQueryLogs.find(matchQuery, {
1820
- limit: 200,
1821
- projection: {
1822
- _id: 1,
1823
- auto_fix_attempt_history: 1,
1824
- auto_fix_attempt_count: 1,
1825
- auto_fix_last_attempt_at: 1
1826
- }
1827
- })];
1828
- case 1:
1829
- matches = _a.sent();
1830
- attempts = 0;
1831
- matches.forEach(function (entry) {
1832
- attempts += _this.countAttemptsWithinWindow(entry, windowStart);
1833
- });
1834
- return [2 /*return*/, attempts];
1835
- }
1836
- });
1837
- });
1838
- };
1839
- SlowQueryVerifier.prototype.resolveCooldownDeadline = function (log) {
1840
- var cooldownMinutes = Number.isFinite(Number(this.config.autoOptimizeCooldownMinutes))
1841
- ? Number(this.config.autoOptimizeCooldownMinutes)
1842
- : 0;
1843
- if (cooldownMinutes <= 0) {
1844
- return null;
1845
- }
1846
- var lastAttemptAt = this.parseDate(log === null || log === void 0 ? void 0 : log.auto_fix_last_attempt_at);
1847
- if (!lastAttemptAt) {
1848
- return null;
1849
- }
1850
- return new Date(lastAttemptAt.getTime() + (cooldownMinutes * 60 * 1000));
1851
- };
1852
- SlowQueryVerifier.prototype.markAutoOptimizeCooldownActive = function (log, cooldownUntil) {
1853
- return __awaiter(this, void 0, void 0, function () {
1854
- var reason;
1855
- return __generator(this, function (_a) {
1856
- switch (_a.label) {
1857
- case 0:
1858
- if (!(log === null || log === void 0 ? void 0 : log._id)) {
1859
- return [2 /*return*/];
1860
- }
1861
- reason = "Auto optimize cooldown is active until ".concat(cooldownUntil.toISOString(), ".");
1862
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: log._id }, {
1863
- $set: {
1864
- status: 'investigating',
1865
- auto_fix_status: 'failed',
1866
- auto_fix_disabled_reason: reason,
1867
- verification_notes: reason,
1868
- verification_status: 'pending',
1869
- verification_next_run_at: cooldownUntil,
1870
- last_triaged_by: 'auto-slow-query',
1871
- last_triaged_at: new Date()
1872
- }
1873
- })];
1874
- case 1:
1875
- _a.sent();
1876
- return [2 /*return*/];
1877
- }
1878
- });
1879
- });
1880
- };
1881
- SlowQueryVerifier.prototype.markAutoOptimizeTokenIneligible = function (log, reason) {
1882
- return __awaiter(this, void 0, void 0, function () {
1883
- var message, refreshed;
1884
- return __generator(this, function (_a) {
1885
- switch (_a.label) {
1886
- case 0:
1887
- if (!(log === null || log === void 0 ? void 0 : log._id)) {
1888
- return [2 /*return*/];
1889
- }
1890
- message = "Auto optimize blocked by AI credit preflight: ".concat(reason);
1891
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: log._id }, {
1892
- $set: {
1893
- status: 'ignored',
1894
- ignored: true,
1895
- auto_fix_status: 'failed',
1896
- auto_fix_disabled_reason: message,
1897
- verification_notes: message,
1898
- last_triaged_by: 'auto-slow-query',
1899
- last_triaged_at: new Date()
1900
- },
1901
- $unset: {
1902
- verification_next_run_at: ''
1903
- }
1904
- })];
1905
- case 1:
1906
- _a.sent();
1907
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: log._id })];
1908
- case 2:
1909
- refreshed = (_a.sent()) || log;
1910
- return [4 /*yield*/, this.sendSlowQueryEscalationNotice(refreshed, message)];
1911
- case 3:
1912
- _a.sent();
1913
- return [4 /*yield*/, this.notifyCustomerSlowQueryStatus('completed_failed', refreshed, { reason: message })];
1914
- case 4:
1915
- _a.sent();
1916
- return [2 /*return*/];
1917
- }
1918
- });
1919
- });
1920
- };
1921
- SlowQueryVerifier.prototype.markAutoOptimizeBudgetExceeded = function (log, reason) {
1922
- return __awaiter(this, void 0, void 0, function () {
1923
- var attemptsUsed, maxAttempts, attemptSummary, message, matchQuery, refreshed;
1924
- return __generator(this, function (_a) {
1925
- switch (_a.label) {
1926
- case 0:
1927
- if (!(log === null || log === void 0 ? void 0 : log._id)) {
1928
- return [2 /*return*/];
1929
- }
1930
- attemptsUsed = Number.isFinite(Number(log.auto_fix_attempt_count))
1931
- ? Number(log.auto_fix_attempt_count)
1932
- : 0;
1933
- maxAttempts = Number.isFinite(Number(this.config.autoOptimizeMaxAttemptsPerQuery))
1934
- ? Number(this.config.autoOptimizeMaxAttemptsPerQuery)
1935
- : 0;
1936
- attemptSummary = maxAttempts > 0
1937
- ? "Attempts on this log: ".concat(attemptsUsed, "/").concat(maxAttempts, ".")
1938
- : "Attempts on this log: ".concat(attemptsUsed, ".");
1939
- message = "".concat(reason, " Query marked ignored pending manual intervention. ").concat(attemptSummary);
1940
- matchQuery = this.buildFingerprintMatchQuery(log);
1941
- return [4 /*yield*/, SlowQueryLogs.updateMany(matchQuery, {
1942
- $set: {
1943
- status: 'ignored',
1944
- ignored: true,
1945
- auto_fix_status: 'failed',
1946
- auto_fix_disabled_reason: message,
1947
- verification_notes: message,
1948
- verification_status: 'failed',
1949
- last_triaged_by: 'auto-slow-query',
1950
- last_triaged_at: new Date()
1951
- },
1952
- $unset: {
1953
- verification_next_run_at: ''
1954
- }
1955
- })];
1956
- case 1:
1957
- _a.sent();
1958
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: log._id })];
1959
- case 2:
1960
- refreshed = (_a.sent()) || log;
1961
- return [4 /*yield*/, this.sendSlowQueryEscalationNotice(refreshed, reason)];
1962
- case 3:
1963
- _a.sent();
1964
- return [4 /*yield*/, this.notifyCustomerSlowQueryStatus('completed_failed', refreshed, { reason: reason })];
1965
- case 4:
1966
- _a.sent();
1967
- return [2 /*return*/];
1968
- }
1969
- });
1970
- });
1971
- };
1972
- SlowQueryVerifier.prototype.maybeStopAutoOptimizeAfterFailure = function (logId, reason) {
1973
- return __awaiter(this, void 0, void 0, function () {
1974
- var maxAttempts, latest, attemptsUsed;
1975
- return __generator(this, function (_a) {
1976
- switch (_a.label) {
1977
- case 0:
1978
- if (!logId) {
1979
- return [2 /*return*/];
1980
- }
1981
- maxAttempts = Number.isFinite(Number(this.config.autoOptimizeMaxAttemptsPerQuery))
1982
- ? Number(this.config.autoOptimizeMaxAttemptsPerQuery)
1983
- : 0;
1984
- if (maxAttempts <= 0) {
1985
- return [2 /*return*/];
1986
- }
1987
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
1988
- case 1:
1989
- latest = _a.sent();
1990
- if (!latest || latest.ignored) {
1991
- return [2 /*return*/];
1992
- }
1993
- attemptsUsed = Number.isFinite(Number(latest.auto_fix_attempt_count))
1994
- ? Number(latest.auto_fix_attempt_count)
1995
- : 0;
1996
- if (attemptsUsed < maxAttempts) {
1997
- return [2 /*return*/];
1998
- }
1999
- return [4 /*yield*/, this.markAutoOptimizeBudgetExceeded(latest, reason)];
2000
- case 2:
2001
- _a.sent();
2002
- return [2 /*return*/];
2003
- }
2004
- });
2005
- });
2006
- };
2007
- SlowQueryVerifier.prototype.shouldFallbackDashboardMethod = function (error) {
2008
- var message = "".concat((error === null || error === void 0 ? void 0 : error.message) || '').toLowerCase();
2009
- return message.includes('not found')
2010
- || message.includes('worker dispatch unavailable')
2011
- || message.includes('no worker')
2012
- || message.includes('unavailable for aidashboard');
2013
- };
2014
- SlowQueryVerifier.prototype.createDashboardJob = function (payload) {
2015
- return __awaiter(this, void 0, void 0, function () {
2016
- var methodManager, error_7, manager;
2017
- return __generator(this, function (_a) {
2018
- switch (_a.label) {
2019
- case 0:
2020
- methodManager = resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager();
2021
- _a.label = 1;
2022
- case 1:
2023
- _a.trys.push([1, 3, , 4]);
2024
- return [4 /*yield*/, methodManager.callMethod('aiDashboardCreateJob', payload)];
2025
- case 2: return [2 /*return*/, _a.sent()];
2026
- case 3:
2027
- error_7 = _a.sent();
2028
- if (!this.shouldFallbackDashboardMethod(error_7)) {
2029
- throw error_7;
2030
- }
2031
- return [3 /*break*/, 4];
2032
- case 4:
2033
- manager = resolveio_server_app_1.ResolveIOServer['AIDashboardManager'];
2034
- if (!(manager && manager.isEnabled && manager.isEnabled())) return [3 /*break*/, 6];
2035
- return [4 /*yield*/, manager.createJob(payload)];
2036
- case 5: return [2 /*return*/, _a.sent()];
2037
- case 6: throw new Error('AI Dashboard manager is not available.');
2038
- }
2039
- });
2040
- });
2041
- };
2042
- SlowQueryVerifier.prototype.waitForDashboardJobStop = function (jobId, timeoutMs) {
2043
- return __awaiter(this, void 0, void 0, function () {
2044
- var methodManager, error_8, manager;
2045
- return __generator(this, function (_a) {
2046
- switch (_a.label) {
2047
- case 0:
2048
- methodManager = resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager();
2049
- _a.label = 1;
2050
- case 1:
2051
- _a.trys.push([1, 3, , 4]);
2052
- return [4 /*yield*/, methodManager.callMethod('aiDashboardWaitForJobStop', jobId, timeoutMs)];
2053
- case 2:
2054
- _a.sent();
2055
- return [2 /*return*/];
2056
- case 3:
2057
- error_8 = _a.sent();
2058
- if (!this.shouldFallbackDashboardMethod(error_8)) {
2059
- throw error_8;
2060
- }
2061
- return [3 /*break*/, 4];
2062
- case 4:
2063
- manager = resolveio_server_app_1.ResolveIOServer['AIDashboardManager'];
2064
- if (!(manager && manager.isEnabled && manager.isEnabled())) return [3 /*break*/, 6];
2065
- return [4 /*yield*/, manager.waitForJobStop(jobId, timeoutMs)];
2066
- case 5:
2067
- _a.sent();
2068
- return [2 /*return*/];
2069
- case 6: throw new Error('AI Dashboard manager is not available.');
2070
- }
2071
- });
2072
- });
2073
- };
2074
- SlowQueryVerifier.prototype.isDashboardJobRunning = function (jobId) {
2075
- return __awaiter(this, void 0, void 0, function () {
2076
- var methodManager, running, error_9, manager;
2077
- return __generator(this, function (_a) {
2078
- switch (_a.label) {
2079
- case 0:
2080
- methodManager = resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager();
2081
- _a.label = 1;
2082
- case 1:
2083
- _a.trys.push([1, 3, , 4]);
2084
- return [4 /*yield*/, methodManager.callMethod('aiDashboardIsJobRunning', jobId)];
2085
- case 2:
2086
- running = _a.sent();
2087
- return [2 /*return*/, !!running];
2088
- case 3:
2089
- error_9 = _a.sent();
2090
- if (!this.shouldFallbackDashboardMethod(error_9)) {
2091
- throw error_9;
2092
- }
2093
- return [3 /*break*/, 4];
2094
- case 4:
2095
- manager = resolveio_server_app_1.ResolveIOServer['AIDashboardManager'];
2096
- if (manager && manager.isEnabled && manager.isEnabled()) {
2097
- return [2 /*return*/, !!manager.isJobRunning(jobId)];
2098
- }
2099
- throw new Error('AI Dashboard manager is not available.');
2100
- }
2101
- });
2102
- });
2103
- };
2104
- SlowQueryVerifier.prototype.publishDashboardJob = function (jobId) {
2105
- return __awaiter(this, void 0, void 0, function () {
2106
- var methodManager, error_10, manager;
2107
- return __generator(this, function (_a) {
2108
- switch (_a.label) {
2109
- case 0:
2110
- methodManager = resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager();
2111
- _a.label = 1;
2112
- case 1:
2113
- _a.trys.push([1, 3, , 4]);
2114
- return [4 /*yield*/, methodManager.callMethod('aiDashboardPublishJob', jobId)];
2115
- case 2: return [2 /*return*/, _a.sent()];
2116
- case 3:
2117
- error_10 = _a.sent();
2118
- if (!this.shouldFallbackDashboardMethod(error_10)) {
2119
- throw error_10;
2120
- }
2121
- return [3 /*break*/, 4];
2122
- case 4:
2123
- manager = resolveio_server_app_1.ResolveIOServer['AIDashboardManager'];
2124
- if (!(manager && manager.isEnabled && manager.isEnabled() && typeof manager.publishJob === 'function')) return [3 /*break*/, 6];
2125
- return [4 /*yield*/, manager.publishJob(jobId)];
2126
- case 5: return [2 /*return*/, _a.sent()];
2127
- case 6: throw new Error('AI Dashboard manager is not available.');
2128
- }
2129
- });
2130
- });
2131
- };
2132
- SlowQueryVerifier.prototype.evaluateDashboardPublishOutcome = function (job) {
2133
- var logEntries = Array.isArray(job === null || job === void 0 ? void 0 : job.log) ? job.log : [];
2134
- var lastMatch = function (predicate) {
2135
- for (var i = logEntries.length - 1; i >= 0; i -= 1) {
2136
- if (predicate(logEntries[i] || '')) {
2137
- return logEntries[i];
2138
- }
2139
- }
2140
- return '';
2141
- };
2142
- var failureEntry = lastMatch(function (entry) { return /publish failed|artifact publish failed|deploy failed/i.test(entry || ''); });
2143
- if (failureEntry) {
2144
- return { success: false, message: failureEntry };
2145
- }
2146
- var publishEntry = lastMatch(function (entry) { return /Published build to /i.test(entry || ''); });
2147
- if (publishEntry) {
2148
- var branchMatch = publishEntry.match(/\(([^()]+)\)\.?$/);
2149
- return {
2150
- success: true,
2151
- message: publishEntry,
2152
- branchName: (branchMatch && branchMatch[1]) ? branchMatch[1].trim() : undefined
2153
- };
2154
- }
2155
- var skippedEntry = lastMatch(function (entry) { return /Publish skipped/i.test(entry || ''); });
2156
- if (skippedEntry) {
2157
- return { success: false, message: skippedEntry };
2158
- }
2159
- return {
2160
- success: false,
2161
- message: 'Dashboard job completed without a publish confirmation log entry.'
2162
- };
2163
- };
2164
- SlowQueryVerifier.prototype.resolveBaselineDurationMs = function (log) {
2165
- var _a;
2166
- var runs = Array.isArray(log.verification_runs) ? log.verification_runs : [];
2167
- for (var i = runs.length - 1; i >= 0; i -= 1) {
2168
- var duration = (_a = runs[i]) === null || _a === void 0 ? void 0 : _a.duration_ms;
2169
- if (SlowQueryVerifier.isValidDuration(duration)) {
2170
- return duration;
2171
- }
2172
- }
2173
- if (SlowQueryVerifier.isValidDuration(log.duration_ms)) {
2174
- return log.duration_ms;
2175
- }
2176
- if (SlowQueryVerifier.isValidDuration(log.avg_duration_ms)) {
2177
- return log.avg_duration_ms;
2178
- }
2179
- return undefined;
2180
- };
2181
- SlowQueryVerifier.collectMetricValues = function (node, keySet, output) {
2182
- if (!node || typeof node !== 'object') {
2183
- return;
2184
- }
2185
- if (Array.isArray(node)) {
2186
- node.forEach(function (entry) { return SlowQueryVerifier.collectMetricValues(entry, keySet, output); });
2187
- return;
2188
- }
2189
- Object.keys(node).forEach(function (key) {
2190
- var value = node[key];
2191
- if (keySet.has(key) && typeof value === 'number' && Number.isFinite(value) && value >= 0) {
2192
- output.push(value);
2193
- }
2194
- SlowQueryVerifier.collectMetricValues(value, keySet, output);
2195
- });
2196
- };
2197
- SlowQueryVerifier.asNonNegativeNumber = function (value) {
2198
- return typeof value === 'number' && Number.isFinite(value) && value >= 0
2199
- ? value
2200
- : undefined;
2201
- };
2202
- SlowQueryVerifier.maxNumber = function (values) {
2203
- var candidates = values.filter(function (value) { return typeof value === 'number'; });
2204
- return candidates.length ? Math.max.apply(Math, __spreadArray([], __read(candidates), false)) : undefined;
2205
- };
2206
- SlowQueryVerifier.sortStageSummaries = function (input) {
2207
- return input.slice().sort(function (left, right) {
2208
- var _a, _b, _c, _d, _e, _f;
2209
- var timeDiff = ((_a = right.executionTimeMs) !== null && _a !== void 0 ? _a : -1) - ((_b = left.executionTimeMs) !== null && _b !== void 0 ? _b : -1);
2210
- if (timeDiff !== 0) {
2211
- return timeDiff;
2212
- }
2213
- var docsDiff = ((_c = right.docsExamined) !== null && _c !== void 0 ? _c : -1) - ((_d = left.docsExamined) !== null && _d !== void 0 ? _d : -1);
2214
- if (docsDiff !== 0) {
2215
- return docsDiff;
2216
- }
2217
- var keysDiff = ((_e = right.keysExamined) !== null && _e !== void 0 ? _e : -1) - ((_f = left.keysExamined) !== null && _f !== void 0 ? _f : -1);
2218
- if (keysDiff !== 0) {
2219
- return keysDiff;
2220
- }
2221
- return "".concat(left.path, "|").concat(left.stage).localeCompare("".concat(right.path, "|").concat(right.stage));
2222
- });
2223
- };
2224
- SlowQueryVerifier.collectExecutionTreeStages = function (node, path, output) {
2225
- if (!node || typeof node !== 'object') {
2226
- return;
2227
- }
2228
- var stageName = typeof node.stage === 'string' ? node.stage : 'execution-stage';
2229
- var executionTimeMs = SlowQueryVerifier.maxNumber([
2230
- SlowQueryVerifier.asNonNegativeNumber(node.executionTimeMillis),
2231
- SlowQueryVerifier.asNonNegativeNumber(node.executionTimeMillisEstimate)
2232
- ]);
2233
- var docsExamined = SlowQueryVerifier.maxNumber([
2234
- SlowQueryVerifier.asNonNegativeNumber(node.totalDocsExamined),
2235
- SlowQueryVerifier.asNonNegativeNumber(node.docsExamined)
2236
- ]);
2237
- var keysExamined = SlowQueryVerifier.maxNumber([
2238
- SlowQueryVerifier.asNonNegativeNumber(node.totalKeysExamined),
2239
- SlowQueryVerifier.asNonNegativeNumber(node.keysExamined)
2240
- ]);
2241
- var nReturned = SlowQueryVerifier.maxNumber([
2242
- SlowQueryVerifier.asNonNegativeNumber(node.nReturned)
2243
- ]);
2244
- if (typeof executionTimeMs === 'number'
2245
- || typeof docsExamined === 'number'
2246
- || typeof keysExamined === 'number'
2247
- || typeof nReturned === 'number') {
2248
- output.push({
2249
- stage: stageName,
2250
- path: path || 'executionStats.executionStages',
2251
- executionTimeMs: executionTimeMs,
2252
- docsExamined: docsExamined,
2253
- keysExamined: keysExamined,
2254
- nReturned: nReturned
2255
- });
2256
- }
2257
- var recurse = function (child, childPath) {
2258
- if (!child) {
2259
- return;
2260
- }
2261
- if (Array.isArray(child)) {
2262
- child.forEach(function (entry, index) {
2263
- SlowQueryVerifier.collectExecutionTreeStages(entry, "".concat(childPath, "[").concat(index, "]"), output);
2264
- });
2265
- return;
2266
- }
2267
- SlowQueryVerifier.collectExecutionTreeStages(child, childPath, output);
2268
- };
2269
- recurse(node.inputStage, "".concat(path, ".inputStage"));
2270
- recurse(node.inputStages, "".concat(path, ".inputStages"));
2271
- recurse(node.executionStages, "".concat(path, ".executionStages"));
2272
- recurse(node.outerStage, "".concat(path, ".outerStage"));
2273
- recurse(node.innerStage, "".concat(path, ".innerStage"));
2274
- recurse(node.leftChild, "".concat(path, ".leftChild"));
2275
- recurse(node.rightChild, "".concat(path, ".rightChild"));
2276
- recurse(node.thenStage, "".concat(path, ".thenStage"));
2277
- recurse(node.elseStage, "".concat(path, ".elseStage"));
2278
- recurse(node.shards, "".concat(path, ".shards"));
2279
- };
2280
- SlowQueryVerifier.extractStageSummaries = function (explainResponse, explainStats) {
2281
- var _a;
2282
- var summaries = [];
2283
- var stages = explainResponse === null || explainResponse === void 0 ? void 0 : explainResponse.stages;
2284
- if (Array.isArray(stages)) {
2285
- stages.forEach(function (stageEntry, index) {
2286
- var _a;
2287
- if (!stageEntry || typeof stageEntry !== 'object') {
2288
- return;
2289
- }
2290
- var stageKey = Object.keys(stageEntry).find(function (key) { return key.startsWith('$'); }) || "stage_".concat(index);
2291
- var stagePayload = stageEntry[stageKey];
2292
- var metricsSource = stageKey === '$cursor' && (stagePayload === null || stagePayload === void 0 ? void 0 : stagePayload.executionStats)
2293
- ? stagePayload.executionStats
2294
- : stagePayload;
2295
- var executionStages = (metricsSource === null || metricsSource === void 0 ? void 0 : metricsSource.executionStages) || ((_a = stagePayload === null || stagePayload === void 0 ? void 0 : stagePayload.executionStats) === null || _a === void 0 ? void 0 : _a.executionStages);
2296
- var executionTimeMs = SlowQueryVerifier.maxNumber([
2297
- SlowQueryVerifier.asNonNegativeNumber(metricsSource === null || metricsSource === void 0 ? void 0 : metricsSource.executionTimeMillis),
2298
- SlowQueryVerifier.asNonNegativeNumber(metricsSource === null || metricsSource === void 0 ? void 0 : metricsSource.executionTimeMillisEstimate),
2299
- SlowQueryVerifier.asNonNegativeNumber(executionStages === null || executionStages === void 0 ? void 0 : executionStages.executionTimeMillis),
2300
- SlowQueryVerifier.asNonNegativeNumber(executionStages === null || executionStages === void 0 ? void 0 : executionStages.executionTimeMillisEstimate)
2301
- ]);
2302
- var docsExamined = SlowQueryVerifier.maxNumber([
2303
- SlowQueryVerifier.asNonNegativeNumber(metricsSource === null || metricsSource === void 0 ? void 0 : metricsSource.totalDocsExamined),
2304
- SlowQueryVerifier.asNonNegativeNumber(metricsSource === null || metricsSource === void 0 ? void 0 : metricsSource.docsExamined),
2305
- SlowQueryVerifier.asNonNegativeNumber(executionStages === null || executionStages === void 0 ? void 0 : executionStages.totalDocsExamined),
2306
- SlowQueryVerifier.asNonNegativeNumber(executionStages === null || executionStages === void 0 ? void 0 : executionStages.docsExamined)
2307
- ]);
2308
- var keysExamined = SlowQueryVerifier.maxNumber([
2309
- SlowQueryVerifier.asNonNegativeNumber(metricsSource === null || metricsSource === void 0 ? void 0 : metricsSource.totalKeysExamined),
2310
- SlowQueryVerifier.asNonNegativeNumber(metricsSource === null || metricsSource === void 0 ? void 0 : metricsSource.keysExamined),
2311
- SlowQueryVerifier.asNonNegativeNumber(executionStages === null || executionStages === void 0 ? void 0 : executionStages.totalKeysExamined),
2312
- SlowQueryVerifier.asNonNegativeNumber(executionStages === null || executionStages === void 0 ? void 0 : executionStages.keysExamined)
2313
- ]);
2314
- var nReturned = SlowQueryVerifier.maxNumber([
2315
- SlowQueryVerifier.asNonNegativeNumber(metricsSource === null || metricsSource === void 0 ? void 0 : metricsSource.nReturned),
2316
- SlowQueryVerifier.asNonNegativeNumber(executionStages === null || executionStages === void 0 ? void 0 : executionStages.nReturned)
2317
- ]);
2318
- if (typeof executionTimeMs === 'number'
2319
- || typeof docsExamined === 'number'
2320
- || typeof keysExamined === 'number'
2321
- || typeof nReturned === 'number') {
2322
- summaries.push({
2323
- stage: stageKey,
2324
- path: "stages[".concat(index, "]"),
2325
- executionTimeMs: executionTimeMs,
2326
- docsExamined: docsExamined,
2327
- keysExamined: keysExamined,
2328
- nReturned: nReturned
2329
- });
2330
- }
2331
- if (executionStages) {
2332
- SlowQueryVerifier.collectExecutionTreeStages(executionStages, "stages[".concat(index, "].").concat(stageKey, ".executionStages"), summaries);
2333
- }
2334
- });
2335
- }
2336
- var executionRoot = (explainStats === null || explainStats === void 0 ? void 0 : explainStats.executionStages)
2337
- || ((_a = explainResponse === null || explainResponse === void 0 ? void 0 : explainResponse.executionStats) === null || _a === void 0 ? void 0 : _a.executionStages)
2338
- || (explainResponse === null || explainResponse === void 0 ? void 0 : explainResponse.executionStats);
2339
- if (executionRoot) {
2340
- SlowQueryVerifier.collectExecutionTreeStages(executionRoot, 'executionStats.executionStages', summaries);
2341
- }
2342
- var deduped = new Map();
2343
- summaries.forEach(function (summary) {
2344
- var key = [
2345
- summary.path,
2346
- summary.stage,
2347
- typeof summary.executionTimeMs === 'number' ? summary.executionTimeMs : '',
2348
- typeof summary.docsExamined === 'number' ? summary.docsExamined : '',
2349
- typeof summary.keysExamined === 'number' ? summary.keysExamined : '',
2350
- typeof summary.nReturned === 'number' ? summary.nReturned : ''
2351
- ].join('|');
2352
- if (!deduped.has(key)) {
2353
- deduped.set(key, summary);
2354
- }
2355
- });
2356
- return SlowQueryVerifier.sortStageSummaries(Array.from(deduped.values()));
2357
- };
2358
- SlowQueryVerifier.prototype.resolveExecutionMetrics = function (explainStats, fallbackDuration, stageSummaries) {
2359
- if (stageSummaries === void 0) { stageSummaries = []; }
2360
- var docsCandidates = [];
2361
- var returnedCandidates = [];
2362
- SlowQueryVerifier.collectMetricValues(explainStats || {}, new Set(['totalDocsExamined', 'docsExamined']), docsCandidates);
2363
- SlowQueryVerifier.collectMetricValues(explainStats || {}, new Set(['nReturned']), returnedCandidates);
2364
- var stageDocsCandidates = stageSummaries
2365
- .map(function (stage) { return stage.docsExamined; })
2366
- .filter(function (value) { return typeof value === 'number'; });
2367
- var stageReturnedCandidates = stageSummaries
2368
- .map(function (stage) { return stage.nReturned; })
2369
- .filter(function (value) { return typeof value === 'number'; });
2370
- var docsExamined = docsCandidates.length
2371
- ? Math.max.apply(Math, __spreadArray([], __read(docsCandidates), false)) : (stageDocsCandidates.length ? Math.max.apply(Math, __spreadArray([], __read(stageDocsCandidates), false)) : undefined);
2372
- var nReturned = returnedCandidates.length
2373
- ? Math.max.apply(Math, __spreadArray([], __read(returnedCandidates), false)) : (stageReturnedCandidates.length ? Math.max.apply(Math, __spreadArray([], __read(stageReturnedCandidates), false)) : undefined);
2374
- var durationMs = SlowQueryVerifier.isValidDuration(fallbackDuration)
2375
- ? fallbackDuration
2376
- : undefined;
2377
- return {
2378
- durationMs: durationMs,
2379
- docsExamined: docsExamined,
2380
- nReturned: nReturned,
2381
- topStages: stageSummaries.slice(0, 5)
2382
- };
2383
- };
2384
- SlowQueryVerifier.prototype.evaluateOptimizationOutcome = function (baseline, after, outputEquivalence) {
2385
- if (this.config.autoOptimizeRequireExactOutput) {
2386
- if (!this.config.autoOptimizeOutputCompareEnabled) {
2387
- return {
2388
- passed: false,
2389
- reason: 'Exact output equivalence is required but output comparison is disabled.',
2390
- outputEquivalence: outputEquivalence
2391
- };
2392
- }
2393
- if (!outputEquivalence) {
2394
- return {
2395
- passed: false,
2396
- reason: 'Output equivalence proof is required but was not generated.',
2397
- outputEquivalence: outputEquivalence
2398
- };
2399
- }
2400
- }
2401
- if (outputEquivalence && !outputEquivalence.passed) {
2402
- return {
2403
- passed: false,
2404
- reason: "Output equivalence failed: ".concat(outputEquivalence.reason),
2405
- outputEquivalence: outputEquivalence
2406
- };
2407
- }
2408
- if (!SlowQueryVerifier.isValidDuration(baseline.durationMs) || !SlowQueryVerifier.isValidDuration(after.durationMs)) {
2409
- return {
2410
- passed: false,
2411
- reason: 'Unable to compare baseline and post-fix duration.',
2412
- outputEquivalence: outputEquivalence
2413
- };
2414
- }
2415
- var durationRatio = baseline.durationMs > 0 ? (after.durationMs / baseline.durationMs) : 1;
2416
- if (durationRatio > this.config.autoOptimizeDurationRatioTarget) {
2417
- return {
2418
- passed: false,
2419
- reason: "Duration did not improve enough (".concat((0, common_1.round)(durationRatio * 100, 0), "% of baseline)."),
2420
- durationRatio: durationRatio,
2421
- outputEquivalence: outputEquivalence
2422
- };
2423
- }
2424
- if (typeof baseline.docsExamined !== 'number' || typeof after.docsExamined !== 'number' || baseline.docsExamined <= 0) {
2425
- return {
2426
- passed: false,
2427
- reason: 'Docs examined metrics are missing for baseline or post-fix explain.',
2428
- durationRatio: durationRatio,
2429
- outputEquivalence: outputEquivalence
2430
- };
2431
- }
2432
- var docsRatio = after.docsExamined / baseline.docsExamined;
2433
- if (docsRatio > this.config.autoOptimizeDocsRatioTarget) {
2434
- return {
2435
- passed: false,
2436
- reason: "Docs examined did not improve enough (".concat((0, common_1.round)(docsRatio * 100, 0), "% of baseline)."),
2437
- durationRatio: durationRatio,
2438
- docsRatio: docsRatio,
2439
- outputEquivalence: outputEquivalence
2440
- };
2441
- }
2442
- if (typeof baseline.nReturned === 'number' && typeof after.nReturned === 'number') {
2443
- var denominator = Math.max(baseline.nReturned, 1);
2444
- var nReturnedDeltaRatio = Math.abs(after.nReturned - baseline.nReturned) / denominator;
2445
- if (nReturnedDeltaRatio > this.config.autoOptimizeReturnedDocsTolerance) {
2446
- return {
2447
- passed: false,
2448
- reason: "Returned document count changed too much (".concat((0, common_1.round)(nReturnedDeltaRatio * 100, 0), "% delta)."),
2449
- durationRatio: durationRatio,
2450
- docsRatio: docsRatio,
2451
- nReturnedDeltaRatio: nReturnedDeltaRatio,
2452
- outputEquivalence: outputEquivalence
2453
- };
2454
- }
2455
- return {
2456
- passed: true,
2457
- reason: 'Query performance improved while keeping returned document count stable.',
2458
- durationRatio: durationRatio,
2459
- docsRatio: docsRatio,
2460
- nReturnedDeltaRatio: nReturnedDeltaRatio,
2461
- outputEquivalence: outputEquivalence
2462
- };
2463
- }
2464
- return {
2465
- passed: false,
2466
- reason: 'Returned document metrics are missing for baseline or post-fix explain.',
2467
- durationRatio: durationRatio,
2468
- docsRatio: docsRatio,
2469
- outputEquivalence: outputEquivalence
2470
- };
2471
- };
2472
- SlowQueryVerifier.prototype.formatStageSummaryForPrompt = function (stage, index) {
2473
- var metrics = [];
2474
- if (typeof stage.executionTimeMs === 'number') {
2475
- metrics.push("time=".concat(stage.executionTimeMs, "ms"));
2476
- }
2477
- if (typeof stage.docsExamined === 'number') {
2478
- metrics.push("docs=".concat(stage.docsExamined));
2479
- }
2480
- if (typeof stage.keysExamined === 'number') {
2481
- metrics.push("keys=".concat(stage.keysExamined));
2482
- }
2483
- if (typeof stage.nReturned === 'number') {
2484
- metrics.push("returned=".concat(stage.nReturned));
2485
- }
2486
- return "".concat(index + 1, ". ").concat(stage.stage, " @ ").concat(stage.path).concat(metrics.length ? " (".concat(metrics.join(', '), ")") : '');
2487
- };
2488
- SlowQueryVerifier.prototype.buildSlowQueryAutoOptimizeDescription = function (log, app, baseline, repoSlug) {
2489
- var _this = this;
2490
- var topStages = Array.isArray(baseline.topStages) ? baseline.topStages : [];
2491
- var lookupExprInCount = SlowQueryVerifier.countLookupExprInPattern(Array.isArray(log.pipeline) ? log.pipeline : []);
2492
- var lines = __spreadArray(__spreadArray([
2493
- 'Autonomous slow-query optimization request.',
2494
- '',
2495
- 'Hard requirements:',
2496
- '1. Before changing code, query the project MongoDB diagnostics logs for the latest slow-query context.',
2497
- '2. Query `slow-query-logs` using `_id` and `query_hash` from this task, then use the newest matching records.',
2498
- '3. If a previous dashboard job id is provided, query `ai-development-jobs` by that `_id` and review recent failure logs before retrying.',
2499
- '4. Treat `.dashboard-output/build-*.log` as primary build evidence, and `.build-output/build-*.log` as retained history when diagnosing failures.',
2500
- '5. Locate the source query in app code and optimize it safely (query shape contract must remain compatible).',
2501
- '6. Add or adjust indexes/code paths so docs examined and processing time drop significantly.',
2502
- '7. Measure before/after `explain(\"executionStats\")` and identify the slowest stages by execution time/docs examined.',
2503
- '8. Returned data must be exactly equivalent before and after optimization. Any output difference is a failed run.',
2504
- '9. In `$lookup`, avoid `$expr` + `$in` when equivalent `localField` / `foreignField` joins are possible and index-friendly.',
2505
- '10. Run build/lint checks and iterate until green.',
2506
- '11. Use workspace context `/var/ai-workspace/<id_slow_query>` and inspect transpiled runtime references under `/var/app/current`.',
2507
- '12. Publish to default branch and deploy artifacts automatically after build success.',
2508
- '',
2509
- "App: ".concat(app.name || app._id),
2510
- "Repo: ".concat(repoSlug || app.repo || 'unknown'),
2511
- "Slow Query #: ".concat(log.slow_query_count_string || log._id || ''),
2512
- "Workspace Context Id: ".concat(String((log === null || log === void 0 ? void 0 : log._id) || '').trim() || 'n/a'),
2513
- "Workspace Path: /var/ai-workspace/".concat(String((log === null || log === void 0 ? void 0 : log._id) || '').trim() || '<id_slow_query>'),
2514
- "Collection: ".concat(log.collection),
2515
- "Query Hash: ".concat(log.query_hash),
2516
- "Slow Query Log Id: ".concat(String((log === null || log === void 0 ? void 0 : log._id) || '').trim() || 'n/a'),
2517
- "Previous Dashboard Job Id: ".concat(String((log === null || log === void 0 ? void 0 : log.openai_task_id) || '').trim() || 'n/a'),
2518
- "Source App: ".concat(log.source_app || 'n/a'),
2519
- "Environment: ".concat(log.environment || 'n/a'),
2520
- "Baseline Duration (ms): ".concat(typeof baseline.durationMs === 'number' ? baseline.durationMs : 'unknown'),
2521
- "Baseline Docs Examined: ".concat(typeof baseline.docsExamined === 'number' ? baseline.docsExamined : 'unknown'),
2522
- "Baseline Returned Docs: ".concat(typeof baseline.nReturned === 'number' ? baseline.nReturned : 'unknown'),
2523
- "Detected $lookup with $expr+$in: ".concat(lookupExprInCount),
2524
- '',
2525
- 'Baseline Hot Stages:'
2526
- ], __read((topStages.length
2527
- ? topStages.map(function (stage, index) { return _this.formatStageSummaryForPrompt(stage, index); })
2528
- : ['No stage-level metrics were captured.'])), false), [
2529
- '',
2530
- 'Filter:',
2531
- '```json',
2532
- JSON.stringify(log.filter || {}, null, 2),
2533
- '```',
2534
- '',
2535
- 'Pipeline:',
2536
- '```json',
2537
- JSON.stringify(Array.isArray(log.pipeline) ? log.pipeline : [], null, 2),
2538
- '```',
2539
- '',
2540
- 'Options:',
2541
- '```json',
2542
- JSON.stringify(log.options || {}, null, 2),
2543
- '```'
2544
- ], false);
2545
- return lines.join('\n');
2546
- };
2547
- SlowQueryVerifier.prototype.resolveAutoOptimizeRepoSlug = function (app) {
2548
- var _a, _b;
2549
- var configuredRepo = String(((_a = this.config) === null || _a === void 0 ? void 0 : _a.autofixGithubRepo) || '').trim();
2550
- var configuredOwner = String(((_b = this.config) === null || _b === void 0 ? void 0 : _b.autofixGithubOwner) || 'resolveio').trim() || 'resolveio';
2551
- if (configuredRepo) {
2552
- return "".concat(configuredOwner, "/").concat(configuredRepo);
2553
- }
2554
- return String((app === null || app === void 0 ? void 0 : app.repo) || '').trim();
2555
- };
2556
- SlowQueryVerifier.prototype.resolveAutoOptimizeRepoPath = function (app) {
2557
- var _a;
2558
- var configuredPath = String(((_a = this.config) === null || _a === void 0 ? void 0 : _a.autofixRepoRoot) || '').trim();
2559
- if (configuredPath) {
2560
- return configuredPath;
2561
- }
2562
- return String((app === null || app === void 0 ? void 0 : app.git_local_path) || '').trim();
2563
- };
2564
- SlowQueryVerifier.queryHasExplicitSort = function (pipeline, findOptions) {
2565
- var hasFindSort = !!((findOptions === null || findOptions === void 0 ? void 0 : findOptions.sort) && typeof findOptions.sort === 'object' && Object.keys(findOptions.sort).length);
2566
- if (hasFindSort) {
2567
- return true;
2568
- }
2569
- if (!Array.isArray(pipeline)) {
2570
- return false;
2571
- }
2572
- return pipeline.some(function (stage) {
2573
- if (!stage || typeof stage !== 'object') {
2574
- return false;
2575
- }
2576
- var sort = stage.$sort;
2577
- return !!(sort && typeof sort === 'object' && Object.keys(sort).length);
2578
- });
2579
- };
2580
- SlowQueryVerifier.countLookupExprInPattern = function (pipeline) {
2581
- if (!Array.isArray(pipeline)) {
2582
- return 0;
2583
- }
2584
- var count = 0;
2585
- pipeline.forEach(function (stage) {
2586
- var lookup = stage && typeof stage === 'object' ? stage.$lookup : undefined;
2587
- if (!lookup || typeof lookup !== 'object' || !Array.isArray(lookup.pipeline)) {
2588
- return;
2589
- }
2590
- var lookupPipelineJson = JSON.stringify(lookup.pipeline);
2591
- if (lookupPipelineJson.includes('"$expr"') && lookupPipelineJson.includes('"$in"')) {
2592
- count += 1;
2593
- }
2594
- });
2595
- return count;
2596
- };
2597
- SlowQueryVerifier.buildBoundedPipelineForOutputCompare = function (pipeline, maxDocs) {
2598
- var cloned = SlowQueryVerifier.deepClone(pipeline);
2599
- if (!Number.isFinite(maxDocs) || maxDocs <= 0) {
2600
- return cloned;
2601
- }
2602
- cloned.push({
2603
- $limit: maxDocs + 1
2604
- });
2605
- return cloned;
2606
- };
2607
- SlowQueryVerifier.buildBoundedFindOptionsForOutputCompare = function (findOptions, maxDocs) {
2608
- var bounded = findOptions ? SlowQueryVerifier.deepClone(findOptions) : {};
2609
- if (!Number.isFinite(maxDocs) || maxDocs <= 0) {
2610
- return Object.keys(bounded).length ? bounded : undefined;
2611
- }
2612
- var compareLimit = maxDocs + 1;
2613
- if (typeof bounded.limit === 'number' && bounded.limit > 0) {
2614
- bounded.limit = Math.min(bounded.limit, compareLimit);
2615
- }
2616
- else {
2617
- bounded.limit = compareLimit;
2618
- }
2619
- return Object.keys(bounded).length ? bounded : undefined;
2620
- };
2621
- SlowQueryVerifier.normalizeOutputValue = function (value) {
2622
- if (value === null) {
2623
- return null;
2624
- }
2625
- if (typeof value === 'undefined') {
2626
- return null;
2627
- }
2628
- if (value instanceof Date) {
2629
- return { $date: value.toISOString() };
2630
- }
2631
- if (Buffer.isBuffer(value)) {
2632
- return { $binary: value.toString('base64') };
2633
- }
2634
- var valueType = typeof value;
2635
- if (valueType === 'string' || valueType === 'boolean') {
2636
- return value;
2637
- }
2638
- if (valueType === 'number') {
2639
- if (!Number.isFinite(value)) {
2640
- return '__non_finite_number__';
2641
- }
2642
- return value;
2643
- }
2644
- if (valueType === 'bigint') {
2645
- return value.toString();
2646
- }
2647
- if (valueType === 'function') {
2648
- return '__function__';
2649
- }
2650
- if (Array.isArray(value)) {
2651
- return value.map(function (entry) { return SlowQueryVerifier.normalizeOutputValue(entry); });
2652
- }
2653
- if (valueType === 'object') {
2654
- if (typeof value.toHexString === 'function') {
2655
- try {
2656
- return { $oid: value.toHexString() };
2657
- }
2658
- catch (_a) {
2659
- // continue into generic object handling
2660
- }
2661
- }
2662
- if (typeof value.toJSON === 'function') {
2663
- try {
2664
- return SlowQueryVerifier.normalizeOutputValue(value.toJSON());
2665
- }
2666
- catch (_b) {
2667
- // continue into generic object handling
2668
- }
2669
- }
2670
- var normalized_1 = {};
2671
- Object.keys(value).sort().forEach(function (key) {
2672
- normalized_1[key] = SlowQueryVerifier.normalizeOutputValue(value[key]);
2673
- });
2674
- return normalized_1;
2675
- }
2676
- return "".concat(value);
2677
- };
2678
- SlowQueryVerifier.digestOutputDocument = function (doc) {
2679
- var normalized = SlowQueryVerifier.normalizeOutputValue(doc);
2680
- var serialized = JSON.stringify(normalized);
2681
- return (0, crypto_1.createHash)('sha256').update(serialized, 'utf8').digest('hex');
2682
- };
2683
- SlowQueryVerifier.prototype.captureOutputFingerprint = function (log, overrides) {
2684
- return __awaiter(this, void 0, void 0, function () {
2685
- var collectionName, target, client, db, maxDocs, effectiveMaxDocs, effectiveLog, pipeline, filter, findOptions, aggregateOptions, explicitSort, cursor, boundedPipeline, boundedFindOptions, orderedHasher, unorderedSum, unorderedXor, docsCompared, truncated, firstDocDigest, lastDocDigest, startedAt, _a, cursor_1, cursor_1_1, doc, docDigest, head, tail, e_5_1, durationMs;
2686
- var _b, e_5, _c, _d;
2687
- var _e;
2688
- return __generator(this, function (_f) {
2689
- switch (_f.label) {
2690
- case 0:
2691
- collectionName = log.collection;
2692
- if (!collectionName) {
2693
- throw new Error('Slow query missing collection name.');
2694
- }
2695
- return [4 /*yield*/, this.resolveExplainTarget(log)];
2696
- case 1:
2697
- target = _f.sent();
2698
- _f.label = 2;
2699
- case 2:
2700
- _f.trys.push([2, , 23, 26]);
2701
- if (!(target.type === 'client')) return [3 /*break*/, 4];
2702
- if (!target.uri) {
2703
- throw new SlowQueryVerifierError('client_db_missing_uri', 'Client DB missing uri.');
2704
- }
2705
- return [4 /*yield*/, mongodb_1.MongoClient.connect(target.uri, {
2706
- connectTimeoutMS: 10000,
2707
- serverSelectionTimeoutMS: 10000,
2708
- readPreference: 'secondaryPreferred'
2709
- })];
2710
- case 3:
2711
- client = _f.sent();
2712
- db = client.db(target.dbName);
2713
- return [3 /*break*/, 5];
2714
- case 4:
2715
- db = resolveio_server_app_1.ResolveIOServer.getMainDB();
2716
- _f.label = 5;
2717
- case 5:
2718
- if (!db) {
2719
- throw new SlowQueryVerifierError('main_db_unavailable', 'Main server DB is not available.');
2720
- }
2721
- maxDocs = Number.isFinite(Number(this.config.autoOptimizeOutputCompareMaxDocs))
2722
- ? Number(this.config.autoOptimizeOutputCompareMaxDocs)
2723
- : AUTO_OPTIMIZE_DEFAULT_OUTPUT_COMPARE_MAX_DOCS;
2724
- effectiveMaxDocs = maxDocs > 0 ? Math.floor(maxDocs) : AUTO_OPTIMIZE_DEFAULT_OUTPUT_COMPARE_MAX_DOCS;
2725
- effectiveLog = SlowQueryVerifier.applyQueryOverrides(log, overrides);
2726
- pipeline = SlowQueryVerifier.extractPipelineFromLog(effectiveLog);
2727
- filter = (_e = effectiveLog.filter) !== null && _e !== void 0 ? _e : {};
2728
- findOptions = SlowQueryVerifier.extractFindOptions(effectiveLog.options);
2729
- aggregateOptions = SlowQueryVerifier.extractAggregateOptions(effectiveLog.options);
2730
- explicitSort = SlowQueryVerifier.queryHasExplicitSort(pipeline, findOptions);
2731
- cursor = void 0;
2732
- if (pipeline) {
2733
- if (SlowQueryVerifier.pipelineHasWriteStage(pipeline)) {
2734
- throw new SlowQueryVerifierError('aggregate_write_stage', 'Aggregate pipeline includes a write stage; output comparison skipped.');
2735
- }
2736
- boundedPipeline = SlowQueryVerifier.buildBoundedPipelineForOutputCompare(pipeline, effectiveMaxDocs);
2737
- cursor = db.collection(collectionName)
2738
- .aggregate(boundedPipeline, __assign(__assign({}, (aggregateOptions || {})), { readPreference: 'secondaryPreferred' }));
2739
- }
2740
- else {
2741
- boundedFindOptions = SlowQueryVerifier.buildBoundedFindOptionsForOutputCompare(findOptions, effectiveMaxDocs);
2742
- cursor = SlowQueryVerifier.buildFindCursor(db.collection(collectionName), filter, boundedFindOptions);
2743
- }
2744
- orderedHasher = (0, crypto_1.createHash)('sha256');
2745
- unorderedSum = 0;
2746
- unorderedXor = 0;
2747
- docsCompared = 0;
2748
- truncated = false;
2749
- firstDocDigest = '';
2750
- lastDocDigest = '';
2751
- startedAt = Date.now();
2752
- _f.label = 6;
2753
- case 6:
2754
- _f.trys.push([6, , 19, 22]);
2755
- _f.label = 7;
2756
- case 7:
2757
- _f.trys.push([7, 12, 13, 18]);
2758
- _a = true, cursor_1 = __asyncValues(cursor);
2759
- _f.label = 8;
2760
- case 8: return [4 /*yield*/, cursor_1.next()];
2761
- case 9:
2762
- if (!(cursor_1_1 = _f.sent(), _b = cursor_1_1.done, !_b)) return [3 /*break*/, 11];
2763
- _d = cursor_1_1.value;
2764
- _a = false;
2765
- doc = _d;
2766
- if (docsCompared >= effectiveMaxDocs) {
2767
- truncated = true;
2768
- return [3 /*break*/, 11];
2769
- }
2770
- docDigest = SlowQueryVerifier.digestOutputDocument(doc);
2771
- if (!firstDocDigest) {
2772
- firstDocDigest = docDigest;
2773
- }
2774
- lastDocDigest = docDigest;
2775
- orderedHasher.update(docDigest, 'utf8');
2776
- head = (parseInt(docDigest.slice(0, 8), 16) ^ parseInt(docDigest.slice(8, 16), 16)) >>> 0;
2777
- tail = (parseInt(docDigest.slice(16, 24), 16) ^ parseInt(docDigest.slice(24, 32), 16)) >>> 0;
2778
- unorderedSum = (unorderedSum + head + tail) >>> 0;
2779
- unorderedXor = (unorderedXor ^ head ^ tail) >>> 0;
2780
- docsCompared += 1;
2781
- _f.label = 10;
2782
- case 10:
2783
- _a = true;
2784
- return [3 /*break*/, 8];
2785
- case 11: return [3 /*break*/, 18];
2786
- case 12:
2787
- e_5_1 = _f.sent();
2788
- e_5 = { error: e_5_1 };
2789
- return [3 /*break*/, 18];
2790
- case 13:
2791
- _f.trys.push([13, , 16, 17]);
2792
- if (!(!_a && !_b && (_c = cursor_1.return))) return [3 /*break*/, 15];
2793
- return [4 /*yield*/, _c.call(cursor_1)];
2794
- case 14:
2795
- _f.sent();
2796
- _f.label = 15;
2797
- case 15: return [3 /*break*/, 17];
2798
- case 16:
2799
- if (e_5) throw e_5.error;
2800
- return [7 /*endfinally*/];
2801
- case 17: return [7 /*endfinally*/];
2802
- case 18: return [3 /*break*/, 22];
2803
- case 19:
2804
- if (!(cursor && typeof cursor.close === 'function')) return [3 /*break*/, 21];
2805
- return [4 /*yield*/, cursor.close()];
2806
- case 20:
2807
- _f.sent();
2808
- _f.label = 21;
2809
- case 21: return [7 /*endfinally*/];
2810
- case 22:
2811
- durationMs = Date.now() - startedAt;
2812
- return [2 /*return*/, {
2813
- explicitSort: explicitSort,
2814
- docsCompared: docsCompared,
2815
- truncated: truncated,
2816
- orderedDigest: orderedHasher.digest('hex'),
2817
- unorderedDigest: "".concat(unorderedSum.toString(16).padStart(8, '0'), ":").concat(unorderedXor.toString(16).padStart(8, '0')),
2818
- firstDocDigest: firstDocDigest,
2819
- lastDocDigest: lastDocDigest,
2820
- durationMs: SlowQueryVerifier.isValidDuration(durationMs) ? durationMs : -1,
2821
- maxDocs: effectiveMaxDocs
2822
- }];
2823
- case 23:
2824
- if (!client) return [3 /*break*/, 25];
2825
- return [4 /*yield*/, client.close()];
2826
- case 24:
2827
- _f.sent();
2828
- _f.label = 25;
2829
- case 25: return [7 /*endfinally*/];
2830
- case 26: return [2 /*return*/];
2831
- }
2832
- });
2833
- });
2834
- };
2835
- SlowQueryVerifier.prototype.compareOutputEquivalence = function (baseline, after) {
2836
- var mode = (baseline.explicitSort || after.explicitSort)
2837
- ? 'ordered'
2838
- : 'unordered';
2839
- if (baseline.truncated || after.truncated) {
2840
- return {
2841
- passed: false,
2842
- reason: "Result set exceeded output comparison cap (".concat(Math.max(baseline.maxDocs, after.maxDocs), " docs)."),
2843
- mode: mode,
2844
- baseline: baseline,
2845
- after: after
2846
- };
2847
- }
2848
- if (baseline.docsCompared !== after.docsCompared) {
2849
- return {
2850
- passed: false,
2851
- reason: "Returned row count changed (".concat(baseline.docsCompared, " -> ").concat(after.docsCompared, ")."),
2852
- mode: mode,
2853
- baseline: baseline,
2854
- after: after
2855
- };
2856
- }
2857
- if (mode === 'ordered') {
2858
- if (baseline.orderedDigest !== after.orderedDigest) {
2859
- return {
2860
- passed: false,
2861
- reason: 'Ordered output digest changed.',
2862
- mode: mode,
2863
- baseline: baseline,
2864
- after: after
2865
- };
2866
- }
2867
- }
2868
- else if (baseline.unorderedDigest !== after.unorderedDigest) {
2869
- return {
2870
- passed: false,
2871
- reason: 'Output set digest changed.',
2872
- mode: mode,
2873
- baseline: baseline,
2874
- after: after
2875
- };
2876
- }
2877
- return {
2878
- passed: true,
2879
- reason: 'Output fingerprints are equivalent.',
2880
- mode: mode,
2881
- baseline: baseline,
2882
- after: after
2883
- };
2884
- };
2885
- SlowQueryVerifier.prototype.resolveAutoOptimizeApp = function (log) {
2886
- return __awaiter(this, void 0, void 0, function () {
2887
- var exactRepoCandidate, escaped, byRepo, clientCandidates, clientCandidates_1, clientCandidates_1_1, candidate, escaped, byApp, clientDoc, byClient, e_6_1;
2888
- var e_6, _a;
2889
- return __generator(this, function (_b) {
2890
- switch (_b.label) {
2891
- case 0:
2892
- exactRepoCandidate = String(log.environment || '').trim();
2893
- if (!(exactRepoCandidate && exactRepoCandidate.includes('/'))) return [3 /*break*/, 2];
2894
- escaped = this.escapeRegex(exactRepoCandidate);
2895
- return [4 /*yield*/, AICoderApps.findOne({
2896
- repo: { $regex: "^".concat(escaped, "$"), $options: 'i' }
2897
- }, {
2898
- sort: {
2899
- updatedAt: -1,
2900
- createdAt: -1
2901
- }
2902
- })];
2903
- case 1:
2904
- byRepo = _b.sent();
2905
- if (byRepo) {
2906
- return [2 /*return*/, byRepo];
2907
- }
2908
- _b.label = 2;
2909
- case 2:
2910
- clientCandidates = [
2911
- String(log.client_slug || '').trim(),
2912
- String(log.client_name || '').trim(),
2913
- String(log.source_app || '').trim()
2914
- ].filter(Boolean);
2915
- _b.label = 3;
2916
- case 3:
2917
- _b.trys.push([3, 10, 11, 12]);
2918
- clientCandidates_1 = __values(clientCandidates), clientCandidates_1_1 = clientCandidates_1.next();
2919
- _b.label = 4;
2920
- case 4:
2921
- if (!!clientCandidates_1_1.done) return [3 /*break*/, 9];
2922
- candidate = clientCandidates_1_1.value;
2923
- escaped = this.escapeRegex(candidate);
2924
- return [4 /*yield*/, AICoderApps.findOne({
2925
- $or: [
2926
- { slug: { $regex: "^".concat(escaped, "$"), $options: 'i' } },
2927
- { name: { $regex: "^".concat(escaped, "$"), $options: 'i' } }
2928
- ]
2929
- }, {
2930
- sort: {
2931
- updatedAt: -1,
2932
- createdAt: -1
2933
- }
2934
- })];
2935
- case 5:
2936
- byApp = _b.sent();
2937
- if (byApp) {
2938
- return [2 /*return*/, byApp];
2939
- }
2940
- return [4 /*yield*/, Clients.findOne({
2941
- $or: [
2942
- { name: { $regex: "^".concat(escaped, "$"), $options: 'i' } },
2943
- { demo_name: { $regex: "^".concat(escaped, "$"), $options: 'i' } },
2944
- { project: { $regex: "^".concat(escaped, "$"), $options: 'i' } },
2945
- { repo: { $regex: "^".concat(escaped, "$"), $options: 'i' } }
2946
- ]
2947
- })];
2948
- case 6:
2949
- clientDoc = _b.sent();
2950
- if (!(clientDoc === null || clientDoc === void 0 ? void 0 : clientDoc._id)) {
2951
- return [3 /*break*/, 8];
2952
- }
2953
- return [4 /*yield*/, AICoderApps.findOne({ client_id: clientDoc._id }, {
2954
- sort: {
2955
- updatedAt: -1,
2956
- createdAt: -1
2957
- }
2958
- })];
2959
- case 7:
2960
- byClient = _b.sent();
2961
- if (byClient) {
2962
- return [2 /*return*/, byClient];
2963
- }
2964
- _b.label = 8;
2965
- case 8:
2966
- clientCandidates_1_1 = clientCandidates_1.next();
2967
- return [3 /*break*/, 4];
2968
- case 9: return [3 /*break*/, 12];
2969
- case 10:
2970
- e_6_1 = _b.sent();
2971
- e_6 = { error: e_6_1 };
2972
- return [3 /*break*/, 12];
2973
- case 11:
2974
- try {
2975
- if (clientCandidates_1_1 && !clientCandidates_1_1.done && (_a = clientCandidates_1.return)) _a.call(clientCandidates_1);
2976
- }
2977
- finally { if (e_6) throw e_6.error; }
2978
- return [7 /*endfinally*/];
2979
- case 12: return [2 /*return*/, null];
2980
- }
2981
- });
2982
- });
2983
- };
2984
- SlowQueryVerifier.prototype.runAutoOptimization = function (logId_1) {
2985
- return __awaiter(this, arguments, void 0, function (logId, force) {
2986
- var autoOptimizeEnabled, log, attemptsUsed, maxAttempts, cooldownDeadline, fingerprintMaxAttempts, windowHours, windowStart, fingerprintAttempts, app, resolvedRepoSlug, resolvedRepoPath, tokenEligibility, reason, baselineExplain, error_11, baselineFallbackDuration, baselineDurationMs, baselineMetrics, baselineOutputFingerprint, error_12, title, description, job, error_13, jobId, attemptStartedAt, queuedLog, error_14, isRunning, error_15, finalJob, publishOutcome, refreshedLog, afterExplain, error_16, afterMetrics, outputEquivalence, afterOutputFingerprint, error_17, validation, autoFixResult, optimizedLog;
2987
- if (force === void 0) { force = false; }
2988
- return __generator(this, function (_a) {
2989
- switch (_a.label) {
2990
- case 0: return [4 /*yield*/, this.resolveAutoOptimizeEnabled()];
2991
- case 1:
2992
- autoOptimizeEnabled = _a.sent();
2993
- if (!logId || (!autoOptimizeEnabled && !force)) {
2994
- return [2 /*return*/];
2995
- }
2996
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
2997
- case 2:
2998
- log = _a.sent();
2999
- if (!log || !log._id || log.ignored) {
3000
- return [2 /*return*/];
3001
- }
3002
- if (log.status === 'optimized' && !force) {
3003
- return [2 /*return*/];
3004
- }
3005
- if (log.auto_fix_status === 'running') {
3006
- return [2 /*return*/];
3007
- }
3008
- if (log.auto_fix_status === 'queued' && String(log.openai_task_id || '').trim()) {
3009
- return [2 /*return*/];
3010
- }
3011
- if (!!force) return [3 /*break*/, 9];
3012
- attemptsUsed = Number.isFinite(Number(log.auto_fix_attempt_count))
3013
- ? Number(log.auto_fix_attempt_count)
3014
- : 0;
3015
- maxAttempts = Number.isFinite(Number(this.config.autoOptimizeMaxAttemptsPerQuery))
3016
- ? Number(this.config.autoOptimizeMaxAttemptsPerQuery)
3017
- : 0;
3018
- if (!(maxAttempts > 0 && attemptsUsed >= maxAttempts)) return [3 /*break*/, 4];
3019
- return [4 /*yield*/, this.markAutoOptimizeBudgetExceeded(log, 'Auto optimize skipped')];
3020
- case 3:
3021
- _a.sent();
3022
- return [2 /*return*/];
3023
- case 4:
3024
- cooldownDeadline = this.resolveCooldownDeadline(log);
3025
- if (!(cooldownDeadline && cooldownDeadline.getTime() > Date.now())) return [3 /*break*/, 6];
3026
- return [4 /*yield*/, this.markAutoOptimizeCooldownActive(log, cooldownDeadline)];
3027
- case 5:
3028
- _a.sent();
3029
- return [2 /*return*/];
3030
- case 6:
3031
- fingerprintMaxAttempts = Number.isFinite(Number(this.config.autoOptimizeMaxAttemptsPerFingerprint))
3032
- ? Number(this.config.autoOptimizeMaxAttemptsPerFingerprint)
3033
- : 0;
3034
- if (!(fingerprintMaxAttempts > 0)) return [3 /*break*/, 9];
3035
- windowHours = Number.isFinite(Number(this.config.autoOptimizeFingerprintWindowHours))
3036
- ? Number(this.config.autoOptimizeFingerprintWindowHours)
3037
- : AUTO_OPTIMIZE_DEFAULT_FINGERPRINT_WINDOW_HOURS;
3038
- windowStart = new Date(Date.now() - (windowHours * 60 * 60 * 1000));
3039
- return [4 /*yield*/, this.resolveFingerprintAttemptsInWindow(log, windowStart)];
3040
- case 7:
3041
- fingerprintAttempts = _a.sent();
3042
- if (!(fingerprintAttempts >= fingerprintMaxAttempts)) return [3 /*break*/, 9];
3043
- return [4 /*yield*/, this.markAutoOptimizeBudgetExceeded(log, "Auto optimize skipped: fingerprint budget reached (".concat(fingerprintAttempts, "/").concat(fingerprintMaxAttempts, ") in the last ").concat(windowHours, "h."))];
3044
- case 8:
3045
- _a.sent();
3046
- return [2 /*return*/];
3047
- case 9: return [4 /*yield*/, this.resolveAutoOptimizeApp(log)];
3048
- case 10:
3049
- app = _a.sent();
3050
- resolvedRepoSlug = this.resolveAutoOptimizeRepoSlug(app);
3051
- resolvedRepoPath = this.resolveAutoOptimizeRepoPath(app);
3052
- if (!(!(app === null || app === void 0 ? void 0 : app._id) || !resolvedRepoSlug)) return [3 /*break*/, 12];
3053
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3054
- $set: {
3055
- status: 'investigating',
3056
- auto_fix_status: 'failed',
3057
- verification_notes: 'Auto optimize skipped: unable to map slow query to AI Coder app/repo configuration.',
3058
- last_triaged_by: 'auto-slow-query',
3059
- last_triaged_at: new Date()
3060
- }
3061
- })];
3062
- case 11:
3063
- _a.sent();
3064
- return [2 /*return*/];
3065
- case 12: return [4 /*yield*/, checkAICoderTokenEligibility(app._id, this.config.autoOptimizeRequiredTokens > 0 ? this.config.autoOptimizeRequiredTokens : undefined)];
3066
- case 13:
3067
- tokenEligibility = _a.sent();
3068
- if (!!tokenEligibility.allowed) return [3 /*break*/, 15];
3069
- reason = "".concat(tokenEligibility.message, " Available: ").concat(tokenEligibility.summary.available_tokens.toLocaleString(), " tokens; required: ").concat(tokenEligibility.required_tokens.toLocaleString(), ".");
3070
- return [4 /*yield*/, this.markAutoOptimizeTokenIneligible(log, reason)];
3071
- case 14:
3072
- _a.sent();
3073
- return [2 /*return*/];
3074
- case 15:
3075
- _a.trys.push([15, 17, , 20]);
3076
- return [4 /*yield*/, this.runExplain(log)];
3077
- case 16:
3078
- baselineExplain = _a.sent();
3079
- return [3 /*break*/, 20];
3080
- case 17:
3081
- error_11 = _a.sent();
3082
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3083
- $set: {
3084
- status: 'investigating',
3085
- auto_fix_status: 'failed',
3086
- auto_fix_result: {
3087
- baseline_error: (error_11 === null || error_11 === void 0 ? void 0 : error_11.message) || 'unknown'
3088
- },
3089
- verification_notes: "Auto optimize baseline measurement failed: ".concat((error_11 === null || error_11 === void 0 ? void 0 : error_11.message) || 'unknown error'),
3090
- last_triaged_by: 'auto-slow-query',
3091
- last_triaged_at: new Date()
3092
- }
3093
- })];
3094
- case 18:
3095
- _a.sent();
3096
- return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize baseline measurement failed')];
3097
- case 19:
3098
- _a.sent();
3099
- return [2 /*return*/];
3100
- case 20:
3101
- baselineFallbackDuration = this.resolveBaselineDurationMs(log);
3102
- baselineDurationMs = SlowQueryVerifier.isValidDuration(baselineExplain.durationMs)
3103
- ? baselineExplain.durationMs
3104
- : baselineFallbackDuration;
3105
- baselineMetrics = this.resolveExecutionMetrics(baselineExplain.explainStats || {}, baselineDurationMs, baselineExplain.stageSummaries || []);
3106
- if (!this.config.autoOptimizeOutputCompareEnabled) return [3 /*break*/, 26];
3107
- _a.label = 21;
3108
- case 21:
3109
- _a.trys.push([21, 23, , 26]);
3110
- return [4 /*yield*/, this.captureOutputFingerprint(log)];
3111
- case 22:
3112
- baselineOutputFingerprint = _a.sent();
3113
- return [3 /*break*/, 26];
3114
- case 23:
3115
- error_12 = _a.sent();
3116
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3117
- $set: {
3118
- status: 'investigating',
3119
- auto_fix_status: 'failed',
3120
- auto_fix_result: {
3121
- baseline_error: (error_12 === null || error_12 === void 0 ? void 0 : error_12.message) || 'unknown'
3122
- },
3123
- verification_notes: "Auto optimize baseline output comparison failed: ".concat((error_12 === null || error_12 === void 0 ? void 0 : error_12.message) || 'unknown error'),
3124
- last_triaged_by: 'auto-slow-query',
3125
- last_triaged_at: new Date()
3126
- }
3127
- })];
3128
- case 24:
3129
- _a.sent();
3130
- return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize baseline output comparison failed')];
3131
- case 25:
3132
- _a.sent();
3133
- return [2 /*return*/];
3134
- case 26:
3135
- title = "Optimize slow query ".concat(log.slow_query_count_string || log.collection);
3136
- description = this.buildSlowQueryAutoOptimizeDescription(log, app, baselineMetrics, resolvedRepoSlug);
3137
- _a.label = 27;
3138
- case 27:
3139
- _a.trys.push([27, 29, , 32]);
3140
- return [4 /*yield*/, this.createDashboardJob({
3141
- project: app._id,
3142
- title: title,
3143
- description: description,
3144
- repo: resolvedRepoSlug,
3145
- path: resolvedRepoPath || undefined,
3146
- projectRoot: app.project_root || undefined
3147
- })];
3148
- case 28:
3149
- job = _a.sent();
3150
- return [3 /*break*/, 32];
3151
- case 29:
3152
- error_13 = _a.sent();
3153
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3154
- $set: {
3155
- status: 'investigating',
3156
- auto_fix_status: 'failed',
3157
- verification_notes: "Auto optimize enqueue failed: ".concat((error_13 === null || error_13 === void 0 ? void 0 : error_13.message) || 'unknown error'),
3158
- last_triaged_by: 'auto-slow-query',
3159
- last_triaged_at: new Date()
3160
- }
3161
- })];
3162
- case 30:
3163
- _a.sent();
3164
- return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize wait failed')];
3165
- case 31:
3166
- _a.sent();
3167
- return [2 /*return*/];
3168
- case 32:
3169
- jobId = String((job === null || job === void 0 ? void 0 : job._id) || '').trim();
3170
- if (!!jobId) return [3 /*break*/, 34];
3171
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3172
- $set: {
3173
- status: 'investigating',
3174
- auto_fix_status: 'failed',
3175
- verification_notes: 'Auto optimize enqueue failed: dashboard job id missing.',
3176
- last_triaged_by: 'auto-slow-query',
3177
- last_triaged_at: new Date()
3178
- }
3179
- })];
3180
- case 33:
3181
- _a.sent();
3182
- return [2 /*return*/];
3183
- case 34:
3184
- attemptStartedAt = new Date();
3185
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3186
- $inc: {
3187
- auto_fix_attempt_count: 1
3188
- },
3189
- $push: {
3190
- auto_fix_attempt_history: {
3191
- $each: [attemptStartedAt],
3192
- $slice: -100
3193
- }
3194
- },
3195
- $set: {
3196
- status: 'queued',
3197
- auto_fix_status: 'running',
3198
- openai_task_id: jobId,
3199
- auto_fix_last_attempt_at: attemptStartedAt,
3200
- auto_fix_disabled_reason: '',
3201
- verification_notes: "Auto optimize job queued (".concat(jobId, ")."),
3202
- last_triaged_by: 'auto-slow-query',
3203
- last_triaged_at: new Date()
3204
- }
3205
- })];
3206
- case 35:
3207
- _a.sent();
3208
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
3209
- case 36:
3210
- queuedLog = (_a.sent()) || log;
3211
- return [4 /*yield*/, this.notifyCustomerSlowQueryStatus('detected_auto_optimize_enabled', queuedLog)];
3212
- case 37:
3213
- _a.sent();
3214
- _a.label = 38;
3215
- case 38:
3216
- _a.trys.push([38, 40, , 43]);
3217
- return [4 /*yield*/, this.waitForDashboardJobStop(jobId, this.config.autoOptimizeWaitTimeoutMs)];
3218
- case 39:
3219
- _a.sent();
3220
- return [3 /*break*/, 43];
3221
- case 40:
3222
- error_14 = _a.sent();
3223
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3224
- $set: {
3225
- status: 'investigating',
3226
- auto_fix_status: 'failed',
3227
- auto_fix_result: {
3228
- job_id: jobId,
3229
- error: (error_14 === null || error_14 === void 0 ? void 0 : error_14.message) || 'timeout'
3230
- },
3231
- verification_notes: "Auto optimize wait failed: ".concat((error_14 === null || error_14 === void 0 ? void 0 : error_14.message) || 'timeout'),
3232
- last_triaged_by: 'auto-slow-query',
3233
- last_triaged_at: new Date()
3234
- }
3235
- })];
3236
- case 41:
3237
- _a.sent();
3238
- return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize job state check failed')];
3239
- case 42:
3240
- _a.sent();
3241
- return [2 /*return*/];
3242
- case 43:
3243
- isRunning = false;
3244
- _a.label = 44;
3245
- case 44:
3246
- _a.trys.push([44, 46, , 48]);
3247
- return [4 /*yield*/, this.isDashboardJobRunning(jobId)];
3248
- case 45:
3249
- isRunning = _a.sent();
3250
- return [3 /*break*/, 48];
3251
- case 46:
3252
- error_15 = _a.sent();
3253
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3254
- $set: {
3255
- status: 'investigating',
3256
- auto_fix_status: 'failed',
3257
- auto_fix_result: {
3258
- job_id: jobId,
3259
- error: (error_15 === null || error_15 === void 0 ? void 0 : error_15.message) || 'unknown'
3260
- },
3261
- verification_notes: "Unable to confirm dashboard job state: ".concat((error_15 === null || error_15 === void 0 ? void 0 : error_15.message) || 'unknown error'),
3262
- last_triaged_by: 'auto-slow-query',
3263
- last_triaged_at: new Date()
3264
- }
3265
- })];
3266
- case 47:
3267
- _a.sent();
3268
- return [2 /*return*/];
3269
- case 48:
3270
- if (!isRunning) return [3 /*break*/, 51];
3271
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3272
- $set: {
3273
- status: 'investigating',
3274
- auto_fix_status: 'failed',
3275
- auto_fix_result: {
3276
- job_id: jobId,
3277
- error: 'still_running_after_timeout'
3278
- },
3279
- verification_notes: "Auto optimize timed out while waiting for dashboard job ".concat(jobId, "."),
3280
- last_triaged_by: 'auto-slow-query',
3281
- last_triaged_at: new Date()
3282
- }
3283
- })];
3284
- case 49:
3285
- _a.sent();
3286
- return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize timed out')];
3287
- case 50:
3288
- _a.sent();
3289
- return [2 /*return*/];
3290
- case 51: return [4 /*yield*/, AIDashboardJobs.findOne({ _id: jobId })];
3291
- case 52:
3292
- finalJob = _a.sent();
3293
- if (!(!finalJob || finalJob.phase !== 'COMPLETE' || finalJob.paused)) return [3 /*break*/, 55];
3294
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3295
- $set: {
3296
- status: 'investigating',
3297
- auto_fix_status: 'failed',
3298
- auto_fix_result: {
3299
- job_id: jobId,
3300
- job_phase: (finalJob === null || finalJob === void 0 ? void 0 : finalJob.phase) || 'missing',
3301
- job_paused: !!(finalJob === null || finalJob === void 0 ? void 0 : finalJob.paused)
3302
- },
3303
- verification_notes: "Auto optimize job ".concat(jobId, " did not complete successfully."),
3304
- last_triaged_by: 'auto-slow-query',
3305
- last_triaged_at: new Date()
3306
- }
3307
- })];
3308
- case 53:
3309
- _a.sent();
3310
- return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize job did not complete')];
3311
- case 54:
3312
- _a.sent();
3313
- return [2 /*return*/];
3314
- case 55:
3315
- publishOutcome = this.evaluateDashboardPublishOutcome(finalJob);
3316
- if (!!publishOutcome.success) return [3 /*break*/, 58];
3317
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3318
- $set: {
3319
- status: 'investigating',
3320
- auto_fix_status: 'failed',
3321
- auto_fix_result: {
3322
- job_id: jobId,
3323
- publish_message: publishOutcome.message,
3324
- publish_branch: publishOutcome.branchName || ''
3325
- },
3326
- verification_notes: "Auto optimize publish/deploy failed: ".concat(publishOutcome.message),
3327
- last_triaged_by: 'auto-slow-query',
3328
- last_triaged_at: new Date()
3329
- }
3330
- })];
3331
- case 56:
3332
- _a.sent();
3333
- return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize publish/deploy failed')];
3334
- case 57:
3335
- _a.sent();
3336
- return [2 /*return*/];
3337
- case 58: return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
3338
- case 59:
3339
- refreshedLog = (_a.sent()) || log;
3340
- _a.label = 60;
3341
- case 60:
3342
- _a.trys.push([60, 62, , 65]);
3343
- return [4 /*yield*/, this.runExplain(refreshedLog)];
3344
- case 61:
3345
- afterExplain = _a.sent();
3346
- return [3 /*break*/, 65];
3347
- case 62:
3348
- error_16 = _a.sent();
3349
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3350
- $set: {
3351
- status: 'investigating',
3352
- auto_fix_status: 'failed',
3353
- auto_fix_result: {
3354
- job_id: jobId,
3355
- publish_message: publishOutcome.message,
3356
- publish_branch: publishOutcome.branchName || '',
3357
- validation_error: (error_16 === null || error_16 === void 0 ? void 0 : error_16.message) || 'unknown'
3358
- },
3359
- verification_notes: "Post-deploy validation failed: ".concat((error_16 === null || error_16 === void 0 ? void 0 : error_16.message) || 'unknown error'),
3360
- last_triaged_by: 'auto-slow-query',
3361
- last_triaged_at: new Date()
3362
- }
3363
- })];
3364
- case 63:
3365
- _a.sent();
3366
- return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize post-deploy validation failed')];
3367
- case 64:
3368
- _a.sent();
3369
- return [2 /*return*/];
3370
- case 65:
3371
- afterMetrics = this.resolveExecutionMetrics(afterExplain.explainStats || {}, afterExplain.durationMs, afterExplain.stageSummaries || []);
3372
- if (!this.config.autoOptimizeOutputCompareEnabled) return [3 /*break*/, 71];
3373
- if (!!baselineOutputFingerprint) return [3 /*break*/, 66];
3374
- outputEquivalence = {
3375
- passed: false,
3376
- reason: 'Baseline output fingerprint missing.',
3377
- mode: 'unknown'
3378
- };
3379
- return [3 /*break*/, 71];
3380
- case 66:
3381
- _a.trys.push([66, 68, , 71]);
3382
- return [4 /*yield*/, this.captureOutputFingerprint(refreshedLog)];
3383
- case 67:
3384
- afterOutputFingerprint = _a.sent();
3385
- outputEquivalence = this.compareOutputEquivalence(baselineOutputFingerprint, afterOutputFingerprint);
3386
- return [3 /*break*/, 71];
3387
- case 68:
3388
- error_17 = _a.sent();
3389
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3390
- $set: {
3391
- status: 'investigating',
3392
- auto_fix_status: 'failed',
3393
- auto_fix_result: {
3394
- job_id: jobId,
3395
- publish_message: publishOutcome.message,
3396
- publish_branch: publishOutcome.branchName || '',
3397
- baseline: baselineMetrics,
3398
- after: afterMetrics,
3399
- output_equivalence_error: (error_17 === null || error_17 === void 0 ? void 0 : error_17.message) || 'unknown'
3400
- },
3401
- verification_notes: "Post-deploy output comparison failed: ".concat((error_17 === null || error_17 === void 0 ? void 0 : error_17.message) || 'unknown error'),
3402
- explain_plan: afterExplain.explainPlan,
3403
- explain_execution_stats: afterExplain.explainStats,
3404
- explain_generated_at: new Date(),
3405
- last_triaged_by: 'auto-slow-query',
3406
- last_triaged_at: new Date()
3407
- },
3408
- $push: {
3409
- verification_runs: {
3410
- timestamp: new Date(),
3411
- duration_ms: afterExplain.durationMs
3412
- }
3413
- }
3414
- })];
3415
- case 69:
3416
- _a.sent();
3417
- return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize output comparison failed')];
3418
- case 70:
3419
- _a.sent();
3420
- return [2 /*return*/];
3421
- case 71:
3422
- validation = this.evaluateOptimizationOutcome(baselineMetrics, afterMetrics, outputEquivalence);
3423
- autoFixResult = {
3424
- job_id: jobId,
3425
- publish_message: publishOutcome.message,
3426
- publish_branch: publishOutcome.branchName || '',
3427
- baseline: baselineMetrics,
3428
- after: afterMetrics,
3429
- output_equivalence: outputEquivalence,
3430
- validation: validation
3431
- };
3432
- if (!!validation.passed) return [3 /*break*/, 74];
3433
- return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3434
- $set: {
3435
- status: 'investigating',
3436
- auto_fix_status: 'failed',
3437
- auto_fix_result: autoFixResult,
3438
- verification_notes: "Auto optimize validation failed: ".concat(validation.reason),
3439
- explain_plan: afterExplain.explainPlan,
3440
- explain_execution_stats: afterExplain.explainStats,
3441
- explain_generated_at: new Date(),
3442
- last_triaged_by: 'auto-slow-query',
3443
- last_triaged_at: new Date()
3444
- },
3445
- $push: {
3446
- verification_runs: {
3447
- timestamp: new Date(),
3448
- duration_ms: afterExplain.durationMs
3449
- }
3450
- }
3451
- })];
3452
- case 72:
3453
- _a.sent();
3454
- return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize validation failed')];
3455
- case 73:
3456
- _a.sent();
3457
- return [2 /*return*/];
3458
- case 74: return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3459
- $set: {
3460
- status: 'optimized',
3461
- auto_fix_status: 'completed',
3462
- auto_fix_result: autoFixResult,
3463
- verification_notes: "Auto optimize completed: ".concat(validation.reason),
3464
- explain_plan: afterExplain.explainPlan,
3465
- explain_execution_stats: afterExplain.explainStats,
3466
- explain_generated_at: new Date(),
3467
- last_triaged_by: 'auto-slow-query',
3468
- last_triaged_at: new Date()
3469
- },
3470
- $push: {
3471
- verification_runs: {
3472
- timestamp: new Date(),
3473
- duration_ms: afterExplain.durationMs
3474
- }
3475
- }
3476
- })];
3477
- case 75:
3478
- _a.sent();
3479
- return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
3480
- case 76:
3481
- optimizedLog = (_a.sent()) || log;
3482
- return [4 /*yield*/, this.notifyCustomerSlowQueryStatus('completed_success', optimizedLog, { notes: validation.reason })];
3483
- case 77:
3484
- _a.sent();
3485
- return [2 /*return*/];
3486
- }
3487
- });
3488
- });
3489
- };
3490
- SlowQueryVerifier.prototype.resolveClientDB = function (log) {
3491
- return __awaiter(this, void 0, void 0, function () {
3492
- var candidates, matches, prodMatch, devMatch;
3493
- return __generator(this, function (_a) {
3494
- switch (_a.label) {
3495
- case 0:
3496
- candidates = [
3497
- log.client_slug,
3498
- log.client_name,
3499
- log.source_app
3500
- ].filter(Boolean);
3501
- if (!candidates.length) {
3502
- return [2 /*return*/, undefined];
3503
- }
3504
- return [4 /*yield*/, ClientDBs.find({
3505
- $or: [
3506
- { client: { $in: candidates } },
3507
- { name: { $in: candidates } }
3508
- ]
3509
- }, {
3510
- limit: 10
3511
- })];
3512
- case 1:
3513
- matches = _a.sent();
3514
- if (!Array.isArray(matches) || !matches.length) {
3515
- return [2 /*return*/, undefined];
3516
- }
3517
- prodMatch = matches.find(function (match) { return match && match.dev_server === false; });
3518
- if (prodMatch) {
3519
- return [2 /*return*/, prodMatch];
3520
- }
3521
- devMatch = matches.find(function (match) { return match && match.dev_server === true; });
3522
- if (devMatch) {
3523
- return [2 /*return*/, devMatch];
3524
- }
3525
- return [2 /*return*/, matches[0]];
3526
- }
3527
- });
3528
- });
3529
- };
3530
- SlowQueryVerifier.prototype.resolveExplainTarget = function (log) {
3531
- return __awaiter(this, void 0, void 0, function () {
3532
- var clientDB, dbName, mainDb, mainDbName;
3533
- return __generator(this, function (_a) {
3534
- switch (_a.label) {
3535
- case 0: return [4 /*yield*/, this.resolveClientDB(log)];
3536
- case 1:
3537
- clientDB = _a.sent();
3538
- if (clientDB) {
3539
- dbName = clientDB.database || clientDB.name;
3540
- if (!dbName) {
3541
- throw new SlowQueryVerifierError('client_db_missing_database', 'Client DB missing database name.');
3542
- }
3543
- return [2 /*return*/, {
3544
- type: 'client',
3545
- dbName: dbName,
3546
- uri: clientDB.uri
3547
- }];
3548
- }
3549
- if (!this.config.fallbackToMainDB) {
3550
- throw new SlowQueryVerifierError('client_db_not_found', 'Could not resolve client DB for slow query verification.');
3551
- }
3552
- mainDb = resolveio_server_app_1.ResolveIOServer.getMainDB();
3553
- mainDbName = mainDb === null || mainDb === void 0 ? void 0 : mainDb.databaseName;
3554
- if (!mainDb || !mainDbName) {
3555
- throw new SlowQueryVerifierError('main_db_unavailable', 'Main server DB is not available.');
3556
- }
3557
- return [2 /*return*/, {
3558
- type: 'main',
3559
- dbName: mainDbName
3560
- }];
3561
- }
3562
- });
3563
- });
3564
- };
3565
- SlowQueryVerifier.extractPipelineFromLog = function (log) {
3566
- if (!log) {
3567
- return undefined;
3568
- }
3569
- if (Array.isArray(log.pipeline)) {
3570
- return log.pipeline;
3571
- }
3572
- if (log.filter && Array.isArray(log.filter.pipeline)) {
3573
- return log.filter.pipeline;
3574
- }
3575
- return SlowQueryVerifier.extractPipelineOptions(log.options);
3576
- };
3577
- SlowQueryVerifier.applyQueryOverrides = function (log, overrides) {
3578
- if (!overrides) {
3579
- return log;
3580
- }
3581
- var merged = __assign({}, log);
3582
- if (overrides.filter !== undefined) {
3583
- merged.filter = overrides.filter;
3584
- }
3585
- if (overrides.options !== undefined) {
3586
- merged.options = overrides.options;
3587
- }
3588
- if (overrides.pipeline !== undefined) {
3589
- merged.pipeline = overrides.pipeline;
3590
- }
3591
- return merged;
3592
- };
3593
- SlowQueryVerifier.extractPipelineOptions = function (options) {
3594
- if (!options) {
3595
- return undefined;
3596
- }
3597
- if (Array.isArray(options)) {
3598
- return options;
3599
- }
3600
- if (Array.isArray(options.pipeline)) {
3601
- return options.pipeline;
3602
- }
3603
- return undefined;
3604
- };
3605
- SlowQueryVerifier.extractFindOptions = function (options) {
3606
- if (!options || Array.isArray(options)) {
3607
- return undefined;
3608
- }
3609
- var normalized = __assign({}, options);
3610
- if (Array.isArray(normalized.pipeline)) {
3611
- delete normalized.pipeline;
3612
- }
3613
- if (!Object.keys(normalized).length) {
3614
- return undefined;
3615
- }
3616
- return normalized;
3617
- };
3618
- SlowQueryVerifier.resolveDurationMs = function (explainResponse) {
3619
- var e_7, _a, e_8, _b, e_9, _c;
3620
- var _d, _e, _f, _g, _h;
3621
- var stats = explainResponse === null || explainResponse === void 0 ? void 0 : explainResponse.executionStats;
3622
- if (!stats) {
3623
- var stages = explainResponse === null || explainResponse === void 0 ? void 0 : explainResponse.stages;
3624
- if (Array.isArray(stages)) {
3625
- try {
3626
- for (var stages_1 = __values(stages), stages_1_1 = stages_1.next(); !stages_1_1.done; stages_1_1 = stages_1.next()) {
3627
- var stage = stages_1_1.value;
3628
- var stageStats = (_d = stage === null || stage === void 0 ? void 0 : stage.$cursor) === null || _d === void 0 ? void 0 : _d.executionStats;
3629
- var candidates_5 = [
3630
- stageStats === null || stageStats === void 0 ? void 0 : stageStats.executionTimeMillis,
3631
- stageStats === null || stageStats === void 0 ? void 0 : stageStats.executionTimeMillisEstimate,
3632
- (_e = stageStats === null || stageStats === void 0 ? void 0 : stageStats.executionStages) === null || _e === void 0 ? void 0 : _e.executionTimeMillis,
3633
- (_f = stageStats === null || stageStats === void 0 ? void 0 : stageStats.executionStages) === null || _f === void 0 ? void 0 : _f.executionTimeMillisEstimate
3634
- ];
3635
- try {
3636
- for (var candidates_3 = (e_8 = void 0, __values(candidates_5)), candidates_3_1 = candidates_3.next(); !candidates_3_1.done; candidates_3_1 = candidates_3.next()) {
3637
- var candidate = candidates_3_1.value;
3638
- if (SlowQueryVerifier.isValidDuration(candidate)) {
3639
- return candidate;
3640
- }
3641
- }
3642
- }
3643
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
3644
- finally {
3645
- try {
3646
- if (candidates_3_1 && !candidates_3_1.done && (_b = candidates_3.return)) _b.call(candidates_3);
3647
- }
3648
- finally { if (e_8) throw e_8.error; }
3649
- }
3650
- }
3651
- }
3652
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
3653
- finally {
3654
- try {
3655
- if (stages_1_1 && !stages_1_1.done && (_a = stages_1.return)) _a.call(stages_1);
3656
- }
3657
- finally { if (e_7) throw e_7.error; }
3658
- }
3659
- }
3660
- return -1;
3661
- }
3662
- var candidates = [
3663
- stats.executionTimeMillis,
3664
- stats.executionTimeMillisEstimate,
3665
- (_g = stats.executionStages) === null || _g === void 0 ? void 0 : _g.executionTimeMillis,
3666
- (_h = stats.executionStages) === null || _h === void 0 ? void 0 : _h.executionTimeMillisEstimate
3667
- ];
3668
- try {
3669
- for (var candidates_4 = __values(candidates), candidates_4_1 = candidates_4.next(); !candidates_4_1.done; candidates_4_1 = candidates_4.next()) {
3670
- var candidate = candidates_4_1.value;
3671
- if (SlowQueryVerifier.isValidDuration(candidate)) {
3672
- return candidate;
3673
- }
3674
- }
3675
- }
3676
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
3677
- finally {
3678
- try {
3679
- if (candidates_4_1 && !candidates_4_1.done && (_c = candidates_4.return)) _c.call(candidates_4);
3680
- }
3681
- finally { if (e_9) throw e_9.error; }
3682
- }
3683
- return -1;
3684
- };
3685
- SlowQueryVerifier.pipelineHasWriteStage = function (pipeline) {
3686
- if (!Array.isArray(pipeline)) {
3687
- return false;
3688
- }
3689
- return pipeline.some(function (stage) {
3690
- if (!stage || typeof stage !== 'object') {
3691
- return false;
3692
- }
3693
- return typeof stage.$out !== 'undefined' || typeof stage.$merge !== 'undefined';
3694
- });
3695
- };
3696
- SlowQueryVerifier.extractAggregateOptions = function (options) {
3697
- if (!options || Array.isArray(options) || typeof options !== 'object') {
3698
- return undefined;
3699
- }
3700
- var allowedKeys = [
3701
- 'allowDiskUse',
3702
- 'bypassDocumentValidation',
3703
- 'collation',
3704
- 'comment',
3705
- 'hint',
3706
- 'let',
3707
- 'maxTimeMS',
3708
- 'maxAwaitTimeMS'
3709
- ];
3710
- var result = {};
3711
- allowedKeys.forEach(function (key) {
3712
- if (typeof options[key] !== 'undefined') {
3713
- result[key] = options[key];
3714
- }
3715
- });
3716
- return Object.keys(result).length ? result : undefined;
3717
- };
3718
- SlowQueryVerifier.buildAggregateExplainCommand = function (collectionName, pipeline, options, verbosity) {
3719
- if (verbosity === void 0) { verbosity = 'executionStats'; }
3720
- var aggregateCommand = {
3721
- aggregate: collectionName,
3722
- pipeline: pipeline,
3723
- cursor: {}
3724
- };
3725
- if (options && typeof options === 'object') {
3726
- Object.keys(options).forEach(function (key) {
3727
- if (typeof options[key] !== 'undefined') {
3728
- aggregateCommand[key] = options[key];
3729
- }
3730
- });
3731
- }
3732
- return {
3733
- explain: aggregateCommand,
3734
- verbosity: verbosity
3735
- };
3736
- };
3737
- SlowQueryVerifier.isAggregateExplainWriteConcernError = function (err) {
3738
- var message = "".concat((err === null || err === void 0 ? void 0 : err.message) || '');
3739
- return message.includes('Option "explain" cannot be used on an aggregate call with writeConcern');
3740
- };
3741
- SlowQueryVerifier.isBsonObjectTooLargeError = function (err) {
3742
- var message = "".concat((err === null || err === void 0 ? void 0 : err.message) || '');
3743
- return message.includes('BSONObj size:') && message.includes('is invalid');
3744
- };
3745
- SlowQueryVerifier.isValidDuration = function (value) {
3746
- return typeof value === 'number' && !Number.isNaN(value) && value >= 0;
3747
- };
3748
- SlowQueryVerifier.buildFindCursor = function (collection, filter, findOptions) {
3749
- var _a;
3750
- var cursorOptions = {};
3751
- if (findOptions) {
3752
- Object.keys(findOptions).forEach(function (key) {
3753
- if (['sort', 'skip', 'limit', 'projection', 'fields'].includes(key)) {
3754
- return;
3755
- }
3756
- cursorOptions[key] = findOptions[key];
3757
- });
3758
- }
3759
- cursorOptions.readPreference = 'secondaryPreferred';
3760
- var cursor = collection.find(filter || {}, cursorOptions);
3761
- var projection = (_a = findOptions === null || findOptions === void 0 ? void 0 : findOptions.projection) !== null && _a !== void 0 ? _a : findOptions === null || findOptions === void 0 ? void 0 : findOptions.fields;
3762
- if (projection && typeof projection === 'object') {
3763
- cursor = cursor.project(projection);
3764
- }
3765
- var sort = findOptions === null || findOptions === void 0 ? void 0 : findOptions.sort;
3766
- if (sort && typeof sort === 'object') {
3767
- cursor = cursor.sort(sort);
3768
- }
3769
- var skip = findOptions === null || findOptions === void 0 ? void 0 : findOptions.skip;
3770
- if (typeof skip === 'number') {
3771
- cursor = cursor.skip(skip);
3772
- }
3773
- var limit = findOptions === null || findOptions === void 0 ? void 0 : findOptions.limit;
3774
- if (typeof limit === 'number') {
3775
- cursor = cursor.limit(limit);
3776
- }
3777
- return cursor;
3778
- };
3779
- SlowQueryVerifier.measureExecution = function (db, collectionName, pipeline, filter, findOptions, aggregateOptions) {
3780
- return __awaiter(this, void 0, void 0, function () {
3781
- var start, cursor, err_5, duration;
3782
- return __generator(this, function (_a) {
3783
- switch (_a.label) {
3784
- case 0:
3785
- start = Date.now();
3786
- _a.label = 1;
3787
- case 1:
3788
- _a.trys.push([1, 6, , 7]);
3789
- if (!Array.isArray(pipeline)) return [3 /*break*/, 3];
3790
- return [4 /*yield*/, db.collection(collectionName)
3791
- .aggregate(pipeline, __assign(__assign({}, (aggregateOptions || {})), { readPreference: 'secondaryPreferred' }))
3792
- .toArray()];
3793
- case 2:
3794
- _a.sent();
3795
- return [3 /*break*/, 5];
3796
- case 3:
3797
- cursor = SlowQueryVerifier.buildFindCursor(db.collection(collectionName), filter !== null && filter !== void 0 ? filter : {}, findOptions);
3798
- return [4 /*yield*/, cursor.toArray()];
3799
- case 4:
3800
- _a.sent();
3801
- _a.label = 5;
3802
- case 5: return [3 /*break*/, 7];
3803
- case 6:
3804
- err_5 = _a.sent();
3805
- if (!SlowQueryVerifier.isBsonObjectTooLargeError(err_5)) {
3806
- console.error('Slow query measurement execution failed for', collectionName, err_5);
3807
- }
3808
- return [2 /*return*/, -1];
3809
- case 7:
3810
- duration = Date.now() - start;
3811
- return [2 /*return*/, SlowQueryVerifier.isValidDuration(duration) ? duration : -1];
3812
- }
3813
- });
3814
- });
3815
- };
3816
- SlowQueryVerifier.normalizeExplainPayload = function (input) {
3817
- var cloned = SlowQueryVerifier.deepClone(input !== null && input !== void 0 ? input : {});
3818
- return typeof cloned === 'object' && cloned !== null ? cloned : {};
3819
- };
3820
- SlowQueryVerifier.sanitizeExplainPayload = function (payload, maxBytes) {
3821
- if (maxBytes === void 0) { maxBytes = 2 * 1024 * 1024; }
3822
- try {
3823
- var json = JSON.stringify(payload);
3824
- var bytes = Buffer.byteLength(json, 'utf8');
3825
- return bytes <= maxBytes ? payload : {};
3826
- }
3827
- catch (_a) {
3828
- return {};
3829
- }
3830
- };
3831
- SlowQueryVerifier.deepClone = function (value) {
3832
- if (value === null || typeof value !== 'object') {
3833
- return value;
3834
- }
3835
- if (Array.isArray(value)) {
3836
- return value.map(function (item) { return SlowQueryVerifier.deepClone(item); });
3837
- }
3838
- if (typeof value.toJSON === 'function') {
3839
- try {
3840
- return SlowQueryVerifier.deepClone(value.toJSON());
3841
- }
3842
- catch (_a) {
3843
- // fall through to manual clone
3844
- }
3845
- }
3846
- var result = {};
3847
- Object.keys(value).forEach(function (key) {
3848
- result[key] = SlowQueryVerifier.deepClone(value[key]);
3849
- });
3850
- return result;
3851
- };
3852
- SlowQueryVerifier.APP_SETTINGS_CACHE_TTL_MS = 10000;
3853
- return SlowQueryVerifier;
3854
- }());
3855
- exports.SlowQueryVerifier = SlowQueryVerifier;
3856
-
3857
- //# sourceMappingURL=slow-query-verifier.manager.js.map