@tamyla/clodo-framework 3.1.5 → 3.1.8

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 (62) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/bin/clodo-service.js +29 -947
  3. package/bin/database/enterprise-db-manager.js +7 -5
  4. package/bin/security/security-cli.js +0 -0
  5. package/bin/service-management/create-service.js +0 -0
  6. package/bin/service-management/init-service.js +0 -0
  7. package/bin/shared/cloudflare/domain-discovery.js +11 -10
  8. package/bin/shared/cloudflare/ops.js +1 -1
  9. package/bin/shared/config/ConfigurationManager.js +539 -0
  10. package/bin/shared/config/index.js +13 -1
  11. package/bin/shared/database/connection-manager.js +2 -2
  12. package/bin/shared/database/orchestrator.js +5 -4
  13. package/bin/shared/deployment/auditor.js +9 -8
  14. package/bin/shared/logging/Logger.js +214 -0
  15. package/bin/shared/monitoring/production-monitor.js +21 -9
  16. package/bin/shared/utils/ErrorHandler.js +675 -0
  17. package/bin/shared/utils/error-recovery.js +33 -13
  18. package/bin/shared/utils/file-manager.js +162 -0
  19. package/bin/shared/utils/formatters.js +247 -0
  20. package/bin/shared/utils/index.js +14 -4
  21. package/bin/shared/validation/ValidationRegistry.js +143 -0
  22. package/dist/deployment/auditor.js +23 -8
  23. package/dist/deployment/orchestration/BaseDeploymentOrchestrator.js +426 -0
  24. package/dist/deployment/orchestration/EnterpriseOrchestrator.js +401 -0
  25. package/dist/deployment/orchestration/PortfolioOrchestrator.js +273 -0
  26. package/dist/deployment/orchestration/SingleServiceOrchestrator.js +231 -0
  27. package/dist/deployment/orchestration/UnifiedDeploymentOrchestrator.js +662 -0
  28. package/dist/deployment/orchestration/index.js +17 -0
  29. package/dist/index.js +12 -0
  30. package/dist/orchestration/modules/DomainResolver.js +8 -6
  31. package/dist/orchestration/multi-domain-orchestrator.js +13 -1
  32. package/dist/security/index.js +2 -2
  33. package/dist/service-management/ConfirmationEngine.js +8 -7
  34. package/dist/service-management/ErrorTracker.js +7 -2
  35. package/dist/service-management/InputCollector.js +18 -12
  36. package/dist/service-management/ServiceCreator.js +22 -7
  37. package/dist/service-management/ServiceInitializer.js +12 -18
  38. package/dist/shared/cloudflare/domain-discovery.js +11 -10
  39. package/dist/shared/cloudflare/ops.js +1 -1
  40. package/dist/shared/config/ConfigurationManager.js +519 -0
  41. package/dist/shared/config/index.js +5 -1
  42. package/dist/shared/database/connection-manager.js +2 -2
  43. package/dist/shared/database/orchestrator.js +13 -4
  44. package/dist/shared/deployment/auditor.js +23 -8
  45. package/dist/shared/logging/Logger.js +209 -0
  46. package/dist/shared/monitoring/production-monitor.js +24 -8
  47. package/dist/{utils → shared/utils}/ErrorHandler.js +306 -28
  48. package/dist/shared/utils/error-recovery.js +33 -13
  49. package/dist/shared/utils/file-manager.js +155 -0
  50. package/dist/shared/utils/formatters.js +215 -0
  51. package/dist/shared/utils/index.js +14 -4
  52. package/dist/shared/validation/ValidationRegistry.js +126 -0
  53. package/dist/utils/config/unified-config-manager.js +14 -12
  54. package/dist/utils/deployment/config-cache.js +3 -1
  55. package/dist/utils/deployment/secret-generator.js +32 -29
  56. package/dist/utils/framework-config.js +6 -3
  57. package/dist/utils/ui-structures-loader.js +3 -0
  58. package/dist/worker/integration.js +11 -1
  59. package/package.json +31 -3
  60. package/dist/config/FeatureManager.js +0 -426
  61. package/dist/config/features.js +0 -230
  62. package/dist/utils/error-recovery.js +0 -240
@@ -19,6 +19,7 @@
19
19
  import { existsSync, writeFileSync, appendFileSync, mkdirSync, readFileSync, readdirSync, statSync } from 'fs';
20
20
  import { join, dirname } from 'path';
21
21
  import { execSync } from 'child_process';
22
+ import { logger } from '../logging/Logger.js';
22
23
  export class DeploymentAuditor {
23
24
  constructor(options = {}) {
24
25
  this.config = {
@@ -302,7 +303,9 @@ export class DeploymentAuditor {
302
303
  logPhase(deploymentId, phaseName, action, details = {}) {
303
304
  const deployment = this.currentSession.deployments.get(deploymentId);
304
305
  if (!deployment) {
305
- console.warn(`⚠️ Deployment not found for phase logging: ${deploymentId}`);
306
+ logger.warn('Deployment not found for phase logging', {
307
+ deploymentId
308
+ });
306
309
  return;
307
310
  }
308
311
  const phaseEvent = {
@@ -360,7 +363,9 @@ export class DeploymentAuditor {
360
363
  error: errorDetails.error,
361
364
  context
362
365
  });
363
- console.error(`❌ Deployment error logged: ${deploymentId}`);
366
+ logger.error('Deployment error logged', {
367
+ deploymentId
368
+ });
364
369
  }
365
370
 
366
371
  /**
@@ -539,7 +544,9 @@ export class DeploymentAuditor {
539
544
  appendFileSync(csvFile, csvEntry + '\n');
540
545
  }
541
546
  } catch (error) {
542
- console.error(`⚠️ Failed to write audit log: ${error.message}`);
547
+ logger.error('Failed to write audit log', {
548
+ error: error.message
549
+ });
543
550
  }
544
551
  }
545
552
 
@@ -562,7 +569,9 @@ export class DeploymentAuditor {
562
569
  timestamp: new Date()
563
570
  });
564
571
  } catch (error) {
565
- console.error(`⚠️ Failed to rotate log file: ${error.message}`);
572
+ logger.error('Failed to rotate log file', {
573
+ error: error.message
574
+ });
566
575
  }
567
576
  }
568
577
 
@@ -574,7 +583,9 @@ export class DeploymentAuditor {
574
583
  generateDeploymentReport(deploymentId) {
575
584
  const deployment = this.currentSession.deployments.get(deploymentId);
576
585
  if (!deployment) {
577
- console.warn(`⚠️ Cannot generate report: deployment ${deploymentId} not found`);
586
+ logger.warn('Cannot generate report: deployment not found', {
587
+ deploymentId
588
+ });
578
589
  return null;
579
590
  }
580
591
  const reportData = {
@@ -813,7 +824,7 @@ export class DeploymentAuditor {
813
824
  */
814
825
  async sendSecurityAlert(securityEvent) {
815
826
  if (!this.config.alertWebhook) {
816
- console.warn('⚠️ Security alert webhook not configured');
827
+ logger.warn('Security alert webhook not configured');
817
828
  return;
818
829
  }
819
830
  const alert = {
@@ -831,7 +842,9 @@ export class DeploymentAuditor {
831
842
  event: securityEvent
832
843
  });
833
844
  } catch (error) {
834
- console.error(`❌ Failed to send security alert: ${error.message}`);
845
+ logger.error('Failed to send security alert', {
846
+ error: error.message
847
+ });
835
848
  }
836
849
  }
837
850
 
@@ -890,7 +903,9 @@ export class DeploymentAuditor {
890
903
  this.logAuditEvent('AUDIT_CLEANUP_COMPLETED', 'SYSTEM', cleanupResults);
891
904
  console.log(`🧹 Audit cleanup completed: ${cleanupResults.filesRemoved} files removed`);
892
905
  } catch (error) {
893
- console.error(`❌ Audit cleanup failed: ${error.message}`);
906
+ logger.error('Audit cleanup failed', {
907
+ error: error.message
908
+ });
894
909
  cleanupResults.errors.push({
895
910
  general: error.message
896
911
  });
@@ -0,0 +1,426 @@
1
+ /**
2
+ * Base Deployment Orchestrator
3
+ *
4
+ * Abstract base class for all deployment orchestration patterns.
5
+ * Provides unified phase pipeline, phase state management, and error handling.
6
+ *
7
+ * Phase Pipeline:
8
+ * 1. Initialization → 2. Validation → 3. Preparation → 4. Deployment → 5. Verification → 6. Monitoring
9
+ *
10
+ * All subclasses must implement phase-specific methods:
11
+ * - onInitialize()
12
+ * - onValidation()
13
+ * - onPrepare()
14
+ * - onDeploy()
15
+ * - onVerify()
16
+ * - onMonitor()
17
+ *
18
+ * @class BaseDeploymentOrchestrator
19
+ * @abstract
20
+ */
21
+
22
+ import { ErrorHandler } from '../../shared/utils/ErrorHandler.js';
23
+
24
+ /**
25
+ * Phase state and execution order
26
+ */
27
+ const DEPLOYMENT_PHASES = {
28
+ INITIALIZATION: 'initialization',
29
+ VALIDATION: 'validation',
30
+ PREPARATION: 'preparation',
31
+ DEPLOYMENT: 'deployment',
32
+ VERIFICATION: 'verification',
33
+ MONITORING: 'monitoring'
34
+ };
35
+
36
+ /**
37
+ * Phase execution order
38
+ */
39
+ const PHASE_SEQUENCE = [DEPLOYMENT_PHASES.INITIALIZATION, DEPLOYMENT_PHASES.VALIDATION, DEPLOYMENT_PHASES.PREPARATION, DEPLOYMENT_PHASES.DEPLOYMENT, DEPLOYMENT_PHASES.VERIFICATION, DEPLOYMENT_PHASES.MONITORING];
40
+
41
+ /**
42
+ * Base Deployment Orchestrator - Abstract orchestration framework
43
+ */
44
+ export class BaseDeploymentOrchestrator {
45
+ /**
46
+ * Constructor
47
+ * @param {Object} options - Configuration options
48
+ * @param {string} options.deploymentId - Unique deployment identifier
49
+ * @param {Object} options.config - Deployment configuration
50
+ * @param {Object} options.auditor - Deployment auditor instance (optional)
51
+ */
52
+ constructor(options = {}) {
53
+ this.deploymentId = options.deploymentId || `deploy-${Date.now()}`;
54
+ this.config = options.config || {};
55
+ this.auditor = options.auditor;
56
+
57
+ // Phase state management
58
+ this.currentPhase = null;
59
+ this.phaseStates = new Map();
60
+ this.phaseResults = new Map();
61
+ this.phaseErrors = new Map();
62
+ this.startTime = Date.now();
63
+ this.phaseTimings = new Map();
64
+
65
+ // Execution context
66
+ this.executionContext = {
67
+ deploymentId: this.deploymentId,
68
+ startTime: this.startTime,
69
+ phases: {},
70
+ errors: []
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Execute complete deployment orchestration
76
+ * Runs through all phases in sequence with error handling and recovery
77
+ *
78
+ * @param {Object} options - Execution options
79
+ * @returns {Promise<Object>} Deployment result
80
+ * @throws {Error} If critical phase fails
81
+ */
82
+ async execute(options = {}) {
83
+ const {
84
+ continueOnError = false
85
+ } = options;
86
+ try {
87
+ console.log(`🎯 Starting deployment orchestration: ${this.deploymentId}`);
88
+ console.log(`📊 Phases: ${PHASE_SEQUENCE.join(' → ')}`);
89
+ console.log('');
90
+
91
+ // Execute each phase in sequence
92
+ for (const phase of PHASE_SEQUENCE) {
93
+ try {
94
+ const result = await this.executePhase(phase);
95
+ this.phaseResults.set(phase, result);
96
+
97
+ // Log phase success
98
+ if (this.auditor) {
99
+ this.auditor.logPhase(this.deploymentId, phase, 'complete', {
100
+ result
101
+ });
102
+ }
103
+ console.log(`✅ Phase '${phase}' completed successfully`);
104
+ } catch (error) {
105
+ // Store phase error
106
+ this.phaseErrors.set(phase, error);
107
+ console.error(`❌ Phase '${phase}' failed: ${error.message}`);
108
+
109
+ // Log phase error
110
+ if (this.auditor) {
111
+ this.auditor.logError(this.deploymentId, error, {
112
+ phase,
113
+ context: this.executionContext
114
+ });
115
+ }
116
+
117
+ // Handle critical phases
118
+ if (this.isCriticalPhase(phase)) {
119
+ if (!continueOnError) {
120
+ throw error;
121
+ }
122
+ console.warn(`⚠️ Continuing despite critical phase failure in '${phase}'`);
123
+ }
124
+ }
125
+ }
126
+
127
+ // Generate execution summary
128
+ const summary = this.generateExecutionSummary();
129
+ console.log('');
130
+ console.log(`✅ Deployment orchestration completed: ${this.deploymentId}`);
131
+ console.log(`📈 Execution time: ${this.getExecutionTime()}ms`);
132
+ return summary;
133
+ } catch (error) {
134
+ // Log fatal error to auditor if available
135
+ if (this.auditor) {
136
+ this.auditor.logError(this.deploymentId, error, {
137
+ fatal: true,
138
+ phase: this.currentPhase,
139
+ context: this.executionContext
140
+ });
141
+ }
142
+
143
+ // Re-throw the error without additional wrapping
144
+ throw error;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Execute single phase
150
+ * @private
151
+ * @param {string} phase - Phase name
152
+ * @returns {Promise<Object>} Phase result
153
+ */
154
+ async executePhase(phase) {
155
+ this.currentPhase = phase;
156
+ const phaseStartTime = Date.now();
157
+ console.log(`\n🔄 Executing phase: '${phase}'`);
158
+ console.log(` ├─ Phase state: pending → executing → complete`);
159
+
160
+ // Update phase state
161
+ this.phaseStates.set(phase, 'executing');
162
+ try {
163
+ // Validate phase method exists
164
+ const phaseMethod = `on${this.capitalize(phase)}`;
165
+ if (typeof this[phaseMethod] !== 'function') {
166
+ throw new Error(`Phase method '${phaseMethod}' not implemented in ${this.constructor.name}`);
167
+ }
168
+
169
+ // Execute phase-specific logic
170
+ const result = await this[phaseMethod]();
171
+
172
+ // Record phase timing
173
+ const phaseDuration = Date.now() - phaseStartTime;
174
+ this.phaseTimings.set(phase, phaseDuration);
175
+
176
+ // Update phase state
177
+ this.phaseStates.set(phase, 'complete');
178
+ return {
179
+ phase,
180
+ status: 'success',
181
+ result,
182
+ duration: phaseDuration,
183
+ timestamp: new Date().toISOString()
184
+ };
185
+ } catch (error) {
186
+ // Record error and re-throw
187
+ const phaseDuration = Date.now() - phaseStartTime;
188
+ this.phaseTimings.set(phase, phaseDuration);
189
+ this.phaseStates.set(phase, 'error');
190
+ throw error;
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Determine if phase is critical to deployment success
196
+ * Critical phases: initialization, validation, deployment
197
+ * Non-critical: monitoring, verification (can warn instead)
198
+ *
199
+ * @private
200
+ * @param {string} phase - Phase name
201
+ * @returns {boolean} True if phase is critical
202
+ */
203
+ isCriticalPhase(phase) {
204
+ const criticalPhases = [DEPLOYMENT_PHASES.INITIALIZATION, DEPLOYMENT_PHASES.DEPLOYMENT];
205
+ return criticalPhases.includes(phase);
206
+ }
207
+
208
+ /**
209
+ * Generate comprehensive execution summary
210
+ * @private
211
+ * @returns {Object} Execution summary
212
+ */
213
+ generateExecutionSummary() {
214
+ const summary = {
215
+ deploymentId: this.deploymentId,
216
+ orchestrator: this.constructor.name,
217
+ totalDuration: this.getExecutionTime(),
218
+ phases: {},
219
+ stats: {
220
+ total: PHASE_SEQUENCE.length,
221
+ completed: 0,
222
+ failed: 0,
223
+ skipped: 0
224
+ },
225
+ errors: Array.from(this.phaseErrors.entries()).map(([phase, error]) => ({
226
+ phase,
227
+ message: error.message,
228
+ severity: this.isCriticalPhase(phase) ? 'critical' : 'warning'
229
+ }))
230
+ };
231
+
232
+ // Add phase details to summary
233
+ for (const phase of PHASE_SEQUENCE) {
234
+ const state = this.phaseStates.get(phase);
235
+ const duration = this.phaseTimings.get(phase) || 0;
236
+ summary.phases[phase] = {
237
+ state,
238
+ duration,
239
+ result: this.phaseResults.get(phase),
240
+ error: this.phaseErrors.get(phase)?.message
241
+ };
242
+ if (state === 'complete') summary.stats.completed++;
243
+ if (state === 'error') summary.stats.failed++;
244
+ if (!state) summary.stats.skipped++;
245
+ }
246
+ summary.stats.successRate = Math.round(summary.stats.completed / summary.stats.total * 100);
247
+ return summary;
248
+ }
249
+
250
+ /**
251
+ * Get total execution time in milliseconds
252
+ * @returns {number} Execution time in ms
253
+ */
254
+ getExecutionTime() {
255
+ return Date.now() - this.startTime;
256
+ }
257
+
258
+ /**
259
+ * Get phase status
260
+ * @param {string} phase - Phase name
261
+ * @returns {string} Phase state: 'pending', 'executing', 'complete', 'error'
262
+ */
263
+ getPhaseStatus(phase) {
264
+ return this.phaseStates.get(phase) || 'pending';
265
+ }
266
+
267
+ /**
268
+ * Get all phase results
269
+ * @returns {Map<string, Object>} Map of phase results
270
+ */
271
+ getPhaseResults() {
272
+ return new Map(this.phaseResults);
273
+ }
274
+
275
+ /**
276
+ * Get specific phase result
277
+ * @param {string} phase - Phase name
278
+ * @returns {Object} Phase result or null
279
+ */
280
+ getPhaseResult(phase) {
281
+ return this.phaseResults.get(phase) || null;
282
+ }
283
+
284
+ /**
285
+ * Get execution context
286
+ * @returns {Object} Current execution context
287
+ */
288
+ getExecutionContext() {
289
+ return {
290
+ ...this.executionContext,
291
+ currentPhase: this.currentPhase,
292
+ phaseStates: Object.fromEntries(this.phaseStates),
293
+ phaseTimings: Object.fromEntries(this.phaseTimings),
294
+ totalDuration: this.getExecutionTime()
295
+ };
296
+ }
297
+
298
+ /**
299
+ * Capitalize first letter of string and convert hyphens to camelCase
300
+ * Used for method name generation with special handling for phase names
301
+ *
302
+ * @private
303
+ * @param {string} str - String to capitalize
304
+ * @returns {string} Capitalized camelCase string
305
+ */
306
+ capitalize(str) {
307
+ // Special mappings for phase names to method names
308
+ const phaseToMethodMap = {
309
+ 'initialization': 'Initialize',
310
+ 'validation': 'Validation',
311
+ 'preparation': 'Prepare',
312
+ 'deployment': 'Deploy',
313
+ 'verification': 'Verify',
314
+ 'monitoring': 'Monitor'
315
+ };
316
+ if (phaseToMethodMap[str]) {
317
+ return phaseToMethodMap[str];
318
+ }
319
+
320
+ // Generic camelCase converter for extensibility
321
+ return str.split('-').map((word, idx) => idx === 0 ? word.charAt(0).toUpperCase() + word.slice(1) : word.charAt(0).toUpperCase() + word.slice(1)).join('');
322
+ }
323
+
324
+ /**
325
+ * Phase lifecycle methods (to be implemented by subclasses)
326
+ * Each phase must be implemented in concrete orchestrator
327
+ */
328
+
329
+ /**
330
+ * Initialization phase
331
+ * Setup and validate deployment environment
332
+ *
333
+ * @abstract
334
+ * @returns {Promise<Object>} Initialization result
335
+ */
336
+ async onInitialize() {
337
+ throw new Error(`onInitialize() must be implemented in ${this.constructor.name}`);
338
+ }
339
+
340
+ /**
341
+ * Validation phase
342
+ * Validate all prerequisites and configurations
343
+ *
344
+ * @abstract
345
+ * @returns {Promise<Object>} Validation result
346
+ */
347
+ async onValidation() {
348
+ throw new Error(`onValidation() must be implemented in ${this.constructor.name}`);
349
+ }
350
+
351
+ /**
352
+ * Preparation phase
353
+ * Prepare resources and deployment artifacts
354
+ *
355
+ * @abstract
356
+ * @returns {Promise<Object>} Preparation result
357
+ */
358
+ async onPrepare() {
359
+ throw new Error(`onPrepare() must be implemented in ${this.constructor.name}`);
360
+ }
361
+
362
+ /**
363
+ * Deployment phase
364
+ * Execute actual deployment operations
365
+ *
366
+ * @abstract
367
+ * @returns {Promise<Object>} Deployment result
368
+ */
369
+ async onDeploy() {
370
+ throw new Error(`onDeploy() must be implemented in ${this.constructor.name}`);
371
+ }
372
+
373
+ /**
374
+ * Verification phase
375
+ * Verify deployment success and health
376
+ *
377
+ * @abstract
378
+ * @returns {Promise<Object>} Verification result
379
+ */
380
+ async onVerify() {
381
+ throw new Error(`onVerify() must be implemented in ${this.constructor.name}`);
382
+ }
383
+
384
+ /**
385
+ * Monitoring phase
386
+ * Setup monitoring and alerting for deployed service
387
+ *
388
+ * @abstract
389
+ * @returns {Promise<Object>} Monitoring result
390
+ */
391
+ async onMonitor() {
392
+ throw new Error(`onMonitor() must be implemented in ${this.constructor.name}`);
393
+ }
394
+
395
+ /**
396
+ * Static helper to get deployment phases
397
+ * @static
398
+ * @returns {Object} Phase constants
399
+ */
400
+ static getPhases() {
401
+ return {
402
+ ...DEPLOYMENT_PHASES
403
+ };
404
+ }
405
+
406
+ /**
407
+ * Static helper to get phase sequence
408
+ * @static
409
+ * @returns {string[]} Ordered phase names
410
+ */
411
+ static getPhaseSequence() {
412
+ return [...PHASE_SEQUENCE];
413
+ }
414
+
415
+ /**
416
+ * Static helper to validate phase name
417
+ * @static
418
+ * @param {string} phase - Phase to validate
419
+ * @returns {boolean} True if valid phase
420
+ */
421
+ static isValidPhase(phase) {
422
+ return PHASE_SEQUENCE.includes(phase);
423
+ }
424
+ }
425
+ export default BaseDeploymentOrchestrator;
426
+ export { DEPLOYMENT_PHASES, PHASE_SEQUENCE };