@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.
- package/CHANGELOG.md +564 -0
- package/LICENSE +21 -0
- package/README.md +1393 -0
- package/bin/README.md +71 -0
- package/bin/clodo-service.js +416 -0
- package/bin/security/security-cli.js +96 -0
- package/bin/service-management/README.md +74 -0
- package/bin/service-management/create-service.js +129 -0
- package/bin/service-management/init-service.js +102 -0
- package/bin/service-management/init-service.js.backup +889 -0
- package/bin/shared/config/customer-cli.js +293 -0
- package/dist/config/ConfigurationManager.js +159 -0
- package/dist/config/CustomerConfigCLI.js +220 -0
- package/dist/config/FeatureManager.js +426 -0
- package/dist/config/customers.js +441 -0
- package/dist/config/domains.js +180 -0
- package/dist/config/features.js +225 -0
- package/dist/config/index.js +6 -0
- package/dist/database/database-orchestrator.js +730 -0
- package/dist/database/index.js +4 -0
- package/dist/deployment/auditor.js +971 -0
- package/dist/deployment/index.js +10 -0
- package/dist/deployment/rollback-manager.js +523 -0
- package/dist/deployment/testers/api-tester.js +80 -0
- package/dist/deployment/testers/auth-tester.js +129 -0
- package/dist/deployment/testers/core.js +217 -0
- package/dist/deployment/testers/database-tester.js +105 -0
- package/dist/deployment/testers/index.js +74 -0
- package/dist/deployment/testers/load-tester.js +120 -0
- package/dist/deployment/testers/performance-tester.js +105 -0
- package/dist/deployment/validator.js +558 -0
- package/dist/deployment/wrangler-deployer.js +574 -0
- package/dist/handlers/GenericRouteHandler.js +532 -0
- package/dist/index.js +39 -0
- package/dist/migration/MigrationAdapters.js +562 -0
- package/dist/modules/ModuleManager.js +668 -0
- package/dist/modules/security.js +98 -0
- package/dist/orchestration/cross-domain-coordinator.js +1083 -0
- package/dist/orchestration/index.js +5 -0
- package/dist/orchestration/modules/DeploymentCoordinator.js +258 -0
- package/dist/orchestration/modules/DomainResolver.js +196 -0
- package/dist/orchestration/modules/StateManager.js +332 -0
- package/dist/orchestration/multi-domain-orchestrator.js +255 -0
- package/dist/routing/EnhancedRouter.js +158 -0
- package/dist/schema/SchemaManager.js +778 -0
- package/dist/security/ConfigurationValidator.js +490 -0
- package/dist/security/DeploymentManager.js +208 -0
- package/dist/security/SecretGenerator.js +142 -0
- package/dist/security/SecurityCLI.js +228 -0
- package/dist/security/index.js +51 -0
- package/dist/security/patterns/environment-rules.js +66 -0
- package/dist/security/patterns/insecure-patterns.js +21 -0
- package/dist/service-management/ConfirmationEngine.js +411 -0
- package/dist/service-management/ErrorTracker.js +294 -0
- package/dist/service-management/GenerationEngine.js +3109 -0
- package/dist/service-management/InputCollector.js +237 -0
- package/dist/service-management/ServiceCreator.js +229 -0
- package/dist/service-management/ServiceInitializer.js +448 -0
- package/dist/service-management/ServiceOrchestrator.js +638 -0
- package/dist/service-management/handlers/ConfigMutator.js +130 -0
- package/dist/service-management/handlers/ConfirmationHandler.js +71 -0
- package/dist/service-management/handlers/GenerationHandler.js +80 -0
- package/dist/service-management/handlers/InputHandler.js +59 -0
- package/dist/service-management/handlers/ValidationHandler.js +203 -0
- package/dist/service-management/index.js +7 -0
- package/dist/services/GenericDataService.js +488 -0
- package/dist/shared/cloudflare/domain-discovery.js +562 -0
- package/dist/shared/cloudflare/domain-manager.js +912 -0
- package/dist/shared/cloudflare/index.js +8 -0
- package/dist/shared/cloudflare/ops.js +387 -0
- package/dist/shared/config/cache.js +1167 -0
- package/dist/shared/config/command-config-manager.js +174 -0
- package/dist/shared/config/customer-cli.js +258 -0
- package/dist/shared/config/index.js +9 -0
- package/dist/shared/config/manager.js +289 -0
- package/dist/shared/database/connection-manager.js +338 -0
- package/dist/shared/database/index.js +7 -0
- package/dist/shared/database/orchestrator.js +632 -0
- package/dist/shared/deployment/auditor.js +971 -0
- package/dist/shared/deployment/index.js +10 -0
- package/dist/shared/deployment/rollback-manager.js +523 -0
- package/dist/shared/deployment/validator.js +558 -0
- package/dist/shared/index.js +32 -0
- package/dist/shared/monitoring/health-checker.js +250 -0
- package/dist/shared/monitoring/index.js +8 -0
- package/dist/shared/monitoring/memory-manager.js +382 -0
- package/dist/shared/monitoring/production-monitor.js +390 -0
- package/dist/shared/production-tester/api-tester.js +80 -0
- package/dist/shared/production-tester/auth-tester.js +129 -0
- package/dist/shared/production-tester/core.js +217 -0
- package/dist/shared/production-tester/database-tester.js +105 -0
- package/dist/shared/production-tester/index.js +74 -0
- package/dist/shared/production-tester/load-tester.js +120 -0
- package/dist/shared/production-tester/performance-tester.js +105 -0
- package/dist/shared/security/api-token-manager.js +296 -0
- package/dist/shared/security/index.js +8 -0
- package/dist/shared/security/secret-generator.js +918 -0
- package/dist/shared/security/secure-token-manager.js +379 -0
- package/dist/shared/utils/error-recovery.js +240 -0
- package/dist/shared/utils/graceful-shutdown-manager.js +380 -0
- package/dist/shared/utils/index.js +9 -0
- package/dist/shared/utils/interactive-prompts.js +134 -0
- package/dist/shared/utils/rate-limiter.js +249 -0
- package/dist/utils/ErrorHandler.js +173 -0
- package/dist/utils/deployment/config-cache.js +1160 -0
- package/dist/utils/deployment/index.js +6 -0
- package/dist/utils/deployment/interactive-prompts.js +97 -0
- package/dist/utils/deployment/secret-generator.js +896 -0
- package/dist/utils/dirname-helper.js +35 -0
- package/dist/utils/domain-config.js +159 -0
- package/dist/utils/error-recovery.js +240 -0
- package/dist/utils/esm-helper.js +52 -0
- package/dist/utils/framework-config.js +481 -0
- package/dist/utils/graceful-shutdown-manager.js +379 -0
- package/dist/utils/health-checker.js +114 -0
- package/dist/utils/index.js +36 -0
- package/dist/utils/prompt-handler.js +98 -0
- package/dist/utils/usage-tracker.js +252 -0
- package/dist/utils/validation.js +112 -0
- package/dist/version/VersionDetector.js +723 -0
- package/dist/worker/index.js +4 -0
- package/dist/worker/integration.js +332 -0
- package/docs/FRAMEWORK-ARCHITECTURE-OVERVIEW.md +206 -0
- package/docs/INTEGRATION_GUIDE.md +2045 -0
- package/docs/README.md +82 -0
- package/docs/SECURITY.md +242 -0
- package/docs/deployment/deployment-guide.md +540 -0
- package/docs/overview.md +280 -0
- package/package.json +176 -0
- package/types/index.d.ts +575 -0
|
@@ -0,0 +1,2045 @@
|
|
|
1
|
+
# Clodo Framework - Integration Guide for Service Developers
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Clodo Framework enables **service autonomy** - each service can discover, validate, and deploy itself independently to Cloudflare Workers + D1. This guide explains how to properly integrate the framework into your services.
|
|
6
|
+
|
|
7
|
+
### ๐ Recent Enhancements: Customer Configuration Management
|
|
8
|
+
|
|
9
|
+
The Clodo Framework has successfully incorporated **enterprise-grade customer configuration management** capabilities:
|
|
10
|
+
|
|
11
|
+
- **โ
Multi-Customer Support**: Isolated configuration management for multiple customers
|
|
12
|
+
- **โ
Template-Based Onboarding**: Automated customer setup from reusable templates
|
|
13
|
+
- **โ
Multi-Environment Configs**: Separate configurations for dev/staging/production
|
|
14
|
+
- **โ
Framework Integration**: Seamless integration with existing domain and feature flag systems
|
|
15
|
+
- **โ
CLI Tools**: Command-line interface for customer management (`clodo-customer-config`)
|
|
16
|
+
- **โ
Service Autonomy**: Customer configs can be embedded in individual service repositories
|
|
17
|
+
- **โ
TypeScript Support**: Comprehensive type definitions with 500+ lines of TypeScript interfaces
|
|
18
|
+
|
|
19
|
+
**Migration Path**: Use framework tools during development, then copy generated configurations to your service repositories for production deployment.
|
|
20
|
+
|
|
21
|
+
### ๐ Recent Enhancements: Deployment & Security Validation
|
|
22
|
+
|
|
23
|
+
The Clodo Framework has been enhanced with **enterprise-grade deployment validation and security features**:
|
|
24
|
+
|
|
25
|
+
- **โ
Real HTTP Health Checks**: Native Node.js HTTP/HTTPS modules replace shell commands for cross-platform reliability
|
|
26
|
+
- **โ
Interactive Deployment Configuration**: User input-driven setup for deployment workflows with validation
|
|
27
|
+
- **โ
Comprehensive Error Reporting**: Actionable error messages with troubleshooting suggestions
|
|
28
|
+
- **โ
Enhanced Security Validation**: Real deployment validation with URL extraction and post-deployment checks
|
|
29
|
+
- **โ
Cross-Platform Compatibility**: Eliminated platform-specific shell command dependencies
|
|
30
|
+
|
|
31
|
+
**Key Benefits**:
|
|
32
|
+
- **Reliable Health Monitoring**: HTTP-based health checks work consistently across Windows, Linux, and macOS
|
|
33
|
+
- **User-Friendly Deployment**: Interactive wizards guide users through configuration setup
|
|
34
|
+
- **Better Error Handling**: Clear, actionable error messages help resolve deployment issues quickly
|
|
35
|
+
- **Enhanced Security**: Real validation ensures deployments meet security requirements
|
|
36
|
+
|
|
37
|
+
**Integration Example**:
|
|
38
|
+
```javascript
|
|
39
|
+
import { deployWithSecurity, InteractiveDeploymentConfigurator } from '@tamyla/clodo-framework/security';
|
|
40
|
+
|
|
41
|
+
// Interactive configuration setup
|
|
42
|
+
const config = await InteractiveDeploymentConfigurator.runConfigurationWizard();
|
|
43
|
+
|
|
44
|
+
// Secure deployment with real validation
|
|
45
|
+
await deployWithSecurity({
|
|
46
|
+
customer: config.customer,
|
|
47
|
+
environment: config.environment,
|
|
48
|
+
deploymentUrl: config.domain,
|
|
49
|
+
dryRun: config.dryRun
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Architecture Overview
|
|
54
|
+
|
|
55
|
+
### Two Runtime Environments
|
|
56
|
+
|
|
57
|
+
**๐ Deployment Time (Your Machine):**
|
|
58
|
+
- Node.js environment during development/build
|
|
59
|
+
- Uses: File system, child processes, network calls
|
|
60
|
+
- Components: Orchestration, validation, deployment scripts
|
|
61
|
+
- Purpose: Build and deploy your service
|
|
62
|
+
|
|
63
|
+
**โ๏ธ Runtime (Cloudflare Workers):**
|
|
64
|
+
- V8 isolate environment
|
|
65
|
+
- Limitations: No file system, no child processes
|
|
66
|
+
- Components: Data services, routing, schema validation
|
|
67
|
+
- Purpose: Handle requests in production
|
|
68
|
+
|
|
69
|
+
### Service Autonomy Philosophy
|
|
70
|
+
|
|
71
|
+
> **Each service discovers and deploys itself independently**
|
|
72
|
+
|
|
73
|
+
Your service should **embed deployment capabilities**, not call external CLI tools.
|
|
74
|
+
|
|
75
|
+
## Integration Patterns
|
|
76
|
+
|
|
77
|
+
### โ WRONG: Calling Bin Scripts Externally
|
|
78
|
+
```bash
|
|
79
|
+
# DON'T DO THIS - Bin scripts have import issues when called from node_modules
|
|
80
|
+
npm install @tamyla/clodo-framework
|
|
81
|
+
# Then in package.json:
|
|
82
|
+
"scripts": {
|
|
83
|
+
"deploy": "node node_modules/@tamyla/clodo-framework/bin/enterprise-deploy.js deploy --interactive"
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### โ
CORRECT: Embed Deployment Logic
|
|
88
|
+
|
|
89
|
+
**1. Add Framework as Dependency:**
|
|
90
|
+
```json
|
|
91
|
+
// package.json
|
|
92
|
+
{
|
|
93
|
+
"name": "my-data-service",
|
|
94
|
+
"dependencies": {
|
|
95
|
+
"@tamyla/clodo-framework": "^1.3.2"
|
|
96
|
+
},
|
|
97
|
+
"scripts": {
|
|
98
|
+
"deploy": "node scripts/deploy.js",
|
|
99
|
+
"dev": "node scripts/dev.js"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**2. Create Service Structure:**
|
|
105
|
+
```
|
|
106
|
+
my-data-service/
|
|
107
|
+
โโโ src/
|
|
108
|
+
โ โโโ config/
|
|
109
|
+
โ โ โโโ domains.js # Domain configuration
|
|
110
|
+
โ โ โโโ schema.js # Data models
|
|
111
|
+
โ โโโ worker/
|
|
112
|
+
โ โโโ index.js # Cloudflare Worker entry
|
|
113
|
+
โโโ scripts/
|
|
114
|
+
โ โโโ deploy.js # Deployment script
|
|
115
|
+
โ โโโ dev.js # Development server
|
|
116
|
+
โโโ wrangler.toml # Cloudflare config
|
|
117
|
+
โโโ package.json
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**3. Domain Configuration:**
|
|
121
|
+
```javascript
|
|
122
|
+
// src/config/domains.js
|
|
123
|
+
export const domains = {
|
|
124
|
+
'my-service.com': {
|
|
125
|
+
name: 'my-service',
|
|
126
|
+
displayName: 'My Data Service',
|
|
127
|
+
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
|
|
128
|
+
zoneId: process.env.CLOUDFLARE_ZONE_ID,
|
|
129
|
+
domains: {
|
|
130
|
+
production: 'api.my-service.com',
|
|
131
|
+
staging: 'staging-api.my-service.com'
|
|
132
|
+
},
|
|
133
|
+
features: {
|
|
134
|
+
dataService: true,
|
|
135
|
+
logging: true,
|
|
136
|
+
cors: true
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**4. Schema Definition:**
|
|
143
|
+
```javascript
|
|
144
|
+
// src/config/schema.js
|
|
145
|
+
import { schemaManager } from '@tamyla/clodo-framework/schema';
|
|
146
|
+
|
|
147
|
+
schemaManager.registerModel('users', {
|
|
148
|
+
columns: {
|
|
149
|
+
id: { type: 'string', primary: true },
|
|
150
|
+
email: { type: 'string', required: true, unique: true },
|
|
151
|
+
name: { type: 'string', required: true },
|
|
152
|
+
created_at: { type: 'datetime', default: 'now' },
|
|
153
|
+
updated_at: { type: 'datetime', default: 'now' }
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
schemaManager.registerModel('posts', {
|
|
158
|
+
columns: {
|
|
159
|
+
id: { type: 'string', primary: true },
|
|
160
|
+
user_id: { type: 'string', required: true, references: 'users.id' },
|
|
161
|
+
title: { type: 'string', required: true },
|
|
162
|
+
content: { type: 'text' },
|
|
163
|
+
created_at: { type: 'datetime', default: 'now' }
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**5. Customer Configuration Management (Optional):**
|
|
169
|
+
|
|
170
|
+
For services that need multi-customer support, you can integrate the Clodo Framework's customer configuration system:
|
|
171
|
+
|
|
172
|
+
```javascript
|
|
173
|
+
// src/config/customers.js (Optional - for multi-customer services)
|
|
174
|
+
import { CustomerConfigurationManager } from '@tamyla/clodo-framework/config';
|
|
175
|
+
|
|
176
|
+
// Initialize customer manager for service environment
|
|
177
|
+
const customerManager = new CustomerConfigurationManager();
|
|
178
|
+
|
|
179
|
+
// Load existing customer configurations
|
|
180
|
+
await customerManager.loadExistingCustomers();
|
|
181
|
+
|
|
182
|
+
// Get current customer from environment
|
|
183
|
+
const currentCustomer = process.env.CUSTOMER_NAME || 'default';
|
|
184
|
+
|
|
185
|
+
// Get customer-specific configuration
|
|
186
|
+
const customerConfig = customerManager.showConfig(currentCustomer, process.env.NODE_ENV || 'development');
|
|
187
|
+
|
|
188
|
+
// Use customer configuration
|
|
189
|
+
const dbUrl = customerConfig.variables.customer.DATABASE_URL;
|
|
190
|
+
const jwtSecret = customerConfig.variables.customer.JWT_SECRET;
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Note**: Customer configurations are typically managed at the service level, not embedded in the framework. Use the framework's customer management tools during development, then copy the generated configurations to your service repositories.
|
|
194
|
+
|
|
195
|
+
**6. Cloudflare Worker (Runtime):**
|
|
196
|
+
```javascript
|
|
197
|
+
// src/worker/index.js
|
|
198
|
+
import { initializeService, COMMON_FEATURES } from '@tamyla/clodo-framework';
|
|
199
|
+
import { GenericDataService } from '@tamyla/clodo-framework/services';
|
|
200
|
+
import { EnhancedRouter } from '@tamyla/clodo-framework/routing';
|
|
201
|
+
import { domains } from '../config/domains.js';
|
|
202
|
+
import '../config/schema.js'; // Register schemas
|
|
203
|
+
|
|
204
|
+
export default {
|
|
205
|
+
async fetch(request, env, ctx) {
|
|
206
|
+
try {
|
|
207
|
+
// Initialize service context
|
|
208
|
+
const service = initializeService(env, domains);
|
|
209
|
+
|
|
210
|
+
// Create data services
|
|
211
|
+
const userService = new GenericDataService(env.DB, 'users');
|
|
212
|
+
const postService = new GenericDataService(env.DB, 'posts');
|
|
213
|
+
|
|
214
|
+
// Create router
|
|
215
|
+
const router = new EnhancedRouter();
|
|
216
|
+
|
|
217
|
+
// Health check
|
|
218
|
+
router.get('/health', async () => {
|
|
219
|
+
return new Response(JSON.stringify({
|
|
220
|
+
status: 'healthy',
|
|
221
|
+
service: service.domain,
|
|
222
|
+
environment: service.environment,
|
|
223
|
+
features: service.features,
|
|
224
|
+
timestamp: new Date().toISOString()
|
|
225
|
+
}), {
|
|
226
|
+
headers: { 'Content-Type': 'application/json' }
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// API routes
|
|
231
|
+
router.get('/api/users', async () => {
|
|
232
|
+
const users = await userService.findAll();
|
|
233
|
+
return new Response(JSON.stringify(users), {
|
|
234
|
+
headers: { 'Content-Type': 'application/json' }
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
router.post('/api/users', async (request) => {
|
|
239
|
+
const data = await request.json();
|
|
240
|
+
const user = await userService.create(data);
|
|
241
|
+
return new Response(JSON.stringify(user), {
|
|
242
|
+
status: 201,
|
|
243
|
+
headers: { 'Content-Type': 'application/json' }
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
router.get('/api/users/:id', async (request, params) => {
|
|
248
|
+
const user = await userService.findById(params.id);
|
|
249
|
+
if (!user) {
|
|
250
|
+
return new Response(JSON.stringify({ error: 'User not found' }), {
|
|
251
|
+
status: 404,
|
|
252
|
+
headers: { 'Content-Type': 'application/json' }
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
return new Response(JSON.stringify(user), {
|
|
256
|
+
headers: { 'Content-Type': 'application/json' }
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// Handle request
|
|
261
|
+
return await router.handle(request, env, ctx);
|
|
262
|
+
|
|
263
|
+
} catch (error) {
|
|
264
|
+
console.error('Worker error:', error);
|
|
265
|
+
|
|
266
|
+
// Log errors if logging is enabled
|
|
267
|
+
if (service?.features?.includes(COMMON_FEATURES.LOGGING)) {
|
|
268
|
+
console.error('Request failed:', request.url, error.message);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return new Response(JSON.stringify({
|
|
272
|
+
error: 'Internal server error',
|
|
273
|
+
message: error.message
|
|
274
|
+
}), {
|
|
275
|
+
status: 500,
|
|
276
|
+
headers: { 'Content-Type': 'application/json' }
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**6. Deployment Script (Build Time):**
|
|
284
|
+
```javascript
|
|
285
|
+
// scripts/deploy.js
|
|
286
|
+
import { MultiDomainOrchestrator, DeploymentValidator, WranglerDeployer } from '@tamyla/clodo-framework/orchestration';
|
|
287
|
+
import { DomainDiscovery } from '@tamyla/clodo-framework/config/discovery';
|
|
288
|
+
import { askChoice, askUser } from '@tamyla/clodo-framework/utils/interactive';
|
|
289
|
+
import { domains } from '../src/config/domains.js';
|
|
290
|
+
|
|
291
|
+
async function deploy() {
|
|
292
|
+
try {
|
|
293
|
+
console.log('๐ Clodo Framework Deployment');
|
|
294
|
+
console.log('==========================');
|
|
295
|
+
|
|
296
|
+
// Select environment
|
|
297
|
+
const environment = await askChoice(
|
|
298
|
+
'Select deployment environment:',
|
|
299
|
+
['development', 'staging', 'production'],
|
|
300
|
+
2 // Default to production
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
// Select domain
|
|
304
|
+
const domainNames = Object.keys(domains);
|
|
305
|
+
const selectedDomain = await askChoice(
|
|
306
|
+
'Select domain to deploy:',
|
|
307
|
+
domainNames,
|
|
308
|
+
0
|
|
309
|
+
);
|
|
310
|
+
const domain = domainNames[selectedDomain];
|
|
311
|
+
|
|
312
|
+
console.log(`\n๐ Deploying ${domain} to ${environment}`);
|
|
313
|
+
console.log('=====================================');
|
|
314
|
+
|
|
315
|
+
// Initialize deployment components
|
|
316
|
+
const discovery = new DomainDiscovery({
|
|
317
|
+
enableCaching: true
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
const validator = new DeploymentValidator({
|
|
321
|
+
validationLevel: 'comprehensive',
|
|
322
|
+
environment
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
const orchestrator = new MultiDomainOrchestrator({
|
|
326
|
+
domains: [domain],
|
|
327
|
+
environment,
|
|
328
|
+
dryRun: false,
|
|
329
|
+
parallelDeployments: 1
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// Validate domain
|
|
333
|
+
console.log('๐ Validating domain configuration...');
|
|
334
|
+
await discovery.initializeDiscovery();
|
|
335
|
+
const domainConfig = await discovery.getDomainConfig(domain);
|
|
336
|
+
|
|
337
|
+
if (!domainConfig) {
|
|
338
|
+
throw new Error(`Domain ${domain} not found in configuration`);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Validate deployment readiness
|
|
342
|
+
console.log('โ
Running pre-deployment validation...');
|
|
343
|
+
const validation = await validator.validateDeploymentReadiness(domain, {
|
|
344
|
+
environment,
|
|
345
|
+
skipEndpointCheck: environment === 'development'
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
if (!validation.valid) {
|
|
349
|
+
console.error('โ Validation failed:');
|
|
350
|
+
validation.errors.forEach(error => console.error(` - ${error}`));
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Deploy
|
|
355
|
+
console.log('๐ Starting deployment...');
|
|
356
|
+
await orchestrator.initialize();
|
|
357
|
+
const result = await orchestrator.deploySingleDomain(domain);
|
|
358
|
+
|
|
359
|
+
console.log('โ
Deployment successful!');
|
|
360
|
+
console.log(`๐ Service URL: ${result.url}`);
|
|
361
|
+
console.log(`โฑ๏ธ Duration: ${result.duration}ms`);
|
|
362
|
+
|
|
363
|
+
} catch (error) {
|
|
364
|
+
console.error('โ Deployment failed:', error.message);
|
|
365
|
+
process.exit(1);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
deploy();
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**7. Development Script:**
|
|
373
|
+
```javascript
|
|
374
|
+
// scripts/dev.js
|
|
375
|
+
import { spawn } from 'child_process';
|
|
376
|
+
import { fileURLToPath } from 'url';
|
|
377
|
+
import { dirname, join } from 'path';
|
|
378
|
+
|
|
379
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
380
|
+
const __dirname = dirname(__filename);
|
|
381
|
+
|
|
382
|
+
console.log('๐ Starting Clodo Framework Development Server');
|
|
383
|
+
console.log('===========================================');
|
|
384
|
+
|
|
385
|
+
// Start Wrangler dev server
|
|
386
|
+
const wrangler = spawn('npx', ['wrangler', 'dev'], {
|
|
387
|
+
cwd: join(__dirname, '..'),
|
|
388
|
+
stdio: 'inherit',
|
|
389
|
+
shell: true
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
wrangler.on('close', (code) => {
|
|
393
|
+
console.log(`\nWrangler exited with code ${code}`);
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
wrangler.on('error', (error) => {
|
|
397
|
+
console.error('Failed to start Wrangler:', error);
|
|
398
|
+
process.exit(1);
|
|
399
|
+
});
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
## Configuration Files
|
|
403
|
+
|
|
404
|
+
### wrangler.toml
|
|
405
|
+
```toml
|
|
406
|
+
name = "my-data-service"
|
|
407
|
+
main = "src/worker/index.js"
|
|
408
|
+
compatibility_date = "2024-01-01"
|
|
409
|
+
|
|
410
|
+
[vars]
|
|
411
|
+
ENVIRONMENT = "production"
|
|
412
|
+
|
|
413
|
+
[[d1_databases]]
|
|
414
|
+
binding = "DB"
|
|
415
|
+
database_name = "my-data-service-db"
|
|
416
|
+
database_id = "your-database-id"
|
|
417
|
+
|
|
418
|
+
[build]
|
|
419
|
+
command = "npm run build"
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### Environment Variables
|
|
423
|
+
```bash
|
|
424
|
+
# Required for deployment
|
|
425
|
+
export CLOUDFLARE_ACCOUNT_ID="your_account_id"
|
|
426
|
+
export CLOUDFLARE_ZONE_ID="your_zone_id"
|
|
427
|
+
export CLOUDFLARE_API_TOKEN="your_api_token"
|
|
428
|
+
|
|
429
|
+
# Optional
|
|
430
|
+
export ENVIRONMENT="production"
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## Usage Commands
|
|
434
|
+
|
|
435
|
+
### Development
|
|
436
|
+
```bash
|
|
437
|
+
# Start development server
|
|
438
|
+
npm run dev
|
|
439
|
+
|
|
440
|
+
# Test endpoints
|
|
441
|
+
curl http://localhost:8787/health
|
|
442
|
+
curl http://localhost:8787/api/users
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Deployment
|
|
446
|
+
```bash
|
|
447
|
+
# Deploy to production
|
|
448
|
+
npm run deploy
|
|
449
|
+
|
|
450
|
+
# Deploy to staging
|
|
451
|
+
ENVIRONMENT=staging npm run deploy
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Validation
|
|
455
|
+
```bash
|
|
456
|
+
# Validate configuration
|
|
457
|
+
node -e "
|
|
458
|
+
import { DeploymentValidator } from '@tamyla/clodo-framework/orchestration';
|
|
459
|
+
const validator = new DeploymentValidator();
|
|
460
|
+
validator.validateDeploymentReadiness('my-service.com').then(console.log);
|
|
461
|
+
"
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Customer Configuration Management
|
|
465
|
+
|
|
466
|
+
For services that support multiple customers, integrate customer-specific configuration:
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
# During development, use framework tools to generate customer configs
|
|
470
|
+
npx clodo-customer-config create-customer mycompany mycompany.com
|
|
471
|
+
|
|
472
|
+
# Copy generated configs to your service
|
|
473
|
+
cp config/customers/mycompany/* src/config/customers/mycompany/
|
|
474
|
+
|
|
475
|
+
# In production, load customer-specific configuration
|
|
476
|
+
node -e "
|
|
477
|
+
import { CustomerConfigurationManager } from '@tamyla/clodo-framework/config';
|
|
478
|
+
const manager = new CustomerConfigurationManager();
|
|
479
|
+
await manager.loadExistingCustomers();
|
|
480
|
+
const config = manager.showConfig(process.env.CUSTOMER_NAME, process.env.NODE_ENV);
|
|
481
|
+
console.log('Customer config loaded:', config.customer);
|
|
482
|
+
"
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
## ๐ง Modular CLI Capabilities
|
|
486
|
+
|
|
487
|
+
The CLODO Framework provides **modular CLI capabilities** that can be imported and used programmatically in your services, enabling seamless integration of CLI functionality into your deployment and management workflows.
|
|
488
|
+
|
|
489
|
+
### Service Management Modules
|
|
490
|
+
|
|
491
|
+
**Programmatic Service Creation:**
|
|
492
|
+
```javascript
|
|
493
|
+
import { ServiceCreator } from '@tamyla/clodo-framework/service-management';
|
|
494
|
+
|
|
495
|
+
const creator = new ServiceCreator();
|
|
496
|
+
|
|
497
|
+
// Create a new service from template
|
|
498
|
+
await creator.createService({
|
|
499
|
+
name: 'my-new-service',
|
|
500
|
+
template: 'data-service',
|
|
501
|
+
domain: 'api.mycompany.com',
|
|
502
|
+
features: ['authentication', 'logging']
|
|
503
|
+
});
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
**Programmatic Service Initialization:**
|
|
507
|
+
```javascript
|
|
508
|
+
import { ServiceInitializer } from '@tamyla/clodo-framework/service-management';
|
|
509
|
+
|
|
510
|
+
const initializer = new ServiceInitializer();
|
|
511
|
+
|
|
512
|
+
// Initialize service with configuration
|
|
513
|
+
await initializer.initializeService({
|
|
514
|
+
serviceName: 'my-service',
|
|
515
|
+
environment: 'production',
|
|
516
|
+
customer: 'mycompany',
|
|
517
|
+
configOverrides: {
|
|
518
|
+
databaseUrl: 'https://prod-db.mycompany.com'
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Security CLI Module
|
|
524
|
+
|
|
525
|
+
**Programmatic Security Operations:**
|
|
526
|
+
```javascript
|
|
527
|
+
import { SecurityCLI } from '@tamyla/clodo-framework/security';
|
|
528
|
+
|
|
529
|
+
const security = new SecurityCLI();
|
|
530
|
+
|
|
531
|
+
// Validate security configuration
|
|
532
|
+
const issues = await security.validateConfig('mycompany', 'production');
|
|
533
|
+
if (issues.length > 0) {
|
|
534
|
+
console.error('Security issues found:', issues);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// Generate secure keys
|
|
538
|
+
const apiKey = await security.generateApiKey();
|
|
539
|
+
const jwtSecret = await security.generateJwtSecret();
|
|
540
|
+
|
|
541
|
+
// Deploy with security validation
|
|
542
|
+
await security.deployWithValidation({
|
|
543
|
+
customer: 'mycompany',
|
|
544
|
+
environment: 'production',
|
|
545
|
+
domain: 'api.mycompany.com'
|
|
546
|
+
});
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### Customer Configuration CLI Module
|
|
550
|
+
|
|
551
|
+
**Programmatic Customer Management:**
|
|
552
|
+
```javascript
|
|
553
|
+
import { CustomerConfigCLI } from '@tamyla/clodo-framework/config';
|
|
554
|
+
|
|
555
|
+
const customerConfig = new CustomerConfigCLI();
|
|
556
|
+
|
|
557
|
+
// Create new customer configuration
|
|
558
|
+
await customerConfig.createCustomer({
|
|
559
|
+
name: 'newcustomer',
|
|
560
|
+
domain: 'api.newcustomer.com',
|
|
561
|
+
environment: 'production'
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
// Show customer configuration
|
|
565
|
+
const config = await customerConfig.showConfig('newcustomer', 'production');
|
|
566
|
+
console.log('Customer config:', config);
|
|
567
|
+
|
|
568
|
+
// Update customer settings
|
|
569
|
+
await customerConfig.updateCustomer('newcustomer', {
|
|
570
|
+
features: { analytics: true, notifications: false }
|
|
571
|
+
});
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### Integration in Deployment Scripts
|
|
575
|
+
|
|
576
|
+
**Combine modular CLI capabilities in your deployment pipeline:**
|
|
577
|
+
```javascript
|
|
578
|
+
// scripts/deploy-and-configure.js
|
|
579
|
+
import { ServiceCreator, ServiceInitializer } from '@tamyla/clodo-framework/service-management';
|
|
580
|
+
import { SecurityCLI } from '@tamyla/clodo-framework/security';
|
|
581
|
+
import { CustomerConfigCLI } from '@tamyla/clodo-framework/config';
|
|
582
|
+
|
|
583
|
+
async function deployAndConfigure() {
|
|
584
|
+
const creator = new ServiceCreator();
|
|
585
|
+
const initializer = new ServiceInitializer();
|
|
586
|
+
const security = new SecurityCLI();
|
|
587
|
+
const customerConfig = new CustomerConfigCLI();
|
|
588
|
+
|
|
589
|
+
try {
|
|
590
|
+
// Create service if it doesn't exist
|
|
591
|
+
await creator.createService({
|
|
592
|
+
name: process.env.SERVICE_NAME,
|
|
593
|
+
domain: process.env.DOMAIN
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
// Configure customer settings
|
|
597
|
+
await customerConfig.createCustomer({
|
|
598
|
+
name: process.env.CUSTOMER_NAME,
|
|
599
|
+
domain: process.env.DOMAIN
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
// Initialize with secure configuration
|
|
603
|
+
await initializer.initializeService({
|
|
604
|
+
serviceName: process.env.SERVICE_NAME,
|
|
605
|
+
environment: process.env.NODE_ENV,
|
|
606
|
+
customer: process.env.CUSTOMER_NAME
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
// Deploy with security validation
|
|
610
|
+
await security.deployWithValidation({
|
|
611
|
+
customer: process.env.CUSTOMER_NAME,
|
|
612
|
+
environment: process.env.NODE_ENV,
|
|
613
|
+
domain: process.env.DOMAIN
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
console.log('โ
Service deployed and configured successfully');
|
|
617
|
+
|
|
618
|
+
} catch (error) {
|
|
619
|
+
console.error('โ Deployment failed:', error.message);
|
|
620
|
+
throw error;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
deployAndConfigure();
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
### Benefits of Modular CLI Integration
|
|
628
|
+
|
|
629
|
+
- **๐ง Programmatic Control**: Use CLI functionality directly in your code without shell commands
|
|
630
|
+
- **๐ Pipeline Integration**: Seamlessly integrate framework capabilities into CI/CD workflows
|
|
631
|
+
- **๐งช Testable Operations**: Test CLI operations programmatically in your test suites
|
|
632
|
+
- **๐ฆ Bundle Optimization**: Import only the CLI modules you need
|
|
633
|
+
- **๐ Type Safety**: Full TypeScript support for all CLI operations
|
|
634
|
+
- **โก Performance**: Direct imports avoid shell command overhead
|
|
635
|
+
|
|
636
|
+
## Common Mistakes to Avoid
|
|
637
|
+
|
|
638
|
+
### 1. Don't Call Bin Scripts Externally
|
|
639
|
+
```javascript
|
|
640
|
+
// โ WRONG
|
|
641
|
+
"scripts": {
|
|
642
|
+
"deploy": "node node_modules/@tamyla/clodo-framework/bin/enterprise-deploy.js deploy --interactive"
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// โ
CORRECT
|
|
646
|
+
"scripts": {
|
|
647
|
+
"deploy": "node scripts/deploy.js"
|
|
648
|
+
}
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
### 2. Don't Use Deployment Components in Workers
|
|
652
|
+
```javascript
|
|
653
|
+
// โ WRONG - Won't work in Cloudflare Workers
|
|
654
|
+
import { MultiDomainOrchestrator } from '@tamyla/clodo-framework/orchestration';
|
|
655
|
+
|
|
656
|
+
export default {
|
|
657
|
+
fetch(request, env) {
|
|
658
|
+
const orchestrator = new MultiDomainOrchestrator(); // Uses fs, child_process
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// โ
CORRECT - Use only runtime components
|
|
663
|
+
import { GenericDataService } from '@tamyla/clodo-framework/services';
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
### 3. Always Handle Async Operations
|
|
667
|
+
```javascript
|
|
668
|
+
// โ WRONG
|
|
669
|
+
router.get('/api/data', () => {
|
|
670
|
+
const data = await dataService.findAll(); // await in non-async function
|
|
671
|
+
return new Response(JSON.stringify(data));
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
// โ
CORRECT
|
|
675
|
+
router.get('/api/data', async () => {
|
|
676
|
+
const data = await dataService.findAll();
|
|
677
|
+
return new Response(JSON.stringify(data));
|
|
678
|
+
});
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
### 4. Always Return Response Objects
|
|
682
|
+
```javascript
|
|
683
|
+
// โ WRONG
|
|
684
|
+
export default {
|
|
685
|
+
fetch(request, env) {
|
|
686
|
+
return { status: 'ok' }; // Not a Response object
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// โ
CORRECT
|
|
691
|
+
export default {
|
|
692
|
+
fetch(request, env) {
|
|
693
|
+
return new Response(JSON.stringify({ status: 'ok' }), {
|
|
694
|
+
headers: { 'Content-Type': 'application/json' }
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
## Component Reference
|
|
701
|
+
|
|
702
|
+
### Runtime Components (Worker-Compatible)
|
|
703
|
+
- `initializeService()` - Service context initialization
|
|
704
|
+
- `GenericDataService` - D1 database operations
|
|
705
|
+
- `schemaManager` - Data validation and modeling
|
|
706
|
+
- `EnhancedRouter` - HTTP request routing
|
|
707
|
+
- `COMMON_FEATURES` - Feature flag constants
|
|
708
|
+
|
|
709
|
+
### Deployment Components (Build-Time Only)
|
|
710
|
+
- `MultiDomainOrchestrator` - Deployment orchestration
|
|
711
|
+
- `DeploymentValidator` - Pre-deployment validation
|
|
712
|
+
- `DomainDiscovery` - Cloudflare domain discovery
|
|
713
|
+
- `WranglerDeployer` - **Intelligent wrangler CLI execution with auto-discovery**
|
|
714
|
+
- `ProductionTester` - Post-deployment testing
|
|
715
|
+
|
|
716
|
+
## Advanced WranglerDeployer Features
|
|
717
|
+
|
|
718
|
+
The `WranglerDeployer` is designed to be maximally generic and intelligent:
|
|
719
|
+
|
|
720
|
+
### ๐ **Automatic Configuration Discovery**
|
|
721
|
+
- **Multi-config support**: Automatically detects `wrangler.toml` vs `config/wrangler.toml`
|
|
722
|
+
- **Environment detection**: Discovers environment-specific configurations
|
|
723
|
+
- **Service information**: Extracts worker names, routes, and settings from config files
|
|
724
|
+
|
|
725
|
+
### ๐ **Intelligent Environment Detection**
|
|
726
|
+
```javascript
|
|
727
|
+
// Automatically detects environment from:
|
|
728
|
+
const deployer = new WranglerDeployer();
|
|
729
|
+
// - Environment variables (NODE_ENV, ENVIRONMENT)
|
|
730
|
+
// - Git branch (main/master โ production, develop โ development)
|
|
731
|
+
// - Cloudflare Pages branch (CF_PAGES_BRANCH)
|
|
732
|
+
console.log(deployer.environment); // 'production', 'staging', or 'development'
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
### ๐ง **Real-time Environment Variable Integration**
|
|
736
|
+
Automatically includes relevant environment variables in deployments:
|
|
737
|
+
```javascript
|
|
738
|
+
// Cloudflare variables
|
|
739
|
+
CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN, CF_API_TOKEN
|
|
740
|
+
|
|
741
|
+
// Service variables
|
|
742
|
+
SERVICE_DOMAIN, SERVICE_NAME, LOG_LEVEL, CORS_ORIGINS
|
|
743
|
+
DATA_SERVICE_URL, AUTH_SERVICE_URL, CONTENT_STORE_SERVICE_URL
|
|
744
|
+
|
|
745
|
+
// Environment-specific
|
|
746
|
+
PRODUCTION_URL, STAGING_DOMAIN, CF_DEVELOPMENT_TOKEN
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
### ๐ **Smart URL Extraction**
|
|
750
|
+
Multiple strategies for extracting deployment URLs:
|
|
751
|
+
1. **Direct parsing** from wrangler output patterns
|
|
752
|
+
2. **Route-based** URLs from wrangler.toml configuration
|
|
753
|
+
3. **Worker name construction** for workers.dev domains
|
|
754
|
+
4. **Environment-aware** URL validation
|
|
755
|
+
|
|
756
|
+
### โ
**Enhanced Validation**
|
|
757
|
+
```javascript
|
|
758
|
+
const validation = await deployer.validateWranglerSetup('production');
|
|
759
|
+
// Returns detailed config info, account details, and actionable suggestions
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
## Intelligent Deployment Example
|
|
763
|
+
|
|
764
|
+
```javascript
|
|
765
|
+
import { WranglerDeployer } from '@tamyla/clodo-framework/deployment';
|
|
766
|
+
|
|
767
|
+
async function deploy() {
|
|
768
|
+
// Create deployer - automatically detects environment and service info
|
|
769
|
+
const deployer = new WranglerDeployer({
|
|
770
|
+
cwd: process.cwd(),
|
|
771
|
+
timeout: 300000
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
console.log(`๐ Detected environment: ${deployer.environment}`);
|
|
775
|
+
console.log(`๐ฆ Service: ${deployer.serviceInfo.name} v${deployer.serviceInfo.version}`);
|
|
776
|
+
|
|
777
|
+
// Validate setup with intelligent discovery
|
|
778
|
+
const validation = await deployer.validateWranglerSetup(deployer.environment);
|
|
779
|
+
if (!validation.valid) {
|
|
780
|
+
console.error('โ Setup issues:', validation.error);
|
|
781
|
+
console.log('๐ก Suggestions:', validation.suggestions);
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// Deploy with automatic configuration discovery
|
|
786
|
+
const result = await deployer.deploy(deployer.environment);
|
|
787
|
+
|
|
788
|
+
console.log(`โ
Deployed to: ${result.url}`);
|
|
789
|
+
console.log(`โฑ๏ธ Duration: ${result.duration}ms`);
|
|
790
|
+
console.log(`๐ง Config used: ${result.config.configPath}`);
|
|
791
|
+
}
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
## Troubleshooting
|
|
795
|
+
|
|
796
|
+
### "require is not defined"
|
|
797
|
+
- **Cause**: Using deployment components in Worker runtime
|
|
798
|
+
- **Fix**: Only use runtime components in `src/worker/index.js`
|
|
799
|
+
|
|
800
|
+
### "Cannot read properties of undefined (reading 'valid')"
|
|
801
|
+
- **Cause**: Validator method not returning expected result
|
|
802
|
+
- **Fix**: Ensure proper error handling in deployment scripts
|
|
803
|
+
|
|
804
|
+
### "Service directory not found"
|
|
805
|
+
- **Cause**: Domain configuration mismatch
|
|
806
|
+
- **Fix**: Verify `src/config/domains.js` has correct domain entries
|
|
807
|
+
|
|
808
|
+
### Import Errors
|
|
809
|
+
- **Cause**: Wrong import paths or missing dependencies
|
|
810
|
+
- **Fix**: Use exact import paths from framework documentation
|
|
811
|
+
|
|
812
|
+
### "Environment auto-detection failed"
|
|
813
|
+
- **Cause**: WranglerDeployer couldn't determine the target environment
|
|
814
|
+
- **Fix**: Set explicit environment variables or pass environment to constructor
|
|
815
|
+
```bash
|
|
816
|
+
export ENVIRONMENT=production
|
|
817
|
+
# or
|
|
818
|
+
export NODE_ENV=production
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
### "Configuration discovery failed"
|
|
822
|
+
- **Cause**: No wrangler.toml found or parsing failed
|
|
823
|
+
- **Fix**: Ensure wrangler.toml exists and has correct format
|
|
824
|
+
```bash
|
|
825
|
+
wrangler init # Creates basic wrangler.toml
|
|
826
|
+
# or create config/wrangler.toml for environment-specific config
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
### "URL extraction failed"
|
|
830
|
+
- **Cause**: Wrangler output format changed or no valid URL found
|
|
831
|
+
- **Fix**: Check wrangler output manually or ensure routes are defined in wrangler.toml
|
|
832
|
+
|
|
833
|
+
## ๐งช Production Testing Suite
|
|
834
|
+
|
|
835
|
+
The `ProductionTester` provides comprehensive post-deployment validation to ensure your Cloudflare Workers are functioning correctly in downstream environments.
|
|
836
|
+
|
|
837
|
+
### **Core Testing Capabilities**
|
|
838
|
+
|
|
839
|
+
```javascript
|
|
840
|
+
import { ProductionTester } from '@tamyla/clodo-framework/deployment';
|
|
841
|
+
|
|
842
|
+
const tester = new ProductionTester({
|
|
843
|
+
verbose: true,
|
|
844
|
+
generateReport: true,
|
|
845
|
+
exportMetrics: true,
|
|
846
|
+
timeout: 30000,
|
|
847
|
+
responseTimeThreshold: 2000
|
|
848
|
+
});
|
|
849
|
+
|
|
850
|
+
// Run comprehensive production tests
|
|
851
|
+
const results = await tester.runProductionTests('https://your-service.workers.dev', {
|
|
852
|
+
testSuites: ['health', 'authentication', 'endpoints', 'database', 'performance']
|
|
853
|
+
});
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
### **Available Test Suites**
|
|
857
|
+
|
|
858
|
+
#### **Health Checks** ๐ฅ
|
|
859
|
+
- **Endpoint Availability**: Verifies service is responding
|
|
860
|
+
- **Response Time Validation**: Ensures acceptable performance
|
|
861
|
+
- **Status Code Validation**: Confirms proper HTTP responses
|
|
862
|
+
- **Basic Connectivity**: Network reachability testing
|
|
863
|
+
|
|
864
|
+
```javascript
|
|
865
|
+
// Quick health check
|
|
866
|
+
const healthResult = await tester.runProductionTests(baseUrl, {
|
|
867
|
+
testSuites: ['health']
|
|
868
|
+
});
|
|
869
|
+
// Returns: { passed: 2, failed: 0, checks: [...] }
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
#### **Authentication Flow Testing** ๐
|
|
873
|
+
- **JWT Token Validation**: Tests authentication endpoints
|
|
874
|
+
- **API Key Verification**: Validates key-based authentication
|
|
875
|
+
- **Session Management**: Tests login/logout flows
|
|
876
|
+
- **Authorization Checks**: Verifies access control
|
|
877
|
+
|
|
878
|
+
```javascript
|
|
879
|
+
// Test authentication flows
|
|
880
|
+
const authResult = await tester.runProductionTests(baseUrl, {
|
|
881
|
+
testSuites: ['authentication'],
|
|
882
|
+
testUser: {
|
|
883
|
+
email: 'test@example.com',
|
|
884
|
+
password: 'testpass123'
|
|
885
|
+
}
|
|
886
|
+
});
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
#### **API Endpoint Testing** ๐
|
|
890
|
+
- **CRUD Operations**: Tests Create, Read, Update, Delete
|
|
891
|
+
- **Error Handling**: Validates proper error responses
|
|
892
|
+
- **Data Validation**: Ensures API contracts are met
|
|
893
|
+
- **Rate Limiting**: Tests throttling behavior
|
|
894
|
+
|
|
895
|
+
#### **Database Connectivity** ๐๏ธ
|
|
896
|
+
- **D1 Connection**: Validates Cloudflare D1 database access
|
|
897
|
+
- **Query Execution**: Tests SQL operations
|
|
898
|
+
- **Transaction Handling**: Verifies ACID compliance
|
|
899
|
+
- **Connection Pooling**: Tests connection management
|
|
900
|
+
|
|
901
|
+
#### **Performance Monitoring** โก
|
|
902
|
+
- **Response Times**: Measures API latency
|
|
903
|
+
- **Throughput Testing**: Validates concurrent requests
|
|
904
|
+
- **Memory Usage**: Monitors resource consumption
|
|
905
|
+
- **Error Rates**: Tracks failure percentages
|
|
906
|
+
|
|
907
|
+
### **Advanced Testing Features**
|
|
908
|
+
|
|
909
|
+
#### **Custom Test Configuration**
|
|
910
|
+
```javascript
|
|
911
|
+
const tester = new ProductionTester({
|
|
912
|
+
retryAttempts: 3,
|
|
913
|
+
retryDelay: 1000,
|
|
914
|
+
timeout: 30000,
|
|
915
|
+
concurrent: true, // Run tests in parallel
|
|
916
|
+
responseTimeThreshold: 2000, // Max acceptable response time
|
|
917
|
+
healthCheckThreshold: 500, // Health check timeout
|
|
918
|
+
authFlowThreshold: 5000 // Auth flow timeout
|
|
919
|
+
});
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
#### **Environment-Specific Testing**
|
|
923
|
+
```javascript
|
|
924
|
+
// Test different environments
|
|
925
|
+
const prodResults = await tester.runProductionTests('https://api.company.com', {
|
|
926
|
+
environment: 'production'
|
|
927
|
+
});
|
|
928
|
+
|
|
929
|
+
const stagingResults = await tester.runProductionTests('https://staging-api.company.com', {
|
|
930
|
+
environment: 'staging'
|
|
931
|
+
});
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
#### **Regression Testing**
|
|
935
|
+
```javascript
|
|
936
|
+
// Compare against baseline metrics
|
|
937
|
+
const results = await tester.runProductionTests(baseUrl, {
|
|
938
|
+
testSuites: ['regression'],
|
|
939
|
+
baselineMetrics: './test-baselines/production.json'
|
|
940
|
+
});
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
### **Test Result Analysis**
|
|
944
|
+
|
|
945
|
+
#### **Structured Results**
|
|
946
|
+
```javascript
|
|
947
|
+
{
|
|
948
|
+
environment: 'production',
|
|
949
|
+
timestamp: '2025-10-08T10:30:00.000Z',
|
|
950
|
+
tests: {
|
|
951
|
+
health: { passed: 3, failed: 0, checks: [...] },
|
|
952
|
+
authentication: { passed: 5, failed: 1, checks: [...] },
|
|
953
|
+
database: { passed: 4, failed: 0, checks: [...] }
|
|
954
|
+
},
|
|
955
|
+
summary: {
|
|
956
|
+
passed: 12,
|
|
957
|
+
failed: 1,
|
|
958
|
+
total: 13,
|
|
959
|
+
successRate: 92.3
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
#### **Report Generation**
|
|
965
|
+
```javascript
|
|
966
|
+
const tester = new ProductionTester({
|
|
967
|
+
generateReport: true,
|
|
968
|
+
exportMetrics: true,
|
|
969
|
+
reportPath: './test-reports',
|
|
970
|
+
metricsPath: './test-metrics'
|
|
971
|
+
});
|
|
972
|
+
|
|
973
|
+
// Generates:
|
|
974
|
+
// - test-reports/production-2025-10-08.json
|
|
975
|
+
// - test-metrics/performance-trends.csv
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
### **Integration with Deployment Pipeline**
|
|
979
|
+
|
|
980
|
+
```javascript
|
|
981
|
+
// Post-deployment validation
|
|
982
|
+
const deployAndTest = async (serviceConfig) => {
|
|
983
|
+
// Deploy the service
|
|
984
|
+
const deployment = await deployer.deploy(serviceConfig);
|
|
985
|
+
|
|
986
|
+
// Run production tests
|
|
987
|
+
const testResults = await tester.runProductionTests(deployment.url, {
|
|
988
|
+
testSuites: ['health', 'authentication', 'endpoints']
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
// Validate results
|
|
992
|
+
if (testResults.summary.failed > 0) {
|
|
993
|
+
console.error('โ Deployment validation failed');
|
|
994
|
+
// Trigger rollback or alert
|
|
995
|
+
await rollbackManager.rollback(deployment.id);
|
|
996
|
+
return { success: false, issues: testResults };
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
return { success: true, deployment, tests: testResults };
|
|
1000
|
+
};
|
|
1001
|
+
```
|
|
1002
|
+
|
|
1003
|
+
### **Third-Party Environment Testing**
|
|
1004
|
+
|
|
1005
|
+
The ProductionTester works seamlessly in any Cloudflare account:
|
|
1006
|
+
|
|
1007
|
+
```javascript
|
|
1008
|
+
// Test service in customer environment
|
|
1009
|
+
const customerTest = await tester.runProductionTests(
|
|
1010
|
+
'https://customer-service.workers.dev',
|
|
1011
|
+
{
|
|
1012
|
+
testSuites: ['health', 'database'],
|
|
1013
|
+
// Uses customer's API keys/tokens from environment
|
|
1014
|
+
apiToken: process.env.CUSTOMER_CLOUDFLARE_TOKEN
|
|
1015
|
+
}
|
|
1016
|
+
);
|
|
1017
|
+
```
|
|
1018
|
+
|
|
1019
|
+
## ๏ฟฝ Individual Testing Modules
|
|
1020
|
+
|
|
1021
|
+
For more granular control, you can import and use individual testing modules instead of the monolithic ProductionTester:
|
|
1022
|
+
|
|
1023
|
+
### **API Testing Only**
|
|
1024
|
+
```javascript
|
|
1025
|
+
import { ApiTester } from '@tamyla/clodo-framework/deployment/testers';
|
|
1026
|
+
|
|
1027
|
+
const apiTester = new ApiTester({
|
|
1028
|
+
timeout: 5000,
|
|
1029
|
+
responseTimeThreshold: 1000
|
|
1030
|
+
});
|
|
1031
|
+
|
|
1032
|
+
const results = await apiTester.runApiTests('production');
|
|
1033
|
+
// Tests only API endpoints, not auth or database
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
### **Authentication Testing Only**
|
|
1037
|
+
```javascript
|
|
1038
|
+
import { AuthTester } from '@tamyla/clodo-framework/deployment/testers';
|
|
1039
|
+
|
|
1040
|
+
const authTester = new AuthTester({
|
|
1041
|
+
timeout: 10000
|
|
1042
|
+
});
|
|
1043
|
+
|
|
1044
|
+
const results = await authTester.runAuthTests('https://api.company.com', {
|
|
1045
|
+
testUser: { email: 'test@example.com', password: 'test123' }
|
|
1046
|
+
});
|
|
1047
|
+
// Tests only authentication flows
|
|
1048
|
+
```
|
|
1049
|
+
|
|
1050
|
+
### **Database Testing Only**
|
|
1051
|
+
```javascript
|
|
1052
|
+
import { DatabaseTester } from '@tamyla/clodo-framework/deployment/testers';
|
|
1053
|
+
|
|
1054
|
+
const dbTester = new DatabaseTester({
|
|
1055
|
+
timeout: 30000
|
|
1056
|
+
});
|
|
1057
|
+
|
|
1058
|
+
const results = await dbTester.runDatabaseTests('production');
|
|
1059
|
+
// Tests only D1 database connectivity and queries
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
### **Performance Testing Only**
|
|
1063
|
+
```javascript
|
|
1064
|
+
import { PerformanceTester } from '@tamyla/clodo-framework/deployment/testers';
|
|
1065
|
+
|
|
1066
|
+
const perfTester = new PerformanceTester({
|
|
1067
|
+
responseTimeThreshold: 500,
|
|
1068
|
+
concurrentRequests: 10
|
|
1069
|
+
});
|
|
1070
|
+
|
|
1071
|
+
const results = await perfTester.runPerformanceTests('https://api.company.com');
|
|
1072
|
+
// Tests only performance metrics and response times
|
|
1073
|
+
```
|
|
1074
|
+
|
|
1075
|
+
### **Load Testing Only**
|
|
1076
|
+
```javascript
|
|
1077
|
+
import { LoadTester } from '@tamyla/clodo-framework/deployment/testers';
|
|
1078
|
+
|
|
1079
|
+
const loadTester = new LoadTester({
|
|
1080
|
+
maxConcurrentUsers: 100,
|
|
1081
|
+
testDuration: 60000, // 1 minute
|
|
1082
|
+
rampUpTime: 10000 // 10 seconds
|
|
1083
|
+
});
|
|
1084
|
+
|
|
1085
|
+
const results = await loadTester.runLoadTests('https://api.company.com');
|
|
1086
|
+
// Tests only load handling and scalability
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1089
|
+
### **Custom Testing Combinations**
|
|
1090
|
+
```javascript
|
|
1091
|
+
import { ApiTester, AuthTester, DatabaseTester } from '@tamyla/clodo-framework/deployment/testers';
|
|
1092
|
+
|
|
1093
|
+
// Run only the tests you need
|
|
1094
|
+
const apiResults = await new ApiTester().runApiTests('production');
|
|
1095
|
+
const authResults = await new AuthTester().runAuthTests(baseUrl, testUser);
|
|
1096
|
+
const dbResults = await new DatabaseTester().runDatabaseTests('production');
|
|
1097
|
+
|
|
1098
|
+
// Combine results as needed
|
|
1099
|
+
const combinedResults = {
|
|
1100
|
+
api: apiResults,
|
|
1101
|
+
auth: authResults,
|
|
1102
|
+
database: dbResults,
|
|
1103
|
+
summary: {
|
|
1104
|
+
passed: apiResults.passed + authResults.passed + dbResults.passed,
|
|
1105
|
+
failed: apiResults.failed + authResults.failed + dbResults.failed
|
|
1106
|
+
}
|
|
1107
|
+
};
|
|
1108
|
+
```
|
|
1109
|
+
|
|
1110
|
+
## ๏ฟฝ๐ Deployment Validator
|
|
1111
|
+
|
|
1112
|
+
The `DeploymentValidator` provides enterprise-grade pre-deployment validation to ensure your services are ready for production deployment and can operate correctly in downstream environments.
|
|
1113
|
+
|
|
1114
|
+
### **Comprehensive Validation Pipeline**
|
|
1115
|
+
|
|
1116
|
+
```javascript
|
|
1117
|
+
import { DeploymentValidator } from '@tamyla/clodo-framework/deployment';
|
|
1118
|
+
|
|
1119
|
+
const validator = new DeploymentValidator({
|
|
1120
|
+
validationLevel: 'comprehensive',
|
|
1121
|
+
strictMode: true,
|
|
1122
|
+
timeout: 30000,
|
|
1123
|
+
retryAttempts: 3
|
|
1124
|
+
});
|
|
1125
|
+
|
|
1126
|
+
// Validate deployment readiness
|
|
1127
|
+
const result = await validator.validateDeployment(['your-service.com'], {
|
|
1128
|
+
environment: 'production'
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
if (!result.valid) {
|
|
1132
|
+
console.error('โ Validation failed:', result.errors);
|
|
1133
|
+
// Involves developer to fix issues
|
|
1134
|
+
}
|
|
1135
|
+
```
|
|
1136
|
+
|
|
1137
|
+
### **Validation Categories**
|
|
1138
|
+
|
|
1139
|
+
#### **Prerequisites Validation** ๐
|
|
1140
|
+
- **Node.js Version**: Ensures compatible Node.js version (16+)
|
|
1141
|
+
- **Required Commands**: Validates wrangler, npm, node availability
|
|
1142
|
+
- **File System**: Checks for required files (package.json, wrangler.toml)
|
|
1143
|
+
- **Permissions**: Verifies file/directory access permissions
|
|
1144
|
+
|
|
1145
|
+
#### **Authentication Validation** ๐
|
|
1146
|
+
- **Cloudflare Tokens**: Validates API token presence and format
|
|
1147
|
+
- **Account Access**: Verifies account permissions and access
|
|
1148
|
+
- **Token Expiration**: Checks for expired credentials
|
|
1149
|
+
- **Multi-Account Support**: Handles different accounts per environment
|
|
1150
|
+
|
|
1151
|
+
#### **Network Validation** ๐
|
|
1152
|
+
- **Cloudflare API**: Tests connectivity to Cloudflare services
|
|
1153
|
+
- **DNS Resolution**: Validates domain name resolution
|
|
1154
|
+
- **SSL/TLS**: Checks certificate validity and configuration
|
|
1155
|
+
- **Firewall Rules**: Verifies network access rules
|
|
1156
|
+
|
|
1157
|
+
#### **Configuration Validation** โ๏ธ
|
|
1158
|
+
- **Environment Variables**: Validates required env vars
|
|
1159
|
+
- **Wrangler Config**: Checks wrangler.toml syntax and settings
|
|
1160
|
+
- **Domain Configuration**: Verifies domain-to-service mapping
|
|
1161
|
+
- **Feature Flags**: Validates feature flag configurations
|
|
1162
|
+
|
|
1163
|
+
#### **Endpoint Validation** ๐ฏ
|
|
1164
|
+
- **Service URLs**: Tests endpoint accessibility
|
|
1165
|
+
- **HTTP Methods**: Validates supported operations
|
|
1166
|
+
- **Response Formats**: Checks API response structure
|
|
1167
|
+
- **CORS Settings**: Verifies cross-origin configurations
|
|
1168
|
+
|
|
1169
|
+
#### **Deployment Readiness** ๐
|
|
1170
|
+
- **Build Process**: Validates build pipeline success
|
|
1171
|
+
- **Disk Space**: Checks available storage for deployment
|
|
1172
|
+
- **Memory Usage**: Monitors resource consumption
|
|
1173
|
+
- **Dependency Checks**: Verifies all dependencies are available
|
|
1174
|
+
|
|
1175
|
+
### **Interactive Developer Involvement**
|
|
1176
|
+
|
|
1177
|
+
When validation issues are detected, the framework **actively involves developers** to resolve problems:
|
|
1178
|
+
|
|
1179
|
+
```javascript
|
|
1180
|
+
// Automatic issue detection and resolution guidance
|
|
1181
|
+
const result = await validator.validateDeploymentReadiness();
|
|
1182
|
+
|
|
1183
|
+
if (!result.valid) {
|
|
1184
|
+
// Framework provides specific guidance
|
|
1185
|
+
for (const issue of result.issues) {
|
|
1186
|
+
console.log(`โ ${issue.category}: ${issue.message}`);
|
|
1187
|
+
console.log(`๐ก Fix: ${issue.suggestion}`);
|
|
1188
|
+
|
|
1189
|
+
// For critical issues, prompt for immediate resolution
|
|
1190
|
+
if (issue.severity === 'critical') {
|
|
1191
|
+
const fix = await promptUser(`How would you like to fix: ${issue.message}?`);
|
|
1192
|
+
await applyFix(issue, fix);
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
```
|
|
1197
|
+
|
|
1198
|
+
#### **Common Validation Issues & Fixes**
|
|
1199
|
+
|
|
1200
|
+
##### **Authentication Issues**
|
|
1201
|
+
```javascript
|
|
1202
|
+
// Issue: "Cloudflare authentication required"
|
|
1203
|
+
const authChoice = await askChoice(
|
|
1204
|
+
'Cloudflare authentication needed. What would you like to do?',
|
|
1205
|
+
[
|
|
1206
|
+
'Login to Cloudflare now',
|
|
1207
|
+
'Provide API token manually',
|
|
1208
|
+
'Skip Cloudflare verification (limited features)',
|
|
1209
|
+
'Cancel deployment'
|
|
1210
|
+
]
|
|
1211
|
+
);
|
|
1212
|
+
|
|
1213
|
+
// Framework guides through resolution
|
|
1214
|
+
if (authChoice === 0) {
|
|
1215
|
+
await runCommand('wrangler login');
|
|
1216
|
+
await validator.revalidateAuthentication();
|
|
1217
|
+
}
|
|
1218
|
+
```
|
|
1219
|
+
|
|
1220
|
+
##### **Configuration Issues**
|
|
1221
|
+
```javascript
|
|
1222
|
+
// Issue: "Missing required environment variables"
|
|
1223
|
+
// Framework identifies missing vars and suggests fixes
|
|
1224
|
+
const missing = ['CLOUDFLARE_API_TOKEN', 'DATABASE_URL'];
|
|
1225
|
+
console.log('Missing environment variables:');
|
|
1226
|
+
missing.forEach(var => console.log(` - ${var}`));
|
|
1227
|
+
|
|
1228
|
+
// Interactive resolution
|
|
1229
|
+
for (const var of missing) {
|
|
1230
|
+
const value = await askUser(`Enter value for ${var}:`);
|
|
1231
|
+
await setEnvironmentVariable(var, value);
|
|
1232
|
+
}
|
|
1233
|
+
```
|
|
1234
|
+
|
|
1235
|
+
##### **Network Issues**
|
|
1236
|
+
```javascript
|
|
1237
|
+
// Issue: "Cannot reach Cloudflare API"
|
|
1238
|
+
// Framework tests connectivity and provides diagnostics
|
|
1239
|
+
const networkTest = await validator.testNetworkConnectivity();
|
|
1240
|
+
if (!networkTest.cloudflare) {
|
|
1241
|
+
console.log('โ Cannot reach Cloudflare API');
|
|
1242
|
+
console.log('๐ก Check your internet connection and firewall settings');
|
|
1243
|
+
console.log('๐ก Verify API token permissions');
|
|
1244
|
+
}
|
|
1245
|
+
```
|
|
1246
|
+
|
|
1247
|
+
### **Third-Party Environment Validation**
|
|
1248
|
+
|
|
1249
|
+
The DeploymentValidator works across different Cloudflare accounts and environments:
|
|
1250
|
+
|
|
1251
|
+
```javascript
|
|
1252
|
+
// Validate deployment in customer environment
|
|
1253
|
+
const customerValidation = await validator.validateDeployment(
|
|
1254
|
+
['customer-service.com'],
|
|
1255
|
+
{
|
|
1256
|
+
environment: 'production',
|
|
1257
|
+
accountId: 'customer-account-id',
|
|
1258
|
+
apiToken: process.env.CUSTOMER_CLOUDFLARE_TOKEN
|
|
1259
|
+
}
|
|
1260
|
+
);
|
|
1261
|
+
|
|
1262
|
+
// Cross-account validation
|
|
1263
|
+
const multiAccountResult = await validator.validateMultiAccountDeployment([
|
|
1264
|
+
{ domain: 'service1.company.com', accountId: 'account1' },
|
|
1265
|
+
{ domain: 'service2.company.com', accountId: 'account2' }
|
|
1266
|
+
]);
|
|
1267
|
+
```
|
|
1268
|
+
|
|
1269
|
+
### **Integration with CI/CD Pipelines**
|
|
1270
|
+
|
|
1271
|
+
```javascript
|
|
1272
|
+
// Pre-deployment validation in CI/CD
|
|
1273
|
+
const validateBeforeDeploy = async () => {
|
|
1274
|
+
console.log('๐ Starting pre-deployment validation...');
|
|
1275
|
+
|
|
1276
|
+
const validator = new DeploymentValidator({
|
|
1277
|
+
validationLevel: 'comprehensive',
|
|
1278
|
+
strictMode: true
|
|
1279
|
+
});
|
|
1280
|
+
|
|
1281
|
+
try {
|
|
1282
|
+
const result = await validator.validateDeploymentReadiness();
|
|
1283
|
+
|
|
1284
|
+
if (!result.valid) {
|
|
1285
|
+
console.error('โ Validation failed - blocking deployment');
|
|
1286
|
+
result.issues.forEach(issue => {
|
|
1287
|
+
console.error(` ${issue.severity.toUpperCase()}: ${issue.message}`);
|
|
1288
|
+
});
|
|
1289
|
+
process.exit(1);
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
console.log('โ
All validations passed - proceeding with deployment');
|
|
1293
|
+
return true;
|
|
1294
|
+
|
|
1295
|
+
} catch (error) {
|
|
1296
|
+
console.error('๐ฅ Validation error:', error.message);
|
|
1297
|
+
process.exit(1);
|
|
1298
|
+
}
|
|
1299
|
+
};
|
|
1300
|
+
```
|
|
1301
|
+
|
|
1302
|
+
### **Advanced Validation Features**
|
|
1303
|
+
|
|
1304
|
+
#### **Custom Validation Rules**
|
|
1305
|
+
```javascript
|
|
1306
|
+
class CustomValidator extends DeploymentValidator {
|
|
1307
|
+
async validateCustomRules() {
|
|
1308
|
+
// Add organization-specific validation
|
|
1309
|
+
const customChecks = [
|
|
1310
|
+
this.validateSecurityCompliance(),
|
|
1311
|
+
this.validatePerformanceRequirements(),
|
|
1312
|
+
this.validateBusinessRules()
|
|
1313
|
+
];
|
|
1314
|
+
|
|
1315
|
+
return await Promise.all(customChecks);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
```
|
|
1319
|
+
|
|
1320
|
+
#### **Validation Result Analysis**
|
|
1321
|
+
```javascript
|
|
1322
|
+
{
|
|
1323
|
+
overall: 'passed|failed',
|
|
1324
|
+
categories: {
|
|
1325
|
+
prerequisites: 'passed',
|
|
1326
|
+
authentication: 'passed',
|
|
1327
|
+
network: 'failed',
|
|
1328
|
+
configuration: 'passed',
|
|
1329
|
+
endpoints: 'passed',
|
|
1330
|
+
deployment: 'passed'
|
|
1331
|
+
},
|
|
1332
|
+
details: [
|
|
1333
|
+
{
|
|
1334
|
+
category: 'network',
|
|
1335
|
+
severity: 'error',
|
|
1336
|
+
message: 'Cannot reach Cloudflare API',
|
|
1337
|
+
suggestion: 'Check internet connection and API token'
|
|
1338
|
+
}
|
|
1339
|
+
],
|
|
1340
|
+
startTime: '2025-10-08T10:00:00.000Z',
|
|
1341
|
+
endTime: '2025-10-08T10:02:30.000Z'
|
|
1342
|
+
}
|
|
1343
|
+
```
|
|
1344
|
+
|
|
1345
|
+
#### **Validation Reporting**
|
|
1346
|
+
```javascript
|
|
1347
|
+
const validator = new DeploymentValidator({
|
|
1348
|
+
generateReport: true,
|
|
1349
|
+
reportPath: './validation-reports'
|
|
1350
|
+
});
|
|
1351
|
+
|
|
1352
|
+
// Generates detailed validation reports
|
|
1353
|
+
const result = await validator.validateDeployment(domains, options);
|
|
1354
|
+
// Creates: validation-reports/deployment-2025-10-08.json
|
|
1355
|
+
```
|
|
1356
|
+
|
|
1357
|
+
## โ๏ธ Cloudflare Account Management
|
|
1358
|
+
|
|
1359
|
+
The `CloudflareDomainManager` enables seamless operation across multiple Cloudflare accounts and environments, making it perfect for third-party downstream deployments and multi-tenant architectures.
|
|
1360
|
+
|
|
1361
|
+
### **Multi-Account Operations**
|
|
1362
|
+
|
|
1363
|
+
```javascript
|
|
1364
|
+
import { CloudflareDomainManager } from '@tamyla/clodo-framework/deployment';
|
|
1365
|
+
|
|
1366
|
+
const manager = new CloudflareDomainManager({
|
|
1367
|
+
apiToken: process.env.CLOUDFLARE_API_TOKEN,
|
|
1368
|
+
accountId: process.env.CLOUDFLARE_ACCOUNT_ID
|
|
1369
|
+
});
|
|
1370
|
+
|
|
1371
|
+
// Verify authentication across accounts
|
|
1372
|
+
await manager.verifyAuthentication();
|
|
1373
|
+
|
|
1374
|
+
// Discover available domains in any account
|
|
1375
|
+
const domains = await manager.discoverDomains();
|
|
1376
|
+
|
|
1377
|
+
// Validate deployment permissions
|
|
1378
|
+
const canDeploy = await manager.validateDeploymentPermissions('customer-service.com');
|
|
1379
|
+
```
|
|
1380
|
+
|
|
1381
|
+
### **Authentication Handling**
|
|
1382
|
+
|
|
1383
|
+
#### **Interactive Authentication Resolution**
|
|
1384
|
+
```javascript
|
|
1385
|
+
// When authentication issues occur, framework involves developer
|
|
1386
|
+
async handleAuthenticationRequired() {
|
|
1387
|
+
console.log(' โ Cloudflare authentication required');
|
|
1388
|
+
|
|
1389
|
+
const authChoice = await askChoice(
|
|
1390
|
+
'Cloudflare authentication needed. What would you like to do?',
|
|
1391
|
+
[
|
|
1392
|
+
'Login to Cloudflare now',
|
|
1393
|
+
'Provide API token manually',
|
|
1394
|
+
'Skip Cloudflare verification (limited features)',
|
|
1395
|
+
'Cancel deployment'
|
|
1396
|
+
]
|
|
1397
|
+
);
|
|
1398
|
+
|
|
1399
|
+
switch (authChoice) {
|
|
1400
|
+
case 0:
|
|
1401
|
+
// Guide developer through wrangler login
|
|
1402
|
+
await runCommand('wrangler login');
|
|
1403
|
+
await this.verifyAuthentication();
|
|
1404
|
+
break;
|
|
1405
|
+
case 1:
|
|
1406
|
+
// Prompt for manual token entry
|
|
1407
|
+
const token = await askUser('Enter Cloudflare API token:');
|
|
1408
|
+
await this.setApiToken(token);
|
|
1409
|
+
break;
|
|
1410
|
+
case 2:
|
|
1411
|
+
// Limited functionality mode
|
|
1412
|
+
console.log('โ ๏ธ Skipping Cloudflare features - limited functionality');
|
|
1413
|
+
break;
|
|
1414
|
+
default:
|
|
1415
|
+
throw new Error('Authentication cancelled by user');
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
```
|
|
1419
|
+
|
|
1420
|
+
#### **Token Management**
|
|
1421
|
+
```javascript
|
|
1422
|
+
// Secure token storage and validation
|
|
1423
|
+
const tokenManager = new CloudflareTokenManager();
|
|
1424
|
+
|
|
1425
|
+
// Store tokens securely
|
|
1426
|
+
await tokenManager.storeToken('production', apiToken);
|
|
1427
|
+
|
|
1428
|
+
// Validate token permissions
|
|
1429
|
+
const permissions = await tokenManager.validatePermissions(apiToken);
|
|
1430
|
+
|
|
1431
|
+
// Check token expiration
|
|
1432
|
+
const isValid = await tokenManager.isTokenValid(apiToken);
|
|
1433
|
+
```
|
|
1434
|
+
|
|
1435
|
+
### **Domain Discovery & Management**
|
|
1436
|
+
|
|
1437
|
+
#### **Automatic Domain Discovery**
|
|
1438
|
+
```javascript
|
|
1439
|
+
// Discover all domains in an account
|
|
1440
|
+
const discovery = await manager.discoverDomains();
|
|
1441
|
+
|
|
1442
|
+
// Returns structured domain information
|
|
1443
|
+
{
|
|
1444
|
+
accountId: 'account-123',
|
|
1445
|
+
domains: [
|
|
1446
|
+
{
|
|
1447
|
+
name: 'api.company.com',
|
|
1448
|
+
zoneId: 'zone-456',
|
|
1449
|
+
status: 'active',
|
|
1450
|
+
sslStatus: 'active',
|
|
1451
|
+
nameservers: ['ns1.cloudflare.com', 'ns2.cloudflare.com']
|
|
1452
|
+
}
|
|
1453
|
+
],
|
|
1454
|
+
workers: [
|
|
1455
|
+
{
|
|
1456
|
+
name: 'data-service',
|
|
1457
|
+
routes: ['api.company.com/api/*'],
|
|
1458
|
+
environment: 'production'
|
|
1459
|
+
}
|
|
1460
|
+
]
|
|
1461
|
+
}
|
|
1462
|
+
```
|
|
1463
|
+
|
|
1464
|
+
#### **Service Matching & Discovery**
|
|
1465
|
+
```javascript
|
|
1466
|
+
// Find existing services by domain
|
|
1467
|
+
const existingServices = await manager.findServicesByDomain('api.company.com');
|
|
1468
|
+
|
|
1469
|
+
// Intelligent service discovery
|
|
1470
|
+
const serviceMatch = await manager.matchServiceToDomain({
|
|
1471
|
+
domain: 'new-service.company.com',
|
|
1472
|
+
serviceName: 'data-service'
|
|
1473
|
+
});
|
|
1474
|
+
```
|
|
1475
|
+
|
|
1476
|
+
### **Third-Party Account Operations**
|
|
1477
|
+
|
|
1478
|
+
#### **Cross-Account Deployment**
|
|
1479
|
+
```javascript
|
|
1480
|
+
// Deploy to customer account
|
|
1481
|
+
const customerManager = new CloudflareDomainManager({
|
|
1482
|
+
apiToken: process.env.CUSTOMER_CLOUDFLARE_TOKEN,
|
|
1483
|
+
accountId: process.env.CUSTOMER_ACCOUNT_ID
|
|
1484
|
+
});
|
|
1485
|
+
|
|
1486
|
+
// Validate customer environment
|
|
1487
|
+
await customerManager.verifyAuthentication();
|
|
1488
|
+
await customerManager.validateDeploymentPermissions('customer-service.com');
|
|
1489
|
+
|
|
1490
|
+
// Deploy service to customer account
|
|
1491
|
+
const deployment = await customerManager.deployService({
|
|
1492
|
+
serviceName: 'data-service',
|
|
1493
|
+
domain: 'customer-service.com',
|
|
1494
|
+
environment: 'production'
|
|
1495
|
+
});
|
|
1496
|
+
```
|
|
1497
|
+
|
|
1498
|
+
#### **Multi-Tenant Deployments**
|
|
1499
|
+
```javascript
|
|
1500
|
+
// Deploy across multiple customer accounts
|
|
1501
|
+
const multiTenantDeployment = async (customers) => {
|
|
1502
|
+
const results = [];
|
|
1503
|
+
|
|
1504
|
+
for (const customer of customers) {
|
|
1505
|
+
const manager = new CloudflareDomainManager({
|
|
1506
|
+
apiToken: customer.apiToken,
|
|
1507
|
+
accountId: customer.accountId
|
|
1508
|
+
});
|
|
1509
|
+
|
|
1510
|
+
try {
|
|
1511
|
+
// Verify customer account access
|
|
1512
|
+
await manager.verifyAuthentication();
|
|
1513
|
+
|
|
1514
|
+
// Deploy service to customer environment
|
|
1515
|
+
const result = await manager.deployService({
|
|
1516
|
+
serviceName: 'shared-service',
|
|
1517
|
+
domain: customer.domain,
|
|
1518
|
+
environment: 'production'
|
|
1519
|
+
});
|
|
1520
|
+
|
|
1521
|
+
results.push({ customer: customer.name, success: true, result });
|
|
1522
|
+
|
|
1523
|
+
} catch (error) {
|
|
1524
|
+
results.push({
|
|
1525
|
+
customer: customer.name,
|
|
1526
|
+
success: false,
|
|
1527
|
+
error: error.message
|
|
1528
|
+
});
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
return results;
|
|
1533
|
+
};
|
|
1534
|
+
```
|
|
1535
|
+
|
|
1536
|
+
### **Permission & Access Control**
|
|
1537
|
+
|
|
1538
|
+
#### **Deployment Permission Validation**
|
|
1539
|
+
```javascript
|
|
1540
|
+
// Comprehensive permission checking
|
|
1541
|
+
const permissions = await manager.validateDeploymentPermissions('service.domain.com');
|
|
1542
|
+
|
|
1543
|
+
// Checks for:
|
|
1544
|
+
// - Account ownership of domain
|
|
1545
|
+
// - Worker deployment permissions
|
|
1546
|
+
// - Zone/DNS management access
|
|
1547
|
+
// - SSL certificate permissions
|
|
1548
|
+
// - API token scope validation
|
|
1549
|
+
|
|
1550
|
+
if (!permissions.canDeploy) {
|
|
1551
|
+
console.error('โ Insufficient permissions for deployment');
|
|
1552
|
+
permissions.missing.forEach(perm => {
|
|
1553
|
+
console.log(` Missing: ${perm}`);
|
|
1554
|
+
});
|
|
1555
|
+
}
|
|
1556
|
+
```
|
|
1557
|
+
|
|
1558
|
+
#### **Environment-Specific Permissions**
|
|
1559
|
+
```javascript
|
|
1560
|
+
// Validate permissions per environment
|
|
1561
|
+
const envPermissions = await manager.validateEnvironmentPermissions({
|
|
1562
|
+
domain: 'service.domain.com',
|
|
1563
|
+
environment: 'production'
|
|
1564
|
+
});
|
|
1565
|
+
|
|
1566
|
+
// Production environment requires stricter permissions
|
|
1567
|
+
if (envPermissions.production) {
|
|
1568
|
+
console.log('โ
Production deployment authorized');
|
|
1569
|
+
} else {
|
|
1570
|
+
console.log('โ Production deployment not authorized');
|
|
1571
|
+
console.log('Required permissions:', envPermissions.required);
|
|
1572
|
+
}
|
|
1573
|
+
```
|
|
1574
|
+
|
|
1575
|
+
### **Integration with Orchestration**
|
|
1576
|
+
|
|
1577
|
+
#### **Multi-Domain Coordination**
|
|
1578
|
+
```javascript
|
|
1579
|
+
import { MultiDomainOrchestrator } from '@tamyla/clodo-framework/deployment';
|
|
1580
|
+
|
|
1581
|
+
const orchestrator = new MultiDomainOrchestrator({
|
|
1582
|
+
maxConcurrentDeployments: 3,
|
|
1583
|
+
crossDomainCoordination: true
|
|
1584
|
+
});
|
|
1585
|
+
|
|
1586
|
+
// Coordinate deployments across accounts
|
|
1587
|
+
await orchestrator.deployMultipleDomains([
|
|
1588
|
+
{
|
|
1589
|
+
domain: 'service1.company.com',
|
|
1590
|
+
accountId: 'account-1',
|
|
1591
|
+
apiToken: 'token-1'
|
|
1592
|
+
},
|
|
1593
|
+
{
|
|
1594
|
+
domain: 'service2.customer.com',
|
|
1595
|
+
accountId: 'account-2',
|
|
1596
|
+
apiToken: 'token-2'
|
|
1597
|
+
}
|
|
1598
|
+
]);
|
|
1599
|
+
```
|
|
1600
|
+
|
|
1601
|
+
#### **Account-Aware Rollback**
|
|
1602
|
+
```javascript
|
|
1603
|
+
// Rollback with account context
|
|
1604
|
+
const rollbackManager = new RollbackManager();
|
|
1605
|
+
|
|
1606
|
+
await rollbackManager.rollbackDeployment(deploymentId, {
|
|
1607
|
+
accountId: targetAccountId,
|
|
1608
|
+
apiToken: accountToken,
|
|
1609
|
+
preserveCustomerData: true // Don't affect customer data
|
|
1610
|
+
});
|
|
1611
|
+
```
|
|
1612
|
+
|
|
1613
|
+
### **Security & Compliance**
|
|
1614
|
+
|
|
1615
|
+
#### **Account Isolation**
|
|
1616
|
+
```javascript
|
|
1617
|
+
// Ensure proper account isolation
|
|
1618
|
+
const isolationCheck = await manager.validateAccountIsolation({
|
|
1619
|
+
sourceAccount: 'your-account',
|
|
1620
|
+
targetAccount: 'customer-account'
|
|
1621
|
+
});
|
|
1622
|
+
|
|
1623
|
+
if (!isolationCheck.isolated) {
|
|
1624
|
+
throw new Error('Account isolation violation detected');
|
|
1625
|
+
}
|
|
1626
|
+
```
|
|
1627
|
+
|
|
1628
|
+
#### **Audit Logging**
|
|
1629
|
+
```javascript
|
|
1630
|
+
// Comprehensive audit trails
|
|
1631
|
+
const auditor = new DeploymentAuditor({
|
|
1632
|
+
auditLevel: 'detailed'
|
|
1633
|
+
});
|
|
1634
|
+
|
|
1635
|
+
await auditor.logAccountOperation({
|
|
1636
|
+
operation: 'deploy',
|
|
1637
|
+
accountId: targetAccountId,
|
|
1638
|
+
domain: deployedDomain,
|
|
1639
|
+
timestamp: new Date(),
|
|
1640
|
+
operator: process.env.USER,
|
|
1641
|
+
permissions: validatedPermissions
|
|
1642
|
+
});
|
|
1643
|
+
```
|
|
1644
|
+
|
|
1645
|
+
## ๐๏ธ Adopting CLODO Framework in Existing Projects
|
|
1646
|
+
|
|
1647
|
+
Most developers have existing codebases and want to **gradually integrate** the CLODO Framework rather than starting from scratch. This section covers **incremental adoption strategies** for brownfield projects.
|
|
1648
|
+
|
|
1649
|
+
### ๐ฏ Understanding Incremental Adoption
|
|
1650
|
+
|
|
1651
|
+
The CLODO Framework is designed for **modular adoption** - you can start with individual components and progressively adopt more features:
|
|
1652
|
+
|
|
1653
|
+
```mermaid
|
|
1654
|
+
graph LR
|
|
1655
|
+
A[Existing Service] --> B[Add Core Utilities]
|
|
1656
|
+
B --> C[Configuration Management]
|
|
1657
|
+
C --> D[Schema Validation]
|
|
1658
|
+
D --> E[Deployment & Security]
|
|
1659
|
+
E --> F[Full Framework Integration]
|
|
1660
|
+
```
|
|
1661
|
+
|
|
1662
|
+
### ๐ฆ Phase 1: Core Utilities (Lowest Risk)
|
|
1663
|
+
|
|
1664
|
+
**Start with error handling, logging, and basic utilities:**
|
|
1665
|
+
|
|
1666
|
+
```javascript
|
|
1667
|
+
// Your existing service
|
|
1668
|
+
import express from 'express';
|
|
1669
|
+
const app = express();
|
|
1670
|
+
|
|
1671
|
+
// Add CLODO error handling (no breaking changes)
|
|
1672
|
+
import { ErrorHandler } from '@tamyla/clodo-framework';
|
|
1673
|
+
|
|
1674
|
+
app.use((err, req, res, next) => {
|
|
1675
|
+
ErrorHandler.handleDeploymentError(err, {
|
|
1676
|
+
customer: 'my-company',
|
|
1677
|
+
environment: process.env.NODE_ENV,
|
|
1678
|
+
phase: 'api'
|
|
1679
|
+
});
|
|
1680
|
+
// Your existing error handling continues...
|
|
1681
|
+
});
|
|
1682
|
+
```
|
|
1683
|
+
|
|
1684
|
+
**Benefits:**
|
|
1685
|
+
- โ
Zero breaking changes to existing code
|
|
1686
|
+
- โ
Immediate improvement in error reporting
|
|
1687
|
+
- โ
Easy rollback if needed
|
|
1688
|
+
|
|
1689
|
+
### ๐ง Phase 2: Data Service Integration
|
|
1690
|
+
|
|
1691
|
+
**Wrap existing database operations with CLODO components:**
|
|
1692
|
+
|
|
1693
|
+
```javascript
|
|
1694
|
+
// Before: Direct database calls
|
|
1695
|
+
class MyDataService {
|
|
1696
|
+
async getUsers() {
|
|
1697
|
+
return db.query('SELECT * FROM users');
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
// After: CLODO-wrapped with validation
|
|
1702
|
+
import { GenericDataService, SchemaManager } from '@tamyla/clodo-framework';
|
|
1703
|
+
|
|
1704
|
+
class EnhancedDataService extends GenericDataService {
|
|
1705
|
+
constructor(existingDb) {
|
|
1706
|
+
super({ d1Database: existingDb });
|
|
1707
|
+
this.existing = existingDb;
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
async getUsers(query = {}) {
|
|
1711
|
+
// CLODO validation + your existing logic
|
|
1712
|
+
const validatedQuery = this.validateQuery(query);
|
|
1713
|
+
return this.existing.query('SELECT * FROM users WHERE ?', validatedQuery);
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
```
|
|
1717
|
+
|
|
1718
|
+
### โ๏ธ Phase 3: Configuration Management
|
|
1719
|
+
|
|
1720
|
+
**Replace hardcoded configurations with CLODO's system:**
|
|
1721
|
+
|
|
1722
|
+
```javascript
|
|
1723
|
+
// Before: Hardcoded configuration
|
|
1724
|
+
const config = {
|
|
1725
|
+
apiVersion: 'v1',
|
|
1726
|
+
corsOrigins: ['https://myapp.com'],
|
|
1727
|
+
databaseUrl: process.env.DATABASE_URL
|
|
1728
|
+
};
|
|
1729
|
+
|
|
1730
|
+
// After: CLODO domain configuration
|
|
1731
|
+
import { createDomainConfigSchema } from '@tamyla/clodo-framework';
|
|
1732
|
+
|
|
1733
|
+
export const domains = {
|
|
1734
|
+
'my-existing-api': {
|
|
1735
|
+
...createDomainConfigSchema(),
|
|
1736
|
+
name: 'my-existing-api',
|
|
1737
|
+
displayName: 'My Existing API Service',
|
|
1738
|
+
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
|
|
1739
|
+
apiVersion: process.env.API_VERSION || 'v1',
|
|
1740
|
+
corsOrigins: process.env.CORS_ORIGINS?.split(',') || ['https://myapp.com'],
|
|
1741
|
+
features: {
|
|
1742
|
+
logging: true,
|
|
1743
|
+
cors: true,
|
|
1744
|
+
authentication: true
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
};
|
|
1748
|
+
```
|
|
1749
|
+
|
|
1750
|
+
### ๐ Phase 4: Deployment Integration
|
|
1751
|
+
|
|
1752
|
+
**Add CLODO deployment capabilities to your existing CI/CD:**
|
|
1753
|
+
|
|
1754
|
+
```javascript
|
|
1755
|
+
// scripts/deploy.js
|
|
1756
|
+
import { deployWithSecurity } from '@tamyla/clodo-framework/security';
|
|
1757
|
+
import { domains } from '../src/config/domains.js';
|
|
1758
|
+
|
|
1759
|
+
async function deploy() {
|
|
1760
|
+
const domain = domains['my-existing-api'];
|
|
1761
|
+
|
|
1762
|
+
await deployWithSecurity({
|
|
1763
|
+
customer: 'my-company',
|
|
1764
|
+
environment: process.env.NODE_ENV || 'staging',
|
|
1765
|
+
deploymentUrl: domain.domains.production,
|
|
1766
|
+
dryRun: process.argv.includes('--dry-run')
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
deploy().catch(console.error);
|
|
1771
|
+
```
|
|
1772
|
+
|
|
1773
|
+
### ๐จ Customizing Generated Services
|
|
1774
|
+
|
|
1775
|
+
Services created with `clodo-create-service` are **starting templates**, not final products. Here's how to customize them:
|
|
1776
|
+
|
|
1777
|
+
#### **1. Replace Generic Logic with Your Business Logic**
|
|
1778
|
+
|
|
1779
|
+
```javascript
|
|
1780
|
+
// Generated: src/worker/index.js (REPLACE THIS)
|
|
1781
|
+
export default {
|
|
1782
|
+
async fetch(request, env) {
|
|
1783
|
+
// Generic placeholder code - replace with your logic
|
|
1784
|
+
return new Response('Hello from CLODO service');
|
|
1785
|
+
}
|
|
1786
|
+
};
|
|
1787
|
+
|
|
1788
|
+
// Customized: Your actual service logic
|
|
1789
|
+
import { GenericDataService } from '@tamyla/clodo-framework';
|
|
1790
|
+
|
|
1791
|
+
export default {
|
|
1792
|
+
async fetch(request, env) {
|
|
1793
|
+
const dataService = new GenericDataService({ d1Database: env.DB });
|
|
1794
|
+
|
|
1795
|
+
if (request.method === 'GET' && new URL(request.url).pathname === '/users') {
|
|
1796
|
+
const users = await dataService.find('users');
|
|
1797
|
+
return Response.json(users);
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
return new Response('Not found', { status: 404 });
|
|
1801
|
+
}
|
|
1802
|
+
};
|
|
1803
|
+
```
|
|
1804
|
+
|
|
1805
|
+
#### **2. Update Domain Configuration**
|
|
1806
|
+
|
|
1807
|
+
```javascript
|
|
1808
|
+
// src/config/domains.js - Customize for your domains
|
|
1809
|
+
export const domains = {
|
|
1810
|
+
'my-custom-service': {
|
|
1811
|
+
...createDomainConfigSchema(),
|
|
1812
|
+
name: 'my-custom-service',
|
|
1813
|
+
displayName: 'My Custom API Service',
|
|
1814
|
+
accountId: 'your-actual-cloudflare-account-id',
|
|
1815
|
+
zoneId: 'your-actual-cloudflare-zone-id',
|
|
1816
|
+
domains: {
|
|
1817
|
+
production: 'api.mycompany.com',
|
|
1818
|
+
staging: 'staging-api.mycompany.com',
|
|
1819
|
+
development: 'dev-api.mycompany.com'
|
|
1820
|
+
},
|
|
1821
|
+
features: {
|
|
1822
|
+
authentication: true,
|
|
1823
|
+
logging: true,
|
|
1824
|
+
cors: true,
|
|
1825
|
+
rateLimiting: false // Your custom features
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
};
|
|
1829
|
+
```
|
|
1830
|
+
|
|
1831
|
+
#### **3. Add Your Dependencies**
|
|
1832
|
+
|
|
1833
|
+
```json
|
|
1834
|
+
// package.json - Add your specific dependencies
|
|
1835
|
+
{
|
|
1836
|
+
"name": "my-custom-service",
|
|
1837
|
+
"dependencies": {
|
|
1838
|
+
"@tamyla/clodo-framework": "^3.0.5",
|
|
1839
|
+
"stripe": "^12.0.0", // Your payment processing
|
|
1840
|
+
"jsonwebtoken": "^9.0.0", // Your auth library
|
|
1841
|
+
"redis": "^4.6.0" // Your caching layer
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
```
|
|
1845
|
+
|
|
1846
|
+
### ๐ Migration Patterns
|
|
1847
|
+
|
|
1848
|
+
#### **Pattern 1: Wrapper Approach (Safest)**
|
|
1849
|
+
|
|
1850
|
+
```javascript
|
|
1851
|
+
// Keep existing service intact
|
|
1852
|
+
class MyLegacyService {
|
|
1853
|
+
async processData(data) {
|
|
1854
|
+
// Your existing business logic
|
|
1855
|
+
return this.legacyProcessing(data);
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
// Add CLODO capabilities via composition
|
|
1860
|
+
import { GenericDataService } from '@tamyla/clodo-framework';
|
|
1861
|
+
|
|
1862
|
+
class ClodoEnhancedService {
|
|
1863
|
+
constructor(legacyService) {
|
|
1864
|
+
this.legacy = legacyService;
|
|
1865
|
+
this.dataService = new GenericDataService();
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
async processData(data) {
|
|
1869
|
+
// CLODO validation
|
|
1870
|
+
const validated = this.dataService.validateData(data);
|
|
1871
|
+
|
|
1872
|
+
// Your existing logic
|
|
1873
|
+
const result = await this.legacy.processData(validated);
|
|
1874
|
+
|
|
1875
|
+
// CLODO error handling
|
|
1876
|
+
return this.dataService.handleResponse(result);
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
```
|
|
1880
|
+
|
|
1881
|
+
#### **Pattern 2: Gradual Replacement**
|
|
1882
|
+
|
|
1883
|
+
```javascript
|
|
1884
|
+
// Phase 1: Add logging
|
|
1885
|
+
import { ErrorHandler } from '@tamyla/clodo-framework';
|
|
1886
|
+
app.use((err, req, res, next) => {
|
|
1887
|
+
ErrorHandler.handleDeploymentError(err, { phase: 'api' });
|
|
1888
|
+
// existing error handling
|
|
1889
|
+
});
|
|
1890
|
+
|
|
1891
|
+
// Phase 2: Add validation
|
|
1892
|
+
import { SchemaManager } from '@tamyla/clodo-framework';
|
|
1893
|
+
const schema = new SchemaManager();
|
|
1894
|
+
app.post('/users', (req, res) => {
|
|
1895
|
+
const validated = schema.validate('users', req.body);
|
|
1896
|
+
// existing logic with validated data
|
|
1897
|
+
});
|
|
1898
|
+
|
|
1899
|
+
// Phase 3: Full migration
|
|
1900
|
+
// Replace entire routes with CLODO components
|
|
1901
|
+
```
|
|
1902
|
+
|
|
1903
|
+
#### **Pattern 3: Feature Flags for Gradual Rollout**
|
|
1904
|
+
|
|
1905
|
+
```javascript
|
|
1906
|
+
import { isFeatureEnabled } from '@tamyla/clodo-framework';
|
|
1907
|
+
|
|
1908
|
+
app.get('/api/users', async (req, res) => {
|
|
1909
|
+
if (isFeatureEnabled('clodo-data-service')) {
|
|
1910
|
+
// Use CLODO data service
|
|
1911
|
+
const dataService = new GenericDataService();
|
|
1912
|
+
const users = await dataService.find('users');
|
|
1913
|
+
res.json(users);
|
|
1914
|
+
} else {
|
|
1915
|
+
// Use existing implementation
|
|
1916
|
+
const users = await legacyUserService.getAll();
|
|
1917
|
+
res.json(users);
|
|
1918
|
+
}
|
|
1919
|
+
});
|
|
1920
|
+
```
|
|
1921
|
+
|
|
1922
|
+
### ๐งช Testing Integration
|
|
1923
|
+
|
|
1924
|
+
**Add tests that validate CLODO integration:**
|
|
1925
|
+
|
|
1926
|
+
```javascript
|
|
1927
|
+
// test/integration.test.js
|
|
1928
|
+
import { GenericDataService, ErrorHandler } from '@tamyla/clodo-framework';
|
|
1929
|
+
|
|
1930
|
+
describe('CLODO Framework Integration', () => {
|
|
1931
|
+
test('should enhance existing data operations', async () => {
|
|
1932
|
+
const service = new GenericDataService({ d1Database: mockDb });
|
|
1933
|
+
|
|
1934
|
+
// Your existing test data
|
|
1935
|
+
const result = await service.find('users', { active: true });
|
|
1936
|
+
|
|
1937
|
+
expect(result).toBeDefined();
|
|
1938
|
+
// CLODO adds validation, error handling, etc.
|
|
1939
|
+
});
|
|
1940
|
+
|
|
1941
|
+
test('should handle errors with CLODO reporting', () => {
|
|
1942
|
+
const error = new Error('Database connection failed');
|
|
1943
|
+
|
|
1944
|
+
expect(() => {
|
|
1945
|
+
ErrorHandler.handleDeploymentError(error, {
|
|
1946
|
+
customer: 'test-customer',
|
|
1947
|
+
phase: 'database'
|
|
1948
|
+
});
|
|
1949
|
+
}).not.toThrow();
|
|
1950
|
+
});
|
|
1951
|
+
});
|
|
1952
|
+
```
|
|
1953
|
+
|
|
1954
|
+
### ๐จ Common Migration Challenges
|
|
1955
|
+
|
|
1956
|
+
#### **1. Import Path Changes**
|
|
1957
|
+
```javascript
|
|
1958
|
+
// Old: Direct database calls
|
|
1959
|
+
const users = await db.query('SELECT * FROM users');
|
|
1960
|
+
|
|
1961
|
+
// New: CLODO-wrapped with validation
|
|
1962
|
+
const dataService = new GenericDataService({ d1Database: db });
|
|
1963
|
+
const users = await dataService.find('users');
|
|
1964
|
+
```
|
|
1965
|
+
|
|
1966
|
+
#### **2. Configuration Structure**
|
|
1967
|
+
```javascript
|
|
1968
|
+
// Old: Flat config object
|
|
1969
|
+
const config = { apiUrl: 'https://api.com', timeout: 5000 };
|
|
1970
|
+
|
|
1971
|
+
// New: Domain-based configuration
|
|
1972
|
+
export const domains = {
|
|
1973
|
+
'my-service': {
|
|
1974
|
+
...createDomainConfigSchema(),
|
|
1975
|
+
apiUrl: 'https://api.com',
|
|
1976
|
+
timeout: 5000
|
|
1977
|
+
}
|
|
1978
|
+
};
|
|
1979
|
+
```
|
|
1980
|
+
|
|
1981
|
+
#### **3. Error Handling**
|
|
1982
|
+
```javascript
|
|
1983
|
+
// Old: Basic error handling
|
|
1984
|
+
try {
|
|
1985
|
+
await operation();
|
|
1986
|
+
} catch (error) {
|
|
1987
|
+
console.error(error);
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
// New: CLODO error reporting
|
|
1991
|
+
try {
|
|
1992
|
+
await operation();
|
|
1993
|
+
} catch (error) {
|
|
1994
|
+
ErrorHandler.handleDeploymentError(error, {
|
|
1995
|
+
customer: 'my-company',
|
|
1996
|
+
environment: 'production',
|
|
1997
|
+
phase: 'operation'
|
|
1998
|
+
});
|
|
1999
|
+
}
|
|
2000
|
+
```
|
|
2001
|
+
|
|
2002
|
+
### ๐ Migration Checklist
|
|
2003
|
+
|
|
2004
|
+
- [ ] **Phase 1**: Add CLODO as dependency, import core utilities
|
|
2005
|
+
- [ ] **Phase 1**: Integrate error handling and logging
|
|
2006
|
+
- [ ] **Phase 2**: Wrap data operations with GenericDataService
|
|
2007
|
+
- [ ] **Phase 2**: Add schema validation for data models
|
|
2008
|
+
- [ ] **Phase 3**: Replace hardcoded configs with domain configuration
|
|
2009
|
+
- [ ] **Phase 3**: Add feature flags for conditional logic
|
|
2010
|
+
- [ ] **Phase 4**: Integrate deployment and security validation
|
|
2011
|
+
- [ ] **Phase 4**: Update CI/CD to use CLODO deployment scripts
|
|
2012
|
+
- [ ] **Testing**: Add integration tests for CLODO components
|
|
2013
|
+
- [ ] **Documentation**: Update API docs to reflect CLODO integration
|
|
2014
|
+
|
|
2015
|
+
### ๐ฏ Success Metrics
|
|
2016
|
+
|
|
2017
|
+
**Track your migration progress:**
|
|
2018
|
+
- โ
**Error reduction**: Fewer production incidents due to better error handling
|
|
2019
|
+
- โ
**Deployment reliability**: More successful deployments with validation
|
|
2020
|
+
- โ
**Development speed**: Faster feature development with reusable components
|
|
2021
|
+
- โ
**Code consistency**: Standardized patterns across services
|
|
2022
|
+
- โ
**Security compliance**: Automatic security validation prevents issues
|
|
2023
|
+
|
|
2024
|
+
## Best Practices
|
|
2025
|
+
|
|
2026
|
+
1. **Service Autonomy**: Each service manages its own deployment
|
|
2027
|
+
2. **Configuration First**: Define domains and schemas before implementing logic
|
|
2028
|
+
3. **Error Handling**: Always wrap routes in try-catch blocks
|
|
2029
|
+
4. **Feature Flags**: Use `service.features` for conditional logic
|
|
2030
|
+
5. **Validation**: Validate data before database operations
|
|
2031
|
+
6. **Logging**: Use feature guards for logging in production
|
|
2032
|
+
|
|
2033
|
+
## Migration from External Scripts
|
|
2034
|
+
|
|
2035
|
+
If you're currently calling bin scripts externally:
|
|
2036
|
+
|
|
2037
|
+
1. **Remove external script calls** from package.json
|
|
2038
|
+
2. **Add framework as dependency** in package.json
|
|
2039
|
+
3. **Create internal deployment script** in `scripts/deploy.js`
|
|
2040
|
+
4. **Move domain configuration** to `src/config/domains.js`
|
|
2041
|
+
5. **Update import statements** to use framework modules
|
|
2042
|
+
6. **Test deployment** from your service directory
|
|
2043
|
+
|
|
2044
|
+
This approach gives you full control over deployment logic while maintaining the benefits of the Clodo Framework's enterprise features.</content>
|
|
2045
|
+
<parameter name="filePath">c:\Users\Admin\Documents\coding\tamyla\clodo-framework\docs\INTEGRATION_GUIDE.md
|