@tamyla/clodo-framework 3.1.21 → 3.1.23

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 (150) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +283 -1
  3. package/dist/{bin → cli}/clodo-service.js +47 -15
  4. package/dist/cli/commands/assess.js +183 -0
  5. package/dist/{bin → cli}/commands/create.js +5 -5
  6. package/dist/{bin → cli}/commands/deploy.js +122 -90
  7. package/dist/{bin → cli}/commands/diagnose.js +5 -5
  8. package/dist/cli/commands/helpers/deployment-ui.js +138 -0
  9. package/dist/cli/commands/helpers/deployment-verification.js +250 -0
  10. package/dist/cli/commands/helpers/error-recovery.js +80 -0
  11. package/dist/cli/commands/helpers/resource-detection.js +113 -0
  12. package/dist/{bin → cli}/commands/helpers.js +0 -28
  13. package/dist/cli/commands/init-config.js +57 -0
  14. package/dist/{bin → cli}/commands/update.js +5 -5
  15. package/dist/{bin → cli}/commands/validate.js +5 -5
  16. package/dist/cli/security-cli.js +118 -0
  17. package/dist/config/FeatureManager.js +6 -0
  18. package/dist/config/clodo-create.example.json +26 -0
  19. package/dist/config/clodo-deploy.example.json +41 -0
  20. package/dist/config/clodo-update.example.json +46 -0
  21. package/dist/config/clodo-validate.example.json +41 -0
  22. package/dist/config/customers/template/development.env.template +37 -0
  23. package/dist/config/customers/template/production.env.template +39 -0
  24. package/dist/config/customers/template/staging.env.template +37 -0
  25. package/dist/config/customers.js +28 -26
  26. package/dist/config/domain-examples/README.md +464 -0
  27. package/dist/config/domain-examples/environment-mapped.json +168 -0
  28. package/dist/config/domain-examples/multi-domain.json +144 -0
  29. package/dist/config/domain-examples/single-domain.json +50 -0
  30. package/dist/config/examples +12 -0
  31. package/dist/config/features.js +61 -0
  32. package/dist/config/staging-deployment.json +60 -0
  33. package/dist/config/validation-config.json +347 -0
  34. package/dist/deployment/wrangler-deployer.js +1 -1
  35. package/dist/{bin → lib}/deployment/modules/DeploymentOrchestrator.js +2 -2
  36. package/dist/{bin → lib}/deployment/modules/EnvironmentManager.js +2 -2
  37. package/dist/lib/deployment/orchestration/EnterpriseOrchestrator.js +21 -0
  38. package/dist/lib/shared/cache/configuration-cache.js +82 -0
  39. package/dist/{bin → lib}/shared/cloudflare/domain-discovery.js +1 -1
  40. package/dist/{bin → lib}/shared/cloudflare/domain-manager.js +1 -1
  41. package/dist/{bin → lib}/shared/cloudflare/index.js +1 -1
  42. package/dist/{bin → lib}/shared/cloudflare/ops.js +10 -8
  43. package/dist/{bin → lib}/shared/config/ConfigurationManager.js +23 -1
  44. package/dist/{bin → lib}/shared/config/command-config-manager.js +19 -3
  45. package/dist/{bin → lib}/shared/config/index.js +1 -1
  46. package/dist/{bin → lib}/shared/deployment/credential-collector.js +30 -7
  47. package/dist/lib/shared/deployment/index.js +10 -0
  48. package/dist/lib/shared/deployment/rollback-manager.js +7 -0
  49. package/dist/lib/shared/deployment/utilities/d1-error-recovery.js +177 -0
  50. package/dist/{bin → lib}/shared/deployment/validator.js +40 -10
  51. package/dist/lib/shared/deployment/workflows/deployment-summary.js +214 -0
  52. package/dist/lib/shared/deployment/workflows/interactive-confirmation.js +188 -0
  53. package/dist/lib/shared/deployment/workflows/interactive-database-workflow.js +234 -0
  54. package/dist/lib/shared/deployment/workflows/interactive-domain-info-gatherer.js +240 -0
  55. package/dist/lib/shared/deployment/workflows/interactive-secret-workflow.js +228 -0
  56. package/dist/lib/shared/deployment/workflows/interactive-testing-workflow.js +235 -0
  57. package/dist/lib/shared/deployment/workflows/interactive-validation.js +218 -0
  58. package/dist/lib/shared/error-handling/error-classifier.js +46 -0
  59. package/dist/{bin → lib}/shared/monitoring/health-checker.js +129 -1
  60. package/dist/{bin → lib}/shared/monitoring/memory-manager.js +17 -6
  61. package/dist/{bin → lib}/shared/routing/domain-router.js +1 -1
  62. package/dist/lib/shared/utils/deployment-validator.js +97 -0
  63. package/dist/{bin → lib}/shared/utils/formatters.js +10 -0
  64. package/dist/{bin → lib}/shared/utils/index.js +13 -1
  65. package/dist/{bin → lib}/shared/utils/interactive-prompts.js +34 -18
  66. package/dist/{bin → lib}/shared/utils/progress-manager.js +2 -2
  67. package/dist/lib/shared/utils/progress-spinner.js +53 -0
  68. package/dist/lib/shared/utils/sensitive-redactor.js +91 -0
  69. package/dist/{bin → lib}/shared/validation/ValidationRegistry.js +1 -1
  70. package/dist/migration/MigrationAdapters.js +50 -4
  71. package/dist/orchestration/cross-domain-coordinator.js +5 -5
  72. package/dist/orchestration/multi-domain-orchestrator.js +63 -22
  73. package/dist/security/index.js +2 -2
  74. package/dist/security/patterns/insecure-patterns.js +1 -1
  75. package/dist/service-management/ConfirmationEngine.js +1 -1
  76. package/dist/service-management/ErrorTracker.js +1 -1
  77. package/dist/service-management/InputCollector.js +1 -1
  78. package/dist/service-management/ServiceCreator.js +11 -255
  79. package/dist/service-management/ServiceOrchestrator.js +0 -2
  80. package/dist/service-management/generators/testing/UnitTestsGenerator.js +4 -4
  81. package/dist/service-management/index.js +1 -1
  82. package/dist/utils/cloudflare/ops.js +1 -1
  83. package/dist/utils/constants.js +102 -0
  84. package/dist/utils/deployment/wrangler-config-manager.js +215 -48
  85. package/dist/utils/file-manager.js +1 -1
  86. package/dist/utils/formatters.js +1 -1
  87. package/dist/utils/framework-config.js +2 -2
  88. package/dist/utils/interactive-prompts.js +10 -59
  89. package/dist/utils/logger.js +1 -1
  90. package/dist/version/VersionDetector.js +99 -9
  91. package/dist/worker/integration.js +1 -1
  92. package/package.json +10 -10
  93. package/dist/bin/clodo-service-old.js +0 -868
  94. package/dist/bin/clodo-service-test.js +0 -10
  95. package/dist/bin/commands/assess.js +0 -91
  96. package/dist/bin/database/enterprise-db-manager.js +0 -457
  97. package/dist/bin/deployment/enterprise-deploy.js +0 -877
  98. package/dist/bin/deployment/master-deploy.js +0 -1376
  99. package/dist/bin/deployment/modular-enterprise-deploy.js +0 -466
  100. package/dist/bin/deployment/orchestration/EnterpriseOrchestrator.js +0 -401
  101. package/dist/bin/deployment/test-interactive-utils.js +0 -66
  102. package/dist/bin/portfolio/portfolio-manager.js +0 -487
  103. package/dist/bin/security/security-cli.js +0 -108
  104. package/dist/bin/service-management/create-service.js +0 -122
  105. package/dist/bin/service-management/init-service.js +0 -79
  106. package/dist/bin/shared/deployment/index.js +0 -10
  107. package/dist/bin/shared/deployment/rollback-manager.js +0 -523
  108. package/dist/deployment/orchestration/EnterpriseOrchestrator.js +0 -401
  109. package/dist/service-management/ServiceInitializer.js +0 -453
  110. /package/dist/{bin → lib}/database/deployment-db-manager.js +0 -0
  111. /package/dist/{bin → lib}/database/wrangler-d1-manager.js +0 -0
  112. /package/dist/{bin → lib}/deployment/modules/DeploymentConfiguration.js +0 -0
  113. /package/dist/{bin → lib}/deployment/modules/MonitoringIntegration.js +0 -0
  114. /package/dist/{bin → lib}/deployment/modules/ValidationManager.js +0 -0
  115. /package/dist/{bin → lib}/deployment/orchestration/BaseDeploymentOrchestrator.js +0 -0
  116. /package/dist/{bin → lib}/deployment/orchestration/PortfolioOrchestrator.js +0 -0
  117. /package/dist/{bin → lib}/deployment/orchestration/SingleServiceOrchestrator.js +0 -0
  118. /package/dist/{bin → lib}/deployment/orchestration/UnifiedDeploymentOrchestrator.js +0 -0
  119. /package/dist/{bin → lib}/shared/config/cache.js +0 -0
  120. /package/dist/{bin → lib}/shared/config/cloudflare-service-validator.js +0 -0
  121. /package/dist/{bin → lib}/shared/config/manager.js +0 -0
  122. /package/dist/{bin → lib}/shared/config/manifest-loader.js +0 -0
  123. /package/dist/{bin → lib}/shared/database/connection-manager.js +0 -0
  124. /package/dist/{bin → lib}/shared/database/index.js +0 -0
  125. /package/dist/{bin → lib}/shared/database/orchestrator.js +0 -0
  126. /package/dist/{bin → lib}/shared/deployment/auditor.js +0 -0
  127. /package/dist/{bin → lib}/shared/index.js +0 -0
  128. /package/dist/{bin → lib}/shared/logging/Logger.js +0 -0
  129. /package/dist/{bin → lib}/shared/monitoring/index.js +0 -0
  130. /package/dist/{bin → lib}/shared/monitoring/production-monitor.js +0 -0
  131. /package/dist/{bin → lib}/shared/production-tester/api-tester.js +0 -0
  132. /package/dist/{bin → lib}/shared/production-tester/auth-tester.js +0 -0
  133. /package/dist/{bin → lib}/shared/production-tester/core.js +0 -0
  134. /package/dist/{bin → lib}/shared/production-tester/database-tester.js +0 -0
  135. /package/dist/{bin → lib}/shared/production-tester/index.js +0 -0
  136. /package/dist/{bin → lib}/shared/production-tester/load-tester.js +0 -0
  137. /package/dist/{bin → lib}/shared/production-tester/performance-tester.js +0 -0
  138. /package/dist/{bin → lib}/shared/security/api-token-manager.js +0 -0
  139. /package/dist/{bin → lib}/shared/security/index.js +0 -0
  140. /package/dist/{bin → lib}/shared/security/secret-generator.js +0 -0
  141. /package/dist/{bin → lib}/shared/security/secure-token-manager.js +0 -0
  142. /package/dist/{bin → lib}/shared/utils/ErrorHandler.js +0 -0
  143. /package/dist/{bin → lib}/shared/utils/cli-options.js +0 -0
  144. /package/dist/{bin → lib}/shared/utils/config-loader.js +0 -0
  145. /package/dist/{bin → lib}/shared/utils/error-recovery.js +0 -0
  146. /package/dist/{bin → lib}/shared/utils/file-manager.js +0 -0
  147. /package/dist/{bin → lib}/shared/utils/graceful-shutdown-manager.js +0 -0
  148. /package/dist/{bin → lib}/shared/utils/interactive-utils.js +0 -0
  149. /package/dist/{bin → lib}/shared/utils/output-formatter.js +0 -0
  150. /package/dist/{bin → lib}/shared/utils/rate-limiter.js +0 -0
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Deployment Summary Module
3
+ *
4
+ * Provides reusable deployment success/failure summary reporting.
5
+ * Extracted from enterprise-deployment/master-deploy.js for modularity.
6
+ *
7
+ * @module deployment-summary
8
+ */
9
+
10
+ /**
11
+ * Deployment Summary Manager
12
+ * Handles success summaries, enterprise summaries, and deployment statistics
13
+ */
14
+ export class DeploymentSummary {
15
+ /**
16
+ * Display standard deployment success summary
17
+ *
18
+ * @param {Object} deploymentState - Deployment state object
19
+ * @param {Object} config - Deployment configuration
20
+ * @param {Object} options - Display options
21
+ * @returns {Promise<void>}
22
+ */
23
+ static async displaySuccessSummary(deploymentState, config, options = {}) {
24
+ const duration = (Date.now() - deploymentState.startTime.getTime()) / 1000;
25
+ console.log('\n🎉 DEPLOYMENT SUCCESSFUL!');
26
+ console.log('=========================');
27
+ console.log(`\n📊 Summary:`);
28
+ console.log(` 🆔 Deployment ID: ${deploymentState.deploymentId}`);
29
+ console.log(` 🌐 Domain: ${config.domain}`);
30
+ console.log(` ⏱️ Duration: ${duration.toFixed(1)}s`);
31
+ console.log(` 🔑 Secrets: ${Object.keys(config.secrets.keys).length} deployed`);
32
+ this.displayEndpoints(config);
33
+ this.displayDistributionFiles(config);
34
+ this.displayNextSteps(config);
35
+ }
36
+
37
+ /**
38
+ * Display enterprise deployment success summary
39
+ *
40
+ * @param {Object} deploymentState - Deployment state object
41
+ * @param {Object} config - Deployment configuration
42
+ * @param {Object} frameworkPaths - Framework paths configuration
43
+ * @param {Object} enterpriseModules - Enterprise modules
44
+ * @returns {Promise<void>}
45
+ */
46
+ static async displayEnterpriseSuccessSummary(deploymentState, config, frameworkPaths, enterpriseModules) {
47
+ console.log('\n🎉 ENTERPRISE DEPLOYMENT SUCCESSFUL!');
48
+ console.log('====================================');
49
+ const duration = (new Date() - deploymentState.startTime) / 1000;
50
+ this.displayDeploymentStats(deploymentState, config, duration);
51
+ this.displayEnterpriseEndpoints(config);
52
+ this.displayGeneratedFiles(frameworkPaths, config, deploymentState);
53
+ this.displayEnabledFeatures(config);
54
+
55
+ // End audit session successfully
56
+ if (enterpriseModules?.auditor) {
57
+ enterpriseModules.auditor.endDeploymentAudit(deploymentState.deploymentId, 'success', {
58
+ duration,
59
+ endpoints: 4,
60
+ testsRun: config.deployment.runTests,
61
+ enterpriseFeatures: Object.keys(config.enterprise).filter(k => config.enterprise[k]).length
62
+ });
63
+ }
64
+ this.displayEnterpriseNextSteps();
65
+ }
66
+
67
+ /**
68
+ * Display deployment statistics
69
+ *
70
+ * @param {Object} deploymentState - Deployment state
71
+ * @param {Object} config - Configuration
72
+ * @param {number} duration - Deployment duration in seconds
73
+ */
74
+ static displayDeploymentStats(deploymentState, config, duration) {
75
+ console.log('\n📊 Deployment Statistics:');
76
+ console.log(` ⏱️ Duration: ${duration.toFixed(1)} seconds`);
77
+ console.log(` 🆔 Deployment ID: ${deploymentState.deploymentId}`);
78
+ console.log(` 🌐 Domain: ${config.domain}`);
79
+ console.log(` 🌍 Environment: ${config.environment}`);
80
+ console.log(` 📱 Mode: ${config.deploymentMode}`);
81
+ }
82
+
83
+ /**
84
+ * Display service endpoints
85
+ *
86
+ * @param {Object} config - Configuration
87
+ */
88
+ static displayEndpoints(config) {
89
+ console.log(`\n🌐 Your service is now live at:`);
90
+ console.log(` ${config.worker.url}/health`);
91
+ console.log(` ${config.worker.url}/auth/magic-link`);
92
+ }
93
+
94
+ /**
95
+ * Display enterprise endpoints
96
+ *
97
+ * @param {Object} config - Configuration
98
+ */
99
+ static displayEnterpriseEndpoints(config) {
100
+ console.log('\n🌐 Enterprise Endpoints:');
101
+ console.log(` 🏠 Main: ${config.worker.url}`);
102
+ console.log(` ❤️ Health: ${config.worker.url}/health`);
103
+ console.log(` 🔐 Auth: ${config.worker.url}/auth/magic-link`);
104
+ console.log(` 📊 API: ${config.worker.url}/api`);
105
+ }
106
+
107
+ /**
108
+ * Display secret distribution files
109
+ *
110
+ * @param {Object} config - Configuration
111
+ */
112
+ static displayDistributionFiles(config) {
113
+ console.log(`\n📄 Secret distribution files:`);
114
+ console.log(` secrets/distribution/${config.domain}/.env`);
115
+ console.log(` secrets/distribution/${config.domain}/secrets.json`);
116
+ console.log(` secrets/distribution/${config.domain}/deploy-secrets.sh`);
117
+ }
118
+
119
+ /**
120
+ * Display generated enterprise files
121
+ *
122
+ * @param {Object} frameworkPaths - Framework paths
123
+ * @param {Object} config - Configuration
124
+ * @param {Object} deploymentState - Deployment state
125
+ */
126
+ static displayGeneratedFiles(frameworkPaths, config, deploymentState) {
127
+ console.log('\n📄 Generated Enterprise Files:');
128
+ console.log(` 📝 Audit Log: ${frameworkPaths.auditLogs}/deployments/session-${deploymentState.deploymentId}.log`);
129
+ console.log(` 📊 Report: ${frameworkPaths.auditReports}/deployment-${deploymentState.deploymentId}.html`);
130
+ console.log(` 🔐 Secrets: ${frameworkPaths.secureTokens}/distribution/${config.domain}/`);
131
+ console.log(` ⚙️ Config: ${frameworkPaths.configCache}/domains/${config.domain}/`);
132
+ }
133
+
134
+ /**
135
+ * Display enabled enterprise features
136
+ *
137
+ * @param {Object} config - Configuration
138
+ */
139
+ static displayEnabledFeatures(config) {
140
+ console.log('\n🚀 Enterprise Features Enabled:');
141
+ console.log(` 🔍 Validation: ${config.deployment.validationLevel}`);
142
+ console.log(` 📋 Audit: ${config.deployment.auditLevel}`);
143
+ console.log(` 🧪 Testing: ${config.deployment.runTests ? 'Comprehensive' : 'Disabled'}`);
144
+ console.log(` 🔄 Rollback: ${config.deployment.enableRollback ? 'Available' : 'Disabled'}`);
145
+ console.log(` 💾 Caching: Smart configuration caching enabled`);
146
+ console.log(` 🎯 Orchestration: Enterprise orchestration active`);
147
+ }
148
+
149
+ /**
150
+ * Display next steps
151
+ *
152
+ * @param {Object} config - Configuration
153
+ */
154
+ static displayNextSteps(config) {
155
+ console.log('\n🚀 Next steps:');
156
+ console.log(' 1. Test the endpoints above');
157
+ console.log(' 2. Distribute secrets to upstream/downstream applications');
158
+ console.log(' 3. Configure DNS if using custom domain');
159
+ console.log(' 4. Update your applications to use the new service');
160
+ }
161
+
162
+ /**
163
+ * Display enterprise next steps
164
+ */
165
+ static displayEnterpriseNextSteps() {
166
+ console.log('\n✅ Enterprise deployment completed successfully!');
167
+ console.log(' Visit the health endpoint to verify deployment');
168
+ console.log(' Check audit logs for detailed deployment history');
169
+ console.log(' Use enterprise modules for ongoing management');
170
+ }
171
+
172
+ /**
173
+ * Display failure summary
174
+ *
175
+ * @param {Error} error - Deployment error
176
+ * @param {Object} deploymentState - Deployment state
177
+ * @param {Object} config - Configuration
178
+ */
179
+ static displayFailureSummary(error, deploymentState, config) {
180
+ const duration = (Date.now() - deploymentState.startTime.getTime()) / 1000;
181
+ console.log('\n❌ DEPLOYMENT FAILED');
182
+ console.log('===================');
183
+ console.log(`\n📊 Summary:`);
184
+ console.log(` 🆔 Deployment ID: ${deploymentState.deploymentId}`);
185
+ console.log(` 🌐 Domain: ${config.domain}`);
186
+ console.log(` ⏱️ Duration: ${duration.toFixed(1)}s`);
187
+ console.log(` ❌ Error: ${error.message}`);
188
+ if (deploymentState.currentPhase) {
189
+ console.log(` 📍 Failed at: ${deploymentState.currentPhase}`);
190
+ }
191
+ console.log('\n🔄 Rollback options:');
192
+ console.log(` ${deploymentState.rollbackActions.length} rollback actions available`);
193
+ }
194
+
195
+ /**
196
+ * Get deployment summary statistics
197
+ *
198
+ * @param {Object} deploymentState - Deployment state
199
+ * @param {Object} config - Configuration
200
+ * @returns {Object} Summary statistics
201
+ */
202
+ static getSummaryStats(deploymentState, config) {
203
+ const duration = (Date.now() - deploymentState.startTime.getTime()) / 1000;
204
+ return {
205
+ deploymentId: deploymentState.deploymentId,
206
+ domain: config.domain,
207
+ environment: config.environment,
208
+ duration: duration.toFixed(1),
209
+ secretsDeployed: Object.keys(config.secrets.keys).length,
210
+ currentPhase: deploymentState.currentPhase,
211
+ rollbackActionsAvailable: deploymentState.rollbackActions.length
212
+ };
213
+ }
214
+ }
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Interactive Confirmation Module
3
+ *
4
+ * Provides reusable interactive confirmation workflows.
5
+ * Extracted from enterprise-deployment/master-deploy.js for modularity.
6
+ *
7
+ * @module interactive-confirmation
8
+ */
9
+
10
+ import { askYesNo } from '../utils/interactive-prompts.js';
11
+
12
+ /**
13
+ * Interactive Confirmation Manager
14
+ * Handles deployment confirmations and configuration reviews
15
+ */
16
+ export class InteractiveConfirmation {
17
+ /**
18
+ * Display final deployment confirmation
19
+ *
20
+ * @param {Object} config - Deployment configuration
21
+ * @param {Object} deploymentState - Deployment state
22
+ * @param {Object} options - Confirmation options
23
+ * @returns {Promise<boolean>} True if confirmed, throws if cancelled
24
+ */
25
+ static async showFinalConfirmation(config, deploymentState, options = {}) {
26
+ console.log('\n🎯 Final Deployment Confirmation');
27
+ console.log('===============================');
28
+ this.displayDeploymentSummary(config, deploymentState);
29
+ this.displayActionsToPerform(config);
30
+ const finalConfirm = await askYesNo('\n🚨 PROCEED WITH DEPLOYMENT? This will make changes to your Cloudflare account.', options.defaultAnswer || 'n');
31
+ if (!finalConfirm) {
32
+ throw new Error('Deployment cancelled by user');
33
+ }
34
+ return true;
35
+ }
36
+
37
+ /**
38
+ * Display deployment summary
39
+ *
40
+ * @param {Object} config - Configuration
41
+ * @param {Object} deploymentState - Deployment state
42
+ */
43
+ static displayDeploymentSummary(config, deploymentState) {
44
+ console.log('\n📋 DEPLOYMENT SUMMARY');
45
+ console.log('=====================');
46
+ console.log(`🌐 Domain: ${config.domain}`);
47
+ console.log(`🌍 Environment: ${config.environment}`);
48
+ console.log(`⚡ Worker: ${config.worker.name}`);
49
+ console.log(`🔗 URL: ${config.worker.url}`);
50
+ console.log(`🗄️ Database: ${config.database.name} (${config.database.id})`);
51
+ console.log(`🔑 Secrets: ${Object.keys(config.secrets.keys).length} configured`);
52
+ console.log(`🆔 Deployment ID: ${deploymentState.deploymentId}`);
53
+ }
54
+
55
+ /**
56
+ * Display actions that will be performed
57
+ *
58
+ * @param {Object} config - Configuration
59
+ */
60
+ static displayActionsToPerform(config) {
61
+ console.log('\n🚀 ACTIONS TO PERFORM:');
62
+ console.log('1. Update wrangler.toml configuration');
63
+ console.log('2. Run database migrations');
64
+ console.log('3. Deploy Cloudflare Worker');
65
+ console.log('4. Verify deployment health');
66
+ if (config.deployment.runTests) {
67
+ console.log('5. Run integration tests');
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Display and confirm configuration review
73
+ *
74
+ * @param {Object} config - Configuration to review
75
+ * @param {Object} deploymentState - Deployment state
76
+ * @param {Function} reconfigureCallback - Callback to reconfigure if rejected
77
+ * @returns {Promise<boolean>} True if confirmed
78
+ */
79
+ static async showConfigurationReview(config, deploymentState, reconfigureCallback) {
80
+ console.log('\n🔍 Configuration Review');
81
+ console.log('======================');
82
+ console.log('\nPlease review your configuration:');
83
+ console.log(` 🌐 Domain: ${config.domain}`);
84
+ console.log(` 🌍 Environment: ${config.environment}`);
85
+ console.log(` ⚡ Worker: ${config.worker.name}`);
86
+ console.log(` 🔗 URL: ${config.worker.url}`);
87
+ console.log(` 🆔 Deployment ID: ${deploymentState.deploymentId}`);
88
+ const confirmed = await askYesNo('\nIs this configuration correct?', 'y');
89
+ if (!confirmed) {
90
+ if (reconfigureCallback && typeof reconfigureCallback === 'function') {
91
+ console.log('\n🔄 Let\'s reconfigure...');
92
+ await reconfigureCallback();
93
+ return this.showConfigurationReview(config, deploymentState, reconfigureCallback);
94
+ } else {
95
+ throw new Error('Configuration rejected by user');
96
+ }
97
+ }
98
+ return true;
99
+ }
100
+
101
+ /**
102
+ * Show enterprise final confirmation with additional details
103
+ *
104
+ * @param {Object} config - Deployment configuration
105
+ * @param {Object} deploymentState - Deployment state
106
+ * @param {Object} enterpriseModules - Enterprise modules
107
+ * @returns {Promise<boolean>} True if confirmed
108
+ */
109
+ static async showEnterpriseFinalConfirmation(config, deploymentState, enterpriseModules) {
110
+ console.log('\n🎯 Enterprise Final Confirmation');
111
+ console.log('================================');
112
+ this.displayEnterpriseDeploymentSummary(config, deploymentState);
113
+ this.displayEnterpriseActionsToPerform(config, enterpriseModules);
114
+ const finalConfirm = await askYesNo('\n🚨 PROCEED WITH ENTERPRISE DEPLOYMENT?', 'n');
115
+ if (!finalConfirm) {
116
+ throw new Error('Enterprise deployment cancelled by user');
117
+ }
118
+ return true;
119
+ }
120
+
121
+ /**
122
+ * Display enterprise deployment summary
123
+ *
124
+ * @param {Object} config - Configuration
125
+ * @param {Object} deploymentState - Deployment state
126
+ */
127
+ static displayEnterpriseDeploymentSummary(config, deploymentState) {
128
+ console.log('\n📋 ENTERPRISE DEPLOYMENT SUMMARY');
129
+ console.log('================================');
130
+ console.log(`🌐 Domain: ${config.domain}`);
131
+ console.log(`🌍 Environment: ${config.environment}`);
132
+ console.log(`📱 Mode: ${config.deploymentMode}`);
133
+ console.log(`⚡ Worker: ${config.worker.name}`);
134
+ console.log(`🔗 URL: ${config.worker.url}`);
135
+ console.log(`🗄️ Database: ${config.database.name} (${config.database.id})`);
136
+ console.log(`🔑 Secrets: ${Object.keys(config.secrets.keys).length} configured`);
137
+ console.log(`🆔 Deployment ID: ${deploymentState.deploymentId}`);
138
+ console.log(`🔍 Validation: ${config.deployment.validationLevel}`);
139
+ console.log(`📋 Audit: ${config.deployment.auditLevel}`);
140
+ }
141
+
142
+ /**
143
+ * Display enterprise actions
144
+ *
145
+ * @param {Object} config - Configuration
146
+ * @param {Object} enterpriseModules - Enterprise modules
147
+ */
148
+ static displayEnterpriseActionsToPerform(config, enterpriseModules) {
149
+ console.log('\n🚀 ENTERPRISE ACTIONS TO PERFORM:');
150
+ console.log('1. Comprehensive validation');
151
+ console.log('2. Database orchestration');
152
+ console.log('3. Enterprise secret management');
153
+ console.log('4. Configuration management');
154
+ console.log('5. Cloudflare Worker deployment with D1 recovery');
155
+ console.log('6. Deployment verification');
156
+ if (config.deployment.runTests) {
157
+ console.log('7. Comprehensive integration tests');
158
+ }
159
+ console.log(`8. Audit logging and reporting`);
160
+ }
161
+
162
+ /**
163
+ * Quick yes/no confirmation
164
+ *
165
+ * @param {string} message - Confirmation message
166
+ * @param {string} defaultAnswer - Default answer ('y' or 'n')
167
+ * @returns {Promise<boolean>} Confirmation result
168
+ */
169
+ static async quickConfirm(message, defaultAnswer = 'y') {
170
+ return await askYesNo(message, defaultAnswer);
171
+ }
172
+
173
+ /**
174
+ * Confirm dangerous action with warning
175
+ *
176
+ * @param {string} action - Action description
177
+ * @param {string} warning - Warning message
178
+ * @returns {Promise<boolean>} Confirmation result
179
+ */
180
+ static async confirmDangerousAction(action, warning) {
181
+ console.log(`\n⚠️ WARNING: ${warning}`);
182
+ const confirm = await askYesNo(`Are you sure you want to ${action}?`, 'n');
183
+ if (!confirm) {
184
+ throw new Error(`Dangerous action cancelled: ${action}`);
185
+ }
186
+ return true;
187
+ }
188
+ }
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Interactive Database Workflow Module
3
+ *
4
+ * Provides reusable interactive database creation and configuration workflows.
5
+ * Extracted from enterprise-deployment/master-deploy.js for modularity.
6
+ *
7
+ * @module interactive-database-workflow
8
+ */
9
+
10
+ import { askUser, askYesNo, askChoice } from '../utils/interactive-prompts.js';
11
+ import { databaseExists, createDatabase, deleteDatabase } from '../../cloudflare/ops.js';
12
+ import { exec } from 'child_process';
13
+ import { promisify } from 'util';
14
+ const execAsync = promisify(exec);
15
+
16
+ /**
17
+ * Interactive Database Workflow
18
+ * Handles database naming, existence checking, and creation with user interaction
19
+ */
20
+ export class InteractiveDatabaseWorkflow {
21
+ /**
22
+ * @param {Object} options - Configuration options
23
+ * @param {Array} options.rollbackActions - Array to track rollback actions
24
+ */
25
+ constructor(options = {}) {
26
+ this.rollbackActions = options.rollbackActions || [];
27
+ }
28
+
29
+ /**
30
+ * Handle complete database setup workflow
31
+ *
32
+ * @param {string} domain - Domain name for database
33
+ * @param {string} environment - Deployment environment
34
+ * @param {Object} options - Additional options
35
+ * @param {string} [options.suggestedName] - Suggested database name
36
+ * @param {boolean} [options.interactive=true] - Enable interactive prompts
37
+ * @returns {Promise<Object>} Database configuration { name, id, created, reused }
38
+ */
39
+ async handleDatabaseSetup(domain, environment, options = {}) {
40
+ console.log('\n🗄️ Database Configuration');
41
+ console.log('=========================');
42
+
43
+ // Generate default database name
44
+ const suggestedName = options.suggestedName || `${domain}-auth-db`;
45
+
46
+ // Get final database name
47
+ const databaseName = await this.promptForDatabaseName(suggestedName, options.interactive);
48
+
49
+ // Check if database exists
50
+ const existingInfo = await this.checkExistingDatabase(databaseName);
51
+ if (existingInfo.exists) {
52
+ return await this.handleExistingDatabase(databaseName, existingInfo, options.interactive);
53
+ } else {
54
+ return await this.createNewDatabase(databaseName, options.interactive);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Prompt user for database name
60
+ *
61
+ * @param {string} suggested - Suggested database name
62
+ * @param {boolean} interactive - Enable interactive prompts
63
+ * @returns {Promise<string>} Final database name
64
+ */
65
+ async promptForDatabaseName(suggested, interactive = true) {
66
+ console.log(`\n📋 Generated database name: ${suggested}`);
67
+ if (!interactive) {
68
+ return suggested;
69
+ }
70
+ const useGeneratedName = await askYesNo('Use this database name?', 'y');
71
+ if (!useGeneratedName) {
72
+ return await askUser('Enter custom database name', suggested);
73
+ }
74
+ return suggested;
75
+ }
76
+
77
+ /**
78
+ * Check if database exists and get its details
79
+ *
80
+ * @param {string} name - Database name
81
+ * @returns {Promise<Object>} { exists: boolean, id?: string, error?: string }
82
+ */
83
+ async checkExistingDatabase(name) {
84
+ console.log('\n🔍 Checking for existing database...');
85
+ try {
86
+ const exists = await databaseExists(name);
87
+ if (exists) {
88
+ console.log(` 📋 Database '${name}' already exists`);
89
+
90
+ // Extract database ID from the list command
91
+ try {
92
+ const dbListResult = await execAsync('npx wrangler d1 list');
93
+ const lines = dbListResult.stdout.split('\n');
94
+ for (const line of lines) {
95
+ if (line.includes(name)) {
96
+ const match = line.match(/([a-f0-9-]{36})/);
97
+ if (match) {
98
+ return {
99
+ exists: true,
100
+ id: match[1]
101
+ };
102
+ }
103
+ }
104
+ }
105
+ } catch (error) {
106
+ console.log(' ⚠️ Could not extract database ID');
107
+ }
108
+ return {
109
+ exists: true
110
+ };
111
+ } else {
112
+ console.log(` ✅ Database '${name}' does not exist`);
113
+ return {
114
+ exists: false
115
+ };
116
+ }
117
+ } catch (error) {
118
+ console.log(' ⚠️ Could not check existing databases');
119
+ return {
120
+ exists: false,
121
+ error: error.message
122
+ };
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Handle workflow for existing database
128
+ *
129
+ * @param {string} name - Database name
130
+ * @param {Object} existingInfo - Information about existing database
131
+ * @param {boolean} interactive - Enable interactive prompts
132
+ * @returns {Promise<Object>} Database configuration
133
+ */
134
+ async handleExistingDatabase(name, existingInfo, interactive = true) {
135
+ if (!interactive) {
136
+ // Non-interactive mode: reuse existing
137
+ console.log(` ✅ Using existing database: ${name}`);
138
+ return {
139
+ name,
140
+ id: existingInfo.id,
141
+ created: false,
142
+ reused: true
143
+ };
144
+ }
145
+ const databaseChoice = await askChoice('What would you like to do with the existing database?', ['Use the existing database (recommended)', 'Create a new database with different name', 'Delete existing and create new (DANGER: DATA LOSS)'], 0);
146
+ switch (databaseChoice) {
147
+ case 0:
148
+ {
149
+ // Use existing database
150
+ if (existingInfo.id) {
151
+ console.log(` ✅ Using existing database ID: ${existingInfo.id}`);
152
+ }
153
+ return {
154
+ name,
155
+ id: existingInfo.id,
156
+ created: false,
157
+ reused: true
158
+ };
159
+ }
160
+ case 1:
161
+ {
162
+ // Create new database with different name
163
+ const newName = await askUser('Enter new database name');
164
+ return await this.createNewDatabase(newName, interactive);
165
+ }
166
+ case 2:
167
+ {
168
+ // Delete and recreate
169
+ const confirmDelete = await askYesNo('⚠️ ARE YOU SURE? This will DELETE all data in the existing database!', 'n');
170
+ if (!confirmDelete) {
171
+ throw new Error('Database deletion cancelled');
172
+ }
173
+ console.log(`\n🗑️ Deleting existing database...`);
174
+ await deleteDatabase(name);
175
+ return await this.createNewDatabase(name, interactive);
176
+ }
177
+ default:
178
+ throw new Error('Invalid database choice');
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Create a new database
184
+ *
185
+ * @param {string} name - Database name
186
+ * @param {boolean} interactive - Enable interactive prompts
187
+ * @returns {Promise<Object>} Database configuration
188
+ */
189
+ async createNewDatabase(name, interactive = true) {
190
+ console.log(`\n🆕 Creating new database: ${name}`);
191
+ if (interactive) {
192
+ const confirmCreate = await askYesNo('Proceed with database creation?', 'y');
193
+ if (!confirmCreate) {
194
+ throw new Error('Database creation cancelled');
195
+ }
196
+ }
197
+ try {
198
+ const databaseId = await createDatabase(name);
199
+ console.log(` ✅ Database created with ID: ${databaseId}`);
200
+
201
+ // Add to rollback actions
202
+ this.rollbackActions.push({
203
+ type: 'delete-database',
204
+ name: name,
205
+ command: `npx wrangler d1 delete ${name} --skip-confirmation`,
206
+ description: `Delete database '${name}' created during deployment`
207
+ });
208
+ return {
209
+ name,
210
+ id: databaseId,
211
+ created: true,
212
+ reused: false
213
+ };
214
+ } catch (error) {
215
+ throw new Error(`Database creation failed: ${error.message}`);
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Get database configuration summary
221
+ *
222
+ * @param {Object} dbConfig - Database configuration
223
+ * @returns {string} Summary message
224
+ */
225
+ getSummary(dbConfig) {
226
+ if (dbConfig.created) {
227
+ return `✅ Database configured: ${dbConfig.name} (${dbConfig.id}) - CREATED`;
228
+ } else if (dbConfig.reused) {
229
+ return `✅ Database configured: ${dbConfig.name} (${dbConfig.id}) - REUSED`;
230
+ } else {
231
+ return `✅ Database configured: ${dbConfig.name} (${dbConfig.id})`;
232
+ }
233
+ }
234
+ }