@friggframework/core 2.0.0-next.45 → 2.0.0-next.47

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 (163) hide show
  1. package/README.md +28 -0
  2. package/application/commands/integration-commands.js +19 -0
  3. package/core/Worker.js +8 -21
  4. package/credential/repositories/credential-repository-mongo.js +14 -8
  5. package/credential/repositories/credential-repository-postgres.js +14 -8
  6. package/credential/repositories/credential-repository.js +3 -8
  7. package/database/MONGODB_TRANSACTION_FIX.md +198 -0
  8. package/database/adapters/lambda-invoker.js +97 -0
  9. package/database/config.js +11 -2
  10. package/database/models/WebsocketConnection.js +11 -10
  11. package/database/prisma.js +63 -3
  12. package/database/repositories/health-check-repository-mongodb.js +3 -0
  13. package/database/repositories/migration-status-repository-s3.js +137 -0
  14. package/database/use-cases/check-database-state-use-case.js +81 -0
  15. package/database/use-cases/check-encryption-health-use-case.js +3 -2
  16. package/database/use-cases/get-database-state-via-worker-use-case.js +61 -0
  17. package/database/use-cases/get-migration-status-use-case.js +93 -0
  18. package/database/use-cases/run-database-migration-use-case.js +137 -0
  19. package/database/use-cases/trigger-database-migration-use-case.js +157 -0
  20. package/database/utils/mongodb-collection-utils.js +91 -0
  21. package/database/utils/mongodb-schema-init.js +106 -0
  22. package/database/utils/prisma-runner.js +400 -0
  23. package/database/utils/prisma-schema-parser.js +182 -0
  24. package/encrypt/Cryptor.js +14 -16
  25. package/generated/prisma-mongodb/client.d.ts +1 -0
  26. package/generated/prisma-mongodb/client.js +4 -0
  27. package/generated/prisma-mongodb/default.d.ts +1 -0
  28. package/generated/prisma-mongodb/default.js +4 -0
  29. package/generated/prisma-mongodb/edge.d.ts +1 -0
  30. package/generated/prisma-mongodb/edge.js +334 -0
  31. package/generated/prisma-mongodb/index-browser.js +316 -0
  32. package/generated/prisma-mongodb/index.d.ts +22897 -0
  33. package/generated/prisma-mongodb/index.js +359 -0
  34. package/generated/prisma-mongodb/package.json +183 -0
  35. package/generated/prisma-mongodb/query-engine-debian-openssl-3.0.x +0 -0
  36. package/generated/prisma-mongodb/query-engine-rhel-openssl-3.0.x +0 -0
  37. package/generated/prisma-mongodb/runtime/binary.d.ts +1 -0
  38. package/generated/prisma-mongodb/runtime/binary.js +289 -0
  39. package/generated/prisma-mongodb/runtime/edge-esm.js +34 -0
  40. package/generated/prisma-mongodb/runtime/edge.js +34 -0
  41. package/generated/prisma-mongodb/runtime/index-browser.d.ts +370 -0
  42. package/generated/prisma-mongodb/runtime/index-browser.js +16 -0
  43. package/generated/prisma-mongodb/runtime/library.d.ts +3977 -0
  44. package/generated/prisma-mongodb/runtime/react-native.js +83 -0
  45. package/generated/prisma-mongodb/runtime/wasm-compiler-edge.js +84 -0
  46. package/generated/prisma-mongodb/runtime/wasm-engine-edge.js +36 -0
  47. package/generated/prisma-mongodb/schema.prisma +362 -0
  48. package/generated/prisma-mongodb/wasm-edge-light-loader.mjs +4 -0
  49. package/generated/prisma-mongodb/wasm-worker-loader.mjs +4 -0
  50. package/generated/prisma-mongodb/wasm.d.ts +1 -0
  51. package/generated/prisma-mongodb/wasm.js +341 -0
  52. package/generated/prisma-postgresql/client.d.ts +1 -0
  53. package/generated/prisma-postgresql/client.js +4 -0
  54. package/generated/prisma-postgresql/default.d.ts +1 -0
  55. package/generated/prisma-postgresql/default.js +4 -0
  56. package/generated/prisma-postgresql/edge.d.ts +1 -0
  57. package/generated/prisma-postgresql/edge.js +356 -0
  58. package/generated/prisma-postgresql/index-browser.js +338 -0
  59. package/generated/prisma-postgresql/index.d.ts +25071 -0
  60. package/generated/prisma-postgresql/index.js +381 -0
  61. package/generated/prisma-postgresql/package.json +183 -0
  62. package/generated/prisma-postgresql/query-engine-debian-openssl-3.0.x +0 -0
  63. package/generated/prisma-postgresql/query-engine-rhel-openssl-3.0.x +0 -0
  64. package/generated/prisma-postgresql/query_engine_bg.js +2 -0
  65. package/generated/prisma-postgresql/query_engine_bg.wasm +0 -0
  66. package/generated/prisma-postgresql/runtime/binary.d.ts +1 -0
  67. package/generated/prisma-postgresql/runtime/binary.js +289 -0
  68. package/generated/prisma-postgresql/runtime/edge-esm.js +34 -0
  69. package/generated/prisma-postgresql/runtime/edge.js +34 -0
  70. package/generated/prisma-postgresql/runtime/index-browser.d.ts +370 -0
  71. package/generated/prisma-postgresql/runtime/index-browser.js +16 -0
  72. package/generated/prisma-postgresql/runtime/library.d.ts +3977 -0
  73. package/generated/prisma-postgresql/runtime/react-native.js +83 -0
  74. package/generated/prisma-postgresql/runtime/wasm-compiler-edge.js +84 -0
  75. package/generated/prisma-postgresql/runtime/wasm-engine-edge.js +36 -0
  76. package/generated/prisma-postgresql/schema.prisma +345 -0
  77. package/generated/prisma-postgresql/wasm-edge-light-loader.mjs +4 -0
  78. package/generated/prisma-postgresql/wasm-worker-loader.mjs +4 -0
  79. package/generated/prisma-postgresql/wasm.d.ts +1 -0
  80. package/generated/prisma-postgresql/wasm.js +363 -0
  81. package/handlers/database-migration-handler.js +227 -0
  82. package/handlers/routers/auth.js +1 -1
  83. package/handlers/routers/db-migration.handler.js +29 -0
  84. package/handlers/routers/db-migration.js +256 -0
  85. package/handlers/routers/health.js +41 -6
  86. package/handlers/routers/integration-webhook-routers.js +2 -2
  87. package/handlers/use-cases/check-integrations-health-use-case.js +22 -10
  88. package/handlers/workers/db-migration.js +352 -0
  89. package/index.js +12 -0
  90. package/integrations/integration-router.js +60 -70
  91. package/integrations/repositories/integration-repository-interface.js +12 -0
  92. package/integrations/repositories/integration-repository-mongo.js +32 -0
  93. package/integrations/repositories/integration-repository-postgres.js +33 -0
  94. package/integrations/repositories/process-repository-postgres.js +2 -2
  95. package/integrations/tests/doubles/test-integration-repository.js +2 -2
  96. package/logs/logger.js +0 -4
  97. package/modules/entity.js +0 -1
  98. package/modules/repositories/module-repository-mongo.js +3 -12
  99. package/modules/repositories/module-repository-postgres.js +0 -11
  100. package/modules/repositories/module-repository.js +1 -12
  101. package/modules/use-cases/get-entity-options-by-id.js +1 -1
  102. package/modules/use-cases/get-module.js +1 -2
  103. package/modules/use-cases/refresh-entity-options.js +1 -1
  104. package/modules/use-cases/test-module-auth.js +1 -1
  105. package/package.json +82 -66
  106. package/prisma-mongodb/schema.prisma +21 -21
  107. package/prisma-postgresql/schema.prisma +15 -15
  108. package/queues/queuer-util.js +24 -21
  109. package/types/core/index.d.ts +2 -2
  110. package/types/module-plugin/index.d.ts +0 -2
  111. package/user/use-cases/authenticate-user.js +127 -0
  112. package/user/use-cases/authenticate-with-shared-secret.js +48 -0
  113. package/user/use-cases/get-user-from-adopter-jwt.js +149 -0
  114. package/user/use-cases/get-user-from-x-frigg-headers.js +106 -0
  115. package/user/user.js +16 -0
  116. package/websocket/repositories/websocket-connection-repository-mongo.js +11 -10
  117. package/websocket/repositories/websocket-connection-repository-postgres.js +11 -10
  118. package/websocket/repositories/websocket-connection-repository.js +11 -10
  119. package/application/commands/integration-commands.test.js +0 -123
  120. package/database/encryption/encryption-integration.test.js +0 -553
  121. package/database/encryption/encryption-schema-registry.test.js +0 -392
  122. package/database/encryption/field-encryption-service.test.js +0 -525
  123. package/database/encryption/mongo-decryption-fix-verification.test.js +0 -348
  124. package/database/encryption/postgres-decryption-fix-verification.test.js +0 -371
  125. package/database/encryption/postgres-relation-decryption.test.js +0 -245
  126. package/database/encryption/prisma-encryption-extension.test.js +0 -439
  127. package/errors/base-error.test.js +0 -32
  128. package/errors/fetch-error.test.js +0 -79
  129. package/errors/halt-error.test.js +0 -11
  130. package/errors/validation-errors.test.js +0 -120
  131. package/handlers/auth-flow.integration.test.js +0 -147
  132. package/handlers/integration-event-dispatcher.test.js +0 -209
  133. package/handlers/routers/health.test.js +0 -210
  134. package/handlers/routers/integration-webhook-routers.test.js +0 -126
  135. package/handlers/webhook-flow.integration.test.js +0 -356
  136. package/handlers/workers/integration-defined-workers.test.js +0 -184
  137. package/integrations/tests/use-cases/create-integration.test.js +0 -131
  138. package/integrations/tests/use-cases/delete-integration-for-user.test.js +0 -150
  139. package/integrations/tests/use-cases/find-integration-context-by-external-entity-id.test.js +0 -92
  140. package/integrations/tests/use-cases/get-integration-for-user.test.js +0 -150
  141. package/integrations/tests/use-cases/get-integration-instance.test.js +0 -176
  142. package/integrations/tests/use-cases/get-integrations-for-user.test.js +0 -176
  143. package/integrations/tests/use-cases/get-possible-integrations.test.js +0 -188
  144. package/integrations/tests/use-cases/update-integration-messages.test.js +0 -142
  145. package/integrations/tests/use-cases/update-integration-status.test.js +0 -103
  146. package/integrations/tests/use-cases/update-integration.test.js +0 -141
  147. package/integrations/use-cases/create-process.test.js +0 -178
  148. package/integrations/use-cases/get-process.test.js +0 -190
  149. package/integrations/use-cases/load-integration-context-full.test.js +0 -329
  150. package/integrations/use-cases/load-integration-context.test.js +0 -114
  151. package/integrations/use-cases/update-process-metrics.test.js +0 -308
  152. package/integrations/use-cases/update-process-state.test.js +0 -256
  153. package/lambda/TimeoutCatcher.test.js +0 -68
  154. package/logs/logger.test.js +0 -76
  155. package/modules/module-hydration.test.js +0 -205
  156. package/modules/requester/requester.test.js +0 -28
  157. package/user/tests/use-cases/create-individual-user.test.js +0 -24
  158. package/user/tests/use-cases/create-organization-user.test.js +0 -28
  159. package/user/tests/use-cases/create-token-for-user-id.test.js +0 -19
  160. package/user/tests/use-cases/get-user-from-bearer-token.test.js +0 -64
  161. package/user/tests/use-cases/login-user.test.js +0 -220
  162. package/user/tests/user-password-encryption-isolation.test.js +0 -237
  163. package/user/tests/user-password-hashing.test.js +0 -235
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Database Migration Router
3
+ *
4
+ * HTTP API for triggering and monitoring database migrations.
5
+ *
6
+ * Endpoints:
7
+ * - GET /db-migrate/status - Check if migrations are pending
8
+ * - POST /db-migrate - Trigger async migration (queues job)
9
+ * - GET /db-migrate/:processId - Check migration status
10
+ *
11
+ * Security:
12
+ * - Requires ADMIN_API_KEY header for all requests
13
+ *
14
+ * Architecture:
15
+ * - Router (Adapter Layer) → Use Cases (Domain) → Repositories (Infrastructure)
16
+ * - Follows DDD/Hexagonal architecture
17
+ */
18
+
19
+ const { Router } = require('express');
20
+ const catchAsyncError = require('express-async-handler');
21
+ const { MigrationStatusRepositoryS3 } = require('../../database/repositories/migration-status-repository-s3');
22
+ const {
23
+ TriggerDatabaseMigrationUseCase,
24
+ ValidationError: TriggerValidationError,
25
+ } = require('../../database/use-cases/trigger-database-migration-use-case');
26
+ const {
27
+ GetMigrationStatusUseCase,
28
+ ValidationError: GetValidationError,
29
+ NotFoundError,
30
+ } = require('../../database/use-cases/get-migration-status-use-case');
31
+ const { LambdaInvoker } = require('../../database/adapters/lambda-invoker');
32
+ const {
33
+ GetDatabaseStateViaWorkerUseCase,
34
+ } = require('../../database/use-cases/get-database-state-via-worker-use-case');
35
+
36
+ const router = Router();
37
+
38
+ // Dependency injection
39
+ // Use S3 repository to avoid User table dependency (chicken-and-egg problem)
40
+ const bucketName = process.env.S3_BUCKET_NAME || process.env.MIGRATION_STATUS_BUCKET;
41
+ const migrationStatusRepository = new MigrationStatusRepositoryS3(bucketName);
42
+
43
+ const triggerMigrationUseCase = new TriggerDatabaseMigrationUseCase({
44
+ migrationStatusRepository,
45
+ // Note: QueuerUtil is used directly in the use case (static utility)
46
+ });
47
+ const getStatusUseCase = new GetMigrationStatusUseCase({ migrationStatusRepository });
48
+
49
+ // Lambda invocation for database state check (keeps router lightweight)
50
+ const lambdaInvoker = new LambdaInvoker();
51
+ const workerFunctionName = process.env.WORKER_FUNCTION_NAME ||
52
+ `${process.env.SERVICE || 'unknown'}-${process.env.STAGE || 'production'}-dbMigrationWorker`;
53
+
54
+ const getDatabaseStateUseCase = new GetDatabaseStateViaWorkerUseCase({
55
+ lambdaInvoker,
56
+ workerFunctionName,
57
+ });
58
+
59
+ /**
60
+ * Admin API key validation middleware
61
+ * Matches pattern from health.js:72-88
62
+ */
63
+ const validateApiKey = (req, res, next) => {
64
+ const apiKey = req.headers['x-frigg-admin-api-key'];
65
+
66
+ if (!apiKey || apiKey !== process.env.ADMIN_API_KEY) {
67
+ console.error('Unauthorized access attempt to db-migrate endpoint');
68
+ return res.status(401).json({
69
+ status: 'error',
70
+ message: 'Unauthorized - x-frigg-admin-api-key header required',
71
+ });
72
+ }
73
+
74
+ next();
75
+ };
76
+
77
+ // Apply API key validation to all routes
78
+ router.use(validateApiKey);
79
+
80
+ /**
81
+ * POST /db-migrate
82
+ *
83
+ * Trigger database migration (async via SQS queue)
84
+ *
85
+ * Request body:
86
+ * {
87
+ * userId: string (optional, defaults to 'admin'),
88
+ * dbType: 'postgresql' | 'mongodb',
89
+ * stage: string (e.g., 'production', 'dev')
90
+ * }
91
+ *
92
+ * Response (202 Accepted):
93
+ * {
94
+ * success: true,
95
+ * processId: string,
96
+ * state: 'INITIALIZING',
97
+ * statusUrl: string,
98
+ * message: string
99
+ * }
100
+ */
101
+ router.post(
102
+ '/db-migrate',
103
+ catchAsyncError(async (req, res) => {
104
+ // Migration infrastructure is PostgreSQL-only, so hardcode dbType
105
+ const dbType = 'postgresql';
106
+ const { stage } = req.body;
107
+ // TODO: Extract userId from JWT token when auth is implemented
108
+ const userId = req.body.userId || 'admin';
109
+
110
+ console.log(`Migration trigger request: dbType=${dbType}, stage=${stage || 'auto-detect'}, userId=${userId}`);
111
+
112
+ try {
113
+ const result = await triggerMigrationUseCase.execute({
114
+ userId,
115
+ dbType,
116
+ stage,
117
+ });
118
+
119
+ // 202 Accepted - request accepted but not completed
120
+ res.status(202).json(result);
121
+ } catch (error) {
122
+ // Handle validation errors (400 Bad Request)
123
+ if (error instanceof TriggerValidationError) {
124
+ return res.status(400).json({
125
+ success: false,
126
+ error: error.message,
127
+ });
128
+ }
129
+
130
+ // Re-throw other errors for global error handler
131
+ throw error;
132
+ }
133
+ })
134
+ );
135
+
136
+ /**
137
+ * GET /db-migrate/status
138
+ *
139
+ * Check if database has pending migrations
140
+ *
141
+ * Query params:
142
+ * - stage: string (optional, defaults to STAGE env var or 'production')
143
+ *
144
+ * Response (200 OK):
145
+ * {
146
+ * upToDate: boolean,
147
+ * pendingMigrations: number,
148
+ * dbType: 'postgresql',
149
+ * stage: string,
150
+ * recommendation?: string (if migrations pending),
151
+ * error?: string (if database check failed)
152
+ * }
153
+ */
154
+ router.get(
155
+ '/db-migrate/status',
156
+ catchAsyncError(async (req, res) => {
157
+ const stage = req.query.stage || process.env.STAGE || 'production';
158
+
159
+ console.log(`Checking database state: stage=${stage}, worker=${workerFunctionName}`);
160
+
161
+ try {
162
+ // Invoke worker Lambda to check database state
163
+ const status = await getDatabaseStateUseCase.execute(stage);
164
+
165
+ res.status(200).json(status);
166
+ } catch (error) {
167
+ // Log full error for debugging
168
+ console.error('Database state check failed:', error);
169
+
170
+ // Return sanitized error to client
171
+ return res.status(500).json({
172
+ success: false,
173
+ error: 'Failed to check database state',
174
+ details: error.message,
175
+ });
176
+ }
177
+ })
178
+ );
179
+
180
+ /**
181
+ * GET /db-migrate/:migrationId
182
+ *
183
+ * Get migration status by migration ID
184
+ *
185
+ * Response (200 OK):
186
+ * {
187
+ * processId: string,
188
+ * type: 'DATABASE_MIGRATION',
189
+ * state: 'INITIALIZING' | 'RUNNING' | 'COMPLETED' | 'FAILED',
190
+ * context: {
191
+ * dbType: string,
192
+ * stage: string,
193
+ * migrationCommand: string (if started)
194
+ * },
195
+ * results: {
196
+ * success: boolean (if completed),
197
+ * duration: string (if completed),
198
+ * error: string (if failed)
199
+ * },
200
+ * createdAt: string,
201
+ * updatedAt: string
202
+ * }
203
+ */
204
+ router.get(
205
+ '/db-migrate/:migrationId',
206
+ catchAsyncError(async (req, res) => {
207
+ const { migrationId } = req.params;
208
+ const stage = req.query.stage || process.env.STAGE || 'production';
209
+
210
+ console.log(`Migration status request: migrationId=${migrationId}, stage=${stage}`);
211
+
212
+ try {
213
+ const status = await getStatusUseCase.execute(migrationId, stage);
214
+
215
+ res.status(200).json(status);
216
+ } catch (error) {
217
+ // Handle not found errors (404 Not Found)
218
+ if (error instanceof NotFoundError) {
219
+ return res.status(404).json({
220
+ success: false,
221
+ error: error.message,
222
+ });
223
+ }
224
+
225
+ // Handle validation errors (400 Bad Request)
226
+ if (error instanceof GetValidationError) {
227
+ return res.status(400).json({
228
+ success: false,
229
+ error: error.message,
230
+ });
231
+ }
232
+
233
+ // Re-throw other errors for global error handler
234
+ throw error;
235
+ }
236
+ })
237
+ );
238
+
239
+ // Minimal Lambda handler (avoids app-handler-helpers which loads core/index.js → user/**)
240
+ const serverlessHttp = require('serverless-http');
241
+ const express = require('express');
242
+ const cors = require('cors');
243
+
244
+ const app = express();
245
+ app.use(cors());
246
+ app.use(express.json());
247
+ app.use(router);
248
+ app.use((err, req, res, next) => {
249
+ console.error('Migration Router Error:', err);
250
+ res.status(500).json({ message: 'Internal Server Error' });
251
+ });
252
+
253
+ const handler = serverlessHttp(app);
254
+
255
+ module.exports = { handler, router };
256
+
@@ -1,6 +1,16 @@
1
1
  const { Router } = require('express');
2
- const { moduleFactory, integrationFactory } = require('./../backend-utils');
3
2
  const { createAppHandler } = require('./../app-handler-helpers');
3
+ const { loadAppDefinition } = require('./../app-definition-loader');
4
+ const { ModuleFactory } = require('../../modules/module-factory');
5
+ const {
6
+ getModulesDefinitionFromIntegrationClasses,
7
+ } = require('../../integrations/utils/map-integration-dto');
8
+ const {
9
+ createModuleRepository,
10
+ } = require('../../modules/repositories/module-repository-factory');
11
+ const {
12
+ createIntegrationRepository,
13
+ } = require('../../integrations/repositories/integration-repository-factory');
4
14
  const {
5
15
  createHealthCheckRepository,
6
16
  } = require('../../database/repositories/health-check-repository-factory');
@@ -22,6 +32,28 @@ const {
22
32
 
23
33
  const router = Router();
24
34
  const healthCheckRepository = createHealthCheckRepository();
35
+
36
+ // Load integrations and create factories just like auth router does
37
+ // This verifies the system can properly load integrations
38
+ let moduleFactory, integrationClasses;
39
+ try {
40
+ const appDef = loadAppDefinition();
41
+ integrationClasses = appDef.integrations || [];
42
+
43
+ const moduleRepository = createModuleRepository();
44
+ const moduleDefinitions = getModulesDefinitionFromIntegrationClasses(integrationClasses);
45
+
46
+ moduleFactory = new ModuleFactory({
47
+ moduleRepository,
48
+ moduleDefinitions,
49
+ });
50
+ } catch (error) {
51
+ console.error('Failed to load integrations for health check:', error.message);
52
+ // Factories will be undefined, health check will report unhealthy
53
+ moduleFactory = undefined;
54
+ integrationClasses = [];
55
+ }
56
+
25
57
  const testEncryptionUseCase = new TestEncryptionUseCase({
26
58
  healthCheckRepository,
27
59
  });
@@ -34,11 +66,11 @@ const checkEncryptionHealthUseCase = new CheckEncryptionHealthUseCase({
34
66
  const checkExternalApisHealthUseCase = new CheckExternalApisHealthUseCase();
35
67
  const checkIntegrationsHealthUseCase = new CheckIntegrationsHealthUseCase({
36
68
  moduleFactory,
37
- integrationFactory,
69
+ integrationClasses,
38
70
  });
39
71
 
40
72
  const validateApiKey = (req, res, next) => {
41
- const apiKey = req.headers['x-api-key'];
73
+ const apiKey = req.headers['x-frigg-health-api-key'];
42
74
 
43
75
  if (req.path === '/health') {
44
76
  return next();
@@ -48,7 +80,7 @@ const validateApiKey = (req, res, next) => {
48
80
  console.error('Unauthorized access attempt to health endpoint');
49
81
  return res.status(401).json({
50
82
  status: 'error',
51
- message: 'Unauthorized',
83
+ message: 'Unauthorized - x-frigg-health-api-key header required',
52
84
  });
53
85
  }
54
86
 
@@ -141,8 +173,11 @@ const detectVpcConfiguration = async () => {
141
173
  }
142
174
  }
143
175
 
144
- results.isInVpc =
145
- !results.hasInternetAccess || results.vpcEndpoints.length > 0;
176
+ // Check if Lambda is in VPC using VPC_ENABLED env var set by infrastructure
177
+ results.isInVpc = process.env.VPC_ENABLED === 'true' ||
178
+ (!results.hasInternetAccess && results.canResolvePublicDns) ||
179
+ results.vpcEndpoints.length > 0;
180
+
146
181
  results.canConnectToAws =
147
182
  results.hasInternetAccess || results.vpcEndpoints.length > 0;
148
183
  } catch (error) {
@@ -20,7 +20,7 @@ for (const IntegrationClass of integrationClasses) {
20
20
  console.log(`\n│ Configuring webhook routes for ${IntegrationClass.Definition.name}:`);
21
21
 
22
22
  // General webhook route (no integration ID)
23
- router.post('/', async (req, res, next) => {
23
+ router.post(basePath, async (req, res, next) => {
24
24
  try {
25
25
  const integrationInstance = new IntegrationClass();
26
26
  const dispatcher = new IntegrationEventDispatcher(integrationInstance);
@@ -37,7 +37,7 @@ for (const IntegrationClass of integrationClasses) {
37
37
  console.log(`│ POST ${basePath}`);
38
38
 
39
39
  // Integration-specific webhook route (with integration ID)
40
- router.post('/:integrationId', async (req, res, next) => {
40
+ router.post(`${basePath}/:integrationId`, async (req, res, next) => {
41
41
  try {
42
42
  const integrationInstance = new IntegrationClass();
43
43
  const dispatcher = new IntegrationEventDispatcher(integrationInstance);
@@ -1,20 +1,32 @@
1
1
  class CheckIntegrationsHealthUseCase {
2
- constructor({ moduleFactory, integrationFactory }) {
2
+ constructor({ moduleFactory, integrationClasses }) {
3
3
  this.moduleFactory = moduleFactory;
4
- this.integrationFactory = integrationFactory;
4
+ this.integrationClasses = integrationClasses;
5
5
  }
6
6
 
7
7
  execute() {
8
- const moduleTypes = Array.isArray(this.moduleFactory.moduleTypes)
9
- ? this.moduleFactory.moduleTypes
8
+ const moduleDefinitions = (this.moduleFactory && this.moduleFactory.moduleDefinitions)
9
+ ? this.moduleFactory.moduleDefinitions
10
10
  : [];
11
11
 
12
- const integrationTypes = Array.isArray(
13
- this.integrationFactory.integrationTypes
14
- )
15
- ? this.integrationFactory.integrationTypes
12
+ const integrationClasses = Array.isArray(this.integrationClasses)
13
+ ? this.integrationClasses
16
14
  : [];
17
15
 
16
+ // Extract module names from definitions
17
+ const moduleTypes = Array.isArray(moduleDefinitions)
18
+ ? moduleDefinitions.map(def => def.moduleName || def.name || def.label || 'Unknown')
19
+ : [];
20
+
21
+ // Extract integration names from classes
22
+ const integrationNames = integrationClasses.map(IntegrationClass => {
23
+ try {
24
+ return IntegrationClass.Definition?.name || IntegrationClass.name || 'Unknown';
25
+ } catch {
26
+ return 'Unknown';
27
+ }
28
+ });
29
+
18
30
  return {
19
31
  status: 'healthy',
20
32
  modules: {
@@ -22,8 +34,8 @@ class CheckIntegrationsHealthUseCase {
22
34
  available: moduleTypes,
23
35
  },
24
36
  integrations: {
25
- count: integrationTypes.length,
26
- available: integrationTypes,
37
+ count: integrationNames.length,
38
+ available: integrationNames,
27
39
  },
28
40
  };
29
41
  }