@friggframework/devtools 2.0.0--canary.517.35ee143.0 → 2.0.0--canary.524.06156322a.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/infrastructure/domains/shared/types/app-definition.js +0 -21
  2. package/infrastructure/domains/shared/utilities/base-definition-factory.js +15 -1
  3. package/infrastructure/infrastructure-composer.js +0 -2
  4. package/package.json +15 -7
  5. package/.eslintrc.json +0 -3
  6. package/CHANGELOG.md +0 -132
  7. package/infrastructure/domains/admin-scripts/admin-script-builder.js +0 -200
  8. package/infrastructure/domains/admin-scripts/admin-script-builder.test.js +0 -499
  9. package/infrastructure/domains/admin-scripts/index.js +0 -5
  10. package/layers/prisma/.build-complete +0 -3
  11. package/layers/prisma/nodejs/package.json +0 -8
  12. package/management-ui/.eslintrc.js +0 -22
  13. package/management-ui/components.json +0 -21
  14. package/management-ui/docs/phase2-integration-guide.md +0 -320
  15. package/management-ui/index.html +0 -13
  16. package/management-ui/package.json +0 -76
  17. package/management-ui/packages/devtools/frigg-cli/ui-command/index.js +0 -302
  18. package/management-ui/postcss.config.js +0 -6
  19. package/management-ui/server/api/backend.js +0 -256
  20. package/management-ui/server/api/cli.js +0 -315
  21. package/management-ui/server/api/codegen.js +0 -663
  22. package/management-ui/server/api/connections.js +0 -857
  23. package/management-ui/server/api/discovery.js +0 -185
  24. package/management-ui/server/api/environment/index.js +0 -1
  25. package/management-ui/server/api/environment/router.js +0 -378
  26. package/management-ui/server/api/environment.js +0 -328
  27. package/management-ui/server/api/integrations.js +0 -876
  28. package/management-ui/server/api/logs.js +0 -248
  29. package/management-ui/server/api/monitoring.js +0 -282
  30. package/management-ui/server/api/open-ide.js +0 -31
  31. package/management-ui/server/api/project.js +0 -1029
  32. package/management-ui/server/api/users/sessions.js +0 -371
  33. package/management-ui/server/api/users/simulation.js +0 -254
  34. package/management-ui/server/api/users.js +0 -362
  35. package/management-ui/server/api-contract.md +0 -275
  36. package/management-ui/server/index.js +0 -873
  37. package/management-ui/server/middleware/errorHandler.js +0 -93
  38. package/management-ui/server/middleware/security.js +0 -32
  39. package/management-ui/server/processManager.js +0 -296
  40. package/management-ui/server/server.js +0 -346
  41. package/management-ui/server/services/aws-monitor.js +0 -413
  42. package/management-ui/server/services/npm-registry.js +0 -347
  43. package/management-ui/server/services/template-engine.js +0 -538
  44. package/management-ui/server/utils/cliIntegration.js +0 -220
  45. package/management-ui/server/utils/environment/auditLogger.js +0 -471
  46. package/management-ui/server/utils/environment/awsParameterStore.js +0 -275
  47. package/management-ui/server/utils/environment/encryption.js +0 -278
  48. package/management-ui/server/utils/environment/envFileManager.js +0 -286
  49. package/management-ui/server/utils/import-commonjs.js +0 -28
  50. package/management-ui/server/utils/response.js +0 -83
  51. package/management-ui/server/websocket/handler.js +0 -325
  52. package/management-ui/src/App.jsx +0 -25
  53. package/management-ui/src/assets/FriggLogo.svg +0 -1
  54. package/management-ui/src/components/AppRouter.jsx +0 -65
  55. package/management-ui/src/components/Button.jsx +0 -70
  56. package/management-ui/src/components/Card.jsx +0 -97
  57. package/management-ui/src/components/EnvironmentCompare.jsx +0 -400
  58. package/management-ui/src/components/EnvironmentEditor.jsx +0 -372
  59. package/management-ui/src/components/EnvironmentImportExport.jsx +0 -469
  60. package/management-ui/src/components/EnvironmentSchema.jsx +0 -491
  61. package/management-ui/src/components/EnvironmentSecurity.jsx +0 -463
  62. package/management-ui/src/components/ErrorBoundary.jsx +0 -73
  63. package/management-ui/src/components/IntegrationCard.jsx +0 -481
  64. package/management-ui/src/components/IntegrationCardEnhanced.jsx +0 -770
  65. package/management-ui/src/components/IntegrationExplorer.jsx +0 -379
  66. package/management-ui/src/components/IntegrationStatus.jsx +0 -336
  67. package/management-ui/src/components/Layout.jsx +0 -716
  68. package/management-ui/src/components/LoadingSpinner.jsx +0 -113
  69. package/management-ui/src/components/RepositoryPicker.jsx +0 -248
  70. package/management-ui/src/components/SessionMonitor.jsx +0 -350
  71. package/management-ui/src/components/StatusBadge.jsx +0 -208
  72. package/management-ui/src/components/UserContextSwitcher.jsx +0 -212
  73. package/management-ui/src/components/UserSimulation.jsx +0 -327
  74. package/management-ui/src/components/Welcome.jsx +0 -434
  75. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +0 -637
  76. package/management-ui/src/components/codegen/APIModuleSelector.jsx +0 -227
  77. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +0 -247
  78. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +0 -316
  79. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +0 -271
  80. package/management-ui/src/components/codegen/FormBuilder.jsx +0 -737
  81. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +0 -855
  82. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +0 -797
  83. package/management-ui/src/components/codegen/SchemaBuilder.jsx +0 -303
  84. package/management-ui/src/components/codegen/TemplateSelector.jsx +0 -586
  85. package/management-ui/src/components/codegen/index.js +0 -10
  86. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +0 -362
  87. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +0 -182
  88. package/management-ui/src/components/connections/ConnectionTester.jsx +0 -200
  89. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +0 -292
  90. package/management-ui/src/components/connections/OAuthFlow.jsx +0 -204
  91. package/management-ui/src/components/connections/index.js +0 -5
  92. package/management-ui/src/components/index.js +0 -21
  93. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +0 -222
  94. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +0 -169
  95. package/management-ui/src/components/monitoring/MetricsChart.jsx +0 -197
  96. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +0 -393
  97. package/management-ui/src/components/monitoring/SQSMetrics.jsx +0 -246
  98. package/management-ui/src/components/monitoring/index.js +0 -6
  99. package/management-ui/src/components/monitoring/monitoring.css +0 -218
  100. package/management-ui/src/components/theme-provider.jsx +0 -52
  101. package/management-ui/src/components/theme-toggle.jsx +0 -39
  102. package/management-ui/src/components/ui/badge.tsx +0 -36
  103. package/management-ui/src/components/ui/button.test.jsx +0 -56
  104. package/management-ui/src/components/ui/button.tsx +0 -57
  105. package/management-ui/src/components/ui/card.tsx +0 -76
  106. package/management-ui/src/components/ui/dropdown-menu.tsx +0 -199
  107. package/management-ui/src/components/ui/select.tsx +0 -157
  108. package/management-ui/src/components/ui/skeleton.jsx +0 -15
  109. package/management-ui/src/hooks/useFrigg.jsx +0 -387
  110. package/management-ui/src/hooks/useSocket.jsx +0 -58
  111. package/management-ui/src/index.css +0 -193
  112. package/management-ui/src/lib/utils.ts +0 -6
  113. package/management-ui/src/main.jsx +0 -10
  114. package/management-ui/src/pages/CodeGeneration.jsx +0 -14
  115. package/management-ui/src/pages/Connections.jsx +0 -252
  116. package/management-ui/src/pages/ConnectionsEnhanced.jsx +0 -633
  117. package/management-ui/src/pages/Dashboard.jsx +0 -311
  118. package/management-ui/src/pages/Environment.jsx +0 -314
  119. package/management-ui/src/pages/IntegrationConfigure.jsx +0 -669
  120. package/management-ui/src/pages/IntegrationDiscovery.jsx +0 -567
  121. package/management-ui/src/pages/IntegrationTest.jsx +0 -742
  122. package/management-ui/src/pages/Integrations.jsx +0 -253
  123. package/management-ui/src/pages/Monitoring.jsx +0 -17
  124. package/management-ui/src/pages/Simulation.jsx +0 -155
  125. package/management-ui/src/pages/Users.jsx +0 -492
  126. package/management-ui/src/services/api.js +0 -41
  127. package/management-ui/src/services/apiModuleService.js +0 -193
  128. package/management-ui/src/services/websocket-handlers.js +0 -120
  129. package/management-ui/src/test/api/project.test.js +0 -273
  130. package/management-ui/src/test/components/Welcome.test.jsx +0 -378
  131. package/management-ui/src/test/mocks/server.js +0 -178
  132. package/management-ui/src/test/setup.js +0 -61
  133. package/management-ui/src/test/utils/test-utils.jsx +0 -134
  134. package/management-ui/src/utils/repository.js +0 -98
  135. package/management-ui/src/utils/repository.test.js +0 -118
  136. package/management-ui/src/workflows/phase2-integration-workflows.js +0 -884
  137. package/management-ui/tailwind.config.js +0 -63
  138. package/management-ui/tsconfig.json +0 -37
  139. package/management-ui/tsconfig.node.json +0 -10
  140. package/management-ui/vite.config.js +0 -26
  141. package/management-ui/vitest.config.js +0 -38
  142. package/test/auther-definition-method-tester.js +0 -45
  143. package/test/index.js +0 -9
  144. package/test/integration-validator.js +0 -2
  145. package/test/mock-api-readme.md +0 -102
  146. package/test/mock-api.js +0 -284
  147. package/test/mock-integration.js +0 -78
@@ -1,884 +0,0 @@
1
- /**
2
- * Phase 2 Integration Workflows
3
- *
4
- * This module implements complete user workflows that integrate all Phase 2 features:
5
- * - Integration discovery → Installation → Configuration → Connection
6
- * - User creation → Credential generation → Entity management
7
- * - Environment setup → Testing → Deployment preparation
8
- */
9
-
10
- import IntegrationDiscoveryService from '../../../core/integrations/discovery/integration-discovery-service.js';
11
- import IntegrationInstallerService from '../../../core/integrations/discovery/integration-installer-service.js';
12
- import { EventEmitter } from 'events';
13
-
14
- export class Phase2IntegrationWorkflows extends EventEmitter {
15
- constructor(config = {}) {
16
- super();
17
- this.config = config;
18
- this.discoveryService = new IntegrationDiscoveryService();
19
- this.installerService = new IntegrationInstallerService();
20
- this.workflows = new Map();
21
- }
22
-
23
- /**
24
- * Complete integration setup workflow
25
- * Discovers → Installs → Configures → Tests an integration
26
- */
27
- async setupIntegration(integrationName, options = {}) {
28
- const workflowId = this.generateWorkflowId();
29
- const workflow = {
30
- id: workflowId,
31
- type: 'integration-setup',
32
- integration: integrationName,
33
- status: 'started',
34
- steps: [],
35
- startTime: Date.now()
36
- };
37
-
38
- this.workflows.set(workflowId, workflow);
39
- this.emit('workflow:started', workflow);
40
-
41
- try {
42
- // Step 1: Discover integration details
43
- await this.executeStep(workflow, 'discover', async () => {
44
- const details = await this.discoveryService.getIntegrationDetails(
45
- `@friggframework/api-module-${integrationName}`
46
- );
47
- workflow.integrationDetails = details;
48
- return details;
49
- });
50
-
51
- // Step 2: Install integration
52
- await this.executeStep(workflow, 'install', async () => {
53
- const result = await this.installerService.installIntegration({
54
- packageName: workflow.integrationDetails.name,
55
- version: workflow.integrationDetails.version
56
- });
57
- workflow.installResult = result;
58
- return result;
59
- });
60
-
61
- // Step 3: Configure integration
62
- await this.executeStep(workflow, 'configure', async () => {
63
- const config = await this.configureIntegration(
64
- integrationName,
65
- workflow.integrationDetails,
66
- options.config || {}
67
- );
68
- workflow.configuration = config;
69
- return config;
70
- });
71
-
72
- // Step 4: Create test user
73
- await this.executeStep(workflow, 'create-test-user', async () => {
74
- const user = await this.createTestUser({
75
- integration: integrationName,
76
- name: options.testUserName || `Test User for ${integrationName}`,
77
- email: options.testUserEmail || `test-${integrationName}@frigg.test`
78
- });
79
- workflow.testUser = user;
80
- return user;
81
- });
82
-
83
- // Step 5: Generate credentials
84
- await this.executeStep(workflow, 'generate-credentials', async () => {
85
- const credentials = await this.generateTestCredentials(
86
- workflow.testUser.id,
87
- integrationName,
88
- workflow.integrationDetails.integrationMetadata
89
- );
90
- workflow.credentials = credentials;
91
- return credentials;
92
- });
93
-
94
- // Step 6: Create connection
95
- await this.executeStep(workflow, 'create-connection', async () => {
96
- const connection = await this.createConnection({
97
- userId: workflow.testUser.id,
98
- integrationName,
99
- credentials: workflow.credentials,
100
- config: workflow.configuration
101
- });
102
- workflow.connection = connection;
103
- return connection;
104
- });
105
-
106
- // Step 7: Test connection
107
- await this.executeStep(workflow, 'test-connection', async () => {
108
- const testResult = await this.testConnection(workflow.connection.id);
109
- workflow.testResult = testResult;
110
- return testResult;
111
- });
112
-
113
- // Step 8: Setup environment variables
114
- await this.executeStep(workflow, 'setup-environment', async () => {
115
- const envVars = await this.setupEnvironmentVariables(
116
- integrationName,
117
- workflow.configuration,
118
- options.environment || 'development'
119
- );
120
- workflow.environmentVariables = envVars;
121
- return envVars;
122
- });
123
-
124
- workflow.status = 'completed';
125
- workflow.endTime = Date.now();
126
- workflow.duration = workflow.endTime - workflow.startTime;
127
-
128
- this.emit('workflow:completed', workflow);
129
- return workflow;
130
-
131
- } catch (error) {
132
- workflow.status = 'failed';
133
- workflow.error = {
134
- message: error.message,
135
- step: workflow.steps[workflow.steps.length - 1]?.name || 'unknown',
136
- stack: error.stack
137
- };
138
- workflow.endTime = Date.now();
139
- workflow.duration = workflow.endTime - workflow.startTime;
140
-
141
- this.emit('workflow:failed', workflow);
142
- throw error;
143
- }
144
- }
145
-
146
- /**
147
- * Bulk integration management workflow
148
- * Handles multiple integrations in parallel with optimized performance
149
- */
150
- async bulkIntegrationSetup(integrations, options = {}) {
151
- const workflowId = this.generateWorkflowId();
152
- const workflow = {
153
- id: workflowId,
154
- type: 'bulk-integration-setup',
155
- integrations,
156
- status: 'started',
157
- results: [],
158
- startTime: Date.now()
159
- };
160
-
161
- this.workflows.set(workflowId, workflow);
162
- this.emit('workflow:started', workflow);
163
-
164
- try {
165
- // Process integrations in batches for optimal performance
166
- const batchSize = options.batchSize || 3;
167
- const batches = this.createBatches(integrations, batchSize);
168
-
169
- for (const [batchIndex, batch] of batches.entries()) {
170
- this.emit('workflow:progress', {
171
- workflowId,
172
- batch: batchIndex + 1,
173
- totalBatches: batches.length,
174
- processing: batch
175
- });
176
-
177
- const batchResults = await Promise.allSettled(
178
- batch.map(integration =>
179
- this.setupIntegration(integration.name, integration.options)
180
- )
181
- );
182
-
183
- workflow.results.push(...batchResults.map((result, index) => ({
184
- integration: batch[index].name,
185
- status: result.status,
186
- result: result.status === 'fulfilled' ? result.value : null,
187
- error: result.status === 'rejected' ? result.reason : null
188
- })));
189
- }
190
-
191
- workflow.status = 'completed';
192
- workflow.endTime = Date.now();
193
- workflow.duration = workflow.endTime - workflow.startTime;
194
- workflow.summary = {
195
- total: integrations.length,
196
- successful: workflow.results.filter(r => r.status === 'fulfilled').length,
197
- failed: workflow.results.filter(r => r.status === 'rejected').length
198
- };
199
-
200
- this.emit('workflow:completed', workflow);
201
- return workflow;
202
-
203
- } catch (error) {
204
- workflow.status = 'failed';
205
- workflow.error = error;
206
- this.emit('workflow:failed', workflow);
207
- throw error;
208
- }
209
- }
210
-
211
- /**
212
- * Development environment setup workflow
213
- * Prepares a complete local development environment
214
- */
215
- async setupDevelopmentEnvironment(options = {}) {
216
- const workflowId = this.generateWorkflowId();
217
- const workflow = {
218
- id: workflowId,
219
- type: 'development-setup',
220
- status: 'started',
221
- steps: [],
222
- startTime: Date.now()
223
- };
224
-
225
- this.workflows.set(workflowId, workflow);
226
- this.emit('workflow:started', workflow);
227
-
228
- try {
229
- // Step 1: Discover recommended integrations
230
- await this.executeStep(workflow, 'discover-recommended', async () => {
231
- const recommended = await this.getRecommendedIntegrations(options.projectType);
232
- workflow.recommendedIntegrations = recommended;
233
- return recommended;
234
- });
235
-
236
- // Step 2: Install core integrations
237
- const coreIntegrations = options.integrations || workflow.recommendedIntegrations.slice(0, 3);
238
- await this.executeStep(workflow, 'install-core', async () => {
239
- const results = await this.bulkIntegrationSetup(
240
- coreIntegrations.map(name => ({ name, options: {} }))
241
- );
242
- workflow.coreIntegrations = results;
243
- return results;
244
- });
245
-
246
- // Step 3: Create test user pool
247
- await this.executeStep(workflow, 'create-user-pool', async () => {
248
- const users = await this.createTestUserPool({
249
- count: options.testUserCount || 5,
250
- integrations: coreIntegrations
251
- });
252
- workflow.testUsers = users;
253
- return users;
254
- });
255
-
256
- // Step 4: Setup mock data
257
- await this.executeStep(workflow, 'setup-mock-data', async () => {
258
- const mockData = await this.setupMockData({
259
- users: workflow.testUsers,
260
- integrations: coreIntegrations,
261
- dataTypes: options.mockDataTypes || ['contacts', 'messages', 'tasks']
262
- });
263
- workflow.mockData = mockData;
264
- return mockData;
265
- });
266
-
267
- // Step 5: Configure environment
268
- await this.executeStep(workflow, 'configure-environment', async () => {
269
- const envConfig = await this.configureDevelopmentEnvironment({
270
- integrations: coreIntegrations,
271
- apiKeys: options.apiKeys || {},
272
- features: options.features || ['debug', 'verbose-logging', 'hot-reload']
273
- });
274
- workflow.environmentConfig = envConfig;
275
- return envConfig;
276
- });
277
-
278
- // Step 6: Validate setup
279
- await this.executeStep(workflow, 'validate-setup', async () => {
280
- const validation = await this.validateDevelopmentSetup(workflow);
281
- workflow.validation = validation;
282
- return validation;
283
- });
284
-
285
- workflow.status = 'completed';
286
- workflow.endTime = Date.now();
287
- workflow.duration = workflow.endTime - workflow.startTime;
288
-
289
- this.emit('workflow:completed', workflow);
290
- return workflow;
291
-
292
- } catch (error) {
293
- workflow.status = 'failed';
294
- workflow.error = error;
295
- this.emit('workflow:failed', workflow);
296
- throw error;
297
- }
298
- }
299
-
300
- /**
301
- * Migration workflow for existing projects
302
- * Migrates from create-frigg-app to new management UI
303
- */
304
- async migrateProject(projectPath, options = {}) {
305
- const workflowId = this.generateWorkflowId();
306
- const workflow = {
307
- id: workflowId,
308
- type: 'project-migration',
309
- projectPath,
310
- status: 'started',
311
- steps: [],
312
- startTime: Date.now()
313
- };
314
-
315
- this.workflows.set(workflowId, workflow);
316
- this.emit('workflow:started', workflow);
317
-
318
- try {
319
- // Step 1: Analyze existing project
320
- await this.executeStep(workflow, 'analyze-project', async () => {
321
- const analysis = await this.analyzeExistingProject(projectPath);
322
- workflow.projectAnalysis = analysis;
323
- return analysis;
324
- });
325
-
326
- // Step 2: Backup current state
327
- await this.executeStep(workflow, 'backup-project', async () => {
328
- const backup = await this.backupProject(projectPath);
329
- workflow.backupPath = backup.path;
330
- return backup;
331
- });
332
-
333
- // Step 3: Migrate integrations
334
- await this.executeStep(workflow, 'migrate-integrations', async () => {
335
- const migrations = await this.migrateIntegrations(
336
- workflow.projectAnalysis.integrations,
337
- options.integrationMapping || {}
338
- );
339
- workflow.integrationMigrations = migrations;
340
- return migrations;
341
- });
342
-
343
- // Step 4: Update configuration
344
- await this.executeStep(workflow, 'update-configuration', async () => {
345
- const config = await this.updateProjectConfiguration({
346
- projectPath,
347
- newStructure: true,
348
- managementUI: true,
349
- preserveCustom: options.preserveCustom !== false
350
- });
351
- workflow.configuration = config;
352
- return config;
353
- });
354
-
355
- // Step 5: Migrate environment variables
356
- await this.executeStep(workflow, 'migrate-environment', async () => {
357
- const envMigration = await this.migrateEnvironmentVariables(
358
- projectPath,
359
- workflow.projectAnalysis.environment
360
- );
361
- workflow.environmentMigration = envMigration;
362
- return envMigration;
363
- });
364
-
365
- // Step 6: Test migration
366
- await this.executeStep(workflow, 'test-migration', async () => {
367
- const tests = await this.testMigratedProject(projectPath);
368
- workflow.testResults = tests;
369
- return tests;
370
- });
371
-
372
- workflow.status = 'completed';
373
- workflow.endTime = Date.now();
374
- workflow.duration = workflow.endTime - workflow.startTime;
375
-
376
- this.emit('workflow:completed', workflow);
377
- return workflow;
378
-
379
- } catch (error) {
380
- // Rollback on failure
381
- if (workflow.backupPath) {
382
- await this.rollbackProject(projectPath, workflow.backupPath);
383
- }
384
-
385
- workflow.status = 'failed';
386
- workflow.error = error;
387
- this.emit('workflow:failed', workflow);
388
- throw error;
389
- }
390
- }
391
-
392
- // Helper methods
393
-
394
- async executeStep(workflow, stepName, stepFunction) {
395
- const step = {
396
- name: stepName,
397
- status: 'started',
398
- startTime: Date.now()
399
- };
400
-
401
- workflow.steps.push(step);
402
- this.emit('step:started', { workflowId: workflow.id, step });
403
-
404
- try {
405
- const result = await stepFunction();
406
- step.status = 'completed';
407
- step.endTime = Date.now();
408
- step.duration = step.endTime - step.startTime;
409
- step.result = result;
410
-
411
- this.emit('step:completed', { workflowId: workflow.id, step });
412
- return result;
413
-
414
- } catch (error) {
415
- step.status = 'failed';
416
- step.endTime = Date.now();
417
- step.duration = step.endTime - step.startTime;
418
- step.error = {
419
- message: error.message,
420
- stack: error.stack
421
- };
422
-
423
- this.emit('step:failed', { workflowId: workflow.id, step });
424
- throw error;
425
- }
426
- }
427
-
428
- async configureIntegration(integrationName, details, userConfig) {
429
- // Merge default configuration with user config
430
- const defaultConfig = this.getDefaultIntegrationConfig(integrationName, details);
431
- const config = { ...defaultConfig, ...userConfig };
432
-
433
- // Validate configuration
434
- const validation = await this.validateIntegrationConfig(integrationName, config);
435
- if (!validation.valid) {
436
- throw new Error(`Invalid configuration: ${validation.errors.join(', ')}`);
437
- }
438
-
439
- // Save configuration
440
- await this.saveIntegrationConfig(integrationName, config);
441
- return config;
442
- }
443
-
444
- async createTestUser(options) {
445
- const user = {
446
- id: this.generateUserId(),
447
- name: options.name,
448
- email: options.email,
449
- integration: options.integration,
450
- isDummy: true,
451
- testId: `test-${options.integration}-${Date.now()}`,
452
- createdAt: new Date().toISOString()
453
- };
454
-
455
- // Store user in runtime memory
456
- await this.storeTestUser(user);
457
- return user;
458
- }
459
-
460
- async generateTestCredentials(userId, integrationName, metadata) {
461
- const authType = metadata.authType || 'oauth2';
462
-
463
- const credentials = {
464
- userId,
465
- integrationName,
466
- authType,
467
- createdAt: new Date().toISOString(),
468
- expiresAt: new Date(Date.now() + 3600000).toISOString() // 1 hour
469
- };
470
-
471
- switch (authType) {
472
- case 'oauth2':
473
- credentials.accessToken = this.generateTestToken('access');
474
- credentials.refreshToken = this.generateTestToken('refresh');
475
- credentials.scope = metadata.requiredScopes || [];
476
- break;
477
- case 'api-key':
478
- credentials.apiKey = this.generateTestToken('api');
479
- break;
480
- case 'basic':
481
- credentials.username = `test-user-${userId}`;
482
- credentials.password = this.generateTestToken('password');
483
- break;
484
- }
485
-
486
- return credentials;
487
- }
488
-
489
- async createConnection(options) {
490
- const connection = {
491
- id: this.generateConnectionId(),
492
- userId: options.userId,
493
- integrationName: options.integrationName,
494
- credentials: options.credentials,
495
- config: options.config,
496
- status: 'active',
497
- createdAt: new Date().toISOString(),
498
- lastSync: null,
499
- entities: []
500
- };
501
-
502
- // Store connection
503
- await this.storeConnection(connection);
504
- return connection;
505
- }
506
-
507
- async testConnection(connectionId) {
508
- // Simulate connection test
509
- const testStart = Date.now();
510
-
511
- // Random delay to simulate API call
512
- await new Promise(resolve => setTimeout(resolve, Math.random() * 500 + 100));
513
-
514
- const testResult = {
515
- connectionId,
516
- healthy: Math.random() > 0.1, // 90% success rate for testing
517
- latency: Date.now() - testStart,
518
- timestamp: new Date().toISOString(),
519
- details: {
520
- apiVersion: '2.0',
521
- rateLimits: {
522
- remaining: 1000,
523
- reset: new Date(Date.now() + 3600000).toISOString()
524
- }
525
- }
526
- };
527
-
528
- if (!testResult.healthy) {
529
- testResult.error = 'Connection test failed: API returned 401 Unauthorized';
530
- }
531
-
532
- return testResult;
533
- }
534
-
535
- async setupEnvironmentVariables(integrationName, config, environment) {
536
- const envVars = {};
537
-
538
- // Generate environment-specific variables
539
- const prefix = integrationName.toUpperCase().replace(/-/g, '_');
540
-
541
- Object.entries(config).forEach(([key, value]) => {
542
- const envKey = `${prefix}_${key.toUpperCase()}`;
543
- envVars[envKey] = value;
544
- });
545
-
546
- // Add environment-specific settings
547
- envVars[`${prefix}_ENVIRONMENT`] = environment;
548
- envVars[`${prefix}_DEBUG`] = environment === 'development' ? 'true' : 'false';
549
-
550
- // Write to .env file
551
- await this.updateEnvironmentFile(envVars);
552
-
553
- return envVars;
554
- }
555
-
556
- // Utility methods
557
-
558
- generateWorkflowId() {
559
- return `workflow-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
560
- }
561
-
562
- generateUserId() {
563
- return `user-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
564
- }
565
-
566
- generateConnectionId() {
567
- return `conn-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
568
- }
569
-
570
- generateTestToken(type) {
571
- const prefix = {
572
- access: 'at',
573
- refresh: 'rt',
574
- api: 'ak',
575
- password: 'pw'
576
- }[type] || 'tk';
577
-
578
- return `${prefix}_test_${Date.now()}_${Math.random().toString(36).substr(2, 16)}`;
579
- }
580
-
581
- createBatches(items, batchSize) {
582
- const batches = [];
583
- for (let i = 0; i < items.length; i += batchSize) {
584
- batches.push(items.slice(i, i + batchSize));
585
- }
586
- return batches;
587
- }
588
-
589
- getDefaultIntegrationConfig(integrationName, details) {
590
- // Return sensible defaults based on integration type
591
- const configs = {
592
- slack: {
593
- clientId: 'test-client-id',
594
- clientSecret: 'test-client-secret',
595
- signingSecret: 'test-signing-secret',
596
- webhookUrl: 'http://localhost:3001/webhooks/slack'
597
- },
598
- hubspot: {
599
- clientId: 'test-client-id',
600
- clientSecret: 'test-client-secret',
601
- portalId: '12345678',
602
- scopes: ['contacts', 'deals']
603
- },
604
- salesforce: {
605
- clientId: 'test-client-id',
606
- clientSecret: 'test-client-secret',
607
- loginUrl: 'https://test.salesforce.com',
608
- apiVersion: 'v56.0'
609
- }
610
- };
611
-
612
- return configs[integrationName] || {
613
- apiKey: 'test-api-key',
614
- baseUrl: `https://api.${integrationName}.com`
615
- };
616
- }
617
-
618
- async validateIntegrationConfig(integrationName, config) {
619
- const errors = [];
620
-
621
- // Basic validation
622
- if (!config || typeof config !== 'object') {
623
- errors.push('Configuration must be an object');
624
- }
625
-
626
- // Integration-specific validation
627
- switch (integrationName) {
628
- case 'slack':
629
- if (!config.clientId) errors.push('clientId is required');
630
- if (!config.clientSecret) errors.push('clientSecret is required');
631
- break;
632
- case 'hubspot':
633
- if (!config.portalId) errors.push('portalId is required');
634
- if (!config.clientId) errors.push('clientId is required');
635
- break;
636
- default:
637
- if (!config.apiKey && !config.clientId) {
638
- errors.push('Either apiKey or clientId is required');
639
- }
640
- }
641
-
642
- return {
643
- valid: errors.length === 0,
644
- errors
645
- };
646
- }
647
-
648
- // Placeholder methods for data persistence
649
- async storeTestUser(user) {
650
- // In a real implementation, this would store to a database or file
651
- return user;
652
- }
653
-
654
- async storeConnection(connection) {
655
- // In a real implementation, this would store to a database or file
656
- return connection;
657
- }
658
-
659
- async saveIntegrationConfig(integrationName, config) {
660
- // In a real implementation, this would save to a config file
661
- return config;
662
- }
663
-
664
- async updateEnvironmentFile(envVars) {
665
- // In a real implementation, this would update the .env file
666
- return envVars;
667
- }
668
-
669
- async getRecommendedIntegrations(projectType) {
670
- const recommendations = {
671
- 'e-commerce': ['stripe', 'shopify', 'mailchimp', 'google-analytics'],
672
- 'saas': ['stripe', 'hubspot', 'slack', 'intercom'],
673
- 'enterprise': ['salesforce', 'slack', 'jira', 'okta'],
674
- 'default': ['slack', 'google-drive', 'github']
675
- };
676
-
677
- return recommendations[projectType] || recommendations.default;
678
- }
679
-
680
- async createTestUserPool(options) {
681
- const users = [];
682
- for (let i = 0; i < options.count; i++) {
683
- const integration = options.integrations[i % options.integrations.length];
684
- const user = await this.createTestUser({
685
- name: `Test User ${i + 1}`,
686
- email: `test${i + 1}@frigg.test`,
687
- integration
688
- });
689
- users.push(user);
690
- }
691
- return users;
692
- }
693
-
694
- async setupMockData(options) {
695
- // Generate mock data for testing
696
- const mockData = {
697
- users: options.users,
698
- dataTypes: options.dataTypes,
699
- generated: {}
700
- };
701
-
702
- for (const dataType of options.dataTypes) {
703
- mockData.generated[dataType] = await this.generateMockData(dataType, options);
704
- }
705
-
706
- return mockData;
707
- }
708
-
709
- async generateMockData(dataType, options) {
710
- const generators = {
711
- contacts: () => ({
712
- id: Math.random().toString(36).substr(2, 9),
713
- name: `Contact ${Math.floor(Math.random() * 1000)}`,
714
- email: `contact${Math.floor(Math.random() * 1000)}@example.com`,
715
- createdAt: new Date().toISOString()
716
- }),
717
- messages: () => ({
718
- id: Math.random().toString(36).substr(2, 9),
719
- from: options.users[Math.floor(Math.random() * options.users.length)].email,
720
- subject: `Test Message ${Math.floor(Math.random() * 1000)}`,
721
- body: 'This is a test message generated for development.',
722
- timestamp: new Date().toISOString()
723
- }),
724
- tasks: () => ({
725
- id: Math.random().toString(36).substr(2, 9),
726
- title: `Task ${Math.floor(Math.random() * 1000)}`,
727
- assignee: options.users[Math.floor(Math.random() * options.users.length)].id,
728
- status: ['pending', 'in-progress', 'completed'][Math.floor(Math.random() * 3)],
729
- dueDate: new Date(Date.now() + Math.random() * 7 * 24 * 60 * 60 * 1000).toISOString()
730
- })
731
- };
732
-
733
- const generator = generators[dataType] || (() => ({ type: dataType, data: {} }));
734
- const count = 10; // Generate 10 items of each type
735
-
736
- return Array(count).fill(null).map(() => generator());
737
- }
738
-
739
- async configureDevelopmentEnvironment(options) {
740
- const config = {
741
- NODE_ENV: 'development',
742
- DEBUG: 'true',
743
- LOG_LEVEL: 'debug'
744
- };
745
-
746
- // Add integration-specific config
747
- for (const integration of options.integrations) {
748
- const prefix = integration.toUpperCase().replace(/-/g, '_');
749
- if (options.apiKeys[integration]) {
750
- config[`${prefix}_API_KEY`] = options.apiKeys[integration];
751
- }
752
- }
753
-
754
- // Add feature flags
755
- for (const feature of options.features) {
756
- config[`FEATURE_${feature.toUpperCase().replace(/-/g, '_')}`] = 'true';
757
- }
758
-
759
- return config;
760
- }
761
-
762
- async validateDevelopmentSetup(workflow) {
763
- const validation = {
764
- valid: true,
765
- checks: [],
766
- warnings: []
767
- };
768
-
769
- // Check integrations
770
- const integrationCheck = {
771
- name: 'Integrations',
772
- passed: workflow.coreIntegrations && workflow.coreIntegrations.summary.successful > 0,
773
- message: `${workflow.coreIntegrations?.summary.successful || 0} integrations installed successfully`
774
- };
775
- validation.checks.push(integrationCheck);
776
-
777
- // Check test users
778
- const userCheck = {
779
- name: 'Test Users',
780
- passed: workflow.testUsers && workflow.testUsers.length > 0,
781
- message: `${workflow.testUsers?.length || 0} test users created`
782
- };
783
- validation.checks.push(userCheck);
784
-
785
- // Check environment
786
- const envCheck = {
787
- name: 'Environment',
788
- passed: workflow.environmentConfig && Object.keys(workflow.environmentConfig).length > 0,
789
- message: 'Environment variables configured'
790
- };
791
- validation.checks.push(envCheck);
792
-
793
- // Add warnings for optional features
794
- if (!workflow.mockData || Object.keys(workflow.mockData.generated).length === 0) {
795
- validation.warnings.push('No mock data generated - testing may be limited');
796
- }
797
-
798
- validation.valid = validation.checks.every(check => check.passed);
799
- return validation;
800
- }
801
-
802
- // Project migration methods
803
- async analyzeExistingProject(projectPath) {
804
- // Analyze create-frigg-app project structure
805
- return {
806
- version: '0.1.0', // Mock version
807
- integrations: ['slack', 'hubspot'], // Mock detected integrations
808
- environment: {
809
- NODE_ENV: 'development',
810
- // Mock environment variables
811
- },
812
- customizations: {
813
- // Detect any custom code
814
- }
815
- };
816
- }
817
-
818
- async backupProject(projectPath) {
819
- const backupPath = `${projectPath}.backup.${Date.now()}`;
820
- // In real implementation, would copy project files
821
- return { path: backupPath, timestamp: new Date().toISOString() };
822
- }
823
-
824
- async migrateIntegrations(oldIntegrations, mapping) {
825
- const migrations = [];
826
- for (const oldIntegration of oldIntegrations) {
827
- const newIntegration = mapping[oldIntegration] || oldIntegration;
828
- migrations.push({
829
- old: oldIntegration,
830
- new: newIntegration,
831
- status: 'migrated'
832
- });
833
- }
834
- return migrations;
835
- }
836
-
837
- async updateProjectConfiguration(options) {
838
- // Update project configuration for new structure
839
- return {
840
- updated: true,
841
- files: ['package.json', 'frigg.config.js'],
842
- changes: {
843
- structure: 'Updated to new project structure',
844
- scripts: 'Added management UI scripts',
845
- dependencies: 'Updated Frigg dependencies'
846
- }
847
- };
848
- }
849
-
850
- async migrateEnvironmentVariables(projectPath, oldEnv) {
851
- // Migrate environment variables to new format
852
- const migrated = {};
853
- for (const [key, value] of Object.entries(oldEnv)) {
854
- // Apply any necessary transformations
855
- migrated[key] = value;
856
- }
857
- return migrated;
858
- }
859
-
860
- async testMigratedProject(projectPath) {
861
- // Run tests on migrated project
862
- return {
863
- passed: true,
864
- tests: [
865
- { name: 'Structure validation', passed: true },
866
- { name: 'Dependency check', passed: true },
867
- { name: 'Configuration validation', passed: true },
868
- { name: 'Integration connectivity', passed: true }
869
- ]
870
- };
871
- }
872
-
873
- async rollbackProject(projectPath, backupPath) {
874
- // Restore project from backup
875
- console.log(`Rolling back project from ${backupPath}`);
876
- return true;
877
- }
878
- }
879
-
880
- // Export singleton instance for convenience
881
- export const phase2Workflows = new Phase2IntegrationWorkflows();
882
-
883
- // Also export class for testing and custom instances
884
- export default Phase2IntegrationWorkflows;