UNPKG

@ahmedhegazee/nestjs-telescope

Version:

Advanced observability and monitoring solution for NestJS applications with ML-powered analytics, enterprise features, and production-ready scaling

585 lines 27.7 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Week8MLAnalyticsController = exports.MLInsightSummary = exports.AlertRuleDto = exports.AlertChannelDto = exports.AnomalyQueryDto = void 0; const common_1 = require("@nestjs/common"); const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const swagger_1 = require("@nestjs/swagger"); const ml_analytics_service_1 = require("../../core/services/ml-analytics.service"); const automated_alerting_service_1 = require("../../core/services/automated-alerting.service"); class AnomalyQueryDto { constructor() { this.limit = 50; } } exports.AnomalyQueryDto = AnomalyQueryDto; class AlertChannelDto { constructor() { this.enabled = true; this.severityFilter = ['warning', 'error', 'critical']; } } exports.AlertChannelDto = AlertChannelDto; class AlertRuleDto { constructor() { this.enabled = true; this.priority = 5; } } exports.AlertRuleDto = AlertRuleDto; class MLInsightSummary { } exports.MLInsightSummary = MLInsightSummary; let Week8MLAnalyticsController = class Week8MLAnalyticsController { constructor(mlAnalyticsService, alertingService) { this.mlAnalyticsService = mlAnalyticsService; this.alertingService = alertingService; } async getMLOverview() { const [anomalies, regressions, optimizations, predictions, alerts] = await Promise.all([ this.mlAnalyticsService.getCurrentAnomalies(), this.mlAnalyticsService.getCurrentRegressions(), this.mlAnalyticsService.getCurrentOptimizations(), this.mlAnalyticsService.getCurrentPredictions(), this.mlAnalyticsService.getCurrentAlerts(), ]); const criticalAnomalies = anomalies.filter((a) => a.severity === 'critical').length; const criticalPredictions = predictions.filter((p) => p.riskLevel === 'critical').length; const criticalAlerts = alerts.filter((a) => a.severity === 'critical').length; let healthScore = 100; healthScore -= criticalAnomalies * 15; healthScore -= criticalPredictions * 10; healthScore -= criticalAlerts * 20; healthScore = Math.max(0, Math.min(100, healthScore)); const riskLevel = healthScore < 30 ? 'critical' : healthScore < 50 ? 'high' : healthScore < 70 ? 'medium' : 'low'; const topConcerns = [ ...anomalies .filter((a) => a.severity === 'critical' || a.severity === 'high') .slice(0, 3) .map((a) => ({ type: 'anomaly', component: a.component, severity: a.severity, description: a.description, })), ...predictions .filter((p) => p.riskLevel === 'critical' || p.riskLevel === 'high') .slice(0, 2) .map((p) => ({ type: 'prediction', component: p.component, severity: p.riskLevel, description: `Predicted ${p.trend} for ${p.metric}`, })), ]; return { timestamp: new Date(), anomaliesCount: anomalies.length, regressionsCount: regressions.length, optimizationsCount: optimizations.length, predictionsCount: predictions.length, alertsCount: alerts.length, healthScore, riskLevel, topConcerns, }; } getAnomalies(query) { let anomalies = this.mlAnalyticsService.getCurrentAnomalies(); if (query.component) { anomalies = anomalies.filter((a) => a.component === query.component); } if (query.severity) { anomalies = anomalies.filter((a) => a.severity === query.severity); } if (query.type) { anomalies = anomalies.filter((a) => a.type === query.type); } if (query.from) { anomalies = anomalies.filter((a) => a.timestamp >= new Date(query.from)); } if (query.to) { anomalies = anomalies.filter((a) => a.timestamp <= new Date(query.to)); } const limit = query.limit || 50; return anomalies.slice(-limit); } getAnomaliesStream() { return this.mlAnalyticsService.getAnomalies(); } dismissAnomaly(anomalyId) { return this.mlAnalyticsService.dismissAnomaly(anomalyId); } getRegressions(component, trend, limit = 50) { let regressions = this.mlAnalyticsService.getCurrentRegressions(); if (component) { regressions = regressions.filter((r) => r.component === component); } if (trend) { regressions = regressions.filter((r) => r.trend === trend); } return regressions.slice(-limit); } getRegressionsStream() { return this.mlAnalyticsService.getRegressionAnalysis(); } getOptimizations(table, type, effort, limit = 50) { let optimizations = this.mlAnalyticsService.getCurrentOptimizations(); if (table) { optimizations = optimizations.filter((o) => o.table === table); } if (type) { optimizations = optimizations.filter((o) => o.optimizationStrategy.type === type); } if (effort) { optimizations = optimizations.filter((o) => o.optimizationStrategy.effort === effort); } return optimizations.slice(-limit); } getOptimizationsStream() { return this.mlAnalyticsService.getOptimizationSuggestions(); } getPredictions(component, predictionType, timeHorizon, riskLevel, limit = 50) { let predictions = this.mlAnalyticsService.getCurrentPredictions(); if (component) { predictions = predictions.filter((p) => p.component === component); } if (predictionType) { predictions = predictions.filter((p) => p.predictionType === predictionType); } if (timeHorizon) { predictions = predictions.filter((p) => p.timeHorizon === timeHorizon); } if (riskLevel) { predictions = predictions.filter((p) => p.riskLevel === riskLevel); } return predictions.slice(-limit); } getPredictionsStream() { return this.mlAnalyticsService.getPredictiveInsights(); } getMLMetrics() { return this.mlAnalyticsService.getMLMetrics(); } getMLAlerts(severity, type, limit = 50) { let alerts = this.mlAnalyticsService.getCurrentAlerts(); if (severity) { alerts = alerts.filter((a) => a.severity === severity); } if (type) { alerts = alerts.filter((a) => a.type === type); } return alerts.slice(-limit); } getMLAlertsStream() { return this.mlAnalyticsService.getMLAlerts(); } acknowledgeMLAlert(alertId) { const acknowledged = this.mlAnalyticsService.acknowledgeAlert(alertId); return { success: acknowledged, alertId, acknowledgedAt: new Date(), }; } getAlertChannels() { return this.alertingService.getAlertChannels(); } createAlertChannel(channelDto) { const channel = { id: `channel_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, enabled: channelDto.enabled ?? true, severityFilter: channelDto.severityFilter ?? ['warning', 'error', 'critical'], ...channelDto, }; this.alertingService.addAlertChannel(channel); return { success: true, channel }; } deleteAlertChannel(channelId) { const deleted = this.alertingService.removeAlertChannel(channelId); if (!deleted) { throw new common_1.BadRequestException('Channel not found'); } } async testAlertChannel(channelId) { try { const success = await this.alertingService.testAlertChannel(channelId); return { success, message: success ? 'Channel test successful' : 'Channel test failed' }; } catch (error) { return { success: false, message: error.message }; } } getAlertRules() { return this.alertingService.getAlertRules(); } createAlertRule(ruleDto) { const rule = { id: `rule_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, enabled: ruleDto.enabled ?? true, priority: ruleDto.priority ?? 5, ...ruleDto, }; this.alertingService.addAlertRule(rule); return { success: true, rule }; } deleteAlertRule(ruleId) { const deleted = this.alertingService.removeAlertRule(ruleId); if (!deleted) { throw new common_1.BadRequestException('Rule not found'); } } getAlertHistory(limit = 100) { return this.alertingService.getAlertHistory(limit); } getAlertHistoryStream() { return this.alertingService.getAlertHistoryStream(); } getAlertMetrics() { return this.alertingService.getAlertMetrics(); } acknowledgeHistoryAlert(alertId) { const acknowledged = this.alertingService.acknowledgeAlert(alertId); return { success: acknowledged, alertId, acknowledgedAt: new Date(), }; } async getDashboardSummary() { const [overview, alertMetrics, mlMetrics] = await Promise.all([ this.getMLOverview(), this.alertingService.getAlertMetrics(), this.mlAnalyticsService.getMLMetrics(), ]); return { timestamp: new Date(), overview, alerting: alertMetrics, mlEngine: mlMetrics, system: { uptime: process.uptime(), memoryUsage: process.memoryUsage(), version: '8.0.0', }, }; } getLiveFeed() { return this.mlAnalyticsService.getMLAlerts().pipe((0, operators_1.map)((alerts) => ({ timestamp: new Date(), type: 'alert_update', data: alerts.slice(-10), }))); } }; exports.Week8MLAnalyticsController = Week8MLAnalyticsController; __decorate([ (0, common_1.Get)('overview'), (0, swagger_1.ApiOperation)({ summary: 'Get comprehensive ML analytics overview' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'ML analytics overview retrieved successfully' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], Week8MLAnalyticsController.prototype, "getMLOverview", null); __decorate([ (0, common_1.Get)('anomalies'), (0, swagger_1.ApiOperation)({ summary: 'Get detected anomalies with filtering' }), (0, swagger_1.ApiQuery)({ name: 'component', required: false, type: String }), (0, swagger_1.ApiQuery)({ name: 'severity', required: false, enum: ['low', 'medium', 'high', 'critical'] }), (0, swagger_1.ApiQuery)({ name: 'type', required: false, enum: ['performance', 'error', 'traffic', 'resource', 'query'], }), (0, swagger_1.ApiQuery)({ name: 'limit', required: false, type: Number }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Anomalies retrieved successfully' }), __param(0, (0, common_1.Query)()), __metadata("design:type", Function), __metadata("design:paramtypes", [AnomalyQueryDto]), __metadata("design:returntype", Array) ], Week8MLAnalyticsController.prototype, "getAnomalies", null); __decorate([ (0, common_1.Get)('anomalies/stream'), (0, swagger_1.ApiOperation)({ summary: 'Get real-time anomaly detection stream' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Anomaly stream established' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", rxjs_1.Observable) ], Week8MLAnalyticsController.prototype, "getAnomaliesStream", null); __decorate([ (0, common_1.Delete)('anomalies/:anomalyId'), (0, swagger_1.ApiOperation)({ summary: 'Dismiss a specific anomaly' }), (0, swagger_1.ApiParam)({ name: 'anomalyId', description: 'Anomaly ID to dismiss' }), (0, common_1.HttpCode)(common_1.HttpStatus.NO_CONTENT), __param(0, (0, common_1.Param)('anomalyId')), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", Boolean) ], Week8MLAnalyticsController.prototype, "dismissAnomaly", null); __decorate([ (0, common_1.Get)('regressions'), (0, swagger_1.ApiOperation)({ summary: 'Get performance regression analysis' }), (0, swagger_1.ApiQuery)({ name: 'component', required: false, type: String }), (0, swagger_1.ApiQuery)({ name: 'trend', required: false, enum: ['improving', 'degrading', 'stable'] }), (0, swagger_1.ApiQuery)({ name: 'limit', required: false, type: Number }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Regression analysis retrieved successfully' }), __param(0, (0, common_1.Query)('component')), __param(1, (0, common_1.Query)('trend')), __param(2, (0, common_1.Query)('limit', new common_1.ParseIntPipe({ optional: true }))), __metadata("design:type", Function), __metadata("design:paramtypes", [String, String, Number]), __metadata("design:returntype", Array) ], Week8MLAnalyticsController.prototype, "getRegressions", null); __decorate([ (0, common_1.Get)('regressions/stream'), (0, swagger_1.ApiOperation)({ summary: 'Get real-time regression analysis stream' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Regression analysis stream established' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", rxjs_1.Observable) ], Week8MLAnalyticsController.prototype, "getRegressionsStream", null); __decorate([ (0, common_1.Get)('optimizations'), (0, swagger_1.ApiOperation)({ summary: 'Get query optimization suggestions' }), (0, swagger_1.ApiQuery)({ name: 'table', required: false, type: String }), (0, swagger_1.ApiQuery)({ name: 'type', required: false, enum: ['index', 'rewrite', 'cache', 'partition', 'normalize'], }), (0, swagger_1.ApiQuery)({ name: 'effort', required: false, enum: ['low', 'medium', 'high'] }), (0, swagger_1.ApiQuery)({ name: 'limit', required: false, type: Number }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Optimization suggestions retrieved successfully' }), __param(0, (0, common_1.Query)('table')), __param(1, (0, common_1.Query)('type')), __param(2, (0, common_1.Query)('effort')), __param(3, (0, common_1.Query)('limit', new common_1.ParseIntPipe({ optional: true }))), __metadata("design:type", Function), __metadata("design:paramtypes", [String, String, String, Number]), __metadata("design:returntype", Array) ], Week8MLAnalyticsController.prototype, "getOptimizations", null); __decorate([ (0, common_1.Get)('optimizations/stream'), (0, swagger_1.ApiOperation)({ summary: 'Get real-time optimization suggestions stream' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Optimization suggestions stream established' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", rxjs_1.Observable) ], Week8MLAnalyticsController.prototype, "getOptimizationsStream", null); __decorate([ (0, common_1.Get)('predictions'), (0, swagger_1.ApiOperation)({ summary: 'Get predictive insights' }), (0, swagger_1.ApiQuery)({ name: 'component', required: false, type: String }), (0, swagger_1.ApiQuery)({ name: 'predictionType', required: false, enum: ['load', 'failure', 'performance', 'resource'], }), (0, swagger_1.ApiQuery)({ name: 'timeHorizon', required: false, enum: ['1h', '6h', '24h', '7d', '30d'] }), (0, swagger_1.ApiQuery)({ name: 'riskLevel', required: false, enum: ['low', 'medium', 'high', 'critical'] }), (0, swagger_1.ApiQuery)({ name: 'limit', required: false, type: Number }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Predictive insights retrieved successfully' }), __param(0, (0, common_1.Query)('component')), __param(1, (0, common_1.Query)('predictionType')), __param(2, (0, common_1.Query)('timeHorizon')), __param(3, (0, common_1.Query)('riskLevel')), __param(4, (0, common_1.Query)('limit', new common_1.ParseIntPipe({ optional: true }))), __metadata("design:type", Function), __metadata("design:paramtypes", [String, String, String, String, Number]), __metadata("design:returntype", Array) ], Week8MLAnalyticsController.prototype, "getPredictions", null); __decorate([ (0, common_1.Get)('predictions/stream'), (0, swagger_1.ApiOperation)({ summary: 'Get real-time predictive insights stream' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Predictive insights stream established' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", rxjs_1.Observable) ], Week8MLAnalyticsController.prototype, "getPredictionsStream", null); __decorate([ (0, common_1.Get)('metrics'), (0, swagger_1.ApiOperation)({ summary: 'Get ML analytics metrics and statistics' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'ML metrics retrieved successfully' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], Week8MLAnalyticsController.prototype, "getMLMetrics", null); __decorate([ (0, common_1.Get)('alerts'), (0, swagger_1.ApiOperation)({ summary: 'Get ML-generated alerts' }), (0, swagger_1.ApiQuery)({ name: 'severity', required: false, enum: ['info', 'warning', 'error', 'critical'] }), (0, swagger_1.ApiQuery)({ name: 'type', required: false, enum: ['anomaly', 'regression', 'prediction', 'optimization'], }), (0, swagger_1.ApiQuery)({ name: 'limit', required: false, type: Number }), (0, swagger_1.ApiResponse)({ status: 200, description: 'ML alerts retrieved successfully' }), __param(0, (0, common_1.Query)('severity')), __param(1, (0, common_1.Query)('type')), __param(2, (0, common_1.Query)('limit', new common_1.ParseIntPipe({ optional: true }))), __metadata("design:type", Function), __metadata("design:paramtypes", [String, String, Number]), __metadata("design:returntype", Array) ], Week8MLAnalyticsController.prototype, "getMLAlerts", null); __decorate([ (0, common_1.Get)('alerts/stream'), (0, swagger_1.ApiOperation)({ summary: 'Get real-time ML alerts stream' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'ML alerts stream established' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", rxjs_1.Observable) ], Week8MLAnalyticsController.prototype, "getMLAlertsStream", null); __decorate([ (0, common_1.Post)('alerts/:alertId/acknowledge'), (0, swagger_1.ApiOperation)({ summary: 'Acknowledge an ML alert' }), (0, swagger_1.ApiParam)({ name: 'alertId', description: 'Alert ID to acknowledge' }), (0, common_1.HttpCode)(common_1.HttpStatus.OK), __param(0, (0, common_1.Param)('alertId')), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", void 0) ], Week8MLAnalyticsController.prototype, "acknowledgeMLAlert", null); __decorate([ (0, common_1.Get)('alert-channels'), (0, swagger_1.ApiOperation)({ summary: 'Get all configured alert channels' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Alert channels retrieved successfully' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Array) ], Week8MLAnalyticsController.prototype, "getAlertChannels", null); __decorate([ (0, common_1.Post)('alert-channels'), (0, swagger_1.ApiOperation)({ summary: 'Create a new alert channel' }), (0, swagger_1.ApiBody)({ type: AlertChannelDto }), (0, swagger_1.ApiResponse)({ status: 201, description: 'Alert channel created successfully' }), __param(0, (0, common_1.Body)(common_1.ValidationPipe)), __metadata("design:type", Function), __metadata("design:paramtypes", [AlertChannelDto]), __metadata("design:returntype", void 0) ], Week8MLAnalyticsController.prototype, "createAlertChannel", null); __decorate([ (0, common_1.Delete)('alert-channels/:channelId'), (0, swagger_1.ApiOperation)({ summary: 'Delete an alert channel' }), (0, swagger_1.ApiParam)({ name: 'channelId', description: 'Channel ID to delete' }), (0, common_1.HttpCode)(common_1.HttpStatus.NO_CONTENT), __param(0, (0, common_1.Param)('channelId')), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", void 0) ], Week8MLAnalyticsController.prototype, "deleteAlertChannel", null); __decorate([ (0, common_1.Post)('alert-channels/:channelId/test'), (0, swagger_1.ApiOperation)({ summary: 'Test an alert channel configuration' }), (0, swagger_1.ApiParam)({ name: 'channelId', description: 'Channel ID to test' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Channel test completed' }), __param(0, (0, common_1.Param)('channelId')), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", Promise) ], Week8MLAnalyticsController.prototype, "testAlertChannel", null); __decorate([ (0, common_1.Get)('alert-rules'), (0, swagger_1.ApiOperation)({ summary: 'Get all configured alert rules' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Alert rules retrieved successfully' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Array) ], Week8MLAnalyticsController.prototype, "getAlertRules", null); __decorate([ (0, common_1.Post)('alert-rules'), (0, swagger_1.ApiOperation)({ summary: 'Create a new alert rule' }), (0, swagger_1.ApiBody)({ type: AlertRuleDto }), (0, swagger_1.ApiResponse)({ status: 201, description: 'Alert rule created successfully' }), __param(0, (0, common_1.Body)(common_1.ValidationPipe)), __metadata("design:type", Function), __metadata("design:paramtypes", [AlertRuleDto]), __metadata("design:returntype", void 0) ], Week8MLAnalyticsController.prototype, "createAlertRule", null); __decorate([ (0, common_1.Delete)('alert-rules/:ruleId'), (0, swagger_1.ApiOperation)({ summary: 'Delete an alert rule' }), (0, swagger_1.ApiParam)({ name: 'ruleId', description: 'Rule ID to delete' }), (0, common_1.HttpCode)(common_1.HttpStatus.NO_CONTENT), __param(0, (0, common_1.Param)('ruleId')), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", void 0) ], Week8MLAnalyticsController.prototype, "deleteAlertRule", null); __decorate([ (0, common_1.Get)('alert-history'), (0, swagger_1.ApiOperation)({ summary: 'Get alert delivery history' }), (0, swagger_1.ApiQuery)({ name: 'limit', required: false, type: Number }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Alert history retrieved successfully' }), __param(0, (0, common_1.Query)('limit', new common_1.ParseIntPipe({ optional: true }))), __metadata("design:type", Function), __metadata("design:paramtypes", [Number]), __metadata("design:returntype", Array) ], Week8MLAnalyticsController.prototype, "getAlertHistory", null); __decorate([ (0, common_1.Get)('alert-history/stream'), (0, swagger_1.ApiOperation)({ summary: 'Get real-time alert history stream' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Alert history stream established' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", rxjs_1.Observable) ], Week8MLAnalyticsController.prototype, "getAlertHistoryStream", null); __decorate([ (0, common_1.Get)('alert-metrics'), (0, swagger_1.ApiOperation)({ summary: 'Get alerting system metrics and performance' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Alert metrics retrieved successfully' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Object) ], Week8MLAnalyticsController.prototype, "getAlertMetrics", null); __decorate([ (0, common_1.Post)('alerts/history/:alertId/acknowledge'), (0, swagger_1.ApiOperation)({ summary: 'Acknowledge an alert from history' }), (0, swagger_1.ApiParam)({ name: 'alertId', description: 'Alert ID to acknowledge' }), (0, common_1.HttpCode)(common_1.HttpStatus.OK), __param(0, (0, common_1.Param)('alertId')), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", void 0) ], Week8MLAnalyticsController.prototype, "acknowledgeHistoryAlert", null); __decorate([ (0, common_1.Get)('dashboard/summary'), (0, swagger_1.ApiOperation)({ summary: 'Get ML analytics dashboard summary' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Dashboard summary retrieved successfully' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], Week8MLAnalyticsController.prototype, "getDashboardSummary", null); __decorate([ (0, common_1.Get)('dashboard/live-feed'), (0, swagger_1.ApiOperation)({ summary: 'Get live feed of ML insights and alerts' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Live feed stream established' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", rxjs_1.Observable) ], Week8MLAnalyticsController.prototype, "getLiveFeed", null); exports.Week8MLAnalyticsController = Week8MLAnalyticsController = __decorate([ (0, swagger_1.ApiTags)('Week 8 ML Analytics'), (0, common_1.Controller)('telescope/ml-analytics'), __metadata("design:paramtypes", [ml_analytics_service_1.MLAnalyticsService, automated_alerting_service_1.AutomatedAlertingService]) ], Week8MLAnalyticsController); //# sourceMappingURL=week8-ml-analytics.controller.js.map