@friggframework/devtools 2.0.0--canary.400.bed3308.0 → 2.0.0--canary.404.e9d4980.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 (182) hide show
  1. package/frigg-cli/build-command/index.js +3 -18
  2. package/frigg-cli/deploy-command/index.js +3 -19
  3. package/frigg-cli/index.js +1 -73
  4. package/frigg-cli/install-command/index.js +2 -15
  5. package/frigg-cli/start-command/index.js +2 -17
  6. package/infrastructure/create-frigg-infrastructure.js +2 -2
  7. package/infrastructure/serverless-template.js +79 -529
  8. package/package.json +5 -9
  9. package/frigg-cli/.eslintrc.js +0 -141
  10. package/frigg-cli/__tests__/jest.config.js +0 -102
  11. package/frigg-cli/__tests__/unit/commands/build.test.js +0 -483
  12. package/frigg-cli/__tests__/unit/commands/install.test.js +0 -418
  13. package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -592
  14. package/frigg-cli/__tests__/utils/command-tester.js +0 -170
  15. package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
  16. package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
  17. package/frigg-cli/__tests__/utils/test-setup.js +0 -286
  18. package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -312
  19. package/frigg-cli/generate-command/azure-generator.js +0 -43
  20. package/frigg-cli/generate-command/gcp-generator.js +0 -47
  21. package/frigg-cli/generate-command/index.js +0 -350
  22. package/frigg-cli/generate-command/terraform-generator.js +0 -555
  23. package/frigg-cli/generate-iam-command.js +0 -115
  24. package/frigg-cli/package.json +0 -75
  25. package/frigg-cli/ui-command/index.js +0 -167
  26. package/frigg-cli/utils/app-resolver.js +0 -319
  27. package/frigg-cli/utils/backend-path.js +0 -38
  28. package/frigg-cli/utils/process-manager.js +0 -199
  29. package/frigg-cli/utils/repo-detection.js +0 -405
  30. package/infrastructure/AWS-DISCOVERY-TROUBLESHOOTING.md +0 -245
  31. package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +0 -620
  32. package/infrastructure/DEPLOYMENT-INSTRUCTIONS.md +0 -268
  33. package/infrastructure/GENERATE-IAM-DOCS.md +0 -253
  34. package/infrastructure/IAM-POLICY-TEMPLATES.md +0 -176
  35. package/infrastructure/README-TESTING.md +0 -332
  36. package/infrastructure/README.md +0 -421
  37. package/infrastructure/WEBSOCKET-CONFIGURATION.md +0 -105
  38. package/infrastructure/__tests__/fixtures/mock-aws-resources.js +0 -391
  39. package/infrastructure/__tests__/helpers/test-utils.js +0 -277
  40. package/infrastructure/aws-discovery.js +0 -568
  41. package/infrastructure/aws-discovery.test.js +0 -373
  42. package/infrastructure/build-time-discovery.js +0 -206
  43. package/infrastructure/build-time-discovery.test.js +0 -375
  44. package/infrastructure/frigg-deployment-iam-stack.yaml +0 -393
  45. package/infrastructure/iam-generator.js +0 -810
  46. package/infrastructure/iam-generator.test.js +0 -169
  47. package/infrastructure/iam-policy-basic.json +0 -236
  48. package/infrastructure/iam-policy-full.json +0 -305
  49. package/infrastructure/integration.test.js +0 -383
  50. package/infrastructure/run-discovery.js +0 -110
  51. package/infrastructure/serverless-template.test.js +0 -553
  52. package/management-ui/.eslintrc.js +0 -22
  53. package/management-ui/README.md +0 -203
  54. package/management-ui/components.json +0 -21
  55. package/management-ui/index.html +0 -13
  56. package/management-ui/merge-conflict-cleaner.py +0 -371
  57. package/management-ui/package-lock.json +0 -10997
  58. package/management-ui/package.json +0 -76
  59. package/management-ui/postcss.config.js +0 -6
  60. package/management-ui/server/api/backend.js +0 -256
  61. package/management-ui/server/api/cli.js +0 -315
  62. package/management-ui/server/api/codegen.js +0 -663
  63. package/management-ui/server/api/connections.js +0 -857
  64. package/management-ui/server/api/discovery.js +0 -185
  65. package/management-ui/server/api/environment/index.js +0 -1
  66. package/management-ui/server/api/environment/router.js +0 -378
  67. package/management-ui/server/api/environment.js +0 -328
  68. package/management-ui/server/api/integrations.js +0 -479
  69. package/management-ui/server/api/logs.js +0 -248
  70. package/management-ui/server/api/monitoring.js +0 -282
  71. package/management-ui/server/api/open-ide.js +0 -31
  72. package/management-ui/server/api/project.js +0 -553
  73. package/management-ui/server/api/users/sessions.js +0 -371
  74. package/management-ui/server/api/users/simulation.js +0 -254
  75. package/management-ui/server/api/users.js +0 -362
  76. package/management-ui/server/api-contract.md +0 -275
  77. package/management-ui/server/index.js +0 -428
  78. package/management-ui/server/middleware/errorHandler.js +0 -70
  79. package/management-ui/server/middleware/security.js +0 -32
  80. package/management-ui/server/processManager.js +0 -296
  81. package/management-ui/server/server.js +0 -188
  82. package/management-ui/server/services/aws-monitor.js +0 -413
  83. package/management-ui/server/services/npm-registry.js +0 -347
  84. package/management-ui/server/services/template-engine.js +0 -538
  85. package/management-ui/server/utils/cliIntegration.js +0 -220
  86. package/management-ui/server/utils/environment/auditLogger.js +0 -471
  87. package/management-ui/server/utils/environment/awsParameterStore.js +0 -264
  88. package/management-ui/server/utils/environment/encryption.js +0 -278
  89. package/management-ui/server/utils/environment/envFileManager.js +0 -286
  90. package/management-ui/server/utils/import-commonjs.js +0 -28
  91. package/management-ui/server/utils/response.js +0 -83
  92. package/management-ui/server/websocket/handler.js +0 -325
  93. package/management-ui/src/App.jsx +0 -51
  94. package/management-ui/src/assets/FriggLogo.svg +0 -1
  95. package/management-ui/src/components/AppRouter.jsx +0 -65
  96. package/management-ui/src/components/Button.jsx +0 -2
  97. package/management-ui/src/components/Card.jsx +0 -9
  98. package/management-ui/src/components/EnvironmentCompare.jsx +0 -400
  99. package/management-ui/src/components/EnvironmentEditor.jsx +0 -372
  100. package/management-ui/src/components/EnvironmentImportExport.jsx +0 -469
  101. package/management-ui/src/components/EnvironmentSchema.jsx +0 -491
  102. package/management-ui/src/components/EnvironmentSecurity.jsx +0 -463
  103. package/management-ui/src/components/ErrorBoundary.jsx +0 -73
  104. package/management-ui/src/components/IntegrationCard.jsx +0 -199
  105. package/management-ui/src/components/IntegrationCardEnhanced.jsx +0 -490
  106. package/management-ui/src/components/IntegrationExplorer.jsx +0 -379
  107. package/management-ui/src/components/IntegrationStatus.jsx +0 -235
  108. package/management-ui/src/components/Layout.jsx +0 -250
  109. package/management-ui/src/components/LoadingSpinner.jsx +0 -45
  110. package/management-ui/src/components/RepositoryPicker.jsx +0 -248
  111. package/management-ui/src/components/SessionMonitor.jsx +0 -255
  112. package/management-ui/src/components/StatusBadge.jsx +0 -70
  113. package/management-ui/src/components/UserContextSwitcher.jsx +0 -154
  114. package/management-ui/src/components/UserSimulation.jsx +0 -299
  115. package/management-ui/src/components/Welcome.jsx +0 -434
  116. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +0 -637
  117. package/management-ui/src/components/codegen/APIModuleSelector.jsx +0 -227
  118. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +0 -247
  119. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +0 -316
  120. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +0 -271
  121. package/management-ui/src/components/codegen/FormBuilder.jsx +0 -737
  122. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +0 -855
  123. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +0 -797
  124. package/management-ui/src/components/codegen/SchemaBuilder.jsx +0 -303
  125. package/management-ui/src/components/codegen/TemplateSelector.jsx +0 -586
  126. package/management-ui/src/components/codegen/index.js +0 -10
  127. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +0 -362
  128. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +0 -182
  129. package/management-ui/src/components/connections/ConnectionTester.jsx +0 -200
  130. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +0 -292
  131. package/management-ui/src/components/connections/OAuthFlow.jsx +0 -204
  132. package/management-ui/src/components/connections/index.js +0 -5
  133. package/management-ui/src/components/index.js +0 -21
  134. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +0 -222
  135. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +0 -169
  136. package/management-ui/src/components/monitoring/MetricsChart.jsx +0 -197
  137. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +0 -393
  138. package/management-ui/src/components/monitoring/SQSMetrics.jsx +0 -246
  139. package/management-ui/src/components/monitoring/index.js +0 -6
  140. package/management-ui/src/components/monitoring/monitoring.css +0 -218
  141. package/management-ui/src/components/theme-provider.jsx +0 -52
  142. package/management-ui/src/components/theme-toggle.jsx +0 -39
  143. package/management-ui/src/components/ui/badge.tsx +0 -36
  144. package/management-ui/src/components/ui/button.test.jsx +0 -56
  145. package/management-ui/src/components/ui/button.tsx +0 -57
  146. package/management-ui/src/components/ui/card.tsx +0 -76
  147. package/management-ui/src/components/ui/dropdown-menu.tsx +0 -199
  148. package/management-ui/src/components/ui/select.tsx +0 -157
  149. package/management-ui/src/components/ui/skeleton.jsx +0 -15
  150. package/management-ui/src/hooks/useFrigg.jsx +0 -387
  151. package/management-ui/src/hooks/useSocket.jsx +0 -58
  152. package/management-ui/src/index.css +0 -194
  153. package/management-ui/src/lib/utils.ts +0 -6
  154. package/management-ui/src/main.jsx +0 -10
  155. package/management-ui/src/pages/CodeGeneration.jsx +0 -14
  156. package/management-ui/src/pages/Connections.jsx +0 -252
  157. package/management-ui/src/pages/ConnectionsEnhanced.jsx +0 -427
  158. package/management-ui/src/pages/Dashboard.jsx +0 -311
  159. package/management-ui/src/pages/Environment.jsx +0 -314
  160. package/management-ui/src/pages/IntegrationConfigure.jsx +0 -544
  161. package/management-ui/src/pages/IntegrationDiscovery.jsx +0 -479
  162. package/management-ui/src/pages/IntegrationTest.jsx +0 -494
  163. package/management-ui/src/pages/Integrations.jsx +0 -254
  164. package/management-ui/src/pages/Monitoring.jsx +0 -17
  165. package/management-ui/src/pages/Simulation.jsx +0 -155
  166. package/management-ui/src/pages/Users.jsx +0 -492
  167. package/management-ui/src/services/api.js +0 -41
  168. package/management-ui/src/services/apiModuleService.js +0 -193
  169. package/management-ui/src/services/websocket-handlers.js +0 -120
  170. package/management-ui/src/test/api/project.test.js +0 -273
  171. package/management-ui/src/test/components/Welcome.test.jsx +0 -378
  172. package/management-ui/src/test/mocks/server.js +0 -178
  173. package/management-ui/src/test/setup.js +0 -61
  174. package/management-ui/src/test/utils/test-utils.jsx +0 -134
  175. package/management-ui/src/utils/repository.js +0 -98
  176. package/management-ui/src/utils/repository.test.js +0 -118
  177. package/management-ui/src/workflows/phase2-integration-workflows.js +0 -884
  178. package/management-ui/tailwind.config.js +0 -63
  179. package/management-ui/tsconfig.json +0 -37
  180. package/management-ui/tsconfig.node.json +0 -10
  181. package/management-ui/vite.config.js +0 -26
  182. package/management-ui/vitest.config.js +0 -38
@@ -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;