snow-flow 1.3.24 → 1.3.27
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.
- package/.claude/config.json +33 -9
- package/.claude-flow/queen/queen-memory.db +0 -0
- package/.roo/README.md +56 -0
- package/.roo/workflows/basic-tdd.json +32 -0
- package/.roomodes +122 -0
- package/CLAUDE.md +140 -752
- package/claude-flow +30 -75
- package/dist/cli.js +250 -7
- package/dist/compliance/advanced-compliance-system.js +857 -0
- package/dist/compliance/index.js +8 -0
- package/dist/documentation/index.js +8 -0
- package/dist/documentation/self-documenting-system.js +1006 -0
- package/dist/healing/index.js +8 -0
- package/dist/healing/self-healing-system.js +1041 -0
- package/dist/intelligence/multi-pass-requirements-analyzer.js +477 -0
- package/dist/intelligence/performance-recommendations-engine.js +960 -0
- package/dist/managers/scope-manager.js +5 -2
- package/dist/mcp/servicenow-deployment-mcp.js +113 -15
- package/dist/mcp/servicenow-flow-composer-mcp.js +604 -15
- package/dist/mcp/servicenow-intelligent-mcp.js +350 -0
- package/dist/mcp/servicenow-operations-mcp.js +2 -2
- package/dist/memory/memory-system.js +146 -0
- package/dist/monitoring/enhanced-monitoring-system.js +1085 -0
- package/dist/optimization/cost-optimization-engine.js +771 -0
- package/dist/optimization/flow-performance-optimizer.js +723 -0
- package/dist/optimization/index.js +10 -0
- package/dist/orchestration/flow-update-orchestrator.js +648 -0
- package/dist/rollback/smart-rollback-system.js +462 -0
- package/dist/templates/flow-template-system.js +625 -0
- package/dist/testing/flow-testing-automation.js +641 -0
- package/dist/testing/integration-test-suite.js +890 -0
- package/dist/utils/flow-structure-builder.js +1 -1
- package/dist/utils/servicenow-client.js +50 -2
- package/dist/utils/snow-oauth.js +66 -8
- package/dist/utils/xml-first-flow-generator.js +35 -8
- package/dist/version.js +13 -1
- package/package.json +1 -1
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 🚀 Smart Rollback System for Deployment Failures
|
|
4
|
+
*
|
|
5
|
+
* Advanced rollback system that automatically detects deployment failures,
|
|
6
|
+
* creates recovery plans, and executes intelligent rollback strategies
|
|
7
|
+
* with minimal downtime and data preservation.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.SmartRollbackSystem = void 0;
|
|
11
|
+
const logger_js_1 = require("../utils/logger.js");
|
|
12
|
+
class SmartRollbackSystem {
|
|
13
|
+
constructor(client, memory) {
|
|
14
|
+
this.rollbackPoints = new Map();
|
|
15
|
+
this.rollbackPlans = new Map();
|
|
16
|
+
this.activeExecutions = new Map();
|
|
17
|
+
this.monitoringEnabled = true;
|
|
18
|
+
this.logger = new logger_js_1.Logger('SmartRollbackSystem');
|
|
19
|
+
this.client = client;
|
|
20
|
+
this.memory = memory;
|
|
21
|
+
// Start monitoring for automatic rollback triggers
|
|
22
|
+
this.startMonitoring();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create a new rollback point before deployment
|
|
26
|
+
*/
|
|
27
|
+
async createRollbackPoint(name, description, options = {}) {
|
|
28
|
+
this.logger.info('🔄 Creating rollback point', { name, options });
|
|
29
|
+
const rollbackPointId = `rb_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`;
|
|
30
|
+
try {
|
|
31
|
+
// Create system snapshot
|
|
32
|
+
const snapshot = await this.createSystemSnapshot(options.includeData || false);
|
|
33
|
+
// Create rollback point
|
|
34
|
+
const rollbackPoint = {
|
|
35
|
+
id: rollbackPointId,
|
|
36
|
+
name,
|
|
37
|
+
description,
|
|
38
|
+
createdAt: new Date().toISOString(),
|
|
39
|
+
type: options.type || 'manual',
|
|
40
|
+
trigger: {
|
|
41
|
+
type: 'manual',
|
|
42
|
+
severity: 'medium'
|
|
43
|
+
},
|
|
44
|
+
snapshot,
|
|
45
|
+
metadata: {
|
|
46
|
+
userId: 'system',
|
|
47
|
+
environment: process.env.NODE_ENV || 'development',
|
|
48
|
+
artifacts: []
|
|
49
|
+
},
|
|
50
|
+
status: 'active',
|
|
51
|
+
retentionPolicy: {
|
|
52
|
+
maxAge: 604800000, // 7 days
|
|
53
|
+
maxCount: 10,
|
|
54
|
+
compressionEnabled: options.compressionEnabled || true
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
// Store rollback point
|
|
58
|
+
this.rollbackPoints.set(rollbackPointId, rollbackPoint);
|
|
59
|
+
await this.memory.store(`rollback_point_${rollbackPointId}`, rollbackPoint, rollbackPoint.retentionPolicy.maxAge);
|
|
60
|
+
// Clean up old rollback points
|
|
61
|
+
await this.cleanupOldRollbackPoints();
|
|
62
|
+
this.logger.info('✅ Rollback point created successfully', {
|
|
63
|
+
id: rollbackPointId,
|
|
64
|
+
snapshotSize: JSON.stringify(snapshot).length,
|
|
65
|
+
artifactsCount: rollbackPoint.metadata.artifacts.length
|
|
66
|
+
});
|
|
67
|
+
return rollbackPoint;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
this.logger.error('❌ Failed to create rollback point', error);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Generate intelligent rollback plan
|
|
76
|
+
*/
|
|
77
|
+
async generateRollbackPlan(rollbackPointId, options = {}) {
|
|
78
|
+
this.logger.info('📋 Generating rollback plan', { rollbackPointId, options });
|
|
79
|
+
const rollbackPoint = this.rollbackPoints.get(rollbackPointId);
|
|
80
|
+
if (!rollbackPoint) {
|
|
81
|
+
throw new Error(`Rollback point not found: ${rollbackPointId}`);
|
|
82
|
+
}
|
|
83
|
+
const planId = `plan_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`;
|
|
84
|
+
try {
|
|
85
|
+
// Analyze current system state vs rollback point
|
|
86
|
+
const currentSnapshot = await this.createSystemSnapshot(false);
|
|
87
|
+
const differences = this.analyzeDifferences(rollbackPoint.snapshot, currentSnapshot);
|
|
88
|
+
// Determine rollback strategy
|
|
89
|
+
const strategy = this.determineOptimalStrategy(differences, options);
|
|
90
|
+
// Generate rollback steps
|
|
91
|
+
const steps = await this.generateRollbackSteps(differences, strategy);
|
|
92
|
+
// Assess impact
|
|
93
|
+
const impactAssessment = this.assessRollbackImpact(differences, strategy);
|
|
94
|
+
// Generate validation checks
|
|
95
|
+
const validationChecks = this.generateValidationChecks(rollbackPoint, steps);
|
|
96
|
+
const rollbackPlan = {
|
|
97
|
+
id: planId,
|
|
98
|
+
name: `Rollback to: ${rollbackPoint.name}`,
|
|
99
|
+
description: `Intelligent rollback plan generated for rollback point: ${rollbackPoint.name}`,
|
|
100
|
+
createdAt: new Date().toISOString(),
|
|
101
|
+
rollbackPointId,
|
|
102
|
+
strategy,
|
|
103
|
+
steps,
|
|
104
|
+
estimatedTime: steps.reduce((total, step) => total + step.estimatedTime, 0),
|
|
105
|
+
riskLevel: this.calculateRiskLevel(impactAssessment, strategy),
|
|
106
|
+
impactAssessment,
|
|
107
|
+
validationChecks
|
|
108
|
+
};
|
|
109
|
+
// Store rollback plan
|
|
110
|
+
this.rollbackPlans.set(planId, rollbackPlan);
|
|
111
|
+
await this.memory.store(`rollback_plan_${planId}`, rollbackPlan, 86400000); // 24 hours
|
|
112
|
+
this.logger.info('✅ Rollback plan generated', {
|
|
113
|
+
planId,
|
|
114
|
+
stepsCount: steps.length,
|
|
115
|
+
estimatedTime: rollbackPlan.estimatedTime,
|
|
116
|
+
riskLevel: rollbackPlan.riskLevel
|
|
117
|
+
});
|
|
118
|
+
return rollbackPlan;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
this.logger.error('❌ Failed to generate rollback plan', error);
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Execute rollback plan with monitoring
|
|
127
|
+
*/
|
|
128
|
+
async executeRollbackPlan(planId, options = {}) {
|
|
129
|
+
this.logger.info('🚀 Executing rollback plan', { planId, options });
|
|
130
|
+
const plan = this.rollbackPlans.get(planId);
|
|
131
|
+
if (!plan) {
|
|
132
|
+
throw new Error(`Rollback plan not found: ${planId}`);
|
|
133
|
+
}
|
|
134
|
+
const executionId = `exec_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`;
|
|
135
|
+
const execution = {
|
|
136
|
+
planId,
|
|
137
|
+
executionId,
|
|
138
|
+
startTime: new Date().toISOString(),
|
|
139
|
+
status: 'pending',
|
|
140
|
+
progress: 0,
|
|
141
|
+
results: [],
|
|
142
|
+
issues: [],
|
|
143
|
+
metrics: {
|
|
144
|
+
totalSteps: plan.steps.length,
|
|
145
|
+
completedSteps: 0,
|
|
146
|
+
failedSteps: 0,
|
|
147
|
+
skippedSteps: 0,
|
|
148
|
+
totalTime: 0,
|
|
149
|
+
averageStepTime: 0,
|
|
150
|
+
resourceUsage: {
|
|
151
|
+
memory: 0,
|
|
152
|
+
cpu: 0,
|
|
153
|
+
disk: 0,
|
|
154
|
+
network: 0
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
this.activeExecutions.set(executionId, execution);
|
|
159
|
+
try {
|
|
160
|
+
execution.status = 'running';
|
|
161
|
+
// Pre-rollback validation
|
|
162
|
+
if (!options.skipValidation) {
|
|
163
|
+
await this.runValidationChecks(plan, 'pre_rollback', execution);
|
|
164
|
+
}
|
|
165
|
+
// Execute rollback steps
|
|
166
|
+
for (let i = 0; i < plan.steps.length; i++) {
|
|
167
|
+
const step = plan.steps[i];
|
|
168
|
+
execution.currentStep = i + 1;
|
|
169
|
+
execution.progress = ((i + 1) / plan.steps.length) * 100;
|
|
170
|
+
this.logger.info(`Executing step ${i + 1}/${plan.steps.length}: ${step.name}`);
|
|
171
|
+
const stepResult = await this.executeRollbackStep(step, options.dryRun || false, execution);
|
|
172
|
+
execution.results.push(stepResult);
|
|
173
|
+
if (stepResult.status === 'failed') {
|
|
174
|
+
execution.metrics.failedSteps++;
|
|
175
|
+
if (step.critical && !options.continueOnError) {
|
|
176
|
+
execution.issues.push({
|
|
177
|
+
severity: 'critical',
|
|
178
|
+
type: 'step_failure',
|
|
179
|
+
description: `Critical step failed: ${step.name}`,
|
|
180
|
+
step: i + 1,
|
|
181
|
+
autoResolved: false
|
|
182
|
+
});
|
|
183
|
+
execution.status = 'failed';
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else if (stepResult.status === 'completed') {
|
|
188
|
+
execution.metrics.completedSteps++;
|
|
189
|
+
}
|
|
190
|
+
else if (stepResult.status === 'skipped') {
|
|
191
|
+
execution.metrics.skippedSteps++;
|
|
192
|
+
}
|
|
193
|
+
// Update metrics
|
|
194
|
+
await this.updateExecutionMetrics(execution);
|
|
195
|
+
}
|
|
196
|
+
// Post-rollback validation
|
|
197
|
+
if (!options.skipValidation && execution.status !== 'failed') {
|
|
198
|
+
await this.runValidationChecks(plan, 'post_rollback', execution);
|
|
199
|
+
}
|
|
200
|
+
// Finalize execution
|
|
201
|
+
if (execution.status === 'running') {
|
|
202
|
+
execution.status = 'completed';
|
|
203
|
+
}
|
|
204
|
+
execution.endTime = new Date().toISOString();
|
|
205
|
+
execution.progress = 100;
|
|
206
|
+
execution.metrics.totalTime = Date.now() - new Date(execution.startTime).getTime();
|
|
207
|
+
execution.metrics.averageStepTime = execution.metrics.totalTime / execution.metrics.totalSteps;
|
|
208
|
+
this.logger.info('✅ Rollback execution completed', {
|
|
209
|
+
executionId,
|
|
210
|
+
status: execution.status,
|
|
211
|
+
completedSteps: execution.metrics.completedSteps,
|
|
212
|
+
failedSteps: execution.metrics.failedSteps,
|
|
213
|
+
totalTime: execution.metrics.totalTime
|
|
214
|
+
});
|
|
215
|
+
return execution;
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
execution.status = 'failed';
|
|
219
|
+
execution.endTime = new Date().toISOString();
|
|
220
|
+
execution.issues.push({
|
|
221
|
+
severity: 'critical',
|
|
222
|
+
type: 'step_failure',
|
|
223
|
+
description: `Rollback execution failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
224
|
+
autoResolved: false
|
|
225
|
+
});
|
|
226
|
+
this.logger.error('❌ Rollback execution failed', error);
|
|
227
|
+
throw error;
|
|
228
|
+
}
|
|
229
|
+
finally {
|
|
230
|
+
// Store execution results
|
|
231
|
+
await this.memory.store(`rollback_execution_${executionId}`, execution, 604800000); // 7 days
|
|
232
|
+
this.activeExecutions.delete(executionId);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Get rollback points with filtering
|
|
237
|
+
*/
|
|
238
|
+
getRollbackPoints(filter) {
|
|
239
|
+
let points = Array.from(this.rollbackPoints.values());
|
|
240
|
+
if (filter) {
|
|
241
|
+
if (filter.type) {
|
|
242
|
+
points = points.filter(p => p.type === filter.type);
|
|
243
|
+
}
|
|
244
|
+
if (filter.status) {
|
|
245
|
+
points = points.filter(p => p.status === filter.status);
|
|
246
|
+
}
|
|
247
|
+
if (filter.maxAge) {
|
|
248
|
+
const cutoff = Date.now() - filter.maxAge;
|
|
249
|
+
points = points.filter(p => new Date(p.createdAt).getTime() > cutoff);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return points.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get active rollback executions
|
|
256
|
+
*/
|
|
257
|
+
getActiveExecutions() {
|
|
258
|
+
return Array.from(this.activeExecutions.values());
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Cancel active rollback execution
|
|
262
|
+
*/
|
|
263
|
+
async cancelExecution(executionId) {
|
|
264
|
+
const execution = this.activeExecutions.get(executionId);
|
|
265
|
+
if (!execution) {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
execution.status = 'cancelled';
|
|
269
|
+
execution.endTime = new Date().toISOString();
|
|
270
|
+
this.logger.info('🛑 Rollback execution cancelled', { executionId });
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Private helper methods
|
|
275
|
+
*/
|
|
276
|
+
async createSystemSnapshot(includeData) {
|
|
277
|
+
// Implementation for creating comprehensive system snapshot
|
|
278
|
+
return {
|
|
279
|
+
timestamp: new Date().toISOString(),
|
|
280
|
+
version: '1.0.0',
|
|
281
|
+
components: [],
|
|
282
|
+
dependencies: [],
|
|
283
|
+
configuration: {
|
|
284
|
+
updateSets: [],
|
|
285
|
+
systemProperties: {},
|
|
286
|
+
userPermissions: [],
|
|
287
|
+
activeSchedules: []
|
|
288
|
+
},
|
|
289
|
+
data: {
|
|
290
|
+
criticalTables: [],
|
|
291
|
+
recentChanges: [],
|
|
292
|
+
transactionLog: [],
|
|
293
|
+
consistencyCheck: {
|
|
294
|
+
valid: true,
|
|
295
|
+
issues: [],
|
|
296
|
+
recommendations: []
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
integrity: {
|
|
300
|
+
checksum: 'placeholder',
|
|
301
|
+
timestamp: new Date().toISOString(),
|
|
302
|
+
valid: true,
|
|
303
|
+
errors: []
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
analyzeDifferences(originalSnapshot, currentSnapshot) {
|
|
308
|
+
// Implementation for analyzing differences between snapshots
|
|
309
|
+
return {
|
|
310
|
+
componentChanges: [],
|
|
311
|
+
configurationChanges: [],
|
|
312
|
+
dataChanges: [],
|
|
313
|
+
severity: 'medium'
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
determineOptimalStrategy(differences, options) {
|
|
317
|
+
// Implementation for determining optimal rollback strategy
|
|
318
|
+
return {
|
|
319
|
+
type: 'selective_restore',
|
|
320
|
+
approach: options.strategy || 'conservative',
|
|
321
|
+
preserveData: options.preserveData !== false,
|
|
322
|
+
maintainSessions: true,
|
|
323
|
+
downtime: 'minimal'
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
async generateRollbackSteps(differences, strategy) {
|
|
327
|
+
// Implementation for generating rollback steps
|
|
328
|
+
return [
|
|
329
|
+
{
|
|
330
|
+
order: 1,
|
|
331
|
+
name: 'Create backup',
|
|
332
|
+
description: 'Create backup of current state before rollback',
|
|
333
|
+
action: 'backup_current_state',
|
|
334
|
+
parameters: {},
|
|
335
|
+
reversible: false,
|
|
336
|
+
critical: true,
|
|
337
|
+
estimatedTime: 30000,
|
|
338
|
+
dependencies: [],
|
|
339
|
+
validationRequired: true
|
|
340
|
+
}
|
|
341
|
+
];
|
|
342
|
+
}
|
|
343
|
+
assessRollbackImpact(differences, strategy) {
|
|
344
|
+
// Implementation for assessing rollback impact
|
|
345
|
+
return {
|
|
346
|
+
affectedUsers: 0,
|
|
347
|
+
affectedSystems: [],
|
|
348
|
+
dataLoss: 'none',
|
|
349
|
+
downtime: 0,
|
|
350
|
+
businessImpact: 'low',
|
|
351
|
+
complianceViolations: []
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
generateValidationChecks(rollbackPoint, steps) {
|
|
355
|
+
// Implementation for generating validation checks
|
|
356
|
+
return [
|
|
357
|
+
{
|
|
358
|
+
name: 'System Health Check',
|
|
359
|
+
description: 'Verify system is healthy after rollback',
|
|
360
|
+
type: 'post_rollback',
|
|
361
|
+
script: 'return system.isHealthy();',
|
|
362
|
+
expectedResult: true,
|
|
363
|
+
critical: true,
|
|
364
|
+
timeout: 30000
|
|
365
|
+
}
|
|
366
|
+
];
|
|
367
|
+
}
|
|
368
|
+
calculateRiskLevel(impact, strategy) {
|
|
369
|
+
// Implementation for calculating risk level
|
|
370
|
+
return 'medium';
|
|
371
|
+
}
|
|
372
|
+
async executeRollbackStep(step, dryRun, execution) {
|
|
373
|
+
const stepResult = {
|
|
374
|
+
stepOrder: step.order,
|
|
375
|
+
name: step.name,
|
|
376
|
+
status: 'running',
|
|
377
|
+
startTime: new Date().toISOString(),
|
|
378
|
+
validationResults: []
|
|
379
|
+
};
|
|
380
|
+
try {
|
|
381
|
+
if (dryRun) {
|
|
382
|
+
this.logger.info(`[DRY RUN] Would execute: ${step.name}`);
|
|
383
|
+
stepResult.status = 'completed';
|
|
384
|
+
stepResult.result = { dryRun: true, message: 'Step would be executed' };
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
// Actual step execution logic would go here
|
|
388
|
+
stepResult.status = 'completed';
|
|
389
|
+
stepResult.result = { success: true };
|
|
390
|
+
}
|
|
391
|
+
stepResult.endTime = new Date().toISOString();
|
|
392
|
+
return stepResult;
|
|
393
|
+
}
|
|
394
|
+
catch (error) {
|
|
395
|
+
stepResult.status = 'failed';
|
|
396
|
+
stepResult.error = error instanceof Error ? error.message : String(error);
|
|
397
|
+
stepResult.endTime = new Date().toISOString();
|
|
398
|
+
this.logger.error(`Step failed: ${step.name}`, error);
|
|
399
|
+
return stepResult;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
async runValidationChecks(plan, type, execution) {
|
|
403
|
+
const checks = plan.validationChecks.filter(check => check.type === type);
|
|
404
|
+
for (const check of checks) {
|
|
405
|
+
try {
|
|
406
|
+
// Run validation check logic
|
|
407
|
+
this.logger.info(`Running validation: ${check.name}`);
|
|
408
|
+
}
|
|
409
|
+
catch (error) {
|
|
410
|
+
if (check.critical) {
|
|
411
|
+
throw error;
|
|
412
|
+
}
|
|
413
|
+
this.logger.warn(`Non-critical validation failed: ${check.name}`, error);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
async updateExecutionMetrics(execution) {
|
|
418
|
+
// Update execution metrics with current resource usage
|
|
419
|
+
execution.metrics.resourceUsage = {
|
|
420
|
+
memory: process.memoryUsage().heapUsed,
|
|
421
|
+
cpu: 0, // Would be calculated from system metrics
|
|
422
|
+
disk: 0,
|
|
423
|
+
network: 0
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
async cleanupOldRollbackPoints() {
|
|
427
|
+
const now = Date.now();
|
|
428
|
+
const pointsToDelete = [];
|
|
429
|
+
for (const [id, point] of this.rollbackPoints.entries()) {
|
|
430
|
+
const age = now - new Date(point.createdAt).getTime();
|
|
431
|
+
if (age > point.retentionPolicy.maxAge) {
|
|
432
|
+
pointsToDelete.push(id);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
for (const id of pointsToDelete) {
|
|
436
|
+
this.rollbackPoints.delete(id);
|
|
437
|
+
await this.memory.delete(`rollback_point_${id}`);
|
|
438
|
+
}
|
|
439
|
+
if (pointsToDelete.length > 0) {
|
|
440
|
+
this.logger.info(`Cleaned up ${pointsToDelete.length} expired rollback points`);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
startMonitoring() {
|
|
444
|
+
if (!this.monitoringEnabled)
|
|
445
|
+
return;
|
|
446
|
+
// Start monitoring for automatic rollback triggers
|
|
447
|
+
setInterval(async () => {
|
|
448
|
+
try {
|
|
449
|
+
await this.checkAutomaticTriggers();
|
|
450
|
+
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
this.logger.error('Error in automatic trigger monitoring', error);
|
|
453
|
+
}
|
|
454
|
+
}, 30000); // Check every 30 seconds
|
|
455
|
+
}
|
|
456
|
+
async checkAutomaticTriggers() {
|
|
457
|
+
// Implementation for checking automatic rollback triggers
|
|
458
|
+
// This would monitor system health, performance metrics, error rates, etc.
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
exports.SmartRollbackSystem = SmartRollbackSystem;
|
|
462
|
+
exports.default = SmartRollbackSystem;
|