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