@tamyla/clodo-framework 1.0.0

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 (130) hide show
  1. package/CHANGELOG.md +564 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1393 -0
  4. package/bin/README.md +71 -0
  5. package/bin/clodo-service.js +416 -0
  6. package/bin/security/security-cli.js +96 -0
  7. package/bin/service-management/README.md +74 -0
  8. package/bin/service-management/create-service.js +129 -0
  9. package/bin/service-management/init-service.js +102 -0
  10. package/bin/service-management/init-service.js.backup +889 -0
  11. package/bin/shared/config/customer-cli.js +293 -0
  12. package/dist/config/ConfigurationManager.js +159 -0
  13. package/dist/config/CustomerConfigCLI.js +220 -0
  14. package/dist/config/FeatureManager.js +426 -0
  15. package/dist/config/customers.js +441 -0
  16. package/dist/config/domains.js +180 -0
  17. package/dist/config/features.js +225 -0
  18. package/dist/config/index.js +6 -0
  19. package/dist/database/database-orchestrator.js +730 -0
  20. package/dist/database/index.js +4 -0
  21. package/dist/deployment/auditor.js +971 -0
  22. package/dist/deployment/index.js +10 -0
  23. package/dist/deployment/rollback-manager.js +523 -0
  24. package/dist/deployment/testers/api-tester.js +80 -0
  25. package/dist/deployment/testers/auth-tester.js +129 -0
  26. package/dist/deployment/testers/core.js +217 -0
  27. package/dist/deployment/testers/database-tester.js +105 -0
  28. package/dist/deployment/testers/index.js +74 -0
  29. package/dist/deployment/testers/load-tester.js +120 -0
  30. package/dist/deployment/testers/performance-tester.js +105 -0
  31. package/dist/deployment/validator.js +558 -0
  32. package/dist/deployment/wrangler-deployer.js +574 -0
  33. package/dist/handlers/GenericRouteHandler.js +532 -0
  34. package/dist/index.js +39 -0
  35. package/dist/migration/MigrationAdapters.js +562 -0
  36. package/dist/modules/ModuleManager.js +668 -0
  37. package/dist/modules/security.js +98 -0
  38. package/dist/orchestration/cross-domain-coordinator.js +1083 -0
  39. package/dist/orchestration/index.js +5 -0
  40. package/dist/orchestration/modules/DeploymentCoordinator.js +258 -0
  41. package/dist/orchestration/modules/DomainResolver.js +196 -0
  42. package/dist/orchestration/modules/StateManager.js +332 -0
  43. package/dist/orchestration/multi-domain-orchestrator.js +255 -0
  44. package/dist/routing/EnhancedRouter.js +158 -0
  45. package/dist/schema/SchemaManager.js +778 -0
  46. package/dist/security/ConfigurationValidator.js +490 -0
  47. package/dist/security/DeploymentManager.js +208 -0
  48. package/dist/security/SecretGenerator.js +142 -0
  49. package/dist/security/SecurityCLI.js +228 -0
  50. package/dist/security/index.js +51 -0
  51. package/dist/security/patterns/environment-rules.js +66 -0
  52. package/dist/security/patterns/insecure-patterns.js +21 -0
  53. package/dist/service-management/ConfirmationEngine.js +411 -0
  54. package/dist/service-management/ErrorTracker.js +294 -0
  55. package/dist/service-management/GenerationEngine.js +3109 -0
  56. package/dist/service-management/InputCollector.js +237 -0
  57. package/dist/service-management/ServiceCreator.js +229 -0
  58. package/dist/service-management/ServiceInitializer.js +448 -0
  59. package/dist/service-management/ServiceOrchestrator.js +638 -0
  60. package/dist/service-management/handlers/ConfigMutator.js +130 -0
  61. package/dist/service-management/handlers/ConfirmationHandler.js +71 -0
  62. package/dist/service-management/handlers/GenerationHandler.js +80 -0
  63. package/dist/service-management/handlers/InputHandler.js +59 -0
  64. package/dist/service-management/handlers/ValidationHandler.js +203 -0
  65. package/dist/service-management/index.js +7 -0
  66. package/dist/services/GenericDataService.js +488 -0
  67. package/dist/shared/cloudflare/domain-discovery.js +562 -0
  68. package/dist/shared/cloudflare/domain-manager.js +912 -0
  69. package/dist/shared/cloudflare/index.js +8 -0
  70. package/dist/shared/cloudflare/ops.js +387 -0
  71. package/dist/shared/config/cache.js +1167 -0
  72. package/dist/shared/config/command-config-manager.js +174 -0
  73. package/dist/shared/config/customer-cli.js +258 -0
  74. package/dist/shared/config/index.js +9 -0
  75. package/dist/shared/config/manager.js +289 -0
  76. package/dist/shared/database/connection-manager.js +338 -0
  77. package/dist/shared/database/index.js +7 -0
  78. package/dist/shared/database/orchestrator.js +632 -0
  79. package/dist/shared/deployment/auditor.js +971 -0
  80. package/dist/shared/deployment/index.js +10 -0
  81. package/dist/shared/deployment/rollback-manager.js +523 -0
  82. package/dist/shared/deployment/validator.js +558 -0
  83. package/dist/shared/index.js +32 -0
  84. package/dist/shared/monitoring/health-checker.js +250 -0
  85. package/dist/shared/monitoring/index.js +8 -0
  86. package/dist/shared/monitoring/memory-manager.js +382 -0
  87. package/dist/shared/monitoring/production-monitor.js +390 -0
  88. package/dist/shared/production-tester/api-tester.js +80 -0
  89. package/dist/shared/production-tester/auth-tester.js +129 -0
  90. package/dist/shared/production-tester/core.js +217 -0
  91. package/dist/shared/production-tester/database-tester.js +105 -0
  92. package/dist/shared/production-tester/index.js +74 -0
  93. package/dist/shared/production-tester/load-tester.js +120 -0
  94. package/dist/shared/production-tester/performance-tester.js +105 -0
  95. package/dist/shared/security/api-token-manager.js +296 -0
  96. package/dist/shared/security/index.js +8 -0
  97. package/dist/shared/security/secret-generator.js +918 -0
  98. package/dist/shared/security/secure-token-manager.js +379 -0
  99. package/dist/shared/utils/error-recovery.js +240 -0
  100. package/dist/shared/utils/graceful-shutdown-manager.js +380 -0
  101. package/dist/shared/utils/index.js +9 -0
  102. package/dist/shared/utils/interactive-prompts.js +134 -0
  103. package/dist/shared/utils/rate-limiter.js +249 -0
  104. package/dist/utils/ErrorHandler.js +173 -0
  105. package/dist/utils/deployment/config-cache.js +1160 -0
  106. package/dist/utils/deployment/index.js +6 -0
  107. package/dist/utils/deployment/interactive-prompts.js +97 -0
  108. package/dist/utils/deployment/secret-generator.js +896 -0
  109. package/dist/utils/dirname-helper.js +35 -0
  110. package/dist/utils/domain-config.js +159 -0
  111. package/dist/utils/error-recovery.js +240 -0
  112. package/dist/utils/esm-helper.js +52 -0
  113. package/dist/utils/framework-config.js +481 -0
  114. package/dist/utils/graceful-shutdown-manager.js +379 -0
  115. package/dist/utils/health-checker.js +114 -0
  116. package/dist/utils/index.js +36 -0
  117. package/dist/utils/prompt-handler.js +98 -0
  118. package/dist/utils/usage-tracker.js +252 -0
  119. package/dist/utils/validation.js +112 -0
  120. package/dist/version/VersionDetector.js +723 -0
  121. package/dist/worker/index.js +4 -0
  122. package/dist/worker/integration.js +332 -0
  123. package/docs/FRAMEWORK-ARCHITECTURE-OVERVIEW.md +206 -0
  124. package/docs/INTEGRATION_GUIDE.md +2045 -0
  125. package/docs/README.md +82 -0
  126. package/docs/SECURITY.md +242 -0
  127. package/docs/deployment/deployment-guide.md +540 -0
  128. package/docs/overview.md +280 -0
  129. package/package.json +176 -0
  130. package/types/index.d.ts +575 -0
@@ -0,0 +1,3109 @@
1
+ /**
2
+ * GenerationEngine - Tier 3: Automated Generation
3
+ *
4
+ * Takes the 6 core inputs and 15 confirmed values to automatically generate
5
+ * 67+ configuration files and components for a complete Clodo Framework service.
6
+ *
7
+ * Core Inputs (6):
8
+ * 1. Service Name
9
+ * 2. Service Type
10
+ * 3. Domain Name
11
+ * 4. Cloudflare Token
12
+ * 5. Cloudflare Account ID
13
+ * 6. Cloudflare Zone ID
14
+ * 7. Environment
15
+ *
16
+ * Confirmed Values (15):
17
+ * 1. Display Name
18
+ * 2. Description
19
+ * 3. Version
20
+ * 4. Author
21
+ * 5. Production URL
22
+ * 6. Staging URL
23
+ * 7. Development URL
24
+ * 8. Features Configuration
25
+ * 9. Database Name
26
+ * 10. Worker Name
27
+ * 11. Package Name
28
+ * 12. Git Repository URL
29
+ * 13. Documentation URL
30
+ * 14. Health Check Path
31
+ * 15. API Base Path
32
+ */
33
+
34
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, cpSync } from 'fs';
35
+ import { join, dirname, resolve, relative } from 'path';
36
+ import { fileURLToPath } from 'url';
37
+ const __filename = fileURLToPath(import.meta.url);
38
+ const __dirname = dirname(__filename);
39
+ export class GenerationEngine {
40
+ constructor(options = {}) {
41
+ this.templatesDir = options.templatesDir || join(__dirname, '..', '..', 'templates');
42
+ this.outputDir = options.outputDir || process.cwd();
43
+ this.force = options.force || false;
44
+ }
45
+
46
+ /**
47
+ * Generate complete service from core inputs and confirmed values
48
+ */
49
+ async generateService(coreInputs, confirmedValues, options = {}) {
50
+ const config = {
51
+ outputPath: this.outputDir,
52
+ ...options
53
+ };
54
+ console.log('⚙️ Tier 3: Automated Generation');
55
+ console.log('Generating 67+ configuration files and service components...\n');
56
+ try {
57
+ const servicePath = join(config.outputPath, coreInputs.serviceName);
58
+
59
+ // Create service directory structure
60
+ this.createDirectoryStructure(servicePath);
61
+
62
+ // Generate all configuration files
63
+ const generatedFiles = await this.generateAllFiles(coreInputs, confirmedValues, servicePath);
64
+
65
+ // Create service manifest
66
+ const serviceManifest = this.createServiceManifest(coreInputs, confirmedValues, generatedFiles);
67
+
68
+ // Write service manifest
69
+ const manifestPath = join(servicePath, 'clodo-service-manifest.json');
70
+ writeFileSync(manifestPath, JSON.stringify(serviceManifest, null, 2), 'utf8');
71
+ generatedFiles.push(manifestPath);
72
+ console.log(`✅ Generated ${generatedFiles.length} files successfully`);
73
+ console.log(`📋 Service manifest created: clodo-service-manifest.json`);
74
+ return {
75
+ success: true,
76
+ serviceName: coreInputs.serviceName,
77
+ servicePath,
78
+ generatedFiles,
79
+ serviceManifest,
80
+ fileCount: generatedFiles.length
81
+ };
82
+ } catch (error) {
83
+ console.error(`❌ Generation failed: ${error.message}`);
84
+ throw new Error(`Service generation failed: ${error.message}`);
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Create the complete directory structure
90
+ */
91
+ createDirectoryStructure(servicePath) {
92
+ const directories = ['src', 'src/config', 'src/worker', 'src/handlers', 'src/middleware', 'src/utils', 'src/schemas', 'scripts', 'test', 'test/unit', 'test/integration', 'docs', 'config', 'logs', '.github', '.github/workflows'];
93
+ for (const dir of directories) {
94
+ const fullPath = join(servicePath, dir);
95
+ if (!existsSync(fullPath)) {
96
+ mkdirSync(fullPath, {
97
+ recursive: true
98
+ });
99
+ }
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Generate all configuration files
105
+ */
106
+ async generateAllFiles(coreInputs, confirmedValues, servicePath) {
107
+ const generatedFiles = [];
108
+
109
+ // Core configuration files
110
+ generatedFiles.push(...this.generateCoreFiles(coreInputs, confirmedValues, servicePath));
111
+
112
+ // Service-specific configuration files
113
+ generatedFiles.push(...this.generateServiceSpecificFiles(coreInputs, confirmedValues, servicePath));
114
+
115
+ // Environment and deployment files
116
+ generatedFiles.push(...this.generateEnvironmentFiles(coreInputs, confirmedValues, servicePath));
117
+
118
+ // Testing and quality assurance files
119
+ generatedFiles.push(...this.generateTestingFiles(coreInputs, confirmedValues, servicePath));
120
+
121
+ // Documentation files
122
+ generatedFiles.push(...this.generateDocumentationFiles(coreInputs, confirmedValues, servicePath));
123
+
124
+ // CI/CD and automation files
125
+ generatedFiles.push(...this.generateAutomationFiles(coreInputs, confirmedValues, servicePath));
126
+ return generatedFiles;
127
+ }
128
+
129
+ /**
130
+ * Generate core configuration files (package.json, wrangler.toml, etc.)
131
+ */
132
+ generateCoreFiles(coreInputs, confirmedValues, servicePath) {
133
+ const files = [];
134
+
135
+ // package.json
136
+ // files.push(this.generatePackageJson(coreInputs, confirmedValues, servicePath));
137
+
138
+ // wrangler.toml
139
+ // files.push(this.generateWranglerToml(coreInputs, confirmedValues, servicePath));
140
+
141
+ // src/config/domains.js
142
+ // files.push(this.generateDomainsConfig(coreInputs, confirmedValues, servicePath));
143
+
144
+ // src/worker/index.js
145
+ // files.push(this.generateWorkerIndex(coreInputs, confirmedValues, servicePath));
146
+
147
+ // .env.example
148
+ // files.push(this.generateEnvExample(coreInputs, confirmedValues, servicePath));
149
+
150
+ return files;
151
+ }
152
+
153
+ /**
154
+ * Generate service-specific configuration files
155
+ */
156
+ generateServiceSpecificFiles(coreInputs, confirmedValues, servicePath) {
157
+ const files = [];
158
+
159
+ // src/schemas/service-schema.js
160
+ // files.push(this.generateServiceSchema(coreInputs, confirmedValues, servicePath));
161
+
162
+ // src/handlers/service-handlers.js
163
+ // files.push(this.generateServiceHandlers(coreInputs, confirmedValues, servicePath));
164
+
165
+ // src/middleware/service-middleware.js
166
+ // files.push(this.generateServiceMiddleware(coreInputs, confirmedValues, servicePath));
167
+
168
+ // src/utils/service-utils.js
169
+ // files.push(this.generateServiceUtils(coreInputs, confirmedValues, servicePath));
170
+
171
+ return files;
172
+ }
173
+
174
+ /**
175
+ * Generate environment and deployment files
176
+ */
177
+ generateEnvironmentFiles(coreInputs, confirmedValues, servicePath) {
178
+ const files = [];
179
+
180
+ // scripts/deploy.ps1
181
+ files.push(this.generateDeployScript(coreInputs, confirmedValues, servicePath));
182
+
183
+ // scripts/setup.ps1
184
+ files.push(this.generateSetupScript(coreInputs, confirmedValues, servicePath));
185
+
186
+ // scripts/health-check.ps1
187
+ files.push(this.generateHealthCheckScript(coreInputs, confirmedValues, servicePath));
188
+
189
+ // config/production.env
190
+ files.push(this.generateProductionEnv(coreInputs, confirmedValues, servicePath));
191
+
192
+ // config/staging.env
193
+ files.push(this.generateStagingEnv(coreInputs, confirmedValues, servicePath));
194
+
195
+ // config/development.env
196
+ files.push(this.generateDevelopmentEnv(coreInputs, confirmedValues, servicePath));
197
+ return files;
198
+ }
199
+
200
+ /**
201
+ * Generate testing and quality assurance files
202
+ */
203
+ generateTestingFiles(coreInputs, confirmedValues, servicePath) {
204
+ const files = [];
205
+
206
+ // test/unit/service.test.js
207
+ files.push(this.generateUnitTests(coreInputs, confirmedValues, servicePath));
208
+
209
+ // test/integration/service.integration.test.js
210
+ files.push(this.generateIntegrationTests(coreInputs, confirmedValues, servicePath));
211
+
212
+ // jest.config.js
213
+ files.push(this.generateJestConfig(coreInputs, confirmedValues, servicePath));
214
+
215
+ // .eslintrc.js
216
+ files.push(this.generateEslintConfig(coreInputs, confirmedValues, servicePath));
217
+ return files;
218
+ }
219
+
220
+ /**
221
+ * Generate documentation files
222
+ */
223
+ generateDocumentationFiles(coreInputs, confirmedValues, servicePath) {
224
+ const files = [];
225
+
226
+ // README.md
227
+ files.push(this.generateReadme(coreInputs, confirmedValues, servicePath));
228
+
229
+ // docs/API.md
230
+ files.push(this.generateApiDocs(coreInputs, confirmedValues, servicePath));
231
+
232
+ // docs/DEPLOYMENT.md
233
+ files.push(this.generateDeploymentDocs(coreInputs, confirmedValues, servicePath));
234
+
235
+ // docs/CONFIGURATION.md
236
+ files.push(this.generateConfigurationDocs(coreInputs, confirmedValues, servicePath));
237
+ return files;
238
+ }
239
+
240
+ /**
241
+ * Generate automation and CI/CD files
242
+ */
243
+ generateAutomationFiles(coreInputs, confirmedValues, servicePath) {
244
+ const files = [];
245
+
246
+ // .github/workflows/ci.yml
247
+ files.push(this.generateCiWorkflow(coreInputs, confirmedValues, servicePath));
248
+
249
+ // .github/workflows/deploy.yml
250
+ files.push(this.generateDeployWorkflow(coreInputs, confirmedValues, servicePath));
251
+
252
+ // .gitignore
253
+ files.push(this.generateGitignore(coreInputs, confirmedValues, servicePath));
254
+
255
+ // docker-compose.yml (for local development)
256
+ files.push(this.generateDockerCompose(coreInputs, confirmedValues, servicePath));
257
+ return files;
258
+ }
259
+
260
+ /**
261
+ * Generate package.json
262
+ */
263
+ generatePackageJson(coreInputs, confirmedValues, servicePath) {
264
+ const packageJson = {
265
+ name: confirmedValues.packageName,
266
+ version: confirmedValues.version,
267
+ description: confirmedValues.description,
268
+ main: "src/worker/index.js",
269
+ type: "module",
270
+ scripts: {
271
+ test: "jest",
272
+ "test:watch": "jest --watch",
273
+ "test:coverage": "jest --coverage",
274
+ dev: "wrangler dev",
275
+ deploy: "powershell .\\scripts\\deploy.ps1",
276
+ setup: "powershell .\\scripts\\setup.ps1",
277
+ "health-check": "powershell .\\scripts\\health-check.ps1",
278
+ lint: "eslint src/ test/",
279
+ "lint:fix": "eslint src/ test/ --fix",
280
+ format: "prettier --write src/ test/",
281
+ build: "wrangler deploy --dry-run",
282
+ clean: "rimraf dist/ coverage/"
283
+ },
284
+ dependencies: {
285
+ "@tamyla/clodo-framework": "^3.0.0",
286
+ "wrangler": "^3.0.0"
287
+ },
288
+ devDependencies: {
289
+ "@types/jest": "^29.5.0",
290
+ "@types/node": "^20.0.0",
291
+ "eslint": "^8.54.0",
292
+ "jest": "^29.7.0",
293
+ "prettier": "^3.1.0",
294
+ "rimraf": "^5.0.0"
295
+ },
296
+ author: confirmedValues.author,
297
+ license: "MIT",
298
+ repository: {
299
+ type: "git",
300
+ url: confirmedValues.gitRepositoryUrl
301
+ },
302
+ keywords: ["clodo-framework", coreInputs.serviceType, "cloudflare", "serverless"],
303
+ engines: {
304
+ node: ">=18.0.0"
305
+ }
306
+ };
307
+ const filePath = join(servicePath, 'package.json');
308
+ writeFileSync(filePath, JSON.stringify(packageJson, null, 2), 'utf8');
309
+ return filePath;
310
+ }
311
+
312
+ /**
313
+ * Generate wrangler.toml
314
+ */
315
+ generateWranglerToml(coreInputs, confirmedValues, servicePath) {
316
+ const wranglerToml = `# Cloudflare Workers Configuration for ${confirmedValues.displayName}
317
+ name = "${confirmedValues.workerName}"
318
+ main = "src/worker/index.js"
319
+ compatibility_date = "${new Date().toISOString().split('T')[0]}"
320
+ compatibility_flags = ["nodejs_compat"]
321
+
322
+ # Account configuration
323
+ account_id = "${coreInputs.cloudflareAccountId}"
324
+
325
+ # Environment configurations
326
+ [env.development]
327
+ name = "${confirmedValues.workerName}-dev"
328
+
329
+ [env.staging]
330
+ name = "${confirmedValues.workerName}-staging"
331
+
332
+ [env.production]
333
+ name = "${confirmedValues.workerName}"
334
+
335
+ # Database bindings
336
+ [[d1_databases]]
337
+ binding = "DB"
338
+ database_name = "${confirmedValues.databaseName}"
339
+ database_id = "" # To be configured during setup
340
+
341
+ # Environment variables
342
+ [vars]
343
+ SERVICE_NAME = "${coreInputs.serviceName}"
344
+ SERVICE_TYPE = "${coreInputs.serviceType}"
345
+ DOMAIN_NAME = "${coreInputs.domainName}"
346
+ ENVIRONMENT = "${coreInputs.environment}"
347
+ API_BASE_PATH = "${confirmedValues.apiBasePath}"
348
+ HEALTH_CHECK_PATH = "${confirmedValues.healthCheckPath}"
349
+
350
+ # Domain-specific variables
351
+ PRODUCTION_URL = "${confirmedValues.productionUrl}"
352
+ STAGING_URL = "${confirmedValues.stagingUrl}"
353
+ DEVELOPMENT_URL = "${confirmedValues.developmentUrl}"
354
+
355
+ # Feature flags
356
+ ${Object.entries(confirmedValues.features).filter(([, enabled]) => enabled).map(([feature, enabled]) => `FEATURE_${feature.toUpperCase()} = ${enabled}`).join('\n')}
357
+
358
+ # Custom environment variables (configure as needed)
359
+ # CUSTOM_VAR = "value"
360
+ `;
361
+ const filePath = join(servicePath, 'wrangler.toml');
362
+ writeFileSync(filePath, wranglerToml, 'utf8');
363
+ return filePath;
364
+ }
365
+
366
+ /**
367
+ * Generate domains.js configuration
368
+ */
369
+ generateDomainsConfig(coreInputs, confirmedValues, servicePath) {
370
+ const domainsConfig = `import { createDomainConfigSchema } from '@tamyla/clodo-framework';
371
+
372
+ /**
373
+ * Domain configuration for ${confirmedValues.displayName}
374
+ *
375
+ * Generated by Clodo Framework GenerationEngine
376
+ * Service Type: ${coreInputs.serviceType}
377
+ * Generated: ${new Date().toISOString()}
378
+ */
379
+
380
+ export const domains = {
381
+ '${coreInputs.serviceName}': {
382
+ ...createDomainConfigSchema(),
383
+ name: '${coreInputs.serviceName}',
384
+ displayName: '${confirmedValues.displayName}',
385
+ description: '${confirmedValues.description}',
386
+ accountId: '${coreInputs.cloudflareAccountId}',
387
+ zoneId: '${coreInputs.cloudflareZoneId}',
388
+ domains: {
389
+ production: '${confirmedValues.productionUrl}',
390
+ staging: '${confirmedValues.stagingUrl}',
391
+ development: '${confirmedValues.developmentUrl}'
392
+ },
393
+ services: [
394
+ '${coreInputs.serviceName}'
395
+ ],
396
+ databases: [
397
+ {
398
+ name: '${confirmedValues.databaseName}',
399
+ type: 'd1',
400
+ binding: 'DB'
401
+ }
402
+ ],
403
+ features: ${JSON.stringify(confirmedValues.features, null, 4)},
404
+ metadata: {
405
+ version: '${confirmedValues.version}',
406
+ author: '${confirmedValues.author}',
407
+ generatedAt: '${new Date().toISOString()}',
408
+ frameworkVersion: '3.0.0',
409
+ serviceType: '${coreInputs.serviceType}',
410
+ environment: '${coreInputs.environment}'
411
+ }
412
+ }
413
+ };
414
+
415
+ export default domains;
416
+ `;
417
+ const filePath = join(servicePath, 'src', 'config', 'domains.js');
418
+ writeFileSync(filePath, domainsConfig, 'utf8');
419
+ return filePath;
420
+ }
421
+
422
+ /**
423
+ * Generate worker index.js
424
+ */
425
+ generateWorkerIndex(coreInputs, confirmedValues, servicePath) {
426
+ const workerIndex = `/**
427
+ * ${confirmedValues.displayName} - Cloudflare Worker
428
+ *
429
+ * Generated by Clodo Framework GenerationEngine
430
+ * Service Type: ${coreInputs.serviceType}
431
+ */
432
+
433
+ import { domains } from '../config/domains.js';
434
+ import { createServiceHandlers } from '../handlers/service-handlers.js';
435
+ import { createServiceMiddleware } from '../middleware/service-middleware.js';
436
+
437
+ export default {
438
+ async fetch(request, env, ctx) {
439
+ try {
440
+ // Get service configuration
441
+ const serviceConfig = domains['${coreInputs.serviceName}'];
442
+
443
+ // Apply middleware
444
+ const middleware = createServiceMiddleware(serviceConfig, env);
445
+ const processedRequest = await middleware.processRequest(request);
446
+
447
+ // Route to appropriate handler
448
+ const handlers = createServiceHandlers(serviceConfig, env);
449
+ const response = await handlers.handleRequest(processedRequest, ctx);
450
+
451
+ // Apply response middleware
452
+ return await middleware.processResponse(response);
453
+
454
+ } catch (error) {
455
+ console.error('Worker error:', error);
456
+
457
+ return new Response(JSON.stringify({
458
+ error: 'Internal Server Error',
459
+ message: error.message,
460
+ timestamp: new Date().toISOString()
461
+ }), {
462
+ status: 500,
463
+ headers: {
464
+ 'Content-Type': 'application/json',
465
+ 'X-Service': '${coreInputs.serviceName}',
466
+ 'X-Version': '${confirmedValues.version}'
467
+ }
468
+ });
469
+ }
470
+ }
471
+ };
472
+ `;
473
+ const filePath = join(servicePath, 'src', 'worker', 'index.js');
474
+ writeFileSync(filePath, workerIndex, 'utf8');
475
+ return filePath;
476
+ }
477
+
478
+ /**
479
+ * Generate .env.example
480
+ */
481
+ generateEnvExample(coreInputs, confirmedValues, servicePath) {
482
+ const envExample = `# ${confirmedValues.displayName} Environment Variables
483
+ # Generated by Clodo Framework GenerationEngine
484
+
485
+ # Cloudflare Configuration
486
+ CLOUDFLARE_ACCOUNT_ID=${coreInputs.cloudflareAccountId}
487
+ CLOUDFLARE_ZONE_ID=${coreInputs.cloudflareZoneId}
488
+ CLOUDFLARE_API_TOKEN=${coreInputs.cloudflareToken}
489
+
490
+ # Service Configuration
491
+ SERVICE_NAME=${coreInputs.serviceName}
492
+ SERVICE_TYPE=${coreInputs.serviceType}
493
+ DOMAIN_NAME=${coreInputs.domainName}
494
+ ENVIRONMENT=${coreInputs.environment}
495
+
496
+ # URLs
497
+ PRODUCTION_URL=${confirmedValues.productionUrl}
498
+ STAGING_URL=${confirmedValues.stagingUrl}
499
+ DEVELOPMENT_URL=${confirmedValues.developmentUrl}
500
+ DOCUMENTATION_URL=${confirmedValues.documentationUrl}
501
+
502
+ # API Configuration
503
+ API_BASE_PATH=${confirmedValues.apiBasePath}
504
+ HEALTH_CHECK_PATH=${confirmedValues.healthCheckPath}
505
+
506
+ # Database Configuration
507
+ DATABASE_NAME=${confirmedValues.databaseName}
508
+
509
+ # Feature Flags
510
+ ${Object.entries(confirmedValues.features).filter(([, enabled]) => enabled).map(([feature]) => `FEATURE_${feature.toUpperCase()}=true`).join('\n')}
511
+
512
+ # Custom environment variables (uncomment and configure as needed)
513
+ # CUSTOM_VAR=value
514
+ # API_KEY=your-api-key-here
515
+ # SECRET_KEY=your-secret-key-here
516
+ `;
517
+ const filePath = join(servicePath, '.env.example');
518
+ writeFileSync(filePath, envExample, 'utf8');
519
+ return filePath;
520
+ }
521
+
522
+ /**
523
+ * Generate service schema
524
+ */
525
+ generateServiceSchema(coreInputs, confirmedValues, servicePath) {
526
+ const schemaContent = `/**
527
+ * ${confirmedValues.displayName} - Service Schema
528
+ *
529
+ * Generated by Clodo Framework GenerationEngine
530
+ * Service Type: ${coreInputs.serviceType}
531
+ */
532
+
533
+ import { z } from 'zod';
534
+
535
+ // Base service schema
536
+ export const baseServiceSchema = z.object({
537
+ id: z.string().uuid(),
538
+ createdAt: z.date(),
539
+ updatedAt: z.date(),
540
+ version: z.string().default('${confirmedValues.version}')
541
+ });
542
+
543
+ // Service-specific schemas based on type
544
+ ${this.generateServiceTypeSchemas(coreInputs.serviceType)}
545
+
546
+ // Request/Response schemas
547
+ export const healthCheckResponseSchema = z.object({
548
+ status: z.enum(['healthy', 'unhealthy']),
549
+ timestamp: z.string().datetime(),
550
+ service: z.string(),
551
+ version: z.string(),
552
+ environment: z.string()
553
+ });
554
+
555
+ export const errorResponseSchema = z.object({
556
+ error: z.string(),
557
+ message: z.string(),
558
+ timestamp: z.string().datetime(),
559
+ service: z.string(),
560
+ version: z.string()
561
+ });
562
+
563
+ // Validation helpers
564
+ export function validateServiceRequest(data, schema) {
565
+ try {
566
+ return { success: true, data: schema.parse(data) };
567
+ } catch (error) {
568
+ return {
569
+ success: false,
570
+ error: error.errors.map(err => ({
571
+ field: err.path.join('.'),
572
+ message: err.message
573
+ }))
574
+ };
575
+ }
576
+ }
577
+
578
+ export function createServiceResponse(data, schema) {
579
+ try {
580
+ return { success: true, data: schema.parse(data) };
581
+ } catch (error) {
582
+ throw new Error(\`Response validation failed: \${error.message}\`);
583
+ }
584
+ }
585
+ `;
586
+ const filePath = join(servicePath, 'src', 'schemas', 'service-schema.js');
587
+ writeFileSync(filePath, schemaContent, 'utf8');
588
+ return filePath;
589
+ }
590
+
591
+ /**
592
+ * Generate service type specific schemas
593
+ */
594
+ generateServiceTypeSchemas(serviceType) {
595
+ const schemas = {
596
+ 'data-service': `
597
+ export const dataItemSchema = z.object({
598
+ id: z.string().uuid(),
599
+ name: z.string().min(1).max(100),
600
+ description: z.string().max(500).optional(),
601
+ data: z.record(z.any()),
602
+ tags: z.array(z.string()).optional(),
603
+ status: z.enum(['active', 'inactive', 'archived']).default('active')
604
+ });
605
+
606
+ export const dataQuerySchema = z.object({
607
+ limit: z.number().min(1).max(100).default(20),
608
+ offset: z.number().min(0).default(0),
609
+ search: z.string().optional(),
610
+ filters: z.record(z.any()).optional(),
611
+ sortBy: z.string().optional(),
612
+ sortOrder: z.enum(['asc', 'desc']).default('asc')
613
+ });`,
614
+ 'auth-service': `
615
+ export const userSchema = z.object({
616
+ id: z.string().uuid(),
617
+ email: z.string().email(),
618
+ username: z.string().min(3).max(50),
619
+ displayName: z.string().min(1).max(100),
620
+ roles: z.array(z.string()),
621
+ isActive: z.boolean().default(true),
622
+ lastLogin: z.date().optional(),
623
+ emailVerified: z.boolean().default(false)
624
+ });
625
+
626
+ export const authTokenSchema = z.object({
627
+ token: z.string(),
628
+ type: z.enum(['access', 'refresh']),
629
+ expiresAt: z.date(),
630
+ userId: z.string().uuid(),
631
+ scopes: z.array(z.string())
632
+ });`,
633
+ 'content-service': `
634
+ export const contentItemSchema = z.object({
635
+ id: z.string().uuid(),
636
+ title: z.string().min(1).max(200),
637
+ content: z.string(),
638
+ contentType: z.enum(['article', 'page', 'media', 'document']),
639
+ slug: z.string().min(1).max(100),
640
+ author: z.string(),
641
+ published: z.boolean().default(false),
642
+ publishedAt: z.date().optional(),
643
+ tags: z.array(z.string()),
644
+ metadata: z.record(z.any())
645
+ });
646
+
647
+ export const mediaAssetSchema = z.object({
648
+ id: z.string().uuid(),
649
+ filename: z.string(),
650
+ originalName: z.string(),
651
+ mimeType: z.string(),
652
+ size: z.number(),
653
+ url: z.string(),
654
+ thumbnailUrl: z.string().optional(),
655
+ altText: z.string().optional()
656
+ });`,
657
+ 'api-gateway': `
658
+ export const apiRouteSchema = z.object({
659
+ path: z.string().regex(/^\\/.*/),
660
+ method: z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS']),
661
+ targetService: z.string(),
662
+ targetPath: z.string(),
663
+ rateLimit: z.number().optional(),
664
+ authentication: z.boolean().default(false),
665
+ authorization: z.array(z.string()).optional()
666
+ });
667
+
668
+ export const apiMetricsSchema = z.object({
669
+ route: z.string(),
670
+ method: z.string(),
671
+ responseTime: z.number(),
672
+ statusCode: z.number(),
673
+ timestamp: z.date(),
674
+ userAgent: z.string().optional(),
675
+ ipAddress: z.string().optional()
676
+ });`,
677
+ 'generic': `
678
+ export const genericItemSchema = z.object({
679
+ id: z.string().uuid(),
680
+ type: z.string(),
681
+ data: z.record(z.any()),
682
+ metadata: z.record(z.any()).optional()
683
+ });`
684
+ };
685
+ return schemas[serviceType] || schemas.generic;
686
+ }
687
+
688
+ /**
689
+ * Generate service handlers
690
+ */
691
+ generateServiceHandlers(coreInputs, confirmedValues, servicePath) {
692
+ const handlersContent = `/**
693
+ * ${confirmedValues.displayName} - Service Handlers
694
+ *
695
+ * Generated by Clodo Framework GenerationEngine
696
+ * Service Type: ${coreInputs.serviceType}
697
+ */
698
+
699
+ import { healthCheckResponseSchema, errorResponseSchema } from '../schemas/service-schema.js';
700
+
701
+ export function createServiceHandlers(serviceConfig, env) {
702
+ return {
703
+ async handleRequest(request, ctx) {
704
+ const url = new URL(request.url);
705
+ const path = url.pathname;
706
+
707
+ // Health check endpoint
708
+ if (path === '${confirmedValues.healthCheckPath}') {
709
+ return this.handleHealthCheck(request, serviceConfig);
710
+ }
711
+
712
+ // API routes
713
+ if (path.startsWith('${confirmedValues.apiBasePath}')) {
714
+ return this.handleApiRequest(request, ctx, serviceConfig, env);
715
+ }
716
+
717
+ // Default 404 response
718
+ return new Response(JSON.stringify({
719
+ error: 'Not Found',
720
+ message: \`Endpoint not found: \${path}\`,
721
+ availableEndpoints: [
722
+ '${confirmedValues.healthCheckPath}',
723
+ '${confirmedValues.apiBasePath}/*'
724
+ ]
725
+ }), {
726
+ status: 404,
727
+ headers: { 'Content-Type': 'application/json' }
728
+ });
729
+ },
730
+
731
+ async handleHealthCheck(request, serviceConfig) {
732
+ try {
733
+ // Perform health checks
734
+ const healthStatus = await this.performHealthChecks(serviceConfig, env);
735
+
736
+ const response = {
737
+ status: healthStatus.overall === 'healthy' ? 'healthy' : 'unhealthy',
738
+ timestamp: new Date().toISOString(),
739
+ service: serviceConfig.name,
740
+ version: '${confirmedValues.version}',
741
+ environment: '${coreInputs.environment}',
742
+ checks: healthStatus.checks
743
+ };
744
+
745
+ return new Response(JSON.stringify(response), {
746
+ status: healthStatus.overall === 'healthy' ? 200 : 503,
747
+ headers: { 'Content-Type': 'application/json' }
748
+ });
749
+ } catch (error) {
750
+ return new Response(JSON.stringify({
751
+ status: 'unhealthy',
752
+ timestamp: new Date().toISOString(),
753
+ service: serviceConfig.name,
754
+ error: error.message
755
+ }), {
756
+ status: 503,
757
+ headers: { 'Content-Type': 'application/json' }
758
+ });
759
+ }
760
+ },
761
+
762
+ async handleApiRequest(request, ctx, serviceConfig, env) {
763
+ try {
764
+ const url = new URL(request.url);
765
+ const path = url.pathname.replace('${confirmedValues.apiBasePath}', '');
766
+
767
+ // Route to service-specific handlers
768
+ switch (request.method) {
769
+ case 'GET':
770
+ return this.handleGet(path, request, ctx, serviceConfig, env);
771
+ case 'POST':
772
+ return this.handlePost(path, request, ctx, serviceConfig, env);
773
+ case 'PUT':
774
+ return this.handlePut(path, request, ctx, serviceConfig, env);
775
+ case 'DELETE':
776
+ return this.handleDelete(path, request, ctx, serviceConfig, env);
777
+ default:
778
+ return new Response(JSON.stringify({
779
+ error: 'Method Not Allowed',
780
+ message: \`Method \${request.method} not supported\`
781
+ }), {
782
+ status: 405,
783
+ headers: { 'Content-Type': 'application/json' }
784
+ });
785
+ }
786
+ } catch (error) {
787
+ return new Response(JSON.stringify({
788
+ error: 'Internal Server Error',
789
+ message: error.message,
790
+ timestamp: new Date().toISOString()
791
+ }), {
792
+ status: 500,
793
+ headers: { 'Content-Type': 'application/json' }
794
+ });
795
+ }
796
+ },
797
+
798
+ async performHealthChecks(serviceConfig, env) {
799
+ const checks = [];
800
+
801
+ // Database connectivity check
802
+ try {
803
+ ${confirmedValues.features.database ? `
804
+ // Check database connection
805
+ const dbCheck = await env.DB.prepare('SELECT 1 as health_check').first();
806
+ checks.push({
807
+ name: 'database',
808
+ status: dbCheck ? 'healthy' : 'unhealthy',
809
+ responseTime: Date.now()
810
+ });` : `
811
+ checks.push({
812
+ name: 'database',
813
+ status: 'disabled',
814
+ message: 'Database not configured for this service type'
815
+ });`}
816
+ } catch (error) {
817
+ checks.push({
818
+ name: 'database',
819
+ status: 'unhealthy',
820
+ error: error.message
821
+ });
822
+ }
823
+
824
+ // Service configuration check
825
+ checks.push({
826
+ name: 'configuration',
827
+ status: serviceConfig ? 'healthy' : 'unhealthy',
828
+ message: serviceConfig ? 'Service configuration loaded' : 'Service configuration missing'
829
+ });
830
+
831
+ // Overall health status
832
+ const overall = checks.every(check => check.status === 'healthy' || check.status === 'disabled')
833
+ ? 'healthy' : 'unhealthy';
834
+
835
+ return { overall, checks };
836
+ },
837
+
838
+ // Placeholder handlers - implement based on service type
839
+ async handleGet(path, request, ctx, serviceConfig, env) {
840
+ return new Response(JSON.stringify({
841
+ message: 'GET handler not implemented',
842
+ path,
843
+ service: serviceConfig.name,
844
+ timestamp: new Date().toISOString()
845
+ }), {
846
+ headers: { 'Content-Type': 'application/json' }
847
+ });
848
+ },
849
+
850
+ async handlePost(path, request, ctx, serviceConfig, env) {
851
+ return new Response(JSON.stringify({
852
+ message: 'POST handler not implemented',
853
+ path,
854
+ service: serviceConfig.name,
855
+ timestamp: new Date().toISOString()
856
+ }), {
857
+ headers: { 'Content-Type': 'application/json' }
858
+ });
859
+ },
860
+
861
+ async handlePut(path, request, ctx, serviceConfig, env) {
862
+ return new Response(JSON.stringify({
863
+ message: 'PUT handler not implemented',
864
+ path,
865
+ service: serviceConfig.name,
866
+ timestamp: new Date().toISOString()
867
+ }), {
868
+ headers: { 'Content-Type': 'application/json' }
869
+ });
870
+ },
871
+
872
+ async handleDelete(path, request, ctx, serviceConfig, env) {
873
+ return new Response(JSON.stringify({
874
+ message: 'DELETE handler not implemented',
875
+ path,
876
+ service: serviceConfig.name,
877
+ timestamp: new Date().toISOString()
878
+ }), {
879
+ headers: { 'Content-Type': 'application/json' }
880
+ });
881
+ }
882
+ };
883
+ }
884
+ `;
885
+ const filePath = join(servicePath, 'src', 'handlers', 'service-handlers.js');
886
+ writeFileSync(filePath, handlersContent, 'utf8');
887
+ return filePath;
888
+ }
889
+
890
+ /**
891
+ * Generate service middleware
892
+ */
893
+ generateServiceMiddleware(coreInputs, confirmedValues, servicePath) {
894
+ const middlewareContent = `/**
895
+ * ${confirmedValues.displayName} - Service Middleware
896
+ *
897
+ * Generated by Clodo Framework GenerationEngine
898
+ * Service Type: ${coreInputs.serviceType}
899
+ */
900
+
901
+ export function createServiceMiddleware(serviceConfig, env) {
902
+ return {
903
+ async processRequest(request) {
904
+ let processedRequest = request;
905
+
906
+ // Add service context headers
907
+ const headers = new Headers(request.headers);
908
+ headers.set('X-Service', serviceConfig.name);
909
+ headers.set('X-Version', '${confirmedValues.version}');
910
+ headers.set('X-Environment', '${coreInputs.environment}');
911
+ headers.set('X-Request-ID', crypto.randomUUID());
912
+
913
+ // CORS headers for API requests
914
+ if (request.url.includes('${confirmedValues.apiBasePath}')) {
915
+ headers.set('Access-Control-Allow-Origin', '*');
916
+ headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
917
+ headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
918
+ }
919
+
920
+ ${confirmedValues.features.logging ? `
921
+ // Request logging
922
+ console.log(\`[\${new Date().toISOString()}] \${request.method} \${request.url}\`);` : ''}
923
+
924
+ ${confirmedValues.features.rateLimiting ? `
925
+ // Rate limiting (placeholder - implement based on requirements)
926
+ // This would typically check request frequency and block if over limit` : ''}
927
+
928
+ ${confirmedValues.features.authentication ? `
929
+ // Authentication middleware (placeholder)
930
+ // This would validate JWT tokens, API keys, etc.` : ''}
931
+
932
+ ${confirmedValues.features.authorization ? `
933
+ // Authorization middleware (placeholder)
934
+ // This would check user permissions and roles` : ''}
935
+
936
+ return new Request(request.url, {
937
+ ...request,
938
+ headers
939
+ });
940
+ },
941
+
942
+ async processResponse(response) {
943
+ const headers = new Headers(response.headers);
944
+
945
+ // Add standard response headers
946
+ headers.set('X-Service', serviceConfig.name);
947
+ headers.set('X-Version', '${confirmedValues.version}');
948
+ headers.set('X-Response-Time', Date.now().toString());
949
+
950
+ ${confirmedValues.features.monitoring ? `
951
+ // Response monitoring
952
+ console.log(\`Response: \${response.status} (\${Date.now()}ms)\`);` : ''}
953
+
954
+ ${confirmedValues.features.caching ? `
955
+ // Cache headers (placeholder - implement based on content type)
956
+ if (response.status === 200) {
957
+ headers.set('Cache-Control', 'public, max-age=300'); // 5 minutes
958
+ }` : ''}
959
+
960
+ return new Response(response.body, {
961
+ ...response,
962
+ headers
963
+ });
964
+ }
965
+ };
966
+ }
967
+ `;
968
+ const filePath = join(servicePath, 'src', 'middleware', 'service-middleware.js');
969
+ writeFileSync(filePath, middlewareContent, 'utf8');
970
+ return filePath;
971
+ }
972
+
973
+ /**
974
+ * Generate service utilities
975
+ */
976
+ generateServiceUtils(coreInputs, confirmedValues, servicePath) {
977
+ const utilsContent = `/**
978
+ * ${confirmedValues.displayName} - Service Utilities
979
+ *
980
+ * Generated by Clodo Framework GenerationEngine
981
+ * Service Type: ${coreInputs.serviceType}
982
+ */
983
+
984
+ /**
985
+ * Utility functions for ${confirmedValues.displayName}
986
+ */
987
+
988
+ // Database utilities
989
+ export class DatabaseUtils {
990
+ static async executeQuery(env, query, params = []) {
991
+ try {
992
+ const stmt = env.DB.prepare(query);
993
+ if (params.length > 0) {
994
+ return await stmt.bind(...params).all();
995
+ }
996
+ return await stmt.all();
997
+ } catch (error) {
998
+ console.error('Database query error:', error);
999
+ throw new Error(\`Database operation failed: \${error.message}\`);
1000
+ }
1001
+ }
1002
+
1003
+ static async getById(env, table, id) {
1004
+ const result = await this.executeQuery(
1005
+ env,
1006
+ \`SELECT * FROM \${table} WHERE id = ?\`,
1007
+ [id]
1008
+ );
1009
+ return result.results[0] || null;
1010
+ }
1011
+
1012
+ static async create(env, table, data) {
1013
+ const columns = Object.keys(data).join(', ');
1014
+ const placeholders = Object.keys(data).map(() => '?').join(', ');
1015
+ const values = Object.values(data);
1016
+
1017
+ const result = await this.executeQuery(
1018
+ env,
1019
+ \`INSERT INTO \${table} (\${columns}) VALUES (\${placeholders})\`,
1020
+ values
1021
+ );
1022
+
1023
+ return result.meta.last_row_id;
1024
+ }
1025
+
1026
+ static async update(env, table, id, data) {
1027
+ const setClause = Object.keys(data).map(key => \`\${key} = ?\`).join(', ');
1028
+ const values = [...Object.values(data), id];
1029
+
1030
+ const result = await this.executeQuery(
1031
+ env,
1032
+ \`UPDATE \${table} SET \${setClause} WHERE id = ?\`,
1033
+ values
1034
+ );
1035
+
1036
+ return result.meta.changes > 0;
1037
+ }
1038
+
1039
+ static async delete(env, table, id) {
1040
+ const result = await this.executeQuery(
1041
+ env,
1042
+ \`DELETE FROM \${table} WHERE id = ?\`,
1043
+ [id]
1044
+ );
1045
+
1046
+ return result.meta.changes > 0;
1047
+ }
1048
+ }
1049
+
1050
+ // Validation utilities
1051
+ export class ValidationUtils {
1052
+ static isValidUUID(uuid) {
1053
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
1054
+ return uuidRegex.test(uuid);
1055
+ }
1056
+
1057
+ static isValidEmail(email) {
1058
+ const emailRegex = /^[^@]+@[^@]+.[^@]+$/;
1059
+ return emailRegex.test(email);
1060
+ }
1061
+
1062
+ static sanitizeString(str, maxLength = 1000) {
1063
+ if (typeof str !== 'string') return '';
1064
+ return str.trim().substring(0, maxLength);
1065
+ }
1066
+
1067
+ static validatePagination(limit = 20, offset = 0) {
1068
+ const maxLimit = 100;
1069
+ const sanitizedLimit = Math.min(Math.max(1, limit), maxLimit);
1070
+ const sanitizedOffset = Math.max(0, offset);
1071
+
1072
+ return { limit: sanitizedLimit, offset: sanitizedOffset };
1073
+ }
1074
+ }
1075
+
1076
+ // Response utilities
1077
+ export class ResponseUtils {
1078
+ static createSuccessResponse(data, status = 200) {
1079
+ return new Response(JSON.stringify({
1080
+ success: true,
1081
+ data,
1082
+ timestamp: new Date().toISOString()
1083
+ }), {
1084
+ status,
1085
+ headers: { 'Content-Type': 'application/json' }
1086
+ });
1087
+ }
1088
+
1089
+ static createErrorResponse(error, status = 500, details = null) {
1090
+ const errorResponse = {
1091
+ success: false,
1092
+ error: error.message || 'Internal Server Error',
1093
+ timestamp: new Date().toISOString()
1094
+ };
1095
+
1096
+ if (details) {
1097
+ errorResponse.details = details;
1098
+ }
1099
+
1100
+ return new Response(JSON.stringify(errorResponse), {
1101
+ status,
1102
+ headers: { 'Content-Type': 'application/json' }
1103
+ });
1104
+ }
1105
+
1106
+ static createPaginatedResponse(data, pagination, status = 200) {
1107
+ return new Response(JSON.stringify({
1108
+ success: true,
1109
+ data,
1110
+ pagination: {
1111
+ ...pagination,
1112
+ hasMore: data.length === pagination.limit
1113
+ },
1114
+ timestamp: new Date().toISOString()
1115
+ }), {
1116
+ status,
1117
+ headers: { 'Content-Type': 'application/json' }
1118
+ });
1119
+ }
1120
+ }
1121
+
1122
+ // Logging utilities
1123
+ export class LoggingUtils {
1124
+ static logRequest(request, context = {}) {
1125
+ console.log(JSON.stringify({
1126
+ timestamp: new Date().toISOString(),
1127
+ level: 'info',
1128
+ type: 'request',
1129
+ method: request.method,
1130
+ url: request.url,
1131
+ userAgent: request.headers.get('User-Agent'),
1132
+ ...context
1133
+ }));
1134
+ }
1135
+
1136
+ static logError(error, context = {}) {
1137
+ console.error(JSON.stringify({
1138
+ timestamp: new Date().toISOString(),
1139
+ level: 'error',
1140
+ type: 'error',
1141
+ message: error.message,
1142
+ stack: error.stack,
1143
+ ...context
1144
+ }));
1145
+ }
1146
+
1147
+ static logPerformance(operation, startTime, context = {}) {
1148
+ const duration = Date.now() - startTime;
1149
+ console.log(JSON.stringify({
1150
+ timestamp: new Date().toISOString(),
1151
+ level: 'info',
1152
+ type: 'performance',
1153
+ operation,
1154
+ duration,
1155
+ ...context
1156
+ }));
1157
+ }
1158
+ }
1159
+
1160
+ // Feature flag utilities
1161
+ export class FeatureUtils {
1162
+ static isFeatureEnabled(featureName, serviceConfig) {
1163
+ return serviceConfig.features && serviceConfig.features[featureName] === true;
1164
+ }
1165
+
1166
+ static getEnabledFeatures(serviceConfig) {
1167
+ if (!serviceConfig.features) return [];
1168
+ return Object.entries(serviceConfig.features)
1169
+ .filter(([, enabled]) => enabled)
1170
+ .map(([feature]) => feature);
1171
+ }
1172
+
1173
+ static getDisabledFeatures(serviceConfig) {
1174
+ if (!serviceConfig.features) return [];
1175
+ return Object.entries(serviceConfig.features)
1176
+ .filter(([, enabled]) => !enabled)
1177
+ .map(([feature]) => feature);
1178
+ }
1179
+ }
1180
+ `;
1181
+ const filePath = join(servicePath, 'src', 'utils', 'service-utils.js');
1182
+ writeFileSync(filePath, utilsContent, 'utf8');
1183
+ return filePath;
1184
+ }
1185
+
1186
+ /**
1187
+ * Generate deployment script
1188
+ */
1189
+ generateDeployScript(coreInputs, confirmedValues, servicePath) {
1190
+ const deployScript = `#!/usr/bin/env pwsh
1191
+
1192
+ <#
1193
+ .SYNOPSIS
1194
+ Deploy ${confirmedValues.displayName} to Cloudflare
1195
+
1196
+ .DESCRIPTION
1197
+ Automated deployment script for ${confirmedValues.displayName}
1198
+ Handles database setup, worker deployment, and environment configuration
1199
+
1200
+ .PARAMETER Environment
1201
+ Target environment (development, staging, production)
1202
+
1203
+ .PARAMETER SkipTests
1204
+ Skip running tests before deployment
1205
+
1206
+ .EXAMPLE
1207
+ .\\scripts\\deploy.ps1 -Environment production
1208
+
1209
+ .EXAMPLE
1210
+ .\\scripts\\deploy.ps1 -Environment staging -SkipTests
1211
+ #>
1212
+
1213
+ param(
1214
+ [Parameter(Mandatory = $false)]
1215
+ [ValidateSet('development', 'staging', 'production')]
1216
+ [string]$Environment = 'development',
1217
+
1218
+ [Parameter(Mandatory = $false)]
1219
+ [switch]$SkipTests
1220
+ )
1221
+
1222
+ Write-Host "🚀 Deploying ${confirmedValues.displayName} to $Environment" -ForegroundColor Cyan
1223
+
1224
+ # Load environment variables
1225
+ if (Test-Path ".env") {
1226
+ Write-Host "📄 Loading environment variables from .env" -ForegroundColor Gray
1227
+ Get-Content ".env" | ForEach-Object {
1228
+ if ($_ -match '^([^=]+)=(.*)$') {
1229
+ $key = $matches[1]
1230
+ $value = $matches[2]
1231
+ [Environment]::SetEnvironmentVariable($key, $value)
1232
+ }
1233
+ }
1234
+ }
1235
+
1236
+ try {
1237
+ # Run tests unless skipped
1238
+ if (-not $SkipTests) {
1239
+ Write-Host "🧪 Running tests..." -ForegroundColor Yellow
1240
+ npm test
1241
+ if ($LASTEXITCODE -ne 0) {
1242
+ throw "Tests failed. Aborting deployment."
1243
+ }
1244
+ }
1245
+
1246
+ # Lint code
1247
+ Write-Host "🔍 Running linter..." -ForegroundColor Yellow
1248
+ npm run lint
1249
+ if ($LASTEXITCODE -ne 0) {
1250
+ throw "Linting failed. Aborting deployment."
1251
+ }
1252
+
1253
+ # Deploy to Cloudflare
1254
+ Write-Host "☁️ Deploying to Cloudflare Workers..." -ForegroundColor Yellow
1255
+ npx wrangler deploy --env $Environment
1256
+
1257
+ if ($LASTEXITCODE -ne 0) {
1258
+ throw "Cloudflare deployment failed."
1259
+ }
1260
+
1261
+ # Run health check
1262
+ Write-Host "🏥 Running health check..." -ForegroundColor Yellow
1263
+ .\\scripts\\health-check.ps1 -Environment $Environment
1264
+
1265
+ Write-Host "✅ Deployment completed successfully!" -ForegroundColor Green
1266
+ Write-Host "🌐 Service URL: ${confirmedValues.productionUrl}" -ForegroundColor Cyan
1267
+
1268
+ } catch {
1269
+ Write-Host "❌ Deployment failed: $_" -ForegroundColor Red
1270
+ exit 1
1271
+ }
1272
+ `;
1273
+ const filePath = join(servicePath, 'scripts', 'deploy.ps1');
1274
+ writeFileSync(filePath, deployScript, 'utf8');
1275
+ return filePath;
1276
+ }
1277
+
1278
+ /**
1279
+ * Generate setup script
1280
+ */
1281
+ generateSetupScript(coreInputs, confirmedValues, servicePath) {
1282
+ const setupScript = `#!/usr/bin/env pwsh
1283
+
1284
+ <#
1285
+ .SYNOPSIS
1286
+ Setup ${confirmedValues.displayName} environment
1287
+
1288
+ .DESCRIPTION
1289
+ Initializes the development environment for ${confirmedValues.displayName}
1290
+ Sets up database, configures environment variables, and prepares for development
1291
+
1292
+ .EXAMPLE
1293
+ .\\scripts\\setup.ps1
1294
+ #>
1295
+
1296
+ Write-Host "🔧 Setting up ${confirmedValues.displayName} development environment" -ForegroundColor Cyan
1297
+
1298
+ try {
1299
+ # Check if .env exists
1300
+ if (-not (Test-Path ".env")) {
1301
+ Write-Host "📄 Creating .env file from template..." -ForegroundColor Yellow
1302
+ Copy-Item ".env.example" ".env" -Force
1303
+ Write-Host "⚠️ Please edit .env file with your actual values" -ForegroundColor Yellow
1304
+ }
1305
+
1306
+ # Install dependencies
1307
+ Write-Host "📦 Installing dependencies..." -ForegroundColor Yellow
1308
+ npm install
1309
+
1310
+ # Create database (if configured)
1311
+ ${confirmedValues.features.database ? `
1312
+ Write-Host "🗄️ Setting up database..." -ForegroundColor Yellow
1313
+ # Database setup would go here
1314
+ Write-Host "⚠️ Database setup requires manual configuration" -ForegroundColor Yellow
1315
+ ` : `
1316
+ Write-Host "ℹ️ Database not required for this service type" -ForegroundColor Gray
1317
+ `}
1318
+
1319
+ # Run initial build
1320
+ Write-Host "🔨 Running initial build..." -ForegroundColor Yellow
1321
+ npm run build
1322
+
1323
+ # Run tests
1324
+ Write-Host "🧪 Running tests..." -ForegroundColor Yellow
1325
+ npm test
1326
+
1327
+ Write-Host "✅ Setup completed successfully!" -ForegroundColor Green
1328
+ Write-Host "🚀 You can now run 'npm run dev' to start development" -ForegroundColor Cyan
1329
+
1330
+ } catch {
1331
+ Write-Host "❌ Setup failed: $_" -ForegroundColor Red
1332
+ exit 1
1333
+ }
1334
+ `;
1335
+ const filePath = join(servicePath, 'scripts', 'setup.ps1');
1336
+ writeFileSync(filePath, setupScript, 'utf8');
1337
+ return filePath;
1338
+ }
1339
+
1340
+ /**
1341
+ * Generate health check script
1342
+ */
1343
+ generateHealthCheckScript(coreInputs, confirmedValues, servicePath) {
1344
+ const healthCheckScript = `#!/usr/bin/env pwsh
1345
+
1346
+ <#
1347
+ .SYNOPSIS
1348
+ Health check for ${confirmedValues.displayName}
1349
+
1350
+ .DESCRIPTION
1351
+ Performs health checks on ${confirmedValues.displayName} service
1352
+ Tests endpoints, database connectivity, and overall service health
1353
+
1354
+ .PARAMETER Environment
1355
+ Target environment to check (development, staging, production)
1356
+
1357
+ .EXAMPLE
1358
+ .\\scripts\\health-check.ps1 -Environment production
1359
+ #>
1360
+
1361
+ param(
1362
+ [Parameter(Mandatory = $false)]
1363
+ [ValidateSet('development', 'staging', 'production')]
1364
+ [string]$Environment = 'development'
1365
+ )
1366
+
1367
+ Write-Host "🏥 Running health checks for ${confirmedValues.displayName} ($Environment)" -ForegroundColor Cyan
1368
+
1369
+ # Determine service URL based on environment
1370
+ $serviceUrl = switch ($Environment) {
1371
+ 'production' { "${confirmedValues.productionUrl}" }
1372
+ 'staging' { "${confirmedValues.stagingUrl}" }
1373
+ 'development' { "${confirmedValues.developmentUrl}" }
1374
+ }
1375
+
1376
+ Write-Host "🌐 Checking service at: $serviceUrl" -ForegroundColor Gray
1377
+
1378
+ try {
1379
+ # Health check endpoint
1380
+ $healthUrl = "$serviceUrl${confirmedValues.healthCheckPath}"
1381
+ Write-Host "🔍 Testing health endpoint: $healthUrl" -ForegroundColor Yellow
1382
+
1383
+ $response = Invoke-RestMethod -Uri $healthUrl -Method GET -TimeoutSec 30
1384
+ if ($response.status -eq 'healthy') {
1385
+ Write-Host "✅ Health check passed" -ForegroundColor Green
1386
+ } else {
1387
+ Write-Host "❌ Health check failed: $($response | ConvertTo-Json)" -ForegroundColor Red
1388
+ exit 1
1389
+ }
1390
+
1391
+ # API endpoint check
1392
+ $apiUrl = "$serviceUrl${confirmedValues.apiBasePath}"
1393
+ Write-Host "🔍 Testing API endpoint: $apiUrl" -ForegroundColor Yellow
1394
+
1395
+ try {
1396
+ $apiResponse = Invoke-WebRequest -Uri $apiUrl -Method GET -TimeoutSec 30
1397
+ Write-Host "✅ API endpoint accessible (Status: $($apiResponse.StatusCode))" -ForegroundColor Green
1398
+ } catch {
1399
+ Write-Host "⚠️ API endpoint returned error (may be expected): $($_.Exception.Message)" -ForegroundColor Yellow
1400
+ }
1401
+
1402
+ Write-Host "✅ All health checks completed successfully!" -ForegroundColor Green
1403
+
1404
+ } catch {
1405
+ Write-Host "❌ Health check failed: $_" -ForegroundColor Red
1406
+ exit 1
1407
+ }
1408
+ `;
1409
+ const filePath = join(servicePath, 'scripts', 'health-check.ps1');
1410
+ writeFileSync(filePath, healthCheckScript, 'utf8');
1411
+ return filePath;
1412
+ }
1413
+
1414
+ /**
1415
+ * Generate environment configuration files
1416
+ */
1417
+ generateProductionEnv(coreInputs, confirmedValues, servicePath) {
1418
+ const envContent = `# Production Environment Configuration
1419
+ # Generated by Clodo Framework GenerationEngine
1420
+
1421
+ # Service Configuration
1422
+ SERVICE_NAME=${coreInputs.serviceName}
1423
+ SERVICE_TYPE=${coreInputs.serviceType}
1424
+ ENVIRONMENT=production
1425
+
1426
+ # URLs
1427
+ PRODUCTION_URL=${confirmedValues.productionUrl}
1428
+ STAGING_URL=${confirmedValues.stagingUrl}
1429
+ DEVELOPMENT_URL=${confirmedValues.developmentUrl}
1430
+
1431
+ # Cloudflare Configuration
1432
+ CLOUDFLARE_ACCOUNT_ID=${coreInputs.cloudflareAccountId}
1433
+ CLOUDFLARE_ZONE_ID=${coreInputs.cloudflareZoneId}
1434
+
1435
+ # Database
1436
+ DATABASE_NAME=${confirmedValues.databaseName}
1437
+
1438
+ # Logging and Monitoring
1439
+ LOG_LEVEL=warn
1440
+ METRICS_ENABLED=true
1441
+ ERROR_REPORTING_ENABLED=true
1442
+ `;
1443
+ const filePath = join(servicePath, 'config', 'production.env');
1444
+ writeFileSync(filePath, envContent, 'utf8');
1445
+ return filePath;
1446
+ }
1447
+ generateStagingEnv(coreInputs, confirmedValues, servicePath) {
1448
+ const envContent = `# Staging Environment Configuration
1449
+ # Generated by Clodo Framework GenerationEngine
1450
+
1451
+ # Service Configuration
1452
+ SERVICE_NAME=${coreInputs.serviceName}
1453
+ SERVICE_TYPE=${coreInputs.serviceType}
1454
+ ENVIRONMENT=staging
1455
+
1456
+ # URLs
1457
+ PRODUCTION_URL=${confirmedValues.productionUrl}
1458
+ STAGING_URL=${confirmedValues.stagingUrl}
1459
+ DEVELOPMENT_URL=${confirmedValues.developmentUrl}
1460
+
1461
+ # Cloudflare Configuration
1462
+ CLOUDFLARE_ACCOUNT_ID=${coreInputs.cloudflareAccountId}
1463
+ CLOUDFLARE_ZONE_ID=${coreInputs.cloudflareZoneId}
1464
+
1465
+ # Database
1466
+ DATABASE_NAME=${confirmedValues.databaseName}
1467
+
1468
+ # Logging and Monitoring
1469
+ LOG_LEVEL=info
1470
+ METRICS_ENABLED=true
1471
+ ERROR_REPORTING_ENABLED=true
1472
+ `;
1473
+ const filePath = join(servicePath, 'config', 'staging.env');
1474
+ writeFileSync(filePath, envContent, 'utf8');
1475
+ return filePath;
1476
+ }
1477
+ generateDevelopmentEnv(coreInputs, confirmedValues, servicePath) {
1478
+ const envContent = `# Development Environment Configuration
1479
+ # Generated by Clodo Framework GenerationEngine
1480
+
1481
+ # Service Configuration
1482
+ SERVICE_NAME=${coreInputs.serviceName}
1483
+ SERVICE_TYPE=${coreInputs.serviceType}
1484
+ ENVIRONMENT=development
1485
+
1486
+ # URLs
1487
+ PRODUCTION_URL=${confirmedValues.productionUrl}
1488
+ STAGING_URL=${confirmedValues.stagingUrl}
1489
+ DEVELOPMENT_URL=${confirmedValues.developmentUrl}
1490
+
1491
+ # Cloudflare Configuration
1492
+ CLOUDFLARE_ACCOUNT_ID=${coreInputs.cloudflareAccountId}
1493
+ CLOUDFLARE_ZONE_ID=${coreInputs.cloudflareZoneId}
1494
+
1495
+ # Database
1496
+ DATABASE_NAME=${confirmedValues.databaseName}
1497
+
1498
+ # Logging and Monitoring
1499
+ LOG_LEVEL=debug
1500
+ METRICS_ENABLED=false
1501
+ ERROR_REPORTING_ENABLED=false
1502
+
1503
+ # Development settings
1504
+ DEBUG_MODE=true
1505
+ HOT_RELOAD=true
1506
+ `;
1507
+ const filePath = join(servicePath, 'config', 'development.env');
1508
+ writeFileSync(filePath, envContent, 'utf8');
1509
+ return filePath;
1510
+ }
1511
+
1512
+ /**
1513
+ * Generate unit tests
1514
+ */
1515
+ generateUnitTests(coreInputs, confirmedValues, servicePath) {
1516
+ const testContent = `/**
1517
+ * ${confirmedValues.displayName} - Unit Tests
1518
+ *
1519
+ * Generated by Clodo Framework GenerationEngine
1520
+ */
1521
+
1522
+ import { describe, test, expect, beforeEach, afterEach } from '@jest/globals';
1523
+ import { createServiceHandlers } from '../../src/handlers/service-handlers.js';
1524
+ import { createServiceMiddleware } from '../../src/middleware/service-middleware.js';
1525
+ import { domains } from '../../src/config/domains.js';
1526
+
1527
+ describe('${confirmedValues.displayName} Service', () => {
1528
+ let mockEnv;
1529
+ let serviceConfig;
1530
+
1531
+ beforeEach(() => {
1532
+ // Mock environment
1533
+ mockEnv = {
1534
+ DB: {
1535
+ prepare: jest.fn(() => ({
1536
+ first: jest.fn().mockResolvedValue({ health_check: 1 }),
1537
+ all: jest.fn().mockResolvedValue({ results: [], meta: {} })
1538
+ }))
1539
+ }
1540
+ };
1541
+
1542
+ serviceConfig = domains['${coreInputs.serviceName}'];
1543
+ });
1544
+
1545
+ describe('Health Check Handler', () => {
1546
+ test('should return healthy status', async () => {
1547
+ const handlers = createServiceHandlers(serviceConfig, mockEnv);
1548
+ const request = new Request('http://localhost${confirmedValues.healthCheckPath}');
1549
+
1550
+ const response = await handlers.handleHealthCheck(request, serviceConfig);
1551
+ const data = await response.json();
1552
+
1553
+ expect(response.status).toBe(200);
1554
+ expect(data.status).toBe('healthy');
1555
+ expect(data.service).toBe('${coreInputs.serviceName}');
1556
+ expect(data.version).toBe('${confirmedValues.version}');
1557
+ });
1558
+
1559
+ test('should handle database errors gracefully', async () => {
1560
+ const failingEnv = {
1561
+ DB: {
1562
+ prepare: jest.fn(() => ({
1563
+ first: jest.fn().mockRejectedValue(new Error('Database connection failed'))
1564
+ }))
1565
+ }
1566
+ };
1567
+
1568
+ const handlers = createServiceHandlers(serviceConfig, failingEnv);
1569
+ const request = new Request('http://localhost${confirmedValues.healthCheckPath}');
1570
+
1571
+ const response = await handlers.handleHealthCheck(request, serviceConfig);
1572
+ const data = await response.json();
1573
+
1574
+ expect(response.status).toBe(200); // Health check still returns 200 but with unhealthy status
1575
+ expect(data.status).toBe('unhealthy');
1576
+ });
1577
+ });
1578
+
1579
+ describe('API Request Handler', () => {
1580
+ test('should handle GET requests', async () => {
1581
+ const handlers = createServiceHandlers(serviceConfig, mockEnv);
1582
+ const request = new Request('http://localhost${confirmedValues.apiBasePath}/test', {
1583
+ method: 'GET'
1584
+ });
1585
+
1586
+ const response = await handlers.handleApiRequest(request, {}, serviceConfig, mockEnv);
1587
+ const data = await response.json();
1588
+
1589
+ expect(response.status).toBe(200);
1590
+ expect(data.message).toContain('GET handler not implemented');
1591
+ });
1592
+
1593
+ test('should handle POST requests', async () => {
1594
+ const handlers = createServiceHandlers(serviceConfig, mockEnv);
1595
+ const request = new Request('http://localhost${confirmedValues.apiBasePath}/test', {
1596
+ method: 'POST'
1597
+ });
1598
+
1599
+ const response = await handlers.handleApiRequest(request, {}, serviceConfig, mockEnv);
1600
+ const data = await response.json();
1601
+
1602
+ expect(response.status).toBe(200);
1603
+ expect(data.message).toContain('POST handler not implemented');
1604
+ });
1605
+
1606
+ test('should return 405 for unsupported methods', async () => {
1607
+ const handlers = createServiceHandlers(serviceConfig, mockEnv);
1608
+ const request = new Request('http://localhost${confirmedValues.apiBasePath}/test', {
1609
+ method: 'PATCH'
1610
+ });
1611
+
1612
+ const response = await handlers.handleApiRequest(request, {}, serviceConfig, mockEnv);
1613
+ const data = await response.json();
1614
+
1615
+ expect(response.status).toBe(405);
1616
+ expect(data.error).toBe('Method Not Allowed');
1617
+ });
1618
+ });
1619
+
1620
+ describe('Middleware', () => {
1621
+ test('should add service headers to requests', async () => {
1622
+ const middleware = createServiceMiddleware(serviceConfig, mockEnv);
1623
+ const request = new Request('http://localhost/test');
1624
+
1625
+ const processedRequest = await middleware.processRequest(request);
1626
+
1627
+ expect(processedRequest.headers.get('X-Service')).toBe('${coreInputs.serviceName}');
1628
+ expect(processedRequest.headers.get('X-Version')).toBe('${confirmedValues.version}');
1629
+ expect(processedRequest.headers.get('X-Environment')).toBe('${coreInputs.environment}');
1630
+ expect(processedRequest.headers.get('X-Request-ID')).toBeDefined();
1631
+ });
1632
+
1633
+ test('should add CORS headers for API requests', async () => {
1634
+ const middleware = createServiceMiddleware(serviceConfig, mockEnv);
1635
+ const request = new Request('http://localhost${confirmedValues.apiBasePath}/test');
1636
+
1637
+ const processedRequest = await middleware.processRequest(request);
1638
+
1639
+ expect(processedRequest.headers.get('Access-Control-Allow-Origin')).toBe('*');
1640
+ expect(processedRequest.headers.get('Access-Control-Allow-Methods')).toBe('GET, POST, PUT, DELETE, OPTIONS');
1641
+ });
1642
+ });
1643
+
1644
+ describe('404 Handler', () => {
1645
+ test('should return 404 for unknown endpoints', async () => {
1646
+ const handlers = createServiceHandlers(serviceConfig, mockEnv);
1647
+ const request = new Request('http://localhost/unknown-endpoint');
1648
+
1649
+ const response = await handlers.handleRequest(request, {});
1650
+ const data = await response.json();
1651
+
1652
+ expect(response.status).toBe(404);
1653
+ expect(data.error).toBe('Not Found');
1654
+ expect(data.availableEndpoints).toContain('${confirmedValues.healthCheckPath}');
1655
+ });
1656
+ });
1657
+ });
1658
+ `;
1659
+ const filePath = join(servicePath, 'test', 'unit', 'service.test.js');
1660
+ writeFileSync(filePath, testContent, 'utf8');
1661
+ return filePath;
1662
+ }
1663
+
1664
+ /**
1665
+ * Generate integration tests
1666
+ */
1667
+ generateIntegrationTests(coreInputs, confirmedValues, servicePath) {
1668
+ const integrationTestContent = `/**
1669
+ * ${confirmedValues.displayName} - Integration Tests
1670
+ *
1671
+ * Generated by Clodo Framework GenerationEngine
1672
+ */
1673
+
1674
+ import { describe, test, expect, beforeAll, afterAll } from '@jest/globals';
1675
+
1676
+ describe('${confirmedValues.displayName} Integration Tests', () => {
1677
+ let testServer;
1678
+ let baseUrl;
1679
+
1680
+ beforeAll(async () => {
1681
+ // Start test server (this would need to be implemented)
1682
+ // testServer = await startTestServer();
1683
+ // baseUrl = testServer.url;
1684
+ baseUrl = 'http://localhost:8787'; // Placeholder
1685
+ });
1686
+
1687
+ afterAll(async () => {
1688
+ // Stop test server
1689
+ // await testServer.stop();
1690
+ });
1691
+
1692
+ describe('End-to-End Service Flow', () => {
1693
+ test('complete service lifecycle', async () => {
1694
+ // This would test the complete flow from request to response
1695
+ // Including middleware, handlers, database operations, etc.
1696
+
1697
+ expect(true).toBe(true); // Placeholder test
1698
+ });
1699
+ });
1700
+
1701
+ describe('API Endpoints', () => {
1702
+ test('health check endpoint', async () => {
1703
+ const response = await fetch(\`\${baseUrl}${confirmedValues.healthCheckPath}\`);
1704
+ const data = await response.json();
1705
+
1706
+ expect(response.status).toBe(200);
1707
+ expect(data.status).toBe('healthy');
1708
+ expect(data.service).toBe('${coreInputs.serviceName}');
1709
+ });
1710
+
1711
+ test('API base path routing', async () => {
1712
+ const response = await fetch(\`\${baseUrl}${confirmedValues.apiBasePath}\`);
1713
+
1714
+ // Should not return 404 (service-specific routing would be implemented)
1715
+ expect([200, 404]).toContain(response.status);
1716
+ });
1717
+ });
1718
+
1719
+ describe('Database Integration', () => {
1720
+ ${confirmedValues.features.database ? `
1721
+ test('database connectivity', async () => {
1722
+ // Test database operations
1723
+ expect(true).toBe(true); // Placeholder
1724
+ });
1725
+
1726
+ test('CRUD operations', async () => {
1727
+ // Test Create, Read, Update, Delete operations
1728
+ expect(true).toBe(true); // Placeholder
1729
+ });` : `
1730
+ test.skip('database tests skipped - not enabled for this service type', () => {
1731
+ expect(true).toBe(true);
1732
+ });`}
1733
+ });
1734
+
1735
+ describe('Middleware Integration', () => {
1736
+ test('request headers added', async () => {
1737
+ const response = await fetch(\`\${baseUrl}${confirmedValues.healthCheckPath}\`);
1738
+
1739
+ expect(response.headers.get('x-service')).toBe('${coreInputs.serviceName}');
1740
+ expect(response.headers.get('x-version')).toBe('${confirmedValues.version}');
1741
+ });
1742
+
1743
+ ${confirmedValues.features.authentication ? `
1744
+ test('authentication middleware', async () => {
1745
+ // Test authentication requirements
1746
+ expect(true).toBe(true); // Placeholder
1747
+ });` : ''}
1748
+
1749
+ ${confirmedValues.features.authorization ? `
1750
+ test('authorization middleware', async () => {
1751
+ // Test authorization checks
1752
+ expect(true).toBe(true); // Placeholder
1753
+ });` : ''}
1754
+ });
1755
+
1756
+ describe('Error Handling', () => {
1757
+ test('graceful error responses', async () => {
1758
+ // Test error scenarios
1759
+ expect(true).toBe(true); // Placeholder
1760
+ });
1761
+
1762
+ test('error logging', async () => {
1763
+ // Test error logging functionality
1764
+ expect(true).toBe(true); // Placeholder
1765
+ });
1766
+ });
1767
+ });
1768
+ `;
1769
+ const filePath = join(servicePath, 'test', 'integration', 'service.integration.test.js');
1770
+ writeFileSync(filePath, integrationTestContent, 'utf8');
1771
+ return filePath;
1772
+ }
1773
+
1774
+ /**
1775
+ * Generate Jest configuration
1776
+ */
1777
+ generateJestConfig(coreInputs, confirmedValues, servicePath) {
1778
+ const jestConfig = `/** @type {import('jest').Config} */
1779
+ export default {
1780
+ testEnvironment: 'node',
1781
+ testMatch: [
1782
+ '<rootDir>/test/**/*.test.js'
1783
+ ],
1784
+ collectCoverageFrom: [
1785
+ 'src/**/*.js',
1786
+ '!src/worker/index.js' // Worker code runs in different environment
1787
+ ],
1788
+ coverageDirectory: 'coverage',
1789
+ coverageReporters: ['text', 'lcov', 'html'],
1790
+ coverageThreshold: {
1791
+ global: {
1792
+ branches: 70,
1793
+ functions: 80,
1794
+ lines: 80,
1795
+ statements: 80
1796
+ }
1797
+ },
1798
+ setupFilesAfterEnv: ['<rootDir>/test/setup.js'],
1799
+ testTimeout: 10000,
1800
+ verbose: true
1801
+ };
1802
+ `;
1803
+ const filePath = join(servicePath, 'jest.config.js');
1804
+ writeFileSync(filePath, jestConfig, 'utf8');
1805
+ return filePath;
1806
+ }
1807
+
1808
+ /**
1809
+ * Generate ESLint configuration
1810
+ */
1811
+ generateEslintConfig(coreInputs, confirmedValues, servicePath) {
1812
+ const eslintConfig = `export default [
1813
+ {
1814
+ languageOptions: {
1815
+ ecmaVersion: 2022,
1816
+ sourceType: 'module',
1817
+ globals: {
1818
+ console: 'readonly',
1819
+ process: 'readonly',
1820
+ Buffer: 'readonly',
1821
+ crypto: 'readonly',
1822
+ fetch: 'readonly',
1823
+ Request: 'readonly',
1824
+ Response: 'readonly',
1825
+ URL: 'readonly',
1826
+ Headers: 'readonly'
1827
+ }
1828
+ },
1829
+ rules: {
1830
+ 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
1831
+ 'no-console': 'off', // Cloudflare Workers use console
1832
+ 'prefer-const': 'error',
1833
+ 'no-var': 'error',
1834
+ 'object-shorthand': 'error',
1835
+ 'prefer-arrow-callback': 'error'
1836
+ }
1837
+ }
1838
+ ];
1839
+ `;
1840
+ const filePath = join(servicePath, '.eslintrc.js');
1841
+ writeFileSync(filePath, eslintConfig, 'utf8');
1842
+ return filePath;
1843
+ }
1844
+
1845
+ /**
1846
+ * Generate README.md
1847
+ */
1848
+ generateReadme(coreInputs, confirmedValues, servicePath) {
1849
+ const readmeContent = `# ${confirmedValues.displayName}
1850
+
1851
+ ${confirmedValues.description}
1852
+
1853
+ ## 🚀 Quick Start
1854
+
1855
+ \\\`\\\`\\\`bash
1856
+ # Setup development environment
1857
+ .\\\\scripts\\\\setup.ps1
1858
+
1859
+ # Start development server
1860
+ npm run dev
1861
+
1862
+ # Run tests
1863
+ npm test
1864
+
1865
+ # Deploy to production
1866
+ .\\\\scripts\\\\deploy.ps1 -Environment production
1867
+ \\\`\\\`\\\`
1868
+
1869
+ ## 📋 Features
1870
+
1871
+ ${Object.entries(confirmedValues.features).filter(([, enabled]) => enabled).map(([feature]) => `- ✅ ${feature.replace(/([A-Z])/g, ' $1').toLowerCase()}`).join('\n')}
1872
+
1873
+ ## 🏗️ Architecture
1874
+
1875
+ This service is built with the **Clodo Framework** and follows a three-tier architecture:
1876
+
1877
+ 1. **Input Collection**: Collects and validates service requirements
1878
+ 2. **Smart Confirmations**: Generates and confirms derived configuration values
1879
+ 3. **Automated Generation**: Creates all necessary configuration files and components
1880
+
1881
+ ## 📁 Project Structure
1882
+
1883
+ \`\`\`
1884
+ ${coreInputs.serviceName}/
1885
+ ├── src/
1886
+ │ ├── config/
1887
+ │ │ └── domains.js # Domain configuration
1888
+ │ ├── worker/
1889
+ │ │ └── index.js # Cloudflare Worker entry point
1890
+ │ ├── handlers/
1891
+ │ │ └── service-handlers.js # Request handlers
1892
+ │ ├── middleware/
1893
+ │ │ └── service-middleware.js # Request/response middleware
1894
+ │ ├── schemas/
1895
+ │ │ └── service-schema.js # Data validation schemas
1896
+ │ └── utils/
1897
+ │ └── service-utils.js # Utility functions
1898
+ ├── scripts/
1899
+ │ ├── deploy.ps1 # Deployment script
1900
+ │ ├── setup.ps1 # Environment setup
1901
+ │ └── health-check.ps1 # Health monitoring
1902
+ ├── test/
1903
+ │ ├── unit/ # Unit tests
1904
+ │ └── integration/ # Integration tests
1905
+ ├── config/ # Environment configurations
1906
+ ├── docs/ # Documentation
1907
+ └── wrangler.toml # Cloudflare Workers config
1908
+ \`\`\`
1909
+
1910
+ ## 🔧 Configuration
1911
+
1912
+ ### Environment Variables
1913
+
1914
+ Copy \`.env.example\` to \`.env\` and configure:
1915
+
1916
+ \`\`\`bash
1917
+ # Cloudflare Configuration
1918
+ CLOUDFLARE_ACCOUNT_ID=your_account_id
1919
+ CLOUDFLARE_ZONE_ID=your_zone_id
1920
+ CLOUDFLARE_API_TOKEN=your_api_token
1921
+
1922
+ # Service Configuration
1923
+ SERVICE_NAME=${coreInputs.serviceName}
1924
+ SERVICE_TYPE=${coreInputs.serviceType}
1925
+ DOMAIN_NAME=${coreInputs.domainName}
1926
+ ENVIRONMENT=${coreInputs.environment}
1927
+ \`\`\`
1928
+
1929
+ ### Service URLs
1930
+
1931
+ - **Production**: ${confirmedValues.productionUrl}
1932
+ - **Staging**: ${confirmedValues.stagingUrl}
1933
+ - **Development**: ${confirmedValues.developmentUrl}
1934
+ - **Documentation**: ${confirmedValues.documentationUrl}
1935
+
1936
+ ## 🧪 Testing
1937
+
1938
+ \`\`\`bash
1939
+ # Run all tests
1940
+ npm test
1941
+
1942
+ # Run with coverage
1943
+ npm run test:coverage
1944
+
1945
+ # Run integration tests only
1946
+ npm test -- --testPathPattern=integration
1947
+ \`\`\`
1948
+
1949
+ ## 🚀 Deployment
1950
+
1951
+ ### Development
1952
+
1953
+ \`\`\`bash
1954
+ npm run dev
1955
+ \`\`\`
1956
+
1957
+ ### Staging
1958
+
1959
+ \`\`\`bash
1960
+ .\\scripts\\deploy.ps1 -Environment staging
1961
+ \`\`\`
1962
+
1963
+ ### Production
1964
+
1965
+ \`\`\`bash
1966
+ .\\scripts\\deploy.ps1 -Environment production
1967
+ \`\`\`
1968
+
1969
+ ## 🏥 Health Checks
1970
+
1971
+ \`\`\`bash
1972
+ # Check service health
1973
+ .\\scripts\\health-check.ps1 -Environment production
1974
+ \`\`\`
1975
+
1976
+ Health check endpoint: \`${confirmedValues.healthCheckPath}\`
1977
+
1978
+ ## 📚 API Documentation
1979
+
1980
+ API Base Path: \`${confirmedValues.apiBasePath}\`
1981
+
1982
+ See [API Documentation](./docs/API.md) for detailed endpoint information.
1983
+
1984
+ ## 🤝 Contributing
1985
+
1986
+ 1. Fork the repository
1987
+ 2. Create a feature branch
1988
+ 3. Make your changes
1989
+ 4. Add tests
1990
+ 5. Submit a pull request
1991
+
1992
+ ## 📄 License
1993
+
1994
+ ${confirmedValues.author} - Generated by Clodo Framework v3.0.0
1995
+
1996
+ ## 🔗 Links
1997
+
1998
+ - **Repository**: ${confirmedValues.gitRepositoryUrl}
1999
+ - **Documentation**: ${confirmedValues.documentationUrl}
2000
+ - **Health Check**: ${confirmedValues.productionUrl}${confirmedValues.healthCheckPath}
2001
+ `;
2002
+ const filePath = join(servicePath, 'README.md');
2003
+ writeFileSync(filePath, readmeContent, 'utf8');
2004
+ return filePath;
2005
+ }
2006
+
2007
+ /**
2008
+ * Generate API documentation
2009
+ */
2010
+ generateApiDocs(coreInputs, confirmedValues, servicePath) {
2011
+ const apiDocsContent = `# ${confirmedValues.displayName} API Documentation
2012
+
2013
+ ## Overview
2014
+
2015
+ ${confirmedValues.description}
2016
+
2017
+ **Base URL**: ${confirmedValues.productionUrl}
2018
+ **API Base Path**: ${confirmedValues.apiBasePath}
2019
+ **Version**: ${confirmedValues.version}
2020
+
2021
+ ## Authentication
2022
+
2023
+ ${confirmedValues.features.authentication ? 'This service requires authentication. Include your API key in the request headers:\n\n' + '```\nAuthorization: Bearer YOUR_API_KEY\n```' : 'This service does not require authentication.'}
2024
+
2025
+ ## Endpoints
2026
+
2027
+ ### Health Check
2028
+
2029
+ **GET** ${confirmedValues.healthCheckPath}
2030
+
2031
+ Check the health status of the service.
2032
+
2033
+ **Response:**
2034
+ \`\`\`json
2035
+ {
2036
+ "status": "healthy",
2037
+ "timestamp": "2024-01-01T00:00:00.000Z",
2038
+ "service": "${coreInputs.serviceName}",
2039
+ "version": "${confirmedValues.version}",
2040
+ "environment": "${coreInputs.environment}",
2041
+ "checks": [
2042
+ {
2043
+ "name": "database",
2044
+ "status": "healthy"
2045
+ },
2046
+ {
2047
+ "name": "configuration",
2048
+ "status": "healthy"
2049
+ }
2050
+ ]
2051
+ }
2052
+ \`\`\`
2053
+
2054
+ ### API Endpoints
2055
+
2056
+ **Base Path**: ${confirmedValues.apiBasePath}
2057
+
2058
+ ${this.generateApiEndpointsForType(coreInputs.serviceType, coreInputs, confirmedValues)}
2059
+
2060
+ ## Error Responses
2061
+
2062
+ All error responses follow this format:
2063
+
2064
+ \`\`\`json
2065
+ {
2066
+ "success": false,
2067
+ "error": "Error message",
2068
+ "timestamp": "2024-01-01T00:00:00.000Z"
2069
+ }
2070
+ \`\`\`
2071
+
2072
+ ### Common HTTP Status Codes
2073
+
2074
+ - **200**: Success
2075
+ - **400**: Bad Request
2076
+ - **401**: Unauthorized
2077
+ - **403**: Forbidden
2078
+ - **404**: Not Found
2079
+ - **500**: Internal Server Error
2080
+
2081
+ ## Rate Limiting
2082
+
2083
+ ${confirmedValues.features.rateLimiting ? 'This service implements rate limiting. Please respect the following limits:\n\n' + '- 1000 requests per hour for authenticated users\n' + '- 100 requests per hour for anonymous users' : 'This service does not implement rate limiting.'}
2084
+
2085
+ ## Data Formats
2086
+
2087
+ All requests and responses use JSON format.
2088
+
2089
+ ### Request Headers
2090
+
2091
+ \`\`\`
2092
+ Content-Type: application/json
2093
+ Authorization: Bearer YOUR_API_KEY (if required)
2094
+ \`\`\`
2095
+
2096
+ ### Response Headers
2097
+
2098
+ \`\`\`
2099
+ Content-Type: application/json
2100
+ X-Service: ${coreInputs.serviceName}
2101
+ X-Version: ${confirmedValues.version}
2102
+ X-Response-Time: 150
2103
+ \`\`\`
2104
+ `;
2105
+ const filePath = join(servicePath, 'docs', 'API.md');
2106
+ writeFileSync(filePath, apiDocsContent, 'utf8');
2107
+ return filePath;
2108
+ }
2109
+
2110
+ /**
2111
+ * Generate API endpoints based on service type
2112
+ */
2113
+ generateApiEndpointsForType(serviceType, coreInputs, confirmedValues) {
2114
+ const endpoints = {
2115
+ 'data-service': `
2116
+ #### List Items
2117
+ **GET** /items
2118
+
2119
+ Retrieve a paginated list of items.
2120
+
2121
+ **Query Parameters:**
2122
+ - \`limit\` (optional): Number of items per page (default: 20, max: 100)
2123
+ - \`offset\` (optional): Number of items to skip (default: 0)
2124
+ - \`search\` (optional): Search query string
2125
+ - \`filters\` (optional): JSON object with filter criteria
2126
+
2127
+ **Response:**
2128
+ \`\`\`json
2129
+ {
2130
+ "success": true,
2131
+ "data": [...],
2132
+ "pagination": {
2133
+ "limit": 20,
2134
+ "offset": 0,
2135
+ "total": 150,
2136
+ "hasMore": true
2137
+ }
2138
+ }
2139
+ \`\`\`
2140
+
2141
+ #### Create Item
2142
+ **POST** /items
2143
+
2144
+ Create a new item.
2145
+
2146
+ **Request Body:**
2147
+ \`\`\`json
2148
+ {
2149
+ "name": "Item Name",
2150
+ "description": "Item description",
2151
+ "data": {}
2152
+ }
2153
+ \`\`\`
2154
+
2155
+ #### Get Item
2156
+ **GET** /items/{id}
2157
+
2158
+ Retrieve a specific item by ID.
2159
+
2160
+ #### Update Item
2161
+ **PUT** /items/{id}
2162
+
2163
+ Update an existing item.
2164
+
2165
+ #### Delete Item
2166
+ **DELETE** /items/{id}
2167
+
2168
+ Delete an item.
2169
+ `,
2170
+ 'auth-service': `
2171
+ #### Register User
2172
+ **POST** /auth/register
2173
+
2174
+ Register a new user account.
2175
+
2176
+ **Request Body:**
2177
+ \`\`\`json
2178
+ {
2179
+ "email": "user@example.com",
2180
+ "username": "username",
2181
+ "password": "password"
2182
+ }
2183
+ \`\`\`
2184
+
2185
+ #### Login
2186
+ **POST** /auth/login
2187
+
2188
+ Authenticate a user and receive access tokens.
2189
+
2190
+ **Request Body:**
2191
+ \`\`\`json
2192
+ {
2193
+ "email": "user@example.com",
2194
+ "password": "password"
2195
+ }
2196
+ \`\`\`
2197
+
2198
+ #### Get Profile
2199
+ **GET** /auth/profile
2200
+
2201
+ Get the current user's profile information.
2202
+
2203
+ #### Update Profile
2204
+ **PUT** /auth/profile
2205
+
2206
+ Update the current user's profile.
2207
+
2208
+ #### Logout
2209
+ **POST** /auth/logout
2210
+
2211
+ Invalidate the current user's session.
2212
+ `,
2213
+ 'content-service': `
2214
+ #### List Content
2215
+ **GET** /content
2216
+
2217
+ Retrieve a list of content items.
2218
+
2219
+ #### Create Content
2220
+ **POST** /content
2221
+
2222
+ Create new content.
2223
+
2224
+ **Request Body:**
2225
+ \`\`\`json
2226
+ {
2227
+ "title": "Content Title",
2228
+ "content": "Content body",
2229
+ "contentType": "article",
2230
+ "tags": ["tag1", "tag2"]
2231
+ }
2232
+ \`\`\`
2233
+
2234
+ #### Get Content
2235
+ **GET** /content/{id}
2236
+
2237
+ Retrieve specific content by ID.
2238
+
2239
+ #### Update Content
2240
+ **PUT** /content/{id}
2241
+
2242
+ Update existing content.
2243
+
2244
+ #### Delete Content
2245
+ **DELETE** /content/{id}
2246
+
2247
+ Delete content.
2248
+
2249
+ #### Upload Media
2250
+ **POST** /media/upload
2251
+
2252
+ Upload media files.
2253
+ `,
2254
+ 'api-gateway': `
2255
+ #### Route Request
2256
+ **ANY** /*
2257
+
2258
+ All requests are routed through the API gateway.
2259
+
2260
+ **Headers:**
2261
+ - \`X-Target-Service\`: Target service name
2262
+ - \`X-Target-Path\`: Path on target service
2263
+
2264
+ #### Get Routes
2265
+ **GET** /routes
2266
+
2267
+ List all configured routes.
2268
+
2269
+ #### Health Status
2270
+ **GET** /status
2271
+
2272
+ Get gateway health and route status.
2273
+ `,
2274
+ 'generic': `
2275
+ #### Service Info
2276
+ **GET** /info
2277
+
2278
+ Get service information and capabilities.
2279
+
2280
+ **Response:**
2281
+ \`\`\`json
2282
+ {
2283
+ "success": true,
2284
+ "data": {
2285
+ "name": "${coreInputs.serviceName}",
2286
+ "type": "${coreInputs.serviceType}",
2287
+ "version": "${confirmedValues.version}",
2288
+ "features": ${JSON.stringify(Object.keys(confirmedValues.features).filter(key => confirmedValues.features[key]), null, 4)}
2289
+ }
2290
+ }
2291
+ \`\`\`
2292
+ `
2293
+ };
2294
+ return endpoints[serviceType] || endpoints.generic;
2295
+ }
2296
+
2297
+ /**
2298
+ * Generate deployment documentation
2299
+ */
2300
+ generateDeploymentDocs(coreInputs, confirmedValues, servicePath) {
2301
+ const deploymentDocsContent = `# ${confirmedValues.displayName} - Deployment Guide
2302
+
2303
+ ## Overview
2304
+
2305
+ This guide covers deploying ${confirmedValues.displayName} to different environments using the Clodo Framework.
2306
+
2307
+ ## Environments
2308
+
2309
+ ### Development
2310
+ - **URL**: ${confirmedValues.developmentUrl}
2311
+ - **Environment**: development
2312
+ - **Configuration**: \`config/development.env\`
2313
+
2314
+ ### Staging
2315
+ - **URL**: ${confirmedValues.stagingUrl}
2316
+ - **Environment**: staging
2317
+ - **Configuration**: \`config/staging.env\`
2318
+
2319
+ ### Production
2320
+ - **URL**: ${confirmedValues.productionUrl}
2321
+ - **Environment**: production
2322
+ - **Configuration**: \`config/production.env\`
2323
+
2324
+ ## Prerequisites
2325
+
2326
+ - Node.js 18+
2327
+ - Cloudflare account with Workers enabled
2328
+ - Wrangler CLI installed
2329
+ - PowerShell (for deployment scripts)
2330
+
2331
+ ## Initial Setup
2332
+
2333
+ 1. **Clone and setup**:
2334
+ \`\`\`bash
2335
+ git clone ${confirmedValues.gitRepositoryUrl}
2336
+ cd ${coreInputs.serviceName}
2337
+ .\\scripts\\setup.ps1
2338
+ \`\`\`
2339
+
2340
+ 2. **Configure environment**:
2341
+ Edit \`.env\` with your Cloudflare credentials:
2342
+ \`\`\`bash
2343
+ CLOUDFLARE_ACCOUNT_ID=your_account_id
2344
+ CLOUDFLARE_ZONE_ID=your_zone_id
2345
+ CLOUDFLARE_API_TOKEN=your_api_token
2346
+ \`\`\`
2347
+
2348
+ 3. **Setup database** (if enabled):
2349
+ ${confirmedValues.features.database ? `
2350
+ Create a Cloudflare D1 database and update \`wrangler.toml\`:
2351
+ \`\`\`toml
2352
+ [[d1_databases]]
2353
+ binding = "DB"
2354
+ database_name = "${confirmedValues.databaseName}"
2355
+ database_id = "your_database_id"
2356
+ \`\`\`
2357
+ ` : 'Database not required for this service type.'}
2358
+
2359
+ ## Development Deployment
2360
+
2361
+ \`\`\`bash
2362
+ # Start local development server
2363
+ npm run dev
2364
+
2365
+ # Server will be available at http://localhost:8787
2366
+ \`\`\`
2367
+
2368
+ ## Staging Deployment
2369
+
2370
+ \`\`\`bash
2371
+ # Deploy to staging
2372
+ .\\scripts\\deploy.ps1 -Environment staging
2373
+
2374
+ # Run health checks
2375
+ .\\scripts\\health-check.ps1 -Environment staging
2376
+ \`\`\`
2377
+
2378
+ ## Production Deployment
2379
+
2380
+ \`\`\`bash
2381
+ # Deploy to production
2382
+ .\\scripts\\deploy.ps1 -Environment production
2383
+
2384
+ # Verify deployment
2385
+ .\\scripts\\health-check.ps1 -Environment production
2386
+ \`\`\`
2387
+
2388
+ ## Automated Deployment
2389
+
2390
+ ### GitHub Actions
2391
+
2392
+ The service includes GitHub Actions workflows for automated deployment:
2393
+
2394
+ - **CI**: Runs on every push to main branch
2395
+ - **Deploy**: Deploys to staging on successful CI
2396
+ - **Release**: Deploys to production on tag creation
2397
+
2398
+ ### Manual CI/CD
2399
+
2400
+ \`\`\`bash
2401
+ # Run full CI pipeline locally
2402
+ npm run lint
2403
+ npm test
2404
+ npm run build
2405
+
2406
+ # Deploy if all checks pass
2407
+ .\\scripts\\deploy.ps1 -Environment production
2408
+ \`\`\`
2409
+
2410
+ ## Monitoring and Health Checks
2411
+
2412
+ ### Health Check Endpoint
2413
+
2414
+ \`\`\`bash
2415
+ curl ${confirmedValues.productionUrl}${confirmedValues.healthCheckPath}
2416
+ \`\`\`
2417
+
2418
+ ### Automated Health Monitoring
2419
+
2420
+ The deployment scripts include automated health checks. For production monitoring, consider:
2421
+
2422
+ - Cloudflare Analytics
2423
+ - External monitoring services
2424
+ - Log aggregation tools
2425
+
2426
+ ## Rollback Strategy
2427
+
2428
+ ### Quick Rollback
2429
+
2430
+ \`\`\`bash
2431
+ # Deploy previous version
2432
+ wrangler deploy --env production
2433
+
2434
+ # Or redeploy from git
2435
+ git checkout previous-version
2436
+ npm run deploy
2437
+ \`\`\`
2438
+
2439
+ ### Database Rollback
2440
+
2441
+ ${confirmedValues.features.database ? `
2442
+ If database schema changes need rollback:
2443
+
2444
+ 1. Restore from backup
2445
+ 2. Run migration rollback scripts
2446
+ 3. Update wrangler.toml if needed
2447
+ ` : 'No database rollback required for this service type.'}
2448
+
2449
+ ## Troubleshooting
2450
+
2451
+ ### Common Issues
2452
+
2453
+ 1. **Deployment fails with authentication error**
2454
+ - Check Cloudflare API token permissions
2455
+ - Verify account ID and zone ID
2456
+
2457
+ 2. **Health check fails**
2458
+ - Check database connectivity
2459
+ - Verify environment variables
2460
+ - Review worker logs
2461
+
2462
+ 3. **API returns 500 errors**
2463
+ - Check worker logs in Cloudflare dashboard
2464
+ - Verify service configuration
2465
+ - Test locally first
2466
+
2467
+ ### Logs and Debugging
2468
+
2469
+ \`\`\`bash
2470
+ # View worker logs
2471
+ wrangler tail
2472
+
2473
+ # Check deployment status
2474
+ wrangler deployments list
2475
+
2476
+ # View environment info
2477
+ wrangler whoami
2478
+ \`\`\`
2479
+
2480
+ ## Security Considerations
2481
+
2482
+ - Store secrets in Cloudflare Workers secrets, not environment variables
2483
+ - Use HTTPS for all production endpoints
2484
+ - Implement proper authentication and authorization
2485
+ - Regularly rotate API tokens
2486
+ - Monitor for unusual activity
2487
+
2488
+ ## Performance Optimization
2489
+
2490
+ - Enable caching where appropriate
2491
+ - Use appropriate database indexes
2492
+ - Monitor response times
2493
+ - Optimize bundle size
2494
+ - Consider edge deployment locations
2495
+ `;
2496
+ const filePath = join(servicePath, 'docs', 'DEPLOYMENT.md');
2497
+ writeFileSync(filePath, deploymentDocsContent, 'utf8');
2498
+ return filePath;
2499
+ }
2500
+
2501
+ /**
2502
+ * Generate configuration documentation
2503
+ */
2504
+ generateConfigurationDocs(coreInputs, confirmedValues, servicePath) {
2505
+ const configDocsContent = `# ${confirmedValues.displayName} - Configuration Guide
2506
+
2507
+ ## Overview
2508
+
2509
+ ${confirmedValues.displayName} is configured using multiple layers of configuration files and environment variables.
2510
+
2511
+ ## Configuration Hierarchy
2512
+
2513
+ 1. **Environment Variables** (.env) - Runtime secrets and environment-specific values
2514
+ 2. **Service Configuration** (src/config/domains.js) - Service-specific settings
2515
+ 3. **Worker Configuration** (wrangler.toml) - Cloudflare Workers deployment settings
2516
+ 4. **Package Configuration** (package.json) - Node.js package settings
2517
+
2518
+ ## Environment Variables
2519
+
2520
+ ### Required Variables
2521
+
2522
+ \`\`\`bash
2523
+ # Cloudflare Configuration
2524
+ CLOUDFLARE_ACCOUNT_ID=${coreInputs.cloudflareAccountId}
2525
+ CLOUDFLARE_ZONE_ID=${coreInputs.cloudflareZoneId}
2526
+ CLOUDFLARE_API_TOKEN=your_api_token
2527
+
2528
+ # Service Configuration
2529
+ SERVICE_NAME=${coreInputs.serviceName}
2530
+ SERVICE_TYPE=${coreInputs.serviceType}
2531
+ DOMAIN_NAME=${coreInputs.domainName}
2532
+ ENVIRONMENT=${coreInputs.environment}
2533
+ \`\`\`
2534
+
2535
+ ### Optional Variables
2536
+
2537
+ \`\`\`bash
2538
+ # URLs (override defaults)
2539
+ PRODUCTION_URL=${confirmedValues.productionUrl}
2540
+ STAGING_URL=${confirmedValues.stagingUrl}
2541
+ DEVELOPMENT_URL=${confirmedValues.developmentUrl}
2542
+ DOCUMENTATION_URL=${confirmedValues.documentationUrl}
2543
+
2544
+ # API Configuration
2545
+ API_BASE_PATH=${confirmedValues.apiBasePath}
2546
+ HEALTH_CHECK_PATH=${confirmedValues.healthCheckPath}
2547
+
2548
+ # Database
2549
+ DATABASE_NAME=${confirmedValues.databaseName}
2550
+
2551
+ # Logging and Monitoring
2552
+ LOG_LEVEL=info
2553
+ METRICS_ENABLED=true
2554
+ ERROR_REPORTING_ENABLED=true
2555
+
2556
+ # Custom Variables
2557
+ CUSTOM_VAR=value
2558
+ \`\`\`
2559
+
2560
+ ## Service Configuration (domains.js)
2561
+
2562
+ Located at \`src/config/domains.js\`, this file contains service-specific configuration:
2563
+
2564
+ \`\`\`javascript
2565
+ export const domains = {
2566
+ '${coreInputs.serviceName}': {
2567
+ name: '${coreInputs.serviceName}',
2568
+ displayName: '${confirmedValues.displayName}',
2569
+ description: '${confirmedValues.description}',
2570
+ accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
2571
+ zoneId: process.env.CLOUDFLARE_ZONE_ID,
2572
+ domains: {
2573
+ production: '${confirmedValues.productionUrl}',
2574
+ staging: '${confirmedValues.stagingUrl}',
2575
+ development: '${confirmedValues.developmentUrl}'
2576
+ },
2577
+ services: [
2578
+ '${coreInputs.serviceName}'
2579
+ ],
2580
+ databases: [
2581
+ {
2582
+ name: '${confirmedValues.databaseName}',
2583
+ type: 'd1',
2584
+ binding: 'DB'
2585
+ }
2586
+ ],
2587
+ features: ${JSON.stringify(confirmedValues.features, null, 4)},
2588
+ metadata: {
2589
+ version: '${confirmedValues.version}',
2590
+ author: '${confirmedValues.author}',
2591
+ generatedAt: '${new Date().toISOString()}',
2592
+ frameworkVersion: '3.0.0',
2593
+ serviceType: '${coreInputs.serviceType}',
2594
+ environment: '${coreInputs.environment}'
2595
+ }
2596
+ }
2597
+ };
2598
+ \`\`\`
2599
+
2600
+ ## Worker Configuration (wrangler.toml)
2601
+
2602
+ Cloudflare Workers configuration with environment-specific settings:
2603
+
2604
+ \`\`\`toml
2605
+ name = "${confirmedValues.workerName}"
2606
+ main = "src/worker/index.js"
2607
+ compatibility_date = "${new Date().toISOString().split('T')[0]}"
2608
+ compatibility_flags = ["nodejs_compat"]
2609
+
2610
+ # Environment configurations
2611
+ [env.development]
2612
+ name = "${confirmedValues.workerName}-dev"
2613
+
2614
+ [env.staging]
2615
+ name = "${confirmedValues.workerName}-staging"
2616
+
2617
+ [env.production]
2618
+ name = "${confirmedValues.workerName}"
2619
+
2620
+ # Database bindings
2621
+ [[d1_databases]]
2622
+ binding = "DB"
2623
+ database_name = "${confirmedValues.databaseName}"
2624
+
2625
+ # Environment variables
2626
+ [vars]
2627
+ SERVICE_NAME = "${coreInputs.serviceName}"
2628
+ SERVICE_TYPE = "${coreInputs.serviceType}"
2629
+ DOMAIN_NAME = "${coreInputs.domainName}"
2630
+ ENVIRONMENT = "${coreInputs.environment}"
2631
+ API_BASE_PATH = "${confirmedValues.apiBasePath}"
2632
+ HEALTH_CHECK_PATH = "${confirmedValues.healthCheckPath}"
2633
+
2634
+ # Domain-specific variables
2635
+ PRODUCTION_URL = "${confirmedValues.productionUrl}"
2636
+ STAGING_URL = "${confirmedValues.stagingUrl}"
2637
+ DEVELOPMENT_URL = "${confirmedValues.developmentUrl}"
2638
+
2639
+ # Feature flags
2640
+ ${Object.entries(confirmedValues.features).filter(([, enabled]) => enabled).map(([feature, enabled]) => `FEATURE_${feature.toUpperCase()} = ${enabled}`).join('\n')}
2641
+
2642
+ # Custom environment variables (configure as needed)
2643
+ # CUSTOM_VAR = "value"
2644
+ \`\`\`
2645
+
2646
+ ## Feature Flags
2647
+
2648
+ The service supports the following feature flags:
2649
+
2650
+ ${Object.entries(confirmedValues.features).map(([feature, enabled]) => `- **${feature}**: ${enabled ? '✅ Enabled' : '❌ Disabled'}`).join('\n')}
2651
+
2652
+ ### Feature Descriptions
2653
+
2654
+ - **logging**: Request/response logging
2655
+ - **monitoring**: Performance monitoring and metrics
2656
+ - **errorReporting**: Error tracking and reporting
2657
+ - **metrics**: Application metrics collection
2658
+ - **healthChecks**: Health check endpoints
2659
+ ${confirmedValues.features.database ? '- **database**: Database operations and connectivity\n' : ''}
2660
+ ${confirmedValues.features.authentication ? '- **authentication**: User authentication\n' : ''}
2661
+ ${confirmedValues.features.authorization ? '- **authorization**: Access control and permissions\n' : ''}
2662
+ ${confirmedValues.features.search ? '- **search**: Search functionality\n' : ''}
2663
+ ${confirmedValues.features.filtering ? '- **filtering**: Data filtering capabilities\n' : ''}
2664
+ ${confirmedValues.features.pagination ? '- **pagination**: Paginated responses\n' : ''}
2665
+ ${confirmedValues.features.caching ? '- **caching**: Response caching\n' : ''}
2666
+ ${confirmedValues.features.backup ? '- **backup**: Data backup functionality\n' : ''}
2667
+
2668
+ ## Environment-Specific Configuration
2669
+
2670
+ ### Development
2671
+ - Full debugging enabled
2672
+ - Local database connections
2673
+ - Hot reload enabled
2674
+ - Less strict validation
2675
+
2676
+ ### Staging
2677
+ - Production-like settings
2678
+ - Separate database
2679
+ - Full feature set enabled
2680
+ - Error reporting enabled
2681
+
2682
+ ### Production
2683
+ - Optimized settings
2684
+ - Production database
2685
+ - Security hardening
2686
+ - Full monitoring enabled
2687
+
2688
+ ## Configuration Validation
2689
+
2690
+ The service validates configuration on startup:
2691
+
2692
+ 1. **Environment Variables**: Required variables present and valid
2693
+ 2. **Service Configuration**: domains.js structure and values
2694
+ 3. **Worker Configuration**: wrangler.toml syntax and bindings
2695
+ 4. **Feature Compatibility**: Feature flags compatible with service type
2696
+
2697
+ ## Runtime Configuration
2698
+
2699
+ Some configuration can be changed at runtime:
2700
+
2701
+ - Environment variables (require restart)
2702
+ - Feature flags (may require restart)
2703
+ - Database connections (handled automatically)
2704
+ - Logging levels (immediate effect)
2705
+
2706
+ ## Security Considerations
2707
+
2708
+ - Never commit secrets to version control
2709
+ - Use Cloudflare Workers secrets for sensitive data
2710
+ - Rotate API tokens regularly
2711
+ - Limit feature access based on environment
2712
+ - Validate all input data
2713
+ - Use HTTPS for all production endpoints
2714
+
2715
+ ## Troubleshooting Configuration Issues
2716
+
2717
+ ### Common Problems
2718
+
2719
+ 1. **Missing environment variables**
2720
+ - Check .env file exists and is loaded
2721
+ - Verify variable names match expectations
2722
+
2723
+ 2. **Invalid Cloudflare credentials**
2724
+ - Check account ID format (32 hex characters)
2725
+ - Verify API token permissions
2726
+ - Confirm zone ID is correct
2727
+
2728
+ 3. **Database connection issues**
2729
+ - Verify D1 database exists
2730
+ - Check database ID in wrangler.toml
2731
+ - Confirm database binding name
2732
+
2733
+ 4. **Feature flag conflicts**
2734
+ - Some features require others to be enabled
2735
+ - Check service type compatibility
2736
+
2737
+ ### Debugging Configuration
2738
+
2739
+ \`\`\`bash
2740
+ # Check environment variables
2741
+ node -e "console.log(process.env)"
2742
+
2743
+ # Validate service configuration
2744
+ node -e "import('./src/config/domains.js').then(config => console.log(JSON.stringify(config, null, 2)))"
2745
+
2746
+ # Test wrangler configuration
2747
+ wrangler dev --dry-run
2748
+ \`\`\`
2749
+ `;
2750
+ const filePath = join(servicePath, 'docs', 'CONFIGURATION.md');
2751
+ writeFileSync(filePath, configDocsContent, 'utf8');
2752
+ return filePath;
2753
+ }
2754
+
2755
+ /**
2756
+ * Generate CI workflow
2757
+ */
2758
+ generateCiWorkflow(coreInputs, confirmedValues, servicePath) {
2759
+ const ciWorkflow = `name: CI
2760
+
2761
+ on:
2762
+ push:
2763
+ branches: [ main, master ]
2764
+ pull_request:
2765
+ branches: [ main, master ]
2766
+
2767
+ jobs:
2768
+ test:
2769
+ runs-on: ubuntu-latest
2770
+
2771
+ steps:
2772
+ - uses: actions/checkout@v4
2773
+
2774
+ - name: Setup Node.js
2775
+ uses: actions/setup-node@v4
2776
+ with:
2777
+ node-version: '18'
2778
+ cache: 'npm'
2779
+
2780
+ - name: Install dependencies
2781
+ run: npm ci
2782
+
2783
+ - name: Lint code
2784
+ run: npm run lint
2785
+
2786
+ - name: Run tests
2787
+ run: npm test
2788
+
2789
+ - name: Build
2790
+ run: npm run build
2791
+
2792
+ - name: Upload coverage reports
2793
+ uses: codecov/codecov-action@v3
2794
+ with:
2795
+ file: ./coverage/lcov.info
2796
+ `;
2797
+ const filePath = join(servicePath, '.github', 'workflows', 'ci.yml');
2798
+ writeFileSync(filePath, ciWorkflow, 'utf8');
2799
+ return filePath;
2800
+ }
2801
+
2802
+ /**
2803
+ * Generate deploy workflow
2804
+ */
2805
+ generateDeployWorkflow(coreInputs, confirmedValues, servicePath) {
2806
+ const deployWorkflow = `name: Deploy
2807
+
2808
+ on:
2809
+ push:
2810
+ branches: [ main, master ]
2811
+ workflow_run:
2812
+ workflows: ["CI"]
2813
+ types:
2814
+ - completed
2815
+
2816
+ jobs:
2817
+ deploy-staging:
2818
+ if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
2819
+ runs-on: ubuntu-latest
2820
+ environment: staging
2821
+
2822
+ steps:
2823
+ - uses: actions/checkout@v4
2824
+
2825
+ - name: Setup Node.js
2826
+ uses: actions/setup-node@v4
2827
+ with:
2828
+ node-version: '18'
2829
+ cache: 'npm'
2830
+
2831
+ - name: Install dependencies
2832
+ run: npm ci
2833
+
2834
+ - name: Deploy to staging
2835
+ run: npx wrangler deploy --env staging
2836
+ env:
2837
+ CLOUDFLARE_API_TOKEN: \${{ secrets.CLOUDFLARE_API_TOKEN }}
2838
+ CLOUDFLARE_ACCOUNT_ID: \${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
2839
+
2840
+ deploy-production:
2841
+ if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
2842
+ runs-on: ubuntu-latest
2843
+ environment: production
2844
+
2845
+ steps:
2846
+ - uses: actions/checkout@v4
2847
+
2848
+ - name: Setup Node.js
2849
+ uses: actions/setup-node@v4
2850
+ with:
2851
+ node-version: '18'
2852
+ cache: 'npm'
2853
+
2854
+ - name: Install dependencies
2855
+ run: npm ci
2856
+
2857
+ - name: Deploy to production
2858
+ run: npx wrangler deploy --env production
2859
+ env:
2860
+ CLOUDFLARE_API_TOKEN: \${{ secrets.CLOUDFLARE_API_TOKEN }}
2861
+ CLOUDFLARE_ACCOUNT_ID: \${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
2862
+ `;
2863
+ const filePath = join(servicePath, '.github', 'workflows', 'deploy.yml');
2864
+ writeFileSync(filePath, deployWorkflow, 'utf8');
2865
+ return filePath;
2866
+ }
2867
+
2868
+ /**
2869
+ * Generate .gitignore
2870
+ */
2871
+ generateGitignore(coreInputs, confirmedValues, servicePath) {
2872
+ const gitignoreContent = `# Dependencies
2873
+ node_modules/
2874
+ npm-debug.log*
2875
+ yarn-debug.log*
2876
+ yarn-error.log*
2877
+
2878
+ # Environment variables
2879
+ .env
2880
+ .env.local
2881
+ .env.development.local
2882
+ .env.test.local
2883
+ .env.production.local
2884
+
2885
+ # Build outputs
2886
+ dist/
2887
+ build/
2888
+ coverage/
2889
+
2890
+ # Logs
2891
+ logs/
2892
+ *.log
2893
+ npm-debug.log*
2894
+ yarn-debug.log*
2895
+ yarn-error.log*
2896
+ lerna-debug.log*
2897
+
2898
+ # Runtime data
2899
+ pids/
2900
+ *.pid
2901
+ *.seed
2902
+ *.pid.lock
2903
+
2904
+ # Coverage directory used by tools like istanbul
2905
+ coverage/
2906
+ *.lcov
2907
+
2908
+ # nyc test coverage
2909
+ .nyc_output/
2910
+
2911
+ # Dependency directories
2912
+ jspm_packages/
2913
+
2914
+ # Optional npm cache directory
2915
+ .npm
2916
+
2917
+ # Optional eslint cache
2918
+ .eslintcache
2919
+
2920
+ # Microbundle cache
2921
+ .rpt2_cache/
2922
+ .rts2_cache_cjs/
2923
+ .rts2_cache_es/
2924
+ .rts2_cache_umd/
2925
+
2926
+ # Optional REPL history
2927
+ .node_repl_history
2928
+
2929
+ # Output of 'npm pack'
2930
+ *.tgz
2931
+
2932
+ # Yarn Integrity file
2933
+ .yarn-integrity
2934
+
2935
+ # parcel-bundler cache (https://parceljs.org/)
2936
+ .cache
2937
+ .parcel-cache
2938
+
2939
+ # Next.js build / generate output
2940
+ .next
2941
+
2942
+ # Nuxt.js build / generate output
2943
+ .nuxt
2944
+ dist
2945
+
2946
+ # Gatsby files
2947
+ .cache/
2948
+ public
2949
+
2950
+ # Storybook build outputs
2951
+ .out
2952
+ .storybook-out
2953
+
2954
+ # Temporary folders
2955
+ tmp/
2956
+ temp/
2957
+
2958
+ # Editor directories and files
2959
+ .vscode/*
2960
+ !.vscode/extensions.json
2961
+ .idea
2962
+ .DS_Store
2963
+ *.suo
2964
+ *.ntvs*
2965
+ *.njsproj
2966
+ *.sln
2967
+ *.sw?
2968
+
2969
+ # Cloudflare
2970
+ .wrangler/
2971
+ `;
2972
+ const filePath = join(servicePath, '.gitignore');
2973
+ writeFileSync(filePath, gitignoreContent, 'utf8');
2974
+ return filePath;
2975
+ }
2976
+
2977
+ /**
2978
+ * Generate docker-compose.yml
2979
+ */
2980
+ generateDockerCompose(coreInputs, confirmedValues, servicePath) {
2981
+ const dockerComposeContent = `version: '3.8'
2982
+
2983
+ services:
2984
+ ${coreInputs.serviceName}:
2985
+ build:
2986
+ context: .
2987
+ dockerfile: Dockerfile
2988
+ ports:
2989
+ - "8787:8787"
2990
+ environment:
2991
+ - NODE_ENV=development
2992
+ - SERVICE_NAME=${coreInputs.serviceName}
2993
+ - SERVICE_TYPE=${coreInputs.serviceType}
2994
+ - ENVIRONMENT=development
2995
+ volumes:
2996
+ - .:/app
2997
+ - /app/node_modules
2998
+ command: npm run dev
2999
+
3000
+ ${coreInputs.serviceName}-db:
3001
+ image: cloudflare/d1
3002
+ ports:
3003
+ - "8788:8787"
3004
+ environment:
3005
+ - DATABASE_NAME=${confirmedValues.databaseName}
3006
+ volumes:
3007
+ - .wrangler:/data
3008
+ `;
3009
+ const filePath = join(servicePath, 'docker-compose.yml');
3010
+ writeFileSync(filePath, dockerComposeContent, 'utf8');
3011
+ return filePath;
3012
+ }
3013
+
3014
+ /**
3015
+ * Create service manifest
3016
+ */
3017
+ createServiceManifest(coreInputs, confirmedValues, generatedFiles) {
3018
+ return {
3019
+ manifestVersion: '1.0.0',
3020
+ frameworkVersion: '3.0.0',
3021
+ generatedAt: new Date().toISOString(),
3022
+ service: {
3023
+ name: coreInputs.serviceName,
3024
+ displayName: confirmedValues.displayName,
3025
+ description: confirmedValues.description,
3026
+ type: coreInputs.serviceType,
3027
+ version: confirmedValues.version,
3028
+ author: confirmedValues.author
3029
+ },
3030
+ configuration: {
3031
+ coreInputs,
3032
+ confirmedValues,
3033
+ urls: {
3034
+ production: confirmedValues.productionUrl,
3035
+ staging: confirmedValues.stagingUrl,
3036
+ development: confirmedValues.developmentUrl,
3037
+ documentation: confirmedValues.documentationUrl
3038
+ },
3039
+ api: {
3040
+ basePath: confirmedValues.apiBasePath,
3041
+ healthCheckPath: confirmedValues.healthCheckPath
3042
+ },
3043
+ cloudflare: {
3044
+ accountId: coreInputs.cloudflareAccountId,
3045
+ zoneId: coreInputs.cloudflareZoneId,
3046
+ workerName: confirmedValues.workerName,
3047
+ databaseName: confirmedValues.databaseName
3048
+ },
3049
+ features: confirmedValues.features
3050
+ },
3051
+ files: {
3052
+ total: generatedFiles.length,
3053
+ list: generatedFiles.map(file => relative(process.cwd(), file)),
3054
+ byCategory: this.categorizeFiles(generatedFiles)
3055
+ },
3056
+ metadata: {
3057
+ generationEngine: 'GenerationEngine v1.0.0',
3058
+ tier: 'Tier 3 - Automated Generation',
3059
+ checksum: this.generateChecksum(generatedFiles)
3060
+ }
3061
+ };
3062
+ }
3063
+
3064
+ /**
3065
+ * Categorize generated files
3066
+ */
3067
+ categorizeFiles(files) {
3068
+ const categories = {
3069
+ core: [],
3070
+ service: [],
3071
+ environment: [],
3072
+ testing: [],
3073
+ documentation: [],
3074
+ automation: []
3075
+ };
3076
+ files.forEach(file => {
3077
+ const relativePath = relative(process.cwd(), file);
3078
+ if (relativePath.includes('package.json') || relativePath.includes('wrangler.toml') || relativePath.includes('.env')) {
3079
+ categories.core.push(relativePath);
3080
+ } else if (relativePath.includes('src/')) {
3081
+ categories.service.push(relativePath);
3082
+ } else if (relativePath.includes('config/') || relativePath.includes('scripts/')) {
3083
+ categories.environment.push(relativePath);
3084
+ } else if (relativePath.includes('test/') || relativePath.includes('jest.config.js') || relativePath.includes('.eslintrc.js')) {
3085
+ categories.testing.push(relativePath);
3086
+ } else if (relativePath.includes('docs/') || relativePath.includes('README.md')) {
3087
+ categories.documentation.push(relativePath);
3088
+ } else if (relativePath.includes('.github/') || relativePath.includes('.gitignore') || relativePath.includes('docker-compose.yml')) {
3089
+ categories.automation.push(relativePath);
3090
+ }
3091
+ });
3092
+ return categories;
3093
+ }
3094
+
3095
+ /**
3096
+ * Generate checksum for verification
3097
+ */
3098
+ generateChecksum(files) {
3099
+ // Simple checksum based on file count and names
3100
+ const fileString = files.map(f => relative(process.cwd(), f)).sort().join('');
3101
+ let hash = 0;
3102
+ for (let i = 0; i < fileString.length; i++) {
3103
+ const char = fileString.charCodeAt(i);
3104
+ hash = (hash << 5) - hash + char;
3105
+ hash = hash & hash; // Convert to 32-bit integer
3106
+ }
3107
+ return Math.abs(hash).toString(16);
3108
+ }
3109
+ }