@friggframework/core 2.0.0--canary.522.cbd3d5a.0 → 2.0.0--canary.517.35ee143.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 (225) hide show
  1. package/CHANGELOG.md +67 -66
  2. package/CLAUDE.md +124 -148
  3. package/README.md +130 -165
  4. package/admin-scripts/index.js +16 -30
  5. package/admin-scripts/repositories/{admin-api-key-repository-documentdb.js → admin-process-repository-documentdb.js} +5 -5
  6. package/admin-scripts/repositories/{admin-api-key-repository-factory.js → admin-process-repository-factory.js} +15 -19
  7. package/admin-scripts/repositories/admin-process-repository-interface.js +150 -0
  8. package/admin-scripts/repositories/admin-process-repository-mongo.js +213 -0
  9. package/admin-scripts/repositories/admin-process-repository-postgres.js +251 -0
  10. package/admin-scripts/repositories/script-schedule-repository-factory.js +2 -6
  11. package/admin-scripts/repositories/script-schedule-repository-interface.js +14 -36
  12. package/admin-scripts/repositories/script-schedule-repository-mongo.js +13 -25
  13. package/admin-scripts/repositories/script-schedule-repository-postgres.js +13 -25
  14. package/application/commands/admin-script-commands.js +102 -266
  15. package/application/commands/integration-commands.js +6 -12
  16. package/application/index.js +3 -1
  17. package/assertions/get.js +4 -1
  18. package/associations/association.js +57 -59
  19. package/associations/model.js +41 -41
  20. package/core/CLAUDE.md +156 -222
  21. package/core/Worker.js +1 -5
  22. package/credential/repositories/credential-repository-documentdb.js +1 -71
  23. package/credential/repositories/credential-repository-interface.js +2 -8
  24. package/credential/repositories/credential-repository-mongo.js +4 -45
  25. package/credential/repositories/credential-repository-postgres.js +3 -44
  26. package/credential/repositories/credential-repository.js +4 -6
  27. package/credential/use-cases/get-credential-for-user.js +3 -21
  28. package/credential/use-cases/update-authentication-status.js +2 -5
  29. package/database/MONGODB_TRANSACTION_FIX.md +52 -72
  30. package/database/adapters/lambda-invoker.js +7 -8
  31. package/database/config.js +13 -15
  32. package/database/documentdb-encryption-service.js +13 -29
  33. package/database/documentdb-utils.js +12 -21
  34. package/database/encryption/README.md +36 -53
  35. package/database/encryption/encryption-schema-registry.js +9 -21
  36. package/database/encryption/field-encryption-service.js +4 -15
  37. package/database/encryption/logger.js +2 -3
  38. package/database/encryption/prisma-encryption-extension.js +8 -5
  39. package/database/index.js +2 -4
  40. package/database/models/IndividualUser.js +15 -15
  41. package/database/models/OrganizationUser.js +4 -6
  42. package/database/models/UserModel.js +2 -2
  43. package/database/models/WebsocketConnection.js +1 -4
  44. package/database/mongoose.js +2 -2
  45. package/database/prisma.js +14 -22
  46. package/database/repositories/health-check-repository-documentdb.js +7 -22
  47. package/database/repositories/health-check-repository-factory.js +3 -9
  48. package/database/repositories/health-check-repository-interface.js +5 -15
  49. package/database/repositories/health-check-repository-mongodb.js +6 -9
  50. package/database/repositories/health-check-repository-postgres.js +1 -1
  51. package/database/repositories/migration-status-repository-s3.js +5 -10
  52. package/database/use-cases/check-database-health-use-case.js +2 -3
  53. package/database/use-cases/check-database-state-use-case.js +7 -9
  54. package/database/use-cases/get-database-state-via-worker-use-case.js +12 -15
  55. package/database/use-cases/get-migration-status-use-case.js +2 -4
  56. package/database/use-cases/run-database-migration-use-case.js +9 -41
  57. package/database/use-cases/test-encryption-use-case.js +5 -4
  58. package/database/use-cases/trigger-database-migration-use-case.js +8 -9
  59. package/database/utils/mongodb-collection-utils.js +3 -11
  60. package/database/utils/mongodb-schema-init.js +4 -10
  61. package/database/utils/prisma-runner.js +74 -144
  62. package/database/utils/prisma-schema-parser.js +2 -2
  63. package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +80 -135
  64. package/encrypt/Cryptor.js +2 -8
  65. package/errors/fetch-error.js +1 -1
  66. package/generated/prisma-mongodb/edge.js +16 -59
  67. package/generated/prisma-mongodb/index-browser.js +12 -62
  68. package/generated/prisma-mongodb/index.d.ts +4850 -8136
  69. package/generated/prisma-mongodb/index.js +16 -59
  70. package/generated/prisma-mongodb/package.json +1 -1
  71. package/generated/prisma-mongodb/schema.prisma +33 -75
  72. package/generated/prisma-mongodb/wasm.js +16 -59
  73. package/generated/prisma-postgresql/edge.js +15 -59
  74. package/generated/prisma-postgresql/index-browser.js +11 -62
  75. package/generated/prisma-postgresql/index.d.ts +5963 -8930
  76. package/generated/prisma-postgresql/index.js +15 -59
  77. package/generated/prisma-postgresql/package.json +1 -1
  78. package/generated/prisma-postgresql/schema.prisma +33 -73
  79. package/generated/prisma-postgresql/wasm.js +15 -59
  80. package/handlers/WEBHOOKS.md +81 -104
  81. package/handlers/app-definition-loader.js +1 -1
  82. package/handlers/app-handler-helpers.js +2 -14
  83. package/handlers/backend-utils.js +1 -0
  84. package/handlers/database-migration-handler.js +45 -64
  85. package/handlers/middleware/admin-auth.js +53 -0
  86. package/handlers/routers/HEALTHCHECK.md +135 -170
  87. package/handlers/routers/auth.js +2 -23
  88. package/handlers/routers/db-migration.handler.js +3 -2
  89. package/handlers/routers/db-migration.js +33 -69
  90. package/handlers/routers/health.js +8 -23
  91. package/handlers/routers/integration-defined-routers.js +4 -4
  92. package/handlers/routers/integration-webhook-routers.js +7 -17
  93. package/handlers/routers/websocket.js +3 -9
  94. package/handlers/use-cases/check-integrations-health-use-case.js +6 -13
  95. package/handlers/workers/db-migration.js +26 -54
  96. package/index.js +9 -5
  97. package/integrations/WEBHOOK-QUICKSTART.md +14 -21
  98. package/integrations/index.js +0 -4
  99. package/integrations/integration-base.js +6 -9
  100. package/integrations/integration-router.js +146 -1817
  101. package/integrations/options.js +20 -47
  102. package/integrations/repositories/integration-repository-documentdb.js +24 -53
  103. package/integrations/repositories/integration-repository-factory.js +2 -6
  104. package/integrations/repositories/integration-repository-interface.js +9 -27
  105. package/integrations/repositories/integration-repository-postgres.js +3 -3
  106. package/integrations/repositories/process-repository-factory.js +1 -0
  107. package/integrations/repositories/process-repository-interface.js +5 -9
  108. package/integrations/repositories/process-repository-mongo.js +3 -7
  109. package/integrations/repositories/process-repository-postgres.js +2 -2
  110. package/integrations/tests/doubles/config-capturing-integration.js +8 -9
  111. package/integrations/tests/doubles/dummy-integration-class.js +8 -81
  112. package/integrations/tests/doubles/test-integration-repository.js +11 -51
  113. package/integrations/use-cases/create-integration.js +32 -36
  114. package/integrations/use-cases/create-process.js +9 -20
  115. package/integrations/use-cases/delete-integration-for-user.js +4 -5
  116. package/integrations/use-cases/get-integration-for-user.js +10 -25
  117. package/integrations/use-cases/get-integration-instance-by-definition.js +7 -13
  118. package/integrations/use-cases/get-integrations-for-user.js +1 -4
  119. package/integrations/use-cases/get-possible-integrations.js +1 -1
  120. package/integrations/use-cases/get-process.js +6 -5
  121. package/integrations/use-cases/index.js +1 -3
  122. package/integrations/use-cases/load-integration-context.js +5 -1
  123. package/integrations/use-cases/update-process-state.js +8 -10
  124. package/integrations/utils/map-integration-dto.js +3 -9
  125. package/jest-setup.js +1 -1
  126. package/jest-teardown.js +1 -1
  127. package/lambda/TimeoutCatcher.js +30 -32
  128. package/lambda/index.js +1 -1
  129. package/logs/index.js +3 -3
  130. package/modules/module.js +1 -3
  131. package/modules/repositories/module-repository-documentdb.js +48 -114
  132. package/modules/repositories/module-repository-interface.js +0 -13
  133. package/modules/repositories/module-repository-mongo.js +6 -46
  134. package/modules/repositories/module-repository-postgres.js +6 -48
  135. package/modules/repositories/module-repository.js +1 -34
  136. package/modules/requester/api-key.js +2 -0
  137. package/modules/requester/basic.js +1 -0
  138. package/modules/requester/oauth-2.js +2 -3
  139. package/modules/test/mock-api/definition.js +10 -15
  140. package/modules/test/mock-api/mocks/hubspot.js +36 -36
  141. package/modules/tests/doubles/test-module-factory.js +4 -10
  142. package/modules/tests/doubles/test-module-repository.js +1 -1
  143. package/modules/use-cases/get-entities-for-user.js +1 -1
  144. package/modules/use-cases/get-entity-options-by-id.js +6 -8
  145. package/modules/use-cases/get-module.js +9 -12
  146. package/modules/use-cases/process-authorization-callback.js +6 -12
  147. package/modules/use-cases/refresh-entity-options.js +6 -8
  148. package/modules/use-cases/test-module-auth.js +6 -8
  149. package/modules/utils/map-module-dto.js +2 -2
  150. package/package.json +5 -7
  151. package/prisma-mongodb/schema.prisma +33 -75
  152. package/prisma-postgresql/schema.prisma +33 -73
  153. package/queues/queuer-util.js +1 -5
  154. package/syncs/model.js +51 -51
  155. package/syncs/repositories/sync-repository-documentdb.js +19 -39
  156. package/syncs/repositories/sync-repository-interface.js +2 -6
  157. package/syncs/repositories/sync-repository-postgres.js +13 -19
  158. package/syncs/sync.js +100 -104
  159. package/token/repositories/token-repository-factory.js +3 -1
  160. package/types/assertions/index.d.ts +72 -72
  161. package/types/associations/index.d.ts +57 -57
  162. package/types/core/index.d.ts +53 -59
  163. package/types/database/index.d.ts +2 -2
  164. package/types/encrypt/index.d.ts +3 -3
  165. package/types/errors/index.d.ts +54 -61
  166. package/types/eslint-config/index.d.ts +40 -40
  167. package/types/integrations/index.d.ts +183 -185
  168. package/types/lambda/index.d.ts +26 -26
  169. package/types/logs/index.d.ts +4 -4
  170. package/types/module-plugin/index.d.ts +237 -239
  171. package/types/prettier-config/index.d.ts +5 -5
  172. package/types/syncs/index.d.ts +108 -102
  173. package/types/test-environment/index.d.ts +14 -14
  174. package/types/tsconfig.json +93 -95
  175. package/user/tests/doubles/test-user-repository.js +2 -5
  176. package/user/use-cases/authenticate-user.js +4 -2
  177. package/user/use-cases/authenticate-with-shared-secret.js +1 -1
  178. package/user/use-cases/create-individual-user.js +7 -8
  179. package/user/use-cases/create-organization-user.js +1 -1
  180. package/user/use-cases/create-token-for-user-id.js +1 -1
  181. package/user/use-cases/get-user-from-adopter-jwt.js +2 -0
  182. package/user/use-cases/get-user-from-bearer-token.js +3 -7
  183. package/user/use-cases/get-user-from-x-frigg-headers.js +11 -14
  184. package/user/use-cases/login-user.js +8 -8
  185. package/user/user.js +4 -18
  186. package/utils/backend-path.js +2 -2
  187. package/utils/index.js +1 -4
  188. package/websocket/repositories/websocket-connection-repository-documentdb.js +8 -21
  189. package/websocket/repositories/websocket-connection-repository-mongo.js +4 -8
  190. package/websocket/repositories/websocket-connection-repository-postgres.js +4 -8
  191. package/websocket/repositories/websocket-connection-repository.js +4 -8
  192. package/admin-scripts/repositories/admin-api-key-repository-interface.js +0 -121
  193. package/admin-scripts/repositories/admin-api-key-repository-mongo.js +0 -155
  194. package/admin-scripts/repositories/admin-api-key-repository-postgres.js +0 -189
  195. package/admin-scripts/repositories/script-execution-repository-documentdb.js +0 -21
  196. package/admin-scripts/repositories/script-execution-repository-factory.js +0 -55
  197. package/admin-scripts/repositories/script-execution-repository-interface.js +0 -193
  198. package/admin-scripts/repositories/script-execution-repository-mongo.js +0 -278
  199. package/admin-scripts/repositories/script-execution-repository-postgres.js +0 -320
  200. package/credential/credential-router.js +0 -262
  201. package/credential/use-cases/delete-credential-for-user.js +0 -50
  202. package/credential/use-cases/list-credentials-for-user.js +0 -31
  203. package/credential/use-cases/reauthorize-credential.js +0 -103
  204. package/handlers/routers/admin.js +0 -450
  205. package/handlers/routers/docs.js +0 -180
  206. package/handlers/routers/middleware/loadUser.js +0 -39
  207. package/handlers/routers/middleware/requireAdmin.js +0 -41
  208. package/handlers/routers/middleware/requireLoggedInUser.js +0 -19
  209. package/integrations/use-cases/execute-proxy-request.js +0 -564
  210. package/modules/domain/entities/AuthorizationSession.js +0 -131
  211. package/modules/domain/entities/index.js +0 -10
  212. package/modules/repositories/authorization-session-repository-factory.js +0 -55
  213. package/modules/repositories/authorization-session-repository-interface.js +0 -75
  214. package/modules/repositories/authorization-session-repository-mongo.js +0 -169
  215. package/modules/repositories/authorization-session-repository-postgres.js +0 -170
  216. package/modules/use-cases/delete-module-entity.js +0 -23
  217. package/modules/use-cases/get-authorization-requirements.js +0 -110
  218. package/modules/use-cases/get-module-entity-by-id.js +0 -16
  219. package/modules/use-cases/process-authorization-step.js +0 -160
  220. package/modules/use-cases/start-authorization-session.js +0 -86
  221. package/modules/use-cases/update-module-entity.js +0 -27
  222. package/openapi/openapi-spec-generator.js +0 -370
  223. package/openapi/openapi-v1.yaml +0 -1360
  224. package/openapi/openapi-v2.yaml +0 -1535
  225. package/user/use-cases/delete-user.js +0 -47
@@ -4,12 +4,14 @@
4
4
  * HTTP API for triggering and monitoring database migrations.
5
5
  *
6
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
7
+ * - GET /admin/db-migrate/status - Check if migrations are pending
8
+ * - POST /admin/db-migrate - Trigger async migration (queues job)
9
+ * - GET /admin/db-migrate/:processId - Check migration status
10
+ * - POST /admin/db-migrate/resolve - Resolve failed migration
10
11
  *
11
12
  * Security:
12
- * - Requires ADMIN_API_KEY header for all requests
13
+ * - Requires x-frigg-admin-api-key header for all requests
14
+ * - Uses shared validateAdminApiKey middleware
13
15
  *
14
16
  * Architecture:
15
17
  * - Router (Adapter Layer) → Use Cases (Domain) → Repositories (Infrastructure)
@@ -18,9 +20,8 @@
18
20
 
19
21
  const { Router } = require('express');
20
22
  const catchAsyncError = require('express-async-handler');
21
- const {
22
- MigrationStatusRepositoryS3,
23
- } = require('../../database/repositories/migration-status-repository-s3');
23
+ const { validateAdminApiKey } = require('../middleware/admin-auth');
24
+ const { MigrationStatusRepositoryS3 } = require('../../database/repositories/migration-status-repository-s3');
24
25
  const {
25
26
  TriggerDatabaseMigrationUseCase,
26
27
  ValidationError: TriggerValidationError,
@@ -39,54 +40,30 @@ const router = Router();
39
40
 
40
41
  // Dependency injection
41
42
  // Use S3 repository to avoid User table dependency (chicken-and-egg problem)
42
- const bucketName =
43
- process.env.S3_BUCKET_NAME || process.env.MIGRATION_STATUS_BUCKET;
43
+ const bucketName = process.env.S3_BUCKET_NAME || process.env.MIGRATION_STATUS_BUCKET;
44
44
  const migrationStatusRepository = new MigrationStatusRepositoryS3(bucketName);
45
45
 
46
46
  const triggerMigrationUseCase = new TriggerDatabaseMigrationUseCase({
47
47
  migrationStatusRepository,
48
48
  // Note: QueuerUtil is used directly in the use case (static utility)
49
49
  });
50
- const getStatusUseCase = new GetMigrationStatusUseCase({
51
- migrationStatusRepository,
52
- });
50
+ const getStatusUseCase = new GetMigrationStatusUseCase({ migrationStatusRepository });
53
51
 
54
52
  // Lambda invocation for database state check (keeps router lightweight)
55
53
  const lambdaInvoker = new LambdaInvoker();
56
- const workerFunctionName =
57
- process.env.WORKER_FUNCTION_NAME ||
58
- `${process.env.SERVICE || 'unknown'}-${
59
- process.env.STAGE || 'production'
60
- }-dbMigrationWorker`;
54
+ const workerFunctionName = process.env.WORKER_FUNCTION_NAME ||
55
+ `${process.env.SERVICE || 'unknown'}-${process.env.STAGE || 'production'}-dbMigrationWorker`;
61
56
 
62
57
  const getDatabaseStateUseCase = new GetDatabaseStateViaWorkerUseCase({
63
58
  lambdaInvoker,
64
59
  workerFunctionName,
65
60
  });
66
61
 
67
- /**
68
- * Admin API key validation middleware
69
- * Matches pattern from health.js:72-88
70
- */
71
- const validateApiKey = (req, res, next) => {
72
- const apiKey = req.headers['x-frigg-admin-api-key'];
73
-
74
- if (!apiKey || apiKey !== process.env.ADMIN_API_KEY) {
75
- console.error('Unauthorized access attempt to db-migrate endpoint');
76
- return res.status(401).json({
77
- status: 'error',
78
- message: 'Unauthorized - x-frigg-admin-api-key header required',
79
- });
80
- }
81
-
82
- next();
83
- };
84
-
85
- // Apply API key validation to all routes
86
- router.use(validateApiKey);
62
+ // Apply admin API key validation to all routes (shared middleware)
63
+ router.use(validateAdminApiKey);
87
64
 
88
65
  /**
89
- * POST /db-migrate
66
+ * POST /admin/db-migrate
90
67
  *
91
68
  * Trigger database migration (async via SQS queue)
92
69
  *
@@ -107,18 +84,14 @@ router.use(validateApiKey);
107
84
  * }
108
85
  */
109
86
  router.post(
110
- '/db-migrate',
87
+ '/admin/db-migrate',
111
88
  catchAsyncError(async (req, res) => {
112
89
  const dbType = req.body.dbType || process.env.DB_TYPE || 'postgresql';
113
90
  const { stage } = req.body;
114
91
  // TODO: Extract userId from JWT token when auth is implemented
115
92
  const userId = req.body.userId || 'admin';
116
93
 
117
- console.log(
118
- `Migration trigger request: dbType=${dbType}, stage=${
119
- stage || 'auto-detect'
120
- }, userId=${userId}`
121
- );
94
+ console.log(`Migration trigger request: dbType=${dbType}, stage=${stage || 'auto-detect'}, userId=${userId}`);
122
95
 
123
96
  try {
124
97
  const result = await triggerMigrationUseCase.execute({
@@ -145,7 +118,7 @@ router.post(
145
118
  );
146
119
 
147
120
  /**
148
- * GET /db-migrate/status
121
+ * GET /admin/db-migrate/status
149
122
  *
150
123
  * Check if database has pending migrations
151
124
  *
@@ -163,13 +136,11 @@ router.post(
163
136
  * }
164
137
  */
165
138
  router.get(
166
- '/db-migrate/status',
139
+ '/admin/db-migrate/status',
167
140
  catchAsyncError(async (req, res) => {
168
141
  const stage = req.query.stage || process.env.STAGE || 'production';
169
142
 
170
- console.log(
171
- `Checking database state: stage=${stage}, worker=${workerFunctionName}`
172
- );
143
+ console.log(`Checking database state: stage=${stage}, worker=${workerFunctionName}`);
173
144
 
174
145
  try {
175
146
  // Invoke worker Lambda to check database state
@@ -191,7 +162,7 @@ router.get(
191
162
  );
192
163
 
193
164
  /**
194
- * GET /db-migrate/:migrationId
165
+ * GET /admin/db-migrate/:migrationId
195
166
  *
196
167
  * Get migration status by migration ID
197
168
  *
@@ -215,14 +186,12 @@ router.get(
215
186
  * }
216
187
  */
217
188
  router.get(
218
- '/db-migrate/:migrationId',
189
+ '/admin/db-migrate/:migrationId',
219
190
  catchAsyncError(async (req, res) => {
220
191
  const { migrationId } = req.params;
221
192
  const stage = req.query.stage || process.env.STAGE || 'production';
222
193
 
223
- console.log(
224
- `Migration status request: migrationId=${migrationId}, stage=${stage}`
225
- );
194
+ console.log(`Migration status request: migrationId=${migrationId}, stage=${stage}`);
226
195
 
227
196
  try {
228
197
  const status = await getStatusUseCase.execute(migrationId, stage);
@@ -252,7 +221,7 @@ router.get(
252
221
  );
253
222
 
254
223
  /**
255
- * POST /db-migrate/resolve
224
+ * POST /admin/db-migrate/resolve
256
225
  *
257
226
  * Resolve a failed migration by marking it as applied or rolled back
258
227
  *
@@ -272,26 +241,24 @@ router.get(
272
241
  * }
273
242
  */
274
243
  router.post(
275
- '/db-migrate/resolve',
244
+ '/admin/db-migrate/resolve',
276
245
  catchAsyncError(async (req, res) => {
277
246
  const { migrationName, action = 'applied' } = req.body;
278
247
 
279
- console.log(
280
- `Migration resolve request: migration=${migrationName}, action=${action}`
281
- );
248
+ console.log(`Migration resolve request: migration=${migrationName}, action=${action}`);
282
249
 
283
250
  // Validation
284
251
  if (!migrationName) {
285
252
  return res.status(400).json({
286
253
  success: false,
287
- error: 'migrationName is required',
254
+ error: 'migrationName is required'
288
255
  });
289
256
  }
290
257
 
291
258
  if (!['applied', 'rolled-back'].includes(action)) {
292
259
  return res.status(400).json({
293
260
  success: false,
294
- error: 'action must be either "applied" or "rolled-back"',
261
+ error: 'action must be either "applied" or "rolled-back"'
295
262
  });
296
263
  }
297
264
 
@@ -299,16 +266,12 @@ router.post(
299
266
  // Import prismaRunner here to avoid circular dependencies
300
267
  const prismaRunner = require('../../database/utils/prisma-runner');
301
268
 
302
- const result = await prismaRunner.runPrismaMigrateResolve(
303
- migrationName,
304
- action,
305
- true
306
- );
269
+ const result = await prismaRunner.runPrismaMigrateResolve(migrationName, action, true);
307
270
 
308
271
  if (!result.success) {
309
272
  return res.status(500).json({
310
273
  success: false,
311
- error: `Failed to resolve migration: ${result.error}`,
274
+ error: `Failed to resolve migration: ${result.error}`
312
275
  });
313
276
  }
314
277
 
@@ -316,13 +279,13 @@ router.post(
316
279
  success: true,
317
280
  message: `Migration ${migrationName} marked as ${action}`,
318
281
  migrationName,
319
- action,
282
+ action
320
283
  });
321
284
  } catch (error) {
322
285
  console.error('Migration resolve failed:', error);
323
286
  return res.status(500).json({
324
287
  success: false,
325
- error: error.message,
288
+ error: error.message
326
289
  });
327
290
  }
328
291
  })
@@ -345,3 +308,4 @@ app.use((err, _req, res, _next) => {
345
308
  const handler = serverlessHttp(app);
346
309
 
347
310
  module.exports = { handler, router };
311
+
@@ -29,9 +29,7 @@ const {
29
29
  } = require('../use-cases/check-integrations-health-use-case');
30
30
 
31
31
  const router = Router();
32
- const healthCheckRepository = createHealthCheckRepository({
33
- prismaClient: prisma,
34
- });
32
+ const healthCheckRepository = createHealthCheckRepository({ prismaClient: prisma });
35
33
 
36
34
  // Load integrations and create factories just like auth router does
37
35
  // This verifies the system can properly load integrations
@@ -41,18 +39,14 @@ try {
41
39
  integrationClasses = appDef.integrations || [];
42
40
 
43
41
  const moduleRepository = createModuleRepository();
44
- const moduleDefinitions =
45
- getModulesDefinitionFromIntegrationClasses(integrationClasses);
42
+ const moduleDefinitions = getModulesDefinitionFromIntegrationClasses(integrationClasses);
46
43
 
47
44
  moduleFactory = new ModuleFactory({
48
45
  moduleRepository,
49
46
  moduleDefinitions,
50
47
  });
51
48
  } catch (error) {
52
- console.error(
53
- 'Failed to load integrations for health check:',
54
- error.message
55
- );
49
+ console.error('Failed to load integrations for health check:', error.message);
56
50
  // Factories will be undefined, health check will report unhealthy
57
51
  moduleFactory = undefined;
58
52
  integrationClasses = [];
@@ -178,8 +172,7 @@ const detectVpcConfiguration = async () => {
178
172
  }
179
173
 
180
174
  // Check if Lambda is in VPC using VPC_ENABLED env var set by infrastructure
181
- results.isInVpc =
182
- process.env.VPC_ENABLED === 'true' ||
175
+ results.isInVpc = process.env.VPC_ENABLED === 'true' ||
183
176
  (!results.hasInternetAccess && results.canResolvePublicDns) ||
184
177
  results.vpcEndpoints.length > 0;
185
178
 
@@ -437,8 +430,7 @@ router.get('/health/detailed', async (_req, res) => {
437
430
  }
438
431
 
439
432
  try {
440
- response.checks.encryption =
441
- await checkEncryptionHealthUseCase.execute();
433
+ response.checks.encryption = await checkEncryptionHealthUseCase.execute();
442
434
  if (response.checks.encryption.status === 'unhealthy') {
443
435
  response.status = 'unhealthy';
444
436
  }
@@ -453,16 +445,12 @@ router.get('/health/detailed', async (_req, res) => {
453
445
  }
454
446
 
455
447
  try {
456
- const { apiStatuses, allReachable } =
457
- await checkExternalApisHealthUseCase.execute();
448
+ const { apiStatuses, allReachable } = await checkExternalApisHealthUseCase.execute();
458
449
  response.checks.externalApis = apiStatuses;
459
450
  if (!allReachable) {
460
451
  response.status = 'unhealthy';
461
452
  }
462
- console.log(
463
- 'External APIs check completed:',
464
- response.checks.externalApis
465
- );
453
+ console.log('External APIs check completed:', response.checks.externalApis);
466
454
  } catch (error) {
467
455
  response.checks.externalApis = {
468
456
  status: 'unhealthy',
@@ -474,10 +462,7 @@ router.get('/health/detailed', async (_req, res) => {
474
462
 
475
463
  try {
476
464
  response.checks.integrations = checkIntegrationsHealthUseCase.execute();
477
- console.log(
478
- 'Integrations check completed:',
479
- response.checks.integrations
480
- );
465
+ console.log('Integrations check completed:', response.checks.integrations);
481
466
  } catch (error) {
482
467
  response.checks.integrations = {
483
468
  status: 'unhealthy',
@@ -1,5 +1,7 @@
1
1
  const { createAppHandler } = require('./../app-handler-helpers');
2
- const { loadAppDefinition } = require('../app-definition-loader');
2
+ const {
3
+ loadAppDefinition,
4
+ } = require('../app-definition-loader');
3
5
  const { Router } = require('express');
4
6
  const { loadRouterFromObject } = require('../backend-utils');
5
7
 
@@ -11,9 +13,7 @@ for (const IntegrationClass of integrationClasses) {
11
13
  const router = Router();
12
14
  const basePath = `/api/${IntegrationClass.Definition.name}-integration`;
13
15
 
14
- console.log(
15
- `\n│ Configuring routes for ${IntegrationClass.Definition.name} Integration:`
16
- );
16
+ console.log(`\n│ Configuring routes for ${IntegrationClass.Definition.name} Integration:`);
17
17
 
18
18
  for (const routeDef of IntegrationClass.Definition.routes) {
19
19
  if (typeof routeDef === 'function') {
@@ -1,9 +1,7 @@
1
1
  const { createAppHandler } = require('./../app-handler-helpers');
2
2
  const { loadAppDefinition } = require('../app-definition-loader');
3
3
  const { Router } = require('express');
4
- const {
5
- IntegrationEventDispatcher,
6
- } = require('../integration-event-dispatcher');
4
+ const { IntegrationEventDispatcher } = require('../integration-event-dispatcher');
7
5
 
8
6
  const handlers = {};
9
7
  const { integrations: integrationClasses } = loadAppDefinition();
@@ -12,27 +10,20 @@ for (const IntegrationClass of integrationClasses) {
12
10
  const webhookConfig = IntegrationClass.Definition.webhooks;
13
11
 
14
12
  // Skip if webhooks not enabled
15
- if (
16
- !webhookConfig ||
17
- (typeof webhookConfig === 'object' && !webhookConfig.enabled)
18
- ) {
13
+ if (!webhookConfig || (typeof webhookConfig === 'object' && !webhookConfig.enabled)) {
19
14
  continue;
20
15
  }
21
16
 
22
17
  const router = Router();
23
18
  const basePath = `/api/${IntegrationClass.Definition.name}-integration/webhooks`;
24
19
 
25
- console.log(
26
- `\n│ Configuring webhook routes for ${IntegrationClass.Definition.name}:`
27
- );
20
+ console.log(`\n│ Configuring webhook routes for ${IntegrationClass.Definition.name}:`);
28
21
 
29
22
  // General webhook route (no integration ID)
30
23
  router.post(basePath, async (req, res, next) => {
31
24
  try {
32
25
  const integrationInstance = new IntegrationClass();
33
- const dispatcher = new IntegrationEventDispatcher(
34
- integrationInstance
35
- );
26
+ const dispatcher = new IntegrationEventDispatcher(integrationInstance);
36
27
  await dispatcher.dispatchHttp({
37
28
  event: 'WEBHOOK_RECEIVED',
38
29
  req,
@@ -49,9 +40,7 @@ for (const IntegrationClass of integrationClasses) {
49
40
  router.post(`${basePath}/:integrationId`, async (req, res, next) => {
50
41
  try {
51
42
  const integrationInstance = new IntegrationClass();
52
- const dispatcher = new IntegrationEventDispatcher(
53
- integrationInstance
54
- );
43
+ const dispatcher = new IntegrationEventDispatcher(integrationInstance);
55
44
  await dispatcher.dispatchHttp({
56
45
  event: 'WEBHOOK_RECEIVED',
57
46
  req,
@@ -69,9 +58,10 @@ for (const IntegrationClass of integrationClasses) {
69
58
  handler: createAppHandler(
70
59
  `HTTP Event: ${IntegrationClass.Definition.name} Webhook`,
71
60
  router,
72
- false // shouldUseDatabase = false
61
+ false // shouldUseDatabase = false
73
62
  ),
74
63
  };
75
64
  }
76
65
 
77
66
  module.exports = { handlers };
67
+
@@ -1,7 +1,5 @@
1
1
  const { createHandler } = require('@friggframework/core');
2
- const {
3
- createWebsocketConnectionRepository,
4
- } = require('../../database/websocket-connection-repository-factory');
2
+ const { createWebsocketConnectionRepository } = require('../../database/websocket-connection-repository-factory');
5
3
 
6
4
  const websocketConnectionRepository = createWebsocketConnectionRepository();
7
5
 
@@ -12,9 +10,7 @@ const handleWebSocketConnection = async (event, context) => {
12
10
  // Handle new connection
13
11
  try {
14
12
  const connectionId = event.requestContext.connectionId;
15
- await websocketConnectionRepository.createConnection(
16
- connectionId
17
- );
13
+ await websocketConnectionRepository.createConnection(connectionId);
18
14
  console.log(`Stored new connection: ${connectionId}`);
19
15
  return { statusCode: 200, body: 'Connected.' };
20
16
  } catch (error) {
@@ -26,9 +22,7 @@ const handleWebSocketConnection = async (event, context) => {
26
22
  // Handle disconnection
27
23
  try {
28
24
  const connectionId = event.requestContext.connectionId;
29
- await websocketConnectionRepository.deleteConnection(
30
- connectionId
31
- );
25
+ await websocketConnectionRepository.deleteConnection(connectionId);
32
26
  console.log(`Removed connection: ${connectionId}`);
33
27
  return { statusCode: 200, body: 'Disconnected.' };
34
28
  } catch (error) {
@@ -5,10 +5,9 @@ class CheckIntegrationsHealthUseCase {
5
5
  }
6
6
 
7
7
  execute() {
8
- const moduleDefinitions =
9
- this.moduleFactory && this.moduleFactory.moduleDefinitions
10
- ? this.moduleFactory.moduleDefinitions
11
- : [];
8
+ const moduleDefinitions = (this.moduleFactory && this.moduleFactory.moduleDefinitions)
9
+ ? this.moduleFactory.moduleDefinitions
10
+ : [];
12
11
 
13
12
  const integrationClasses = Array.isArray(this.integrationClasses)
14
13
  ? this.integrationClasses
@@ -16,19 +15,13 @@ class CheckIntegrationsHealthUseCase {
16
15
 
17
16
  // Extract module names from definitions
18
17
  const moduleTypes = Array.isArray(moduleDefinitions)
19
- ? moduleDefinitions.map(
20
- (def) => def.moduleName || def.name || def.label || 'Unknown'
21
- )
18
+ ? moduleDefinitions.map(def => def.moduleName || def.name || def.label || 'Unknown')
22
19
  : [];
23
20
 
24
21
  // Extract integration names from classes
25
- const integrationNames = integrationClasses.map((IntegrationClass) => {
22
+ const integrationNames = integrationClasses.map(IntegrationClass => {
26
23
  try {
27
- return (
28
- IntegrationClass.Definition?.name ||
29
- IntegrationClass.name ||
30
- 'Unknown'
31
- );
24
+ return IntegrationClass.Definition?.name || IntegrationClass.name || 'Unknown';
32
25
  } catch {
33
26
  return 'Unknown';
34
27
  }
@@ -57,8 +57,7 @@ const {
57
57
  const prismaRunner = require('../../database/utils/prisma-runner');
58
58
 
59
59
  // Use S3 repository for migration status tracking (no User table dependency)
60
- const bucketName =
61
- process.env.S3_BUCKET_NAME || process.env.MIGRATION_STATUS_BUCKET;
60
+ const bucketName = process.env.S3_BUCKET_NAME || process.env.MIGRATION_STATUS_BUCKET;
62
61
  const migrationStatusRepository = new MigrationStatusRepositoryS3(bucketName);
63
62
 
64
63
  /**
@@ -69,27 +68,19 @@ const migrationStatusRepository = new MigrationStatusRepositoryS3(bucketName);
69
68
  function sanitizeError(errorMessage) {
70
69
  if (!errorMessage) return 'Unknown error';
71
70
 
72
- return (
73
- String(errorMessage)
74
- // Remove PostgreSQL connection strings
75
- .replace(
76
- /postgresql:\/\/[^@\s]+@[^\s/]+/gi,
77
- 'postgresql://***:***@***'
78
- )
79
- // Remove MongoDB connection strings
80
- .replace(
81
- /mongodb(\+srv)?:\/\/[^@\s]+@[^\s/]+/gi,
82
- 'mongodb$1://***:***@***'
83
- )
84
- // Remove password parameters
85
- .replace(/password[=:]\s*[^\s,;)]+/gi, 'password=***')
86
- // Remove API keys
87
- .replace(/apikey[=:]\s*[^\s,;)]+/gi, 'apikey=***')
88
- .replace(/api[_-]?key[=:]\s*[^\s,;)]+/gi, 'api_key=***')
89
- // Remove tokens
90
- .replace(/token[=:]\s*[^\s,;)]+/gi, 'token=***')
91
- .replace(/bearer\s+[^\s,;)]+/gi, 'bearer ***')
92
- );
71
+ return String(errorMessage)
72
+ // Remove PostgreSQL connection strings
73
+ .replace(/postgresql:\/\/[^@\s]+@[^\s/]+/gi, 'postgresql://***:***@***')
74
+ // Remove MongoDB connection strings
75
+ .replace(/mongodb(\+srv)?:\/\/[^@\s]+@[^\s/]+/gi, 'mongodb$1://***:***@***')
76
+ // Remove password parameters
77
+ .replace(/password[=:]\s*[^\s,;)]+/gi, 'password=***')
78
+ // Remove API keys
79
+ .replace(/apikey[=:]\s*[^\s,;)]+/gi, 'apikey=***')
80
+ .replace(/api[_-]?key[=:]\s*[^\s,;)]+/gi, 'api_key=***')
81
+ // Remove tokens
82
+ .replace(/token[=:]\s*[^\s,;)]+/gi, 'token=***')
83
+ .replace(/bearer\s+[^\s,;)]+/gi, 'bearer ***');
93
84
  }
94
85
 
95
86
  /**
@@ -154,18 +145,11 @@ exports.handler = async (event, context) => {
154
145
  console.log('Database Migration Lambda Started');
155
146
  console.log('========================================');
156
147
  console.log('Event:', JSON.stringify(event, null, 2));
157
- console.log(
158
- 'Context:',
159
- JSON.stringify(
160
- {
161
- requestId: context.requestId,
162
- functionName: context.functionName,
163
- remainingTimeInMillis: context.getRemainingTimeInMillis(),
164
- },
165
- null,
166
- 2
167
- )
168
- );
148
+ console.log('Context:', JSON.stringify({
149
+ requestId: context.requestId,
150
+ functionName: context.functionName,
151
+ remainingTimeInMillis: context.getRemainingTimeInMillis(),
152
+ }, null, 2));
169
153
 
170
154
  // Extract migration parameters from event
171
155
  const { migrationId, dbType, stage } = extractMigrationParams(event);
@@ -180,9 +164,7 @@ exports.handler = async (event, context) => {
180
164
  console.log(`========================================`);
181
165
 
182
166
  try {
183
- const checkDbStateUseCase = new CheckDatabaseStateUseCase({
184
- prismaRunner,
185
- });
167
+ const checkDbStateUseCase = new CheckDatabaseStateUseCase({ prismaRunner });
186
168
  const status = await checkDbStateUseCase.execute(dbType, stage);
187
169
 
188
170
  console.log('✓ Database state check completed');
@@ -235,9 +217,7 @@ exports.handler = async (event, context) => {
235
217
 
236
218
  // Update migration status to RUNNING (if migrationId provided)
237
219
  if (migrationId) {
238
- console.log(
239
- `\n✓ Updating migration status to RUNNING: ${migrationId}`
240
- );
220
+ console.log(`\n✓ Updating migration status to RUNNING: ${migrationId}`);
241
221
  await migrationStatusRepository.update({
242
222
  migrationId,
243
223
  stage,
@@ -275,9 +255,7 @@ exports.handler = async (event, context) => {
275
255
 
276
256
  // Update migration status to COMPLETED (if migrationId provided)
277
257
  if (migrationId) {
278
- console.log(
279
- `\n✓ Updating migration status to COMPLETED: ${migrationId}`
280
- );
258
+ console.log(`\n✓ Updating migration status to COMPLETED: ${migrationId}`);
281
259
  await migrationStatusRepository.update({
282
260
  migrationId,
283
261
  stage,
@@ -306,6 +284,7 @@ exports.handler = async (event, context) => {
306
284
  statusCode: 200,
307
285
  body: JSON.stringify(responseBody),
308
286
  };
287
+
309
288
  } catch (error) {
310
289
  console.error('\n========================================');
311
290
  console.error('Migration Failed');
@@ -338,9 +317,7 @@ exports.handler = async (event, context) => {
338
317
  // Update migration status to FAILED (if migrationId provided)
339
318
  if (migrationId) {
340
319
  try {
341
- console.log(
342
- `\n✓ Updating migration status to FAILED: ${migrationId}`
343
- );
320
+ console.log(`\n✓ Updating migration status to FAILED: ${migrationId}`);
344
321
  await migrationStatusRepository.update({
345
322
  migrationId,
346
323
  stage,
@@ -350,10 +327,7 @@ exports.handler = async (event, context) => {
350
327
  failedAt: new Date().toISOString(),
351
328
  });
352
329
  } catch (updateError) {
353
- console.error(
354
- 'Failed to update migration status:',
355
- updateError.message
356
- );
330
+ console.error('Failed to update migration status:', updateError.message);
357
331
  // Continue - don't let status update failure block error response
358
332
  }
359
333
  }
@@ -363,9 +337,7 @@ exports.handler = async (event, context) => {
363
337
  error: sanitizedError,
364
338
  errorType: error.name || 'Error',
365
339
  // Only include stack traces in development environments
366
- ...(stage === 'dev' || stage === 'local' || stage === 'test'
367
- ? { stack: error.stack }
368
- : {}),
340
+ ...(stage === 'dev' || stage === 'local' || stage === 'test' ? { stack: error.stack } : {}),
369
341
  };
370
342
 
371
343
  if (migrationId) {
package/index.js CHANGED
@@ -39,7 +39,9 @@ const {
39
39
  const {
40
40
  GetUserFromAdopterJwt,
41
41
  } = require('./user/use-cases/get-user-from-adopter-jwt');
42
- const { AuthenticateUser } = require('./user/use-cases/authenticate-user');
42
+ const {
43
+ AuthenticateUser,
44
+ } = require('./user/use-cases/authenticate-user');
43
45
 
44
46
  const {
45
47
  CredentialRepository,
@@ -50,14 +52,18 @@ const {
50
52
  const {
51
53
  IntegrationMappingRepository,
52
54
  } = require('./integrations/repositories/integration-mapping-repository');
53
- const { CreateProcess } = require('./integrations/use-cases/create-process');
55
+ const {
56
+ CreateProcess,
57
+ } = require('./integrations/use-cases/create-process');
54
58
  const {
55
59
  UpdateProcessState,
56
60
  } = require('./integrations/use-cases/update-process-state');
57
61
  const {
58
62
  UpdateProcessMetrics,
59
63
  } = require('./integrations/use-cases/update-process-metrics');
60
- const { GetProcess } = require('./integrations/use-cases/get-process');
64
+ const {
65
+ GetProcess,
66
+ } = require('./integrations/use-cases/get-process');
61
67
  const { Cryptor } = require('./encrypt');
62
68
  const {
63
69
  BaseError,
@@ -73,7 +79,6 @@ const {
73
79
  checkRequiredParams,
74
80
  getModulesDefinitionFromIntegrationClasses,
75
81
  LoadIntegrationContextUseCase,
76
- createProcessRepository,
77
82
  } = require('./integrations/index');
78
83
  const { TimeoutCatcher } = require('./lambda/index');
79
84
  const { debug, initDebugLog, flushDebugLog } = require('./logs/index');
@@ -153,7 +158,6 @@ module.exports = {
153
158
  UpdateProcessState,
154
159
  UpdateProcessMetrics,
155
160
  GetProcess,
156
- createProcessRepository,
157
161
 
158
162
  // application - Command factories for integration developers
159
163
  application,