@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,562 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration Adapters for CLODO Framework
|
|
3
|
+
* Maintains backwards compatibility while enabling enhanced features
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { featureManager, FEATURES } from '../config/FeatureManager.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Schema Manager Migration Adapter
|
|
10
|
+
* Wraps enhanced SchemaManager to maintain legacy API compatibility
|
|
11
|
+
*/
|
|
12
|
+
export class SchemaManagerAdapter {
|
|
13
|
+
constructor(enhancedSchemaManager, legacySchemaManager = null) {
|
|
14
|
+
this.enhanced = enhancedSchemaManager;
|
|
15
|
+
this.legacy = legacySchemaManager;
|
|
16
|
+
this.migrationState = {
|
|
17
|
+
callCounts: new Map(),
|
|
18
|
+
errorCounts: new Map(),
|
|
19
|
+
performanceMetrics: new Map()
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Validate data with progressive enhancement
|
|
25
|
+
*/
|
|
26
|
+
validateData(tableName, data, options = {}) {
|
|
27
|
+
return this._withMigrationLogging('validateData', () => {
|
|
28
|
+
return featureManager.withFeature(FEATURES.ENABLE_COMPREHENSIVE_VALIDATION, () => {
|
|
29
|
+
// Use enhanced validation with detailed error reporting
|
|
30
|
+
return this.enhanced.validateData(tableName, data, {
|
|
31
|
+
...options,
|
|
32
|
+
comprehensive: true,
|
|
33
|
+
returnDetailedErrors: true
|
|
34
|
+
});
|
|
35
|
+
}, () => {
|
|
36
|
+
// Fallback to basic validation
|
|
37
|
+
if (this.legacy && this.legacy.validateData) {
|
|
38
|
+
return this.legacy.validateData(tableName, data);
|
|
39
|
+
}
|
|
40
|
+
// Minimal compatibility validation
|
|
41
|
+
return this._basicValidation(tableName, data);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Generate SQL with optional caching
|
|
48
|
+
*/
|
|
49
|
+
generateCreateSQL(tableName, options = {}) {
|
|
50
|
+
return this._withMigrationLogging('generateCreateSQL', () => {
|
|
51
|
+
return featureManager.withFeature(FEATURES.ENABLE_SQL_CACHING, () => {
|
|
52
|
+
// Use cached SQL generation
|
|
53
|
+
return this.enhanced.generateCreateSQL(tableName, {
|
|
54
|
+
...options,
|
|
55
|
+
useCache: true
|
|
56
|
+
});
|
|
57
|
+
}, () => {
|
|
58
|
+
// Direct SQL generation without caching
|
|
59
|
+
if (this.legacy && this.legacy.generateCreateSQL) {
|
|
60
|
+
return this.legacy.generateCreateSQL(tableName, options);
|
|
61
|
+
}
|
|
62
|
+
return this.enhanced.generateCreateSQL(tableName, {
|
|
63
|
+
...options,
|
|
64
|
+
useCache: false
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get schema with optional caching
|
|
72
|
+
*/
|
|
73
|
+
getSchema(tableName) {
|
|
74
|
+
return this._withMigrationLogging('getSchema', () => {
|
|
75
|
+
return featureManager.withFeature(FEATURES.ENABLE_SCHEMA_CACHING, () => this.enhanced.getSchema(tableName), () => {
|
|
76
|
+
if (this.legacy && this.legacy.getSchema) {
|
|
77
|
+
return this.legacy.getSchema(tableName);
|
|
78
|
+
}
|
|
79
|
+
return this.enhanced.getSchemaFromConfig(tableName);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Add table with validation
|
|
86
|
+
*/
|
|
87
|
+
addTable(tableName, schema, options = {}) {
|
|
88
|
+
return this._withMigrationLogging('addTable', () => {
|
|
89
|
+
const enhancedOptions = {
|
|
90
|
+
...options,
|
|
91
|
+
validateSchema: featureManager.isEnabled(FEATURES.ENABLE_ENHANCED_SCHEMA),
|
|
92
|
+
enableCaching: featureManager.isEnabled(FEATURES.ENABLE_SCHEMA_CACHING)
|
|
93
|
+
};
|
|
94
|
+
if (this.enhanced.addTable) {
|
|
95
|
+
return this.enhanced.addTable(tableName, schema, enhancedOptions);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Fallback implementation
|
|
99
|
+
if (this.legacy && this.legacy.addTable) {
|
|
100
|
+
return this.legacy.addTable(tableName, schema, options);
|
|
101
|
+
}
|
|
102
|
+
throw new Error('No implementation available for addTable');
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get migration statistics
|
|
108
|
+
*/
|
|
109
|
+
getMigrationStats() {
|
|
110
|
+
return {
|
|
111
|
+
callCounts: Object.fromEntries(this.migrationState.callCounts),
|
|
112
|
+
errorCounts: Object.fromEntries(this.migrationState.errorCounts),
|
|
113
|
+
performanceMetrics: Object.fromEntries(this.migrationState.performanceMetrics),
|
|
114
|
+
featureUsage: this._getFeatureUsageStats()
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Private methods
|
|
119
|
+
|
|
120
|
+
_withMigrationLogging(methodName, callback) {
|
|
121
|
+
const startTime = Date.now();
|
|
122
|
+
this.migrationState.callCounts.set(methodName, (this.migrationState.callCounts.get(methodName) || 0) + 1);
|
|
123
|
+
try {
|
|
124
|
+
const result = callback();
|
|
125
|
+
this._recordPerformance(methodName, Date.now() - startTime);
|
|
126
|
+
return result;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
this.migrationState.errorCounts.set(methodName, (this.migrationState.errorCounts.get(methodName) || 0) + 1);
|
|
129
|
+
if (featureManager.isEnabled(FEATURES.ENABLE_DEBUG_LOGGING)) {
|
|
130
|
+
console.error(`Migration adapter error in ${methodName}:`, error);
|
|
131
|
+
}
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
_recordPerformance(methodName, duration) {
|
|
136
|
+
const existing = this.migrationState.performanceMetrics.get(methodName) || {
|
|
137
|
+
totalTime: 0,
|
|
138
|
+
callCount: 0,
|
|
139
|
+
averageTime: 0
|
|
140
|
+
};
|
|
141
|
+
existing.totalTime += duration;
|
|
142
|
+
existing.callCount += 1;
|
|
143
|
+
existing.averageTime = existing.totalTime / existing.callCount;
|
|
144
|
+
this.migrationState.performanceMetrics.set(methodName, existing);
|
|
145
|
+
}
|
|
146
|
+
_basicValidation(tableName, data) {
|
|
147
|
+
// Basic validation fallback
|
|
148
|
+
const schema = this.enhanced.getSchemaFromConfig(tableName);
|
|
149
|
+
if (!schema) {
|
|
150
|
+
return {
|
|
151
|
+
isValid: false,
|
|
152
|
+
errors: ['Schema not found']
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
const errors = [];
|
|
156
|
+
for (const [fieldName, fieldConfig] of Object.entries(schema.fields || {})) {
|
|
157
|
+
if (fieldConfig.required && (data[fieldName] === undefined || data[fieldName] === null)) {
|
|
158
|
+
errors.push(`Field '${fieldName}' is required`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
isValid: errors.length === 0,
|
|
163
|
+
errors
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
_getFeatureUsageStats() {
|
|
167
|
+
const features = {};
|
|
168
|
+
const allFeatures = featureManager.getAllFeatures();
|
|
169
|
+
for (const [featureName, featureInfo] of Object.entries(allFeatures)) {
|
|
170
|
+
if (featureName.startsWith('ENABLE_SCHEMA') || featureName.startsWith('ENABLE_COMPREHENSIVE')) {
|
|
171
|
+
features[featureName] = featureInfo.enabled;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return features;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Generic Data Service Migration Adapter
|
|
180
|
+
* Wraps enhanced GenericDataService for compatibility
|
|
181
|
+
*/
|
|
182
|
+
export class DataServiceAdapter {
|
|
183
|
+
constructor(enhancedDataService, legacyDataService = null) {
|
|
184
|
+
this.enhanced = enhancedDataService;
|
|
185
|
+
this.legacy = legacyDataService;
|
|
186
|
+
this.migrationState = {
|
|
187
|
+
callCounts: new Map(),
|
|
188
|
+
cacheHitRates: new Map(),
|
|
189
|
+
performanceGains: new Map()
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Create with optional security and validation
|
|
195
|
+
*/
|
|
196
|
+
async create(tableName, data, options = {}) {
|
|
197
|
+
return this._withAsyncMigrationLogging('create', async () => {
|
|
198
|
+
return featureManager.withFeature(FEATURES.ENABLE_SECURITY_CONTROLS, async () => {
|
|
199
|
+
return await this.enhanced.create(tableName, data, {
|
|
200
|
+
...options,
|
|
201
|
+
validateSecurity: true,
|
|
202
|
+
auditAction: true
|
|
203
|
+
});
|
|
204
|
+
}, async () => {
|
|
205
|
+
if (this.legacy && this.legacy.create) {
|
|
206
|
+
return await this.legacy.create(tableName, data, options);
|
|
207
|
+
}
|
|
208
|
+
return await this.enhanced.create(tableName, data, {
|
|
209
|
+
...options,
|
|
210
|
+
validateSecurity: false,
|
|
211
|
+
auditAction: false
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Read with optional caching and pagination
|
|
219
|
+
*/
|
|
220
|
+
async read(tableName, id, options = {}) {
|
|
221
|
+
return this._withAsyncMigrationLogging('read', async () => {
|
|
222
|
+
return featureManager.withFeature(FEATURES.ENABLE_QUERY_CACHING, async () => {
|
|
223
|
+
return await this.enhanced.read(tableName, id, {
|
|
224
|
+
...options,
|
|
225
|
+
useCache: true
|
|
226
|
+
});
|
|
227
|
+
}, async () => {
|
|
228
|
+
if (this.legacy && this.legacy.read) {
|
|
229
|
+
return await this.legacy.read(tableName, id, options);
|
|
230
|
+
}
|
|
231
|
+
return await this.enhanced.readDirect(tableName, id, options);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Update with optional validation and security
|
|
238
|
+
*/
|
|
239
|
+
async update(tableName, id, data, options = {}) {
|
|
240
|
+
return this._withAsyncMigrationLogging('update', async () => {
|
|
241
|
+
const enhancedOptions = {
|
|
242
|
+
...options,
|
|
243
|
+
validateSecurity: featureManager.isEnabled(FEATURES.ENABLE_SECURITY_CONTROLS),
|
|
244
|
+
invalidateCache: featureManager.isEnabled(FEATURES.ENABLE_QUERY_CACHING)
|
|
245
|
+
};
|
|
246
|
+
if (this.enhanced.update) {
|
|
247
|
+
return await this.enhanced.update(tableName, id, data, enhancedOptions);
|
|
248
|
+
}
|
|
249
|
+
if (this.legacy && this.legacy.update) {
|
|
250
|
+
return await this.legacy.update(tableName, id, data, options);
|
|
251
|
+
}
|
|
252
|
+
throw new Error('No implementation available for update');
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Delete with optional security and cleanup
|
|
258
|
+
*/
|
|
259
|
+
async delete(tableName, id, options = {}) {
|
|
260
|
+
return this._withAsyncMigrationLogging('delete', async () => {
|
|
261
|
+
return featureManager.withFeature(FEATURES.ENABLE_SECURITY_CONTROLS, async () => {
|
|
262
|
+
return await this.enhanced.delete(tableName, id, {
|
|
263
|
+
...options,
|
|
264
|
+
validateSecurity: true,
|
|
265
|
+
auditAction: true,
|
|
266
|
+
cascadeDelete: options.cascade || false
|
|
267
|
+
});
|
|
268
|
+
}, async () => {
|
|
269
|
+
if (this.legacy && this.legacy.delete) {
|
|
270
|
+
return await this.legacy.delete(tableName, id, options);
|
|
271
|
+
}
|
|
272
|
+
return await this.enhanced.deleteDirect(tableName, id, options);
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* List with optional advanced pagination
|
|
279
|
+
*/
|
|
280
|
+
async list(tableName, options = {}) {
|
|
281
|
+
return this._withAsyncMigrationLogging('list', async () => {
|
|
282
|
+
return featureManager.withFeature(FEATURES.ENABLE_ADVANCED_PAGINATION, async () => {
|
|
283
|
+
return await this.enhanced.list(tableName, {
|
|
284
|
+
...options,
|
|
285
|
+
advancedPagination: true,
|
|
286
|
+
includeMetadata: true
|
|
287
|
+
});
|
|
288
|
+
}, async () => {
|
|
289
|
+
if (this.legacy && this.legacy.list) {
|
|
290
|
+
return await this.legacy.list(tableName, options);
|
|
291
|
+
}
|
|
292
|
+
return await this.enhanced.listBasic(tableName, options);
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Get cache statistics for monitoring
|
|
299
|
+
*/
|
|
300
|
+
getCacheStats() {
|
|
301
|
+
if (featureManager.isEnabled(FEATURES.ENABLE_CACHE_METRICS)) {
|
|
302
|
+
return this.enhanced.getCacheMetrics();
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
message: 'Cache metrics not enabled'
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Get migration progress and statistics
|
|
311
|
+
*/
|
|
312
|
+
getMigrationStats() {
|
|
313
|
+
return {
|
|
314
|
+
callCounts: Object.fromEntries(this.migrationState.callCounts),
|
|
315
|
+
cacheHitRates: Object.fromEntries(this.migrationState.cacheHitRates),
|
|
316
|
+
performanceGains: Object.fromEntries(this.migrationState.performanceGains),
|
|
317
|
+
featureUsage: this._getFeatureUsageStats()
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Private methods
|
|
322
|
+
|
|
323
|
+
async _withAsyncMigrationLogging(methodName, callback) {
|
|
324
|
+
const startTime = Date.now();
|
|
325
|
+
this.migrationState.callCounts.set(methodName, (this.migrationState.callCounts.get(methodName) || 0) + 1);
|
|
326
|
+
try {
|
|
327
|
+
const result = await callback();
|
|
328
|
+
const duration = Date.now() - startTime;
|
|
329
|
+
this._recordPerformanceGain(methodName, duration);
|
|
330
|
+
return result;
|
|
331
|
+
} catch (error) {
|
|
332
|
+
if (featureManager.isEnabled(FEATURES.ENABLE_DEBUG_LOGGING)) {
|
|
333
|
+
console.error(`Data service migration adapter error in ${methodName}:`, error);
|
|
334
|
+
}
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
_recordPerformanceGain(methodName, duration) {
|
|
339
|
+
// Record whether enhanced features provided performance benefits
|
|
340
|
+
const usesCaching = featureManager.isEnabled(FEATURES.ENABLE_QUERY_CACHING);
|
|
341
|
+
const existing = this.migrationState.performanceGains.get(methodName) || {
|
|
342
|
+
cachedCalls: 0,
|
|
343
|
+
uncachedCalls: 0,
|
|
344
|
+
averageCachedTime: 0,
|
|
345
|
+
averageUncachedTime: 0
|
|
346
|
+
};
|
|
347
|
+
if (usesCaching && (methodName === 'read' || methodName === 'list')) {
|
|
348
|
+
existing.cachedCalls += 1;
|
|
349
|
+
existing.averageCachedTime = (existing.averageCachedTime + duration) / existing.cachedCalls;
|
|
350
|
+
} else {
|
|
351
|
+
existing.uncachedCalls += 1;
|
|
352
|
+
existing.averageUncachedTime = (existing.averageUncachedTime + duration) / existing.uncachedCalls;
|
|
353
|
+
}
|
|
354
|
+
this.migrationState.performanceGains.set(methodName, existing);
|
|
355
|
+
}
|
|
356
|
+
_getFeatureUsageStats() {
|
|
357
|
+
const features = {};
|
|
358
|
+
const allFeatures = featureManager.getAllFeatures();
|
|
359
|
+
for (const [featureName, featureInfo] of Object.entries(allFeatures)) {
|
|
360
|
+
if (featureName.includes('QUERY_CACHING') || featureName.includes('SECURITY') || featureName.includes('PAGINATION')) {
|
|
361
|
+
features[featureName] = featureInfo.enabled;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return features;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Module Manager Migration Adapter
|
|
370
|
+
* Wraps enhanced ModuleManager for compatibility
|
|
371
|
+
*/
|
|
372
|
+
export class ModuleManagerAdapter {
|
|
373
|
+
constructor(enhancedModuleManager, legacyModuleManager = null) {
|
|
374
|
+
this.enhanced = enhancedModuleManager;
|
|
375
|
+
this.legacy = legacyModuleManager;
|
|
376
|
+
this.migrationState = {
|
|
377
|
+
hookExecutions: new Map(),
|
|
378
|
+
timeoutEvents: new Map(),
|
|
379
|
+
performanceMetrics: new Map()
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Register module with optional enhanced features
|
|
385
|
+
*/
|
|
386
|
+
async registerModule(name, module, options = {}) {
|
|
387
|
+
return this._withAsyncMigrationLogging('registerModule', async () => {
|
|
388
|
+
const enhancedOptions = {
|
|
389
|
+
...options,
|
|
390
|
+
enableMetrics: featureManager.isEnabled(FEATURES.ENABLE_HOOK_METRICS),
|
|
391
|
+
enableTimeout: featureManager.isEnabled(FEATURES.ENABLE_HOOK_TIMEOUT)
|
|
392
|
+
};
|
|
393
|
+
if (this.enhanced.registerModule) {
|
|
394
|
+
return await this.enhanced.registerModule(name, module, enhancedOptions);
|
|
395
|
+
}
|
|
396
|
+
if (this.legacy && this.legacy.registerModule) {
|
|
397
|
+
return await this.legacy.registerModule(name, module, options);
|
|
398
|
+
}
|
|
399
|
+
throw new Error('No implementation available for registerModule');
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Execute hooks with optional enhancements
|
|
405
|
+
*/
|
|
406
|
+
async executeHooks(hookName, context = {}) {
|
|
407
|
+
return this._withAsyncMigrationLogging('executeHooks', async () => {
|
|
408
|
+
return featureManager.withFeature(FEATURES.ENABLE_ENHANCED_HOOKS, async () => {
|
|
409
|
+
return await this.enhanced.executeHooks(hookName, context, {
|
|
410
|
+
enableTimeout: featureManager.isEnabled(FEATURES.ENABLE_HOOK_TIMEOUT),
|
|
411
|
+
enableMetrics: featureManager.isEnabled(FEATURES.ENABLE_HOOK_METRICS),
|
|
412
|
+
parallelExecution: featureManager.isEnabled(FEATURES.ENABLE_PARALLEL_EXECUTION)
|
|
413
|
+
});
|
|
414
|
+
}, async () => {
|
|
415
|
+
if (this.legacy && this.legacy.executeHooks) {
|
|
416
|
+
return await this.legacy.executeHooks(hookName, context);
|
|
417
|
+
}
|
|
418
|
+
return await this.enhanced.executeHooksBasic(hookName, context);
|
|
419
|
+
});
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Get hook metrics if available
|
|
425
|
+
*/
|
|
426
|
+
getHookMetrics() {
|
|
427
|
+
return featureManager.withFeature(FEATURES.ENABLE_HOOK_METRICS, () => this.enhanced.getMetrics(), () => ({
|
|
428
|
+
message: 'Hook metrics not enabled'
|
|
429
|
+
}));
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Get migration statistics
|
|
434
|
+
*/
|
|
435
|
+
getMigrationStats() {
|
|
436
|
+
return {
|
|
437
|
+
hookExecutions: Object.fromEntries(this.migrationState.hookExecutions),
|
|
438
|
+
timeoutEvents: Object.fromEntries(this.migrationState.timeoutEvents),
|
|
439
|
+
performanceMetrics: Object.fromEntries(this.migrationState.performanceMetrics),
|
|
440
|
+
featureUsage: this._getFeatureUsageStats()
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Private methods
|
|
445
|
+
|
|
446
|
+
async _withAsyncMigrationLogging(methodName, callback) {
|
|
447
|
+
const startTime = Date.now();
|
|
448
|
+
this.migrationState.hookExecutions.set(methodName, (this.migrationState.hookExecutions.get(methodName) || 0) + 1);
|
|
449
|
+
try {
|
|
450
|
+
const result = await callback();
|
|
451
|
+
this._recordMetrics(methodName, Date.now() - startTime);
|
|
452
|
+
return result;
|
|
453
|
+
} catch (error) {
|
|
454
|
+
if (error.name === 'TimeoutError') {
|
|
455
|
+
this.migrationState.timeoutEvents.set(methodName, (this.migrationState.timeoutEvents.get(methodName) || 0) + 1);
|
|
456
|
+
}
|
|
457
|
+
if (featureManager.isEnabled(FEATURES.ENABLE_DEBUG_LOGGING)) {
|
|
458
|
+
console.error(`Module manager migration adapter error in ${methodName}:`, error);
|
|
459
|
+
}
|
|
460
|
+
throw error;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
_recordMetrics(methodName, duration) {
|
|
464
|
+
const existing = this.migrationState.performanceMetrics.get(methodName) || {
|
|
465
|
+
totalTime: 0,
|
|
466
|
+
callCount: 0,
|
|
467
|
+
averageTime: 0,
|
|
468
|
+
enhancedFeatureUsage: 0
|
|
469
|
+
};
|
|
470
|
+
existing.totalTime += duration;
|
|
471
|
+
existing.callCount += 1;
|
|
472
|
+
existing.averageTime = existing.totalTime / existing.callCount;
|
|
473
|
+
if (featureManager.isEnabled(FEATURES.ENABLE_ENHANCED_HOOKS)) {
|
|
474
|
+
existing.enhancedFeatureUsage += 1;
|
|
475
|
+
}
|
|
476
|
+
this.migrationState.performanceMetrics.set(methodName, existing);
|
|
477
|
+
}
|
|
478
|
+
_getFeatureUsageStats() {
|
|
479
|
+
const features = {};
|
|
480
|
+
const allFeatures = featureManager.getAllFeatures();
|
|
481
|
+
for (const [featureName, featureInfo] of Object.entries(allFeatures)) {
|
|
482
|
+
if (featureName.includes('HOOK') || featureName.includes('PARALLEL')) {
|
|
483
|
+
features[featureName] = featureInfo.enabled;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
return features;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Migration Factory
|
|
492
|
+
* Creates appropriate adapters for different components
|
|
493
|
+
*/
|
|
494
|
+
export class MigrationFactory {
|
|
495
|
+
static createSchemaManagerAdapter(enhanced, legacy = null) {
|
|
496
|
+
return new SchemaManagerAdapter(enhanced, legacy);
|
|
497
|
+
}
|
|
498
|
+
static createDataServiceAdapter(enhanced, legacy = null) {
|
|
499
|
+
return new DataServiceAdapter(enhanced, legacy);
|
|
500
|
+
}
|
|
501
|
+
static createModuleManagerAdapter(enhanced, legacy = null) {
|
|
502
|
+
return new ModuleManagerAdapter(enhanced, legacy);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Create a complete migration suite
|
|
507
|
+
*/
|
|
508
|
+
static createMigrationSuite(enhancedComponents, legacyComponents = {}) {
|
|
509
|
+
return {
|
|
510
|
+
schemaManager: this.createSchemaManagerAdapter(enhancedComponents.schemaManager, legacyComponents.schemaManager),
|
|
511
|
+
dataService: this.createDataServiceAdapter(enhancedComponents.dataService, legacyComponents.dataService),
|
|
512
|
+
moduleManager: this.createModuleManagerAdapter(enhancedComponents.moduleManager, legacyComponents.moduleManager),
|
|
513
|
+
/**
|
|
514
|
+
* Get comprehensive migration statistics
|
|
515
|
+
*/
|
|
516
|
+
getMigrationStats() {
|
|
517
|
+
return {
|
|
518
|
+
schemaManager: this.schemaManager.getMigrationStats(),
|
|
519
|
+
dataService: this.dataService.getMigrationStats(),
|
|
520
|
+
moduleManager: this.moduleManager.getMigrationStats(),
|
|
521
|
+
overallFeatureUsage: featureManager.getAllFeatures()
|
|
522
|
+
};
|
|
523
|
+
},
|
|
524
|
+
/**
|
|
525
|
+
* Generate migration report
|
|
526
|
+
*/
|
|
527
|
+
generateMigrationReport() {
|
|
528
|
+
const stats = this.getMigrationStats();
|
|
529
|
+
return {
|
|
530
|
+
summary: {
|
|
531
|
+
totalCalls: Object.values(stats.schemaManager.callCounts).reduce((a, b) => a + b, 0) + Object.values(stats.dataService.callCounts).reduce((a, b) => a + b, 0) + Object.values(stats.moduleManager.hookExecutions).reduce((a, b) => a + b, 0),
|
|
532
|
+
featuresEnabled: Object.values(stats.overallFeatureUsage).filter(f => f.enabled).length,
|
|
533
|
+
totalFeatures: Object.keys(stats.overallFeatureUsage).length
|
|
534
|
+
},
|
|
535
|
+
details: stats,
|
|
536
|
+
recommendations: this._generateRecommendations(stats)
|
|
537
|
+
};
|
|
538
|
+
},
|
|
539
|
+
_generateRecommendations(stats) {
|
|
540
|
+
const recommendations = [];
|
|
541
|
+
|
|
542
|
+
// Check cache usage
|
|
543
|
+
if (stats.dataService.cacheHitRates && Object.keys(stats.dataService.cacheHitRates).length === 0) {
|
|
544
|
+
recommendations.push('Consider enabling query caching for better performance');
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Check hook timeouts
|
|
548
|
+
if (stats.moduleManager.timeoutEvents && Object.values(stats.moduleManager.timeoutEvents).some(count => count > 0)) {
|
|
549
|
+
recommendations.push('Review hook timeout configurations - some hooks are timing out');
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Check feature adoption
|
|
553
|
+
const enabledFeatures = Object.values(stats.overallFeatureUsage).filter(f => f.enabled).length;
|
|
554
|
+
const totalFeatures = Object.keys(stats.overallFeatureUsage).length;
|
|
555
|
+
if (enabledFeatures < totalFeatures * 0.5) {
|
|
556
|
+
recommendations.push('Consider enabling more enhanced features for better functionality');
|
|
557
|
+
}
|
|
558
|
+
return recommendations;
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
}
|