@resolveio/server-lib 22.2.18 → 22.2.20

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 (36) hide show
  1. package/managers/error-auto-fix.manager.d.ts +6 -0
  2. package/managers/error-auto-fix.manager.js +215 -85
  3. package/managers/error-auto-fix.manager.js.map +1 -1
  4. package/managers/method.manager.js +2 -0
  5. package/managers/method.manager.js.map +1 -1
  6. package/managers/mongo.manager.d.ts +3 -0
  7. package/managers/mongo.manager.js +184 -65
  8. package/managers/mongo.manager.js.map +1 -1
  9. package/managers/slow-query-verifier.manager.d.ts +30 -0
  10. package/managers/slow-query-verifier.manager.js +691 -192
  11. package/managers/slow-query-verifier.manager.js.map +1 -1
  12. package/managers/subscription.manager.d.ts +1 -0
  13. package/managers/subscription.manager.js +60 -21
  14. package/managers/subscription.manager.js.map +1 -1
  15. package/managers/worker-dispatcher.manager.js +60 -6
  16. package/managers/worker-dispatcher.manager.js.map +1 -1
  17. package/methods/ai-terminal.d.ts +4 -0
  18. package/methods/ai-terminal.js +64 -26
  19. package/methods/ai-terminal.js.map +1 -1
  20. package/methods/app-settings.js +2 -2
  21. package/methods/app-settings.js.map +1 -1
  22. package/methods/diagnostics.d.ts +2 -0
  23. package/methods/diagnostics.js +514 -0
  24. package/methods/diagnostics.js.map +1 -0
  25. package/methods.ts +15 -0
  26. package/package.json +1 -1
  27. package/resolveio-server-app.d.ts +17 -1
  28. package/resolveio-server-app.js +293 -25
  29. package/resolveio-server-app.js.map +1 -1
  30. package/server-app.js +22 -36
  31. package/server-app.js.map +1 -1
  32. package/util/error-reporter.js +26 -126
  33. package/util/error-reporter.js.map +1 -1
  34. package/util/slow-query-reporter.d.ts +0 -3
  35. package/util/slow-query-reporter.js +13 -120
  36. package/util/slow-query-reporter.js.map +1 -1
@@ -113,6 +113,7 @@ var resolveio_server_app_1 = require("../resolveio-server-app");
113
113
  var common_1 = require("../util/common");
114
114
  var mongodb_1 = require("mongodb");
115
115
  var user_collection_1 = require("../collections/user.collection");
116
+ var app_setting_collection_1 = require("../collections/app-setting.collection");
116
117
  var customer_notification_content_manager_1 = require("./customer-notification-content.manager");
117
118
  var OPTIONAL_COLLECTION = {
118
119
  findOne: function () { return Promise.resolve(null); },
@@ -192,12 +193,12 @@ var SlowQueryVerifier = /** @class */ (function () {
192
193
  function SlowQueryVerifier(serverConfig, dependencies) {
193
194
  var _this = this;
194
195
  this.autoOptimizeInFlight = new Set();
196
+ this.appSettingsAutoOptimizeCacheExpiresAt = 0;
197
+ this.appSettingsAutoOptimizeCacheValue = null;
195
198
  var resolvedDependencies = resolveSlowQueryVerifierDependencies(dependencies);
196
199
  applySlowQueryVerifierDependencies(resolvedDependencies);
197
200
  this.config = SlowQueryVerifier.resolveConfig(serverConfig);
198
- if (!resolvedDependencies.AICoderApps || !resolvedDependencies.AIDashboardJobs) {
199
- this.config.autoOptimizeEnabled = false;
200
- }
201
+ this.autoOptimizeDependenciesAvailable = !!(resolvedDependencies.AICoderApps && resolvedDependencies.AIDashboardJobs);
201
202
  if (this.config.enabled) {
202
203
  this._timer = setInterval(function () {
203
204
  // eslint-disable-next-line no-restricted-syntax
@@ -214,6 +215,7 @@ var SlowQueryVerifier = /** @class */ (function () {
214
215
  SlowQueryVerifier.resolveConfig = function (serverConfig) {
215
216
  var slowQueryConfig = (serverConfig && (serverConfig.slowQuery || serverConfig.SLOW_QUERY)) || {};
216
217
  var verifierConfig = (slowQueryConfig && (slowQueryConfig.verifier || slowQueryConfig.slowQueryVerifier)) || {};
218
+ var autofixConfig = (serverConfig && (serverConfig.autofix || serverConfig.AUTOFIX)) || {};
217
219
  var getBoolean = function (envKey, configKey, fallback) {
218
220
  if (fallback === void 0) { fallback = true; }
219
221
  if (typeof process.env[envKey] !== 'undefined') {
@@ -239,6 +241,22 @@ var SlowQueryVerifier = /** @class */ (function () {
239
241
  }
240
242
  return fallback;
241
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
+ };
242
260
  var parseEmails = function (value) {
243
261
  if (Array.isArray(value)) {
244
262
  return value.map(function (item) { return "".concat(item || '').trim().toLowerCase(); }).filter(Boolean);
@@ -275,11 +293,14 @@ var SlowQueryVerifier = /** @class */ (function () {
275
293
  || slowQueryConfig.escalationEmails
276
294
  || slowQueryConfig.notifyEmails);
277
295
  return {
278
- enabled: getBoolean('SLOW_QUERY_VERIFIER_ENABLED', 'enabled', true),
296
+ enabled: true,
279
297
  fallbackToMainDB: getBoolean('SLOW_QUERY_VERIFIER_FALLBACK_MAIN_DB', 'fallbackToMainDB', true),
280
298
  debugLogging: getBoolean('SLOW_QUERY_VERIFIER_DEBUG_LOGS', 'debugLogging', false),
281
- configSource: process.env.SLOW_QUERY_VERIFIER_ENABLED ? 'environment' : (Object.keys(verifierConfig).length ? 'serverConfig' : 'defaults'),
282
- autoOptimizeEnabled: getBoolean('SLOW_QUERY_AUTO_OPTIMIZE_ENABLED', 'autoOptimizeEnabled', true),
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),
283
304
  autoOptimizeWaitTimeoutMs: getNumber('SLOW_QUERY_AUTO_OPTIMIZE_WAIT_TIMEOUT_MS', 'autoOptimizeWaitTimeoutMs', 45 * 60 * 1000),
284
305
  autoOptimizeDurationRatioTarget: clampRatio(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_DURATION_RATIO', 'autoOptimizeDurationRatioTarget', AUTO_OPTIMIZE_DEFAULT_IMPROVEMENT_RATIO), AUTO_OPTIMIZE_DEFAULT_IMPROVEMENT_RATIO),
285
306
  autoOptimizeDocsRatioTarget: clampRatio(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_DOCS_RATIO', 'autoOptimizeDocsRatioTarget', AUTO_OPTIMIZE_DEFAULT_IMPROVEMENT_RATIO), AUTO_OPTIMIZE_DEFAULT_IMPROVEMENT_RATIO),
@@ -290,17 +311,93 @@ var SlowQueryVerifier = /** @class */ (function () {
290
311
  autoOptimizeFingerprintWindowHours: normalizePositiveInt(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_FINGERPRINT_WINDOW_HOURS', 'autoOptimizeFingerprintWindowHours', AUTO_OPTIMIZE_DEFAULT_FINGERPRINT_WINDOW_HOURS), AUTO_OPTIMIZE_DEFAULT_FINGERPRINT_WINDOW_HOURS),
291
312
  autoOptimizeRequiredTokens: normalizeNonNegativeInt(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_REQUIRED_TOKENS', 'autoOptimizeRequiredTokens', 0), 0),
292
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),
293
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),
294
317
  escalationEmails: escalationEmails
295
318
  };
296
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
+ };
297
389
  SlowQueryVerifier.prototype.poll = function () {
298
390
  return __awaiter(this, void 0, void 0, function () {
299
- var now, candidates, candidates_1, candidates_1_1, candidate, e_1_1;
391
+ var autoOptimizeEnabled, now, candidates, candidates_1, candidates_1_1, candidate, e_1_1;
300
392
  var e_1, _a;
301
393
  return __generator(this, function (_b) {
302
394
  switch (_b.label) {
303
- case 0:
395
+ case 0: return [4 /*yield*/, this.resolveAutoOptimizeEnabled()];
396
+ case 1:
397
+ autoOptimizeEnabled = _b.sent();
398
+ if (!autoOptimizeEnabled) {
399
+ return [2 /*return*/];
400
+ }
304
401
  now = new Date();
305
402
  return [4 /*yield*/, SlowQueryLogs.find({
306
403
  ignored: {
@@ -328,35 +425,35 @@ var SlowQueryVerifier = /** @class */ (function () {
328
425
  },
329
426
  limit: 5
330
427
  })];
331
- case 1:
332
- candidates = _b.sent();
333
- _b.label = 2;
334
428
  case 2:
335
- _b.trys.push([2, 7, 8, 9]);
336
- candidates_1 = __values(candidates), candidates_1_1 = candidates_1.next();
429
+ candidates = _b.sent();
337
430
  _b.label = 3;
338
431
  case 3:
339
- if (!!candidates_1_1.done) return [3 /*break*/, 6];
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];
340
437
  candidate = candidates_1_1.value;
341
438
  return [4 /*yield*/, this.processCandidate(candidate)];
342
- case 4:
343
- _b.sent();
344
- _b.label = 5;
345
439
  case 5:
440
+ _b.sent();
441
+ _b.label = 6;
442
+ case 6:
346
443
  candidates_1_1 = candidates_1.next();
347
- return [3 /*break*/, 3];
348
- case 6: return [3 /*break*/, 9];
349
- case 7:
444
+ return [3 /*break*/, 4];
445
+ case 7: return [3 /*break*/, 10];
446
+ case 8:
350
447
  e_1_1 = _b.sent();
351
448
  e_1 = { error: e_1_1 };
352
- return [3 /*break*/, 9];
353
- case 8:
449
+ return [3 /*break*/, 10];
450
+ case 9:
354
451
  try {
355
452
  if (candidates_1_1 && !candidates_1_1.done && (_a = candidates_1.return)) _a.call(candidates_1);
356
453
  }
357
454
  finally { if (e_1) throw e_1.error; }
358
455
  return [7 /*endfinally*/];
359
- case 9: return [2 /*return*/];
456
+ case 10: return [2 /*return*/];
360
457
  }
361
458
  });
362
459
  });
@@ -435,6 +532,325 @@ var SlowQueryVerifier = /** @class */ (function () {
435
532
  });
436
533
  });
437
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
+ };
438
854
  SlowQueryVerifier.prototype.runExplain = function (log, overrides) {
439
855
  return __awaiter(this, void 0, void 0, function () {
440
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;
@@ -807,7 +1223,7 @@ var SlowQueryVerifier = /** @class */ (function () {
807
1223
  });
808
1224
  };
809
1225
  SlowQueryVerifier.prototype.scheduleAutoOptimization = function (logId) {
810
- if (!this.config.autoOptimizeEnabled || !logId) {
1226
+ if (!logId) {
811
1227
  return;
812
1228
  }
813
1229
  if (this.autoOptimizeInFlight.has(logId)) {
@@ -819,7 +1235,7 @@ var SlowQueryVerifier = /** @class */ (function () {
819
1235
  SlowQueryVerifier.prototype.runAutoOptimizationInBackground = function (logId) {
820
1236
  var _this = this;
821
1237
  setImmediate(function () { return __awaiter(_this, void 0, void 0, function () {
822
- var error_1;
1238
+ var error_4;
823
1239
  return __generator(this, function (_a) {
824
1240
  switch (_a.label) {
825
1241
  case 0:
@@ -829,8 +1245,8 @@ var SlowQueryVerifier = /** @class */ (function () {
829
1245
  _a.sent();
830
1246
  return [3 /*break*/, 4];
831
1247
  case 2:
832
- error_1 = _a.sent();
833
- console.error('Slow query auto optimization failed', { logId: logId, error: (error_1 === null || error_1 === void 0 ? void 0 : error_1.message) || error_1 });
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 });
834
1250
  return [3 /*break*/, 4];
835
1251
  case 3:
836
1252
  this.autoOptimizeInFlight.delete(logId);
@@ -858,7 +1274,7 @@ var SlowQueryVerifier = /** @class */ (function () {
858
1274
  };
859
1275
  SlowQueryVerifier.prototype.sendSlowQueryEscalationNotice = function (log, reason) {
860
1276
  return __awaiter(this, void 0, void 0, function () {
861
- var recipients, subject, body, methodManager, recipients_1, recipients_1_1, recipient, error_2, e_2_1;
1277
+ var recipients, subject, body, methodManager, recipients_1, recipients_1_1, recipient, error_5, e_2_1;
862
1278
  var e_2, _a;
863
1279
  return __generator(this, function (_b) {
864
1280
  switch (_b.label) {
@@ -899,8 +1315,8 @@ var SlowQueryVerifier = /** @class */ (function () {
899
1315
  _b.sent();
900
1316
  return [3 /*break*/, 6];
901
1317
  case 5:
902
- error_2 = _b.sent();
903
- console.error('Failed sending slow-query escalation email', { recipient: recipient, logId: log._id, error: error_2 });
1318
+ error_5 = _b.sent();
1319
+ console.error('Failed sending slow-query escalation email', { recipient: recipient, logId: log._id, error: error_5 });
904
1320
  return [3 /*break*/, 6];
905
1321
  case 6:
906
1322
  recipients_1_1 = recipients_1.next();
@@ -1163,7 +1579,7 @@ var SlowQueryVerifier = /** @class */ (function () {
1163
1579
  };
1164
1580
  SlowQueryVerifier.prototype.notifyCustomerSlowQueryStatus = function (stage, log, extra) {
1165
1581
  return __awaiter(this, void 0, void 0, function () {
1166
- var target, isGeneratedApp, generatedApp, issueKey, dedupeKey, metadata, targetPayload, idUsers, payload, error_3;
1582
+ var target, isGeneratedApp, generatedApp, issueKey, dedupeKey, metadata, targetPayload, idUsers, payload, error_6;
1167
1583
  return __generator(this, function (_a) {
1168
1584
  switch (_a.label) {
1169
1585
  case 0:
@@ -1259,12 +1675,12 @@ var SlowQueryVerifier = /** @class */ (function () {
1259
1675
  _a.sent();
1260
1676
  return [3 /*break*/, 12];
1261
1677
  case 11:
1262
- error_3 = _a.sent();
1678
+ error_6 = _a.sent();
1263
1679
  if (this.config.debugLogging) {
1264
1680
  console.warn('Slow query customer notification failed', {
1265
1681
  logId: log._id,
1266
1682
  stage: stage,
1267
- error: (error_3 === null || error_3 === void 0 ? void 0 : error_3.message) || error_3
1683
+ error: (error_6 === null || error_6 === void 0 ? void 0 : error_6.message) || error_6
1268
1684
  });
1269
1685
  }
1270
1686
  return [3 /*break*/, 12];
@@ -1597,7 +2013,7 @@ var SlowQueryVerifier = /** @class */ (function () {
1597
2013
  };
1598
2014
  SlowQueryVerifier.prototype.createDashboardJob = function (payload) {
1599
2015
  return __awaiter(this, void 0, void 0, function () {
1600
- var methodManager, error_4, manager;
2016
+ var methodManager, error_7, manager;
1601
2017
  return __generator(this, function (_a) {
1602
2018
  switch (_a.label) {
1603
2019
  case 0:
@@ -1608,9 +2024,9 @@ var SlowQueryVerifier = /** @class */ (function () {
1608
2024
  return [4 /*yield*/, methodManager.callMethod('aiDashboardCreateJob', payload)];
1609
2025
  case 2: return [2 /*return*/, _a.sent()];
1610
2026
  case 3:
1611
- error_4 = _a.sent();
1612
- if (!this.shouldFallbackDashboardMethod(error_4)) {
1613
- throw error_4;
2027
+ error_7 = _a.sent();
2028
+ if (!this.shouldFallbackDashboardMethod(error_7)) {
2029
+ throw error_7;
1614
2030
  }
1615
2031
  return [3 /*break*/, 4];
1616
2032
  case 4:
@@ -1625,7 +2041,7 @@ var SlowQueryVerifier = /** @class */ (function () {
1625
2041
  };
1626
2042
  SlowQueryVerifier.prototype.waitForDashboardJobStop = function (jobId, timeoutMs) {
1627
2043
  return __awaiter(this, void 0, void 0, function () {
1628
- var methodManager, error_5, manager;
2044
+ var methodManager, error_8, manager;
1629
2045
  return __generator(this, function (_a) {
1630
2046
  switch (_a.label) {
1631
2047
  case 0:
@@ -1638,9 +2054,9 @@ var SlowQueryVerifier = /** @class */ (function () {
1638
2054
  _a.sent();
1639
2055
  return [2 /*return*/];
1640
2056
  case 3:
1641
- error_5 = _a.sent();
1642
- if (!this.shouldFallbackDashboardMethod(error_5)) {
1643
- throw error_5;
2057
+ error_8 = _a.sent();
2058
+ if (!this.shouldFallbackDashboardMethod(error_8)) {
2059
+ throw error_8;
1644
2060
  }
1645
2061
  return [3 /*break*/, 4];
1646
2062
  case 4:
@@ -1657,7 +2073,7 @@ var SlowQueryVerifier = /** @class */ (function () {
1657
2073
  };
1658
2074
  SlowQueryVerifier.prototype.isDashboardJobRunning = function (jobId) {
1659
2075
  return __awaiter(this, void 0, void 0, function () {
1660
- var methodManager, running, error_6, manager;
2076
+ var methodManager, running, error_9, manager;
1661
2077
  return __generator(this, function (_a) {
1662
2078
  switch (_a.label) {
1663
2079
  case 0:
@@ -1670,9 +2086,9 @@ var SlowQueryVerifier = /** @class */ (function () {
1670
2086
  running = _a.sent();
1671
2087
  return [2 /*return*/, !!running];
1672
2088
  case 3:
1673
- error_6 = _a.sent();
1674
- if (!this.shouldFallbackDashboardMethod(error_6)) {
1675
- throw error_6;
2089
+ error_9 = _a.sent();
2090
+ if (!this.shouldFallbackDashboardMethod(error_9)) {
2091
+ throw error_9;
1676
2092
  }
1677
2093
  return [3 /*break*/, 4];
1678
2094
  case 4:
@@ -1685,6 +2101,34 @@ var SlowQueryVerifier = /** @class */ (function () {
1685
2101
  });
1686
2102
  });
1687
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
+ };
1688
2132
  SlowQueryVerifier.prototype.evaluateDashboardPublishOutcome = function (job) {
1689
2133
  var logEntries = Array.isArray(job === null || job === void 0 ? void 0 : job.log) ? job.log : [];
1690
2134
  var lastMatch = function (predicate) {
@@ -1701,7 +2145,12 @@ var SlowQueryVerifier = /** @class */ (function () {
1701
2145
  }
1702
2146
  var publishEntry = lastMatch(function (entry) { return /Published build to /i.test(entry || ''); });
1703
2147
  if (publishEntry) {
1704
- return { success: true, message: publishEntry };
2148
+ var branchMatch = publishEntry.match(/\(([^()]+)\)\.?$/);
2149
+ return {
2150
+ success: true,
2151
+ message: publishEntry,
2152
+ branchName: (branchMatch && branchMatch[1]) ? branchMatch[1].trim() : undefined
2153
+ };
1705
2154
  }
1706
2155
  var skippedEntry = lastMatch(function (entry) { return /Publish skipped/i.test(entry || ''); });
1707
2156
  if (skippedEntry) {
@@ -1933,6 +2382,22 @@ var SlowQueryVerifier = /** @class */ (function () {
1933
2382
  };
1934
2383
  };
1935
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
+ }
1936
2401
  if (outputEquivalence && !outputEquivalence.passed) {
1937
2402
  return {
1938
2403
  passed: false,
@@ -2020,7 +2485,7 @@ var SlowQueryVerifier = /** @class */ (function () {
2020
2485
  }
2021
2486
  return "".concat(index + 1, ". ").concat(stage.stage, " @ ").concat(stage.path).concat(metrics.length ? " (".concat(metrics.join(', '), ")") : '');
2022
2487
  };
2023
- SlowQueryVerifier.prototype.buildSlowQueryAutoOptimizeDescription = function (log, app, baseline) {
2488
+ SlowQueryVerifier.prototype.buildSlowQueryAutoOptimizeDescription = function (log, app, baseline, repoSlug) {
2024
2489
  var _this = this;
2025
2490
  var topStages = Array.isArray(baseline.topStages) ? baseline.topStages : [];
2026
2491
  var lookupExprInCount = SlowQueryVerifier.countLookupExprInPattern(Array.isArray(log.pipeline) ? log.pipeline : []);
@@ -2035,14 +2500,17 @@ var SlowQueryVerifier = /** @class */ (function () {
2035
2500
  '5. Locate the source query in app code and optimize it safely (query shape contract must remain compatible).',
2036
2501
  '6. Add or adjust indexes/code paths so docs examined and processing time drop significantly.',
2037
2502
  '7. Measure before/after `explain(\"executionStats\")` and identify the slowest stages by execution time/docs examined.',
2038
- '8. Keep returned data behavior stable for existing consumers (output fingerprint + row count must remain equivalent).',
2503
+ '8. Returned data must be exactly equivalent before and after optimization. Any output difference is a failed run.',
2039
2504
  '9. In `$lookup`, avoid `$expr` + `$in` when equivalent `localField` / `foreignField` joins are possible and index-friendly.',
2040
2505
  '10. Run build/lint checks and iterate until green.',
2041
- '11. Publish to default branch and deploy artifacts automatically after build success.',
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.',
2042
2508
  '',
2043
2509
  "App: ".concat(app.name || app._id),
2044
- "Repo: ".concat(app.repo || 'unknown'),
2510
+ "Repo: ".concat(repoSlug || app.repo || 'unknown'),
2045
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>'),
2046
2514
  "Collection: ".concat(log.collection),
2047
2515
  "Query Hash: ".concat(log.query_hash),
2048
2516
  "Slow Query Log Id: ".concat(String((log === null || log === void 0 ? void 0 : log._id) || '').trim() || 'n/a'),
@@ -2076,6 +2544,23 @@ var SlowQueryVerifier = /** @class */ (function () {
2076
2544
  ], false);
2077
2545
  return lines.join('\n');
2078
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
+ };
2079
2564
  SlowQueryVerifier.queryHasExplicitSort = function (pipeline, findOptions) {
2080
2565
  var hasFindSort = !!((findOptions === null || findOptions === void 0 ? void 0 : findOptions.sort) && typeof findOptions.sort === 'object' && Object.keys(findOptions.sort).length);
2081
2566
  if (hasFindSort) {
@@ -2496,184 +2981,193 @@ var SlowQueryVerifier = /** @class */ (function () {
2496
2981
  });
2497
2982
  });
2498
2983
  };
2499
- SlowQueryVerifier.prototype.runAutoOptimization = function (logId) {
2500
- return __awaiter(this, void 0, void 0, function () {
2501
- var log, attemptsUsed, maxAttempts, cooldownDeadline, fingerprintMaxAttempts, windowHours, windowStart, fingerprintAttempts, app, tokenEligibility, reason, baselineExplain, error_7, baselineFallbackDuration, baselineDurationMs, baselineMetrics, baselineOutputFingerprint, error_8, title, description, job, error_9, jobId, attemptStartedAt, queuedLog, error_10, isRunning, error_11, finalJob, publishOutcome, refreshedLog, afterExplain, error_12, afterMetrics, outputEquivalence, afterOutputFingerprint, error_13, validation, autoFixResult, optimizedLog;
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; }
2502
2988
  return __generator(this, function (_a) {
2503
2989
  switch (_a.label) {
2504
- case 0:
2505
- if (!logId || !this.config.autoOptimizeEnabled) {
2990
+ case 0: return [4 /*yield*/, this.resolveAutoOptimizeEnabled()];
2991
+ case 1:
2992
+ autoOptimizeEnabled = _a.sent();
2993
+ if (!logId || (!autoOptimizeEnabled && !force)) {
2506
2994
  return [2 /*return*/];
2507
2995
  }
2508
2996
  return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
2509
- case 1:
2997
+ case 2:
2510
2998
  log = _a.sent();
2511
2999
  if (!log || !log._id || log.ignored) {
2512
3000
  return [2 /*return*/];
2513
3001
  }
2514
- if (log.status === 'optimized') {
3002
+ if (log.status === 'optimized' && !force) {
2515
3003
  return [2 /*return*/];
2516
3004
  }
2517
- if (log.auto_fix_status === 'running' || log.auto_fix_status === 'queued') {
3005
+ if (log.auto_fix_status === 'running') {
2518
3006
  return [2 /*return*/];
2519
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];
2520
3012
  attemptsUsed = Number.isFinite(Number(log.auto_fix_attempt_count))
2521
3013
  ? Number(log.auto_fix_attempt_count)
2522
3014
  : 0;
2523
3015
  maxAttempts = Number.isFinite(Number(this.config.autoOptimizeMaxAttemptsPerQuery))
2524
3016
  ? Number(this.config.autoOptimizeMaxAttemptsPerQuery)
2525
3017
  : 0;
2526
- if (!(maxAttempts > 0 && attemptsUsed >= maxAttempts)) return [3 /*break*/, 3];
3018
+ if (!(maxAttempts > 0 && attemptsUsed >= maxAttempts)) return [3 /*break*/, 4];
2527
3019
  return [4 /*yield*/, this.markAutoOptimizeBudgetExceeded(log, 'Auto optimize skipped')];
2528
- case 2:
3020
+ case 3:
2529
3021
  _a.sent();
2530
3022
  return [2 /*return*/];
2531
- case 3:
3023
+ case 4:
2532
3024
  cooldownDeadline = this.resolveCooldownDeadline(log);
2533
- if (!(cooldownDeadline && cooldownDeadline.getTime() > Date.now())) return [3 /*break*/, 5];
3025
+ if (!(cooldownDeadline && cooldownDeadline.getTime() > Date.now())) return [3 /*break*/, 6];
2534
3026
  return [4 /*yield*/, this.markAutoOptimizeCooldownActive(log, cooldownDeadline)];
2535
- case 4:
3027
+ case 5:
2536
3028
  _a.sent();
2537
3029
  return [2 /*return*/];
2538
- case 5:
3030
+ case 6:
2539
3031
  fingerprintMaxAttempts = Number.isFinite(Number(this.config.autoOptimizeMaxAttemptsPerFingerprint))
2540
3032
  ? Number(this.config.autoOptimizeMaxAttemptsPerFingerprint)
2541
3033
  : 0;
2542
- if (!(fingerprintMaxAttempts > 0)) return [3 /*break*/, 8];
3034
+ if (!(fingerprintMaxAttempts > 0)) return [3 /*break*/, 9];
2543
3035
  windowHours = Number.isFinite(Number(this.config.autoOptimizeFingerprintWindowHours))
2544
3036
  ? Number(this.config.autoOptimizeFingerprintWindowHours)
2545
3037
  : AUTO_OPTIMIZE_DEFAULT_FINGERPRINT_WINDOW_HOURS;
2546
3038
  windowStart = new Date(Date.now() - (windowHours * 60 * 60 * 1000));
2547
3039
  return [4 /*yield*/, this.resolveFingerprintAttemptsInWindow(log, windowStart)];
2548
- case 6:
3040
+ case 7:
2549
3041
  fingerprintAttempts = _a.sent();
2550
- if (!(fingerprintAttempts >= fingerprintMaxAttempts)) return [3 /*break*/, 8];
3042
+ if (!(fingerprintAttempts >= fingerprintMaxAttempts)) return [3 /*break*/, 9];
2551
3043
  return [4 /*yield*/, this.markAutoOptimizeBudgetExceeded(log, "Auto optimize skipped: fingerprint budget reached (".concat(fingerprintAttempts, "/").concat(fingerprintMaxAttempts, ") in the last ").concat(windowHours, "h."))];
2552
- case 7:
3044
+ case 8:
2553
3045
  _a.sent();
2554
3046
  return [2 /*return*/];
2555
- case 8: return [4 /*yield*/, this.resolveAutoOptimizeApp(log)];
2556
- case 9:
3047
+ case 9: return [4 /*yield*/, this.resolveAutoOptimizeApp(log)];
3048
+ case 10:
2557
3049
  app = _a.sent();
2558
- if (!(!(app === null || app === void 0 ? void 0 : app._id) || !app.repo)) return [3 /*break*/, 11];
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];
2559
3053
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2560
3054
  $set: {
2561
3055
  status: 'investigating',
2562
3056
  auto_fix_status: 'failed',
2563
- verification_notes: 'Auto optimize skipped: unable to map slow query to AI Coder app/repo.',
3057
+ verification_notes: 'Auto optimize skipped: unable to map slow query to AI Coder app/repo configuration.',
2564
3058
  last_triaged_by: 'auto-slow-query',
2565
3059
  last_triaged_at: new Date()
2566
3060
  }
2567
3061
  })];
2568
- case 10:
3062
+ case 11:
2569
3063
  _a.sent();
2570
3064
  return [2 /*return*/];
2571
- case 11: return [4 /*yield*/, checkAICoderTokenEligibility(app._id, this.config.autoOptimizeRequiredTokens > 0 ? this.config.autoOptimizeRequiredTokens : undefined)];
2572
- case 12:
3065
+ case 12: return [4 /*yield*/, checkAICoderTokenEligibility(app._id, this.config.autoOptimizeRequiredTokens > 0 ? this.config.autoOptimizeRequiredTokens : undefined)];
3066
+ case 13:
2573
3067
  tokenEligibility = _a.sent();
2574
- if (!!tokenEligibility.allowed) return [3 /*break*/, 14];
3068
+ if (!!tokenEligibility.allowed) return [3 /*break*/, 15];
2575
3069
  reason = "".concat(tokenEligibility.message, " Available: ").concat(tokenEligibility.summary.available_tokens.toLocaleString(), " tokens; required: ").concat(tokenEligibility.required_tokens.toLocaleString(), ".");
2576
3070
  return [4 /*yield*/, this.markAutoOptimizeTokenIneligible(log, reason)];
2577
- case 13:
3071
+ case 14:
2578
3072
  _a.sent();
2579
3073
  return [2 /*return*/];
2580
- case 14:
2581
- _a.trys.push([14, 16, , 19]);
2582
- return [4 /*yield*/, this.runExplain(log)];
2583
3074
  case 15:
2584
- baselineExplain = _a.sent();
2585
- return [3 /*break*/, 19];
3075
+ _a.trys.push([15, 17, , 20]);
3076
+ return [4 /*yield*/, this.runExplain(log)];
2586
3077
  case 16:
2587
- error_7 = _a.sent();
3078
+ baselineExplain = _a.sent();
3079
+ return [3 /*break*/, 20];
3080
+ case 17:
3081
+ error_11 = _a.sent();
2588
3082
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2589
3083
  $set: {
2590
3084
  status: 'investigating',
2591
3085
  auto_fix_status: 'failed',
2592
3086
  auto_fix_result: {
2593
- baseline_error: (error_7 === null || error_7 === void 0 ? void 0 : error_7.message) || 'unknown'
3087
+ baseline_error: (error_11 === null || error_11 === void 0 ? void 0 : error_11.message) || 'unknown'
2594
3088
  },
2595
- verification_notes: "Auto optimize baseline measurement failed: ".concat((error_7 === null || error_7 === void 0 ? void 0 : error_7.message) || 'unknown error'),
3089
+ verification_notes: "Auto optimize baseline measurement failed: ".concat((error_11 === null || error_11 === void 0 ? void 0 : error_11.message) || 'unknown error'),
2596
3090
  last_triaged_by: 'auto-slow-query',
2597
3091
  last_triaged_at: new Date()
2598
3092
  }
2599
3093
  })];
2600
- case 17:
3094
+ case 18:
2601
3095
  _a.sent();
2602
3096
  return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize baseline measurement failed')];
2603
- case 18:
3097
+ case 19:
2604
3098
  _a.sent();
2605
3099
  return [2 /*return*/];
2606
- case 19:
3100
+ case 20:
2607
3101
  baselineFallbackDuration = this.resolveBaselineDurationMs(log);
2608
3102
  baselineDurationMs = SlowQueryVerifier.isValidDuration(baselineExplain.durationMs)
2609
3103
  ? baselineExplain.durationMs
2610
3104
  : baselineFallbackDuration;
2611
3105
  baselineMetrics = this.resolveExecutionMetrics(baselineExplain.explainStats || {}, baselineDurationMs, baselineExplain.stageSummaries || []);
2612
- if (!this.config.autoOptimizeOutputCompareEnabled) return [3 /*break*/, 25];
2613
- _a.label = 20;
2614
- case 20:
2615
- _a.trys.push([20, 22, , 25]);
2616
- return [4 /*yield*/, this.captureOutputFingerprint(log)];
3106
+ if (!this.config.autoOptimizeOutputCompareEnabled) return [3 /*break*/, 26];
3107
+ _a.label = 21;
2617
3108
  case 21:
2618
- baselineOutputFingerprint = _a.sent();
2619
- return [3 /*break*/, 25];
3109
+ _a.trys.push([21, 23, , 26]);
3110
+ return [4 /*yield*/, this.captureOutputFingerprint(log)];
2620
3111
  case 22:
2621
- error_8 = _a.sent();
3112
+ baselineOutputFingerprint = _a.sent();
3113
+ return [3 /*break*/, 26];
3114
+ case 23:
3115
+ error_12 = _a.sent();
2622
3116
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2623
3117
  $set: {
2624
3118
  status: 'investigating',
2625
3119
  auto_fix_status: 'failed',
2626
3120
  auto_fix_result: {
2627
- baseline_error: (error_8 === null || error_8 === void 0 ? void 0 : error_8.message) || 'unknown'
3121
+ baseline_error: (error_12 === null || error_12 === void 0 ? void 0 : error_12.message) || 'unknown'
2628
3122
  },
2629
- verification_notes: "Auto optimize baseline output comparison failed: ".concat((error_8 === null || error_8 === void 0 ? void 0 : error_8.message) || 'unknown error'),
3123
+ verification_notes: "Auto optimize baseline output comparison failed: ".concat((error_12 === null || error_12 === void 0 ? void 0 : error_12.message) || 'unknown error'),
2630
3124
  last_triaged_by: 'auto-slow-query',
2631
3125
  last_triaged_at: new Date()
2632
3126
  }
2633
3127
  })];
2634
- case 23:
3128
+ case 24:
2635
3129
  _a.sent();
2636
3130
  return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize baseline output comparison failed')];
2637
- case 24:
3131
+ case 25:
2638
3132
  _a.sent();
2639
3133
  return [2 /*return*/];
2640
- case 25:
2641
- title = "Optimize slow query ".concat(log.slow_query_count_string || log.collection);
2642
- description = this.buildSlowQueryAutoOptimizeDescription(log, app, baselineMetrics);
2643
- _a.label = 26;
2644
3134
  case 26:
2645
- _a.trys.push([26, 28, , 31]);
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]);
2646
3140
  return [4 /*yield*/, this.createDashboardJob({
2647
3141
  project: app._id,
2648
3142
  title: title,
2649
3143
  description: description,
2650
- repo: app.repo,
2651
- path: app.git_local_path || undefined,
3144
+ repo: resolvedRepoSlug,
3145
+ path: resolvedRepoPath || undefined,
2652
3146
  projectRoot: app.project_root || undefined
2653
3147
  })];
2654
- case 27:
2655
- job = _a.sent();
2656
- return [3 /*break*/, 31];
2657
3148
  case 28:
2658
- error_9 = _a.sent();
3149
+ job = _a.sent();
3150
+ return [3 /*break*/, 32];
3151
+ case 29:
3152
+ error_13 = _a.sent();
2659
3153
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2660
3154
  $set: {
2661
3155
  status: 'investigating',
2662
3156
  auto_fix_status: 'failed',
2663
- verification_notes: "Auto optimize enqueue failed: ".concat((error_9 === null || error_9 === void 0 ? void 0 : error_9.message) || 'unknown error'),
3157
+ verification_notes: "Auto optimize enqueue failed: ".concat((error_13 === null || error_13 === void 0 ? void 0 : error_13.message) || 'unknown error'),
2664
3158
  last_triaged_by: 'auto-slow-query',
2665
3159
  last_triaged_at: new Date()
2666
3160
  }
2667
3161
  })];
2668
- case 29:
3162
+ case 30:
2669
3163
  _a.sent();
2670
3164
  return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize wait failed')];
2671
- case 30:
3165
+ case 31:
2672
3166
  _a.sent();
2673
3167
  return [2 /*return*/];
2674
- case 31:
3168
+ case 32:
2675
3169
  jobId = String((job === null || job === void 0 ? void 0 : job._id) || '').trim();
2676
- if (!!jobId) return [3 /*break*/, 33];
3170
+ if (!!jobId) return [3 /*break*/, 34];
2677
3171
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2678
3172
  $set: {
2679
3173
  status: 'investigating',
@@ -2683,10 +3177,10 @@ var SlowQueryVerifier = /** @class */ (function () {
2683
3177
  last_triaged_at: new Date()
2684
3178
  }
2685
3179
  })];
2686
- case 32:
3180
+ case 33:
2687
3181
  _a.sent();
2688
3182
  return [2 /*return*/];
2689
- case 33:
3183
+ case 34:
2690
3184
  attemptStartedAt = new Date();
2691
3185
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2692
3186
  $inc: {
@@ -2709,71 +3203,71 @@ var SlowQueryVerifier = /** @class */ (function () {
2709
3203
  last_triaged_at: new Date()
2710
3204
  }
2711
3205
  })];
2712
- case 34:
3206
+ case 35:
2713
3207
  _a.sent();
2714
3208
  return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
2715
- case 35:
3209
+ case 36:
2716
3210
  queuedLog = (_a.sent()) || log;
2717
3211
  return [4 /*yield*/, this.notifyCustomerSlowQueryStatus('detected_auto_optimize_enabled', queuedLog)];
2718
- case 36:
2719
- _a.sent();
2720
- _a.label = 37;
2721
3212
  case 37:
2722
- _a.trys.push([37, 39, , 42]);
2723
- return [4 /*yield*/, this.waitForDashboardJobStop(jobId, this.config.autoOptimizeWaitTimeoutMs)];
2724
- case 38:
2725
3213
  _a.sent();
2726
- return [3 /*break*/, 42];
3214
+ _a.label = 38;
3215
+ case 38:
3216
+ _a.trys.push([38, 40, , 43]);
3217
+ return [4 /*yield*/, this.waitForDashboardJobStop(jobId, this.config.autoOptimizeWaitTimeoutMs)];
2727
3218
  case 39:
2728
- error_10 = _a.sent();
3219
+ _a.sent();
3220
+ return [3 /*break*/, 43];
3221
+ case 40:
3222
+ error_14 = _a.sent();
2729
3223
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2730
3224
  $set: {
2731
3225
  status: 'investigating',
2732
3226
  auto_fix_status: 'failed',
2733
3227
  auto_fix_result: {
2734
3228
  job_id: jobId,
2735
- error: (error_10 === null || error_10 === void 0 ? void 0 : error_10.message) || 'timeout'
3229
+ error: (error_14 === null || error_14 === void 0 ? void 0 : error_14.message) || 'timeout'
2736
3230
  },
2737
- verification_notes: "Auto optimize wait failed: ".concat((error_10 === null || error_10 === void 0 ? void 0 : error_10.message) || 'timeout'),
3231
+ verification_notes: "Auto optimize wait failed: ".concat((error_14 === null || error_14 === void 0 ? void 0 : error_14.message) || 'timeout'),
2738
3232
  last_triaged_by: 'auto-slow-query',
2739
3233
  last_triaged_at: new Date()
2740
3234
  }
2741
3235
  })];
2742
- case 40:
3236
+ case 41:
2743
3237
  _a.sent();
2744
3238
  return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize job state check failed')];
2745
- case 41:
3239
+ case 42:
2746
3240
  _a.sent();
2747
3241
  return [2 /*return*/];
2748
- case 42:
2749
- isRunning = false;
2750
- _a.label = 43;
2751
3242
  case 43:
2752
- _a.trys.push([43, 45, , 47]);
2753
- return [4 /*yield*/, this.isDashboardJobRunning(jobId)];
3243
+ isRunning = false;
3244
+ _a.label = 44;
2754
3245
  case 44:
2755
- isRunning = _a.sent();
2756
- return [3 /*break*/, 47];
3246
+ _a.trys.push([44, 46, , 48]);
3247
+ return [4 /*yield*/, this.isDashboardJobRunning(jobId)];
2757
3248
  case 45:
2758
- error_11 = _a.sent();
3249
+ isRunning = _a.sent();
3250
+ return [3 /*break*/, 48];
3251
+ case 46:
3252
+ error_15 = _a.sent();
2759
3253
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2760
3254
  $set: {
2761
3255
  status: 'investigating',
2762
3256
  auto_fix_status: 'failed',
2763
3257
  auto_fix_result: {
2764
3258
  job_id: jobId,
2765
- error: (error_11 === null || error_11 === void 0 ? void 0 : error_11.message) || 'unknown'
3259
+ error: (error_15 === null || error_15 === void 0 ? void 0 : error_15.message) || 'unknown'
2766
3260
  },
2767
- verification_notes: "Unable to confirm dashboard job state: ".concat((error_11 === null || error_11 === void 0 ? void 0 : error_11.message) || 'unknown error'),
3261
+ verification_notes: "Unable to confirm dashboard job state: ".concat((error_15 === null || error_15 === void 0 ? void 0 : error_15.message) || 'unknown error'),
2768
3262
  last_triaged_by: 'auto-slow-query',
2769
3263
  last_triaged_at: new Date()
2770
3264
  }
2771
3265
  })];
2772
- case 46:
3266
+ case 47:
2773
3267
  _a.sent();
2774
3268
  return [2 /*return*/];
2775
- case 47:
2776
- if (!isRunning) return [3 /*break*/, 50];
3269
+ case 48:
3270
+ if (!isRunning) return [3 /*break*/, 51];
2777
3271
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2778
3272
  $set: {
2779
3273
  status: 'investigating',
@@ -2787,16 +3281,16 @@ var SlowQueryVerifier = /** @class */ (function () {
2787
3281
  last_triaged_at: new Date()
2788
3282
  }
2789
3283
  })];
2790
- case 48:
3284
+ case 49:
2791
3285
  _a.sent();
2792
3286
  return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize timed out')];
2793
- case 49:
3287
+ case 50:
2794
3288
  _a.sent();
2795
3289
  return [2 /*return*/];
2796
- case 50: return [4 /*yield*/, AIDashboardJobs.findOne({ _id: jobId })];
2797
- case 51:
3290
+ case 51: return [4 /*yield*/, AIDashboardJobs.findOne({ _id: jobId })];
3291
+ case 52:
2798
3292
  finalJob = _a.sent();
2799
- if (!(!finalJob || finalJob.phase !== 'COMPLETE' || finalJob.paused)) return [3 /*break*/, 54];
3293
+ if (!(!finalJob || finalJob.phase !== 'COMPLETE' || finalJob.paused)) return [3 /*break*/, 55];
2800
3294
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2801
3295
  $set: {
2802
3296
  status: 'investigating',
@@ -2811,46 +3305,47 @@ var SlowQueryVerifier = /** @class */ (function () {
2811
3305
  last_triaged_at: new Date()
2812
3306
  }
2813
3307
  })];
2814
- case 52:
3308
+ case 53:
2815
3309
  _a.sent();
2816
3310
  return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize job did not complete')];
2817
- case 53:
3311
+ case 54:
2818
3312
  _a.sent();
2819
3313
  return [2 /*return*/];
2820
- case 54:
3314
+ case 55:
2821
3315
  publishOutcome = this.evaluateDashboardPublishOutcome(finalJob);
2822
- if (!!publishOutcome.success) return [3 /*break*/, 57];
3316
+ if (!!publishOutcome.success) return [3 /*break*/, 58];
2823
3317
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2824
3318
  $set: {
2825
3319
  status: 'investigating',
2826
3320
  auto_fix_status: 'failed',
2827
3321
  auto_fix_result: {
2828
3322
  job_id: jobId,
2829
- publish_message: publishOutcome.message
3323
+ publish_message: publishOutcome.message,
3324
+ publish_branch: publishOutcome.branchName || ''
2830
3325
  },
2831
3326
  verification_notes: "Auto optimize publish/deploy failed: ".concat(publishOutcome.message),
2832
3327
  last_triaged_by: 'auto-slow-query',
2833
3328
  last_triaged_at: new Date()
2834
3329
  }
2835
3330
  })];
2836
- case 55:
3331
+ case 56:
2837
3332
  _a.sent();
2838
3333
  return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize publish/deploy failed')];
2839
- case 56:
3334
+ case 57:
2840
3335
  _a.sent();
2841
3336
  return [2 /*return*/];
2842
- case 57: return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
2843
- case 58:
2844
- refreshedLog = (_a.sent()) || log;
2845
- _a.label = 59;
3337
+ case 58: return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
2846
3338
  case 59:
2847
- _a.trys.push([59, 61, , 64]);
2848
- return [4 /*yield*/, this.runExplain(refreshedLog)];
3339
+ refreshedLog = (_a.sent()) || log;
3340
+ _a.label = 60;
2849
3341
  case 60:
2850
- afterExplain = _a.sent();
2851
- return [3 /*break*/, 64];
3342
+ _a.trys.push([60, 62, , 65]);
3343
+ return [4 /*yield*/, this.runExplain(refreshedLog)];
2852
3344
  case 61:
2853
- error_12 = _a.sent();
3345
+ afterExplain = _a.sent();
3346
+ return [3 /*break*/, 65];
3347
+ case 62:
3348
+ error_16 = _a.sent();
2854
3349
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2855
3350
  $set: {
2856
3351
  status: 'investigating',
@@ -2858,38 +3353,39 @@ var SlowQueryVerifier = /** @class */ (function () {
2858
3353
  auto_fix_result: {
2859
3354
  job_id: jobId,
2860
3355
  publish_message: publishOutcome.message,
2861
- validation_error: (error_12 === null || error_12 === void 0 ? void 0 : error_12.message) || 'unknown'
3356
+ publish_branch: publishOutcome.branchName || '',
3357
+ validation_error: (error_16 === null || error_16 === void 0 ? void 0 : error_16.message) || 'unknown'
2862
3358
  },
2863
- verification_notes: "Post-deploy validation failed: ".concat((error_12 === null || error_12 === void 0 ? void 0 : error_12.message) || 'unknown error'),
3359
+ verification_notes: "Post-deploy validation failed: ".concat((error_16 === null || error_16 === void 0 ? void 0 : error_16.message) || 'unknown error'),
2864
3360
  last_triaged_by: 'auto-slow-query',
2865
3361
  last_triaged_at: new Date()
2866
3362
  }
2867
3363
  })];
2868
- case 62:
3364
+ case 63:
2869
3365
  _a.sent();
2870
3366
  return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize post-deploy validation failed')];
2871
- case 63:
3367
+ case 64:
2872
3368
  _a.sent();
2873
3369
  return [2 /*return*/];
2874
- case 64:
3370
+ case 65:
2875
3371
  afterMetrics = this.resolveExecutionMetrics(afterExplain.explainStats || {}, afterExplain.durationMs, afterExplain.stageSummaries || []);
2876
- if (!this.config.autoOptimizeOutputCompareEnabled) return [3 /*break*/, 70];
2877
- if (!!baselineOutputFingerprint) return [3 /*break*/, 65];
3372
+ if (!this.config.autoOptimizeOutputCompareEnabled) return [3 /*break*/, 71];
3373
+ if (!!baselineOutputFingerprint) return [3 /*break*/, 66];
2878
3374
  outputEquivalence = {
2879
3375
  passed: false,
2880
3376
  reason: 'Baseline output fingerprint missing.',
2881
3377
  mode: 'unknown'
2882
3378
  };
2883
- return [3 /*break*/, 70];
2884
- case 65:
2885
- _a.trys.push([65, 67, , 70]);
2886
- return [4 /*yield*/, this.captureOutputFingerprint(refreshedLog)];
3379
+ return [3 /*break*/, 71];
2887
3380
  case 66:
3381
+ _a.trys.push([66, 68, , 71]);
3382
+ return [4 /*yield*/, this.captureOutputFingerprint(refreshedLog)];
3383
+ case 67:
2888
3384
  afterOutputFingerprint = _a.sent();
2889
3385
  outputEquivalence = this.compareOutputEquivalence(baselineOutputFingerprint, afterOutputFingerprint);
2890
- return [3 /*break*/, 70];
2891
- case 67:
2892
- error_13 = _a.sent();
3386
+ return [3 /*break*/, 71];
3387
+ case 68:
3388
+ error_17 = _a.sent();
2893
3389
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2894
3390
  $set: {
2895
3391
  status: 'investigating',
@@ -2897,11 +3393,12 @@ var SlowQueryVerifier = /** @class */ (function () {
2897
3393
  auto_fix_result: {
2898
3394
  job_id: jobId,
2899
3395
  publish_message: publishOutcome.message,
3396
+ publish_branch: publishOutcome.branchName || '',
2900
3397
  baseline: baselineMetrics,
2901
3398
  after: afterMetrics,
2902
- output_equivalence_error: (error_13 === null || error_13 === void 0 ? void 0 : error_13.message) || 'unknown'
3399
+ output_equivalence_error: (error_17 === null || error_17 === void 0 ? void 0 : error_17.message) || 'unknown'
2903
3400
  },
2904
- verification_notes: "Post-deploy output comparison failed: ".concat((error_13 === null || error_13 === void 0 ? void 0 : error_13.message) || 'unknown error'),
3401
+ verification_notes: "Post-deploy output comparison failed: ".concat((error_17 === null || error_17 === void 0 ? void 0 : error_17.message) || 'unknown error'),
2905
3402
  explain_plan: afterExplain.explainPlan,
2906
3403
  explain_execution_stats: afterExplain.explainStats,
2907
3404
  explain_generated_at: new Date(),
@@ -2915,23 +3412,24 @@ var SlowQueryVerifier = /** @class */ (function () {
2915
3412
  }
2916
3413
  }
2917
3414
  })];
2918
- case 68:
3415
+ case 69:
2919
3416
  _a.sent();
2920
3417
  return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize output comparison failed')];
2921
- case 69:
3418
+ case 70:
2922
3419
  _a.sent();
2923
3420
  return [2 /*return*/];
2924
- case 70:
3421
+ case 71:
2925
3422
  validation = this.evaluateOptimizationOutcome(baselineMetrics, afterMetrics, outputEquivalence);
2926
3423
  autoFixResult = {
2927
3424
  job_id: jobId,
2928
3425
  publish_message: publishOutcome.message,
3426
+ publish_branch: publishOutcome.branchName || '',
2929
3427
  baseline: baselineMetrics,
2930
3428
  after: afterMetrics,
2931
3429
  output_equivalence: outputEquivalence,
2932
3430
  validation: validation
2933
3431
  };
2934
- if (!!validation.passed) return [3 /*break*/, 73];
3432
+ if (!!validation.passed) return [3 /*break*/, 74];
2935
3433
  return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2936
3434
  $set: {
2937
3435
  status: 'investigating',
@@ -2951,13 +3449,13 @@ var SlowQueryVerifier = /** @class */ (function () {
2951
3449
  }
2952
3450
  }
2953
3451
  })];
2954
- case 71:
3452
+ case 72:
2955
3453
  _a.sent();
2956
3454
  return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize validation failed')];
2957
- case 72:
3455
+ case 73:
2958
3456
  _a.sent();
2959
3457
  return [2 /*return*/];
2960
- case 73: return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
3458
+ case 74: return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
2961
3459
  $set: {
2962
3460
  status: 'optimized',
2963
3461
  auto_fix_status: 'completed',
@@ -2976,13 +3474,13 @@ var SlowQueryVerifier = /** @class */ (function () {
2976
3474
  }
2977
3475
  }
2978
3476
  })];
2979
- case 74:
3477
+ case 75:
2980
3478
  _a.sent();
2981
3479
  return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
2982
- case 75:
3480
+ case 76:
2983
3481
  optimizedLog = (_a.sent()) || log;
2984
3482
  return [4 /*yield*/, this.notifyCustomerSlowQueryStatus('completed_success', optimizedLog, { notes: validation.reason })];
2985
- case 76:
3483
+ case 77:
2986
3484
  _a.sent();
2987
3485
  return [2 /*return*/];
2988
3486
  }
@@ -3351,6 +3849,7 @@ var SlowQueryVerifier = /** @class */ (function () {
3351
3849
  });
3352
3850
  return result;
3353
3851
  };
3852
+ SlowQueryVerifier.APP_SETTINGS_CACHE_TTL_MS = 10000;
3354
3853
  return SlowQueryVerifier;
3355
3854
  }());
3356
3855
  exports.SlowQueryVerifier = SlowQueryVerifier;