@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
@@ -5,36 +5,31 @@ This document explains how to implement webhook handling for your Frigg integrat
5
5
  ## Overview
6
6
 
7
7
  Frigg provides a scalable webhook architecture that:
8
-
9
- - **Receives webhooks without database connections** for fast response times
10
- - **Queues webhooks to SQS** for async processing
11
- - **Processes webhooks with fully hydrated integrations** (with DB and API modules loaded)
12
- - **Supports custom signature verification** for security
13
- - **Throttles database connections** using SQS to handle webhook bursts
8
+ - **Receives webhooks without database connections** for fast response times
9
+ - **Queues webhooks to SQS** for async processing
10
+ - **Processes webhooks with fully hydrated integrations** (with DB and API modules loaded)
11
+ - **Supports custom signature verification** for security
12
+ - **Throttles database connections** using SQS to handle webhook bursts
14
13
 
15
14
  ## Architecture
16
15
 
17
16
  The webhook flow consists of two stages:
18
17
 
19
18
  ### Stage 1: HTTP Webhook Receiver (No DB)
20
-
21
19
  ```
22
20
  Webhook → Lambda → WEBHOOK_RECEIVED event → Queue to SQS → 200 OK Response
23
21
  ```
24
-
25
- - Fast response (no database query)
26
- - Optional signature verification
27
- - Messages queued for processing
22
+ - Fast response (no database query)
23
+ - Optional signature verification
24
+ - Messages queued for processing
28
25
 
29
26
  ### Stage 2: Queue Worker (DB-Connected)
30
-
31
27
  ```
32
28
  SQS Queue → Lambda Worker → ON_WEBHOOK event → Process with hydrated integration
33
29
  ```
34
-
35
- - Full database access
36
- - API modules loaded
37
- - Can use integration context
30
+ - Full database access
31
+ - API modules loaded
32
+ - Can use integration context
38
33
 
39
34
  ## Enabling Webhooks
40
35
 
@@ -64,9 +59,7 @@ class MyIntegration extends IntegrationBase {
64
59
  static Definition = {
65
60
  name: 'my-integration',
66
61
  version: '1.0.0',
67
- modules: {
68
- /* ... */
69
- },
62
+ modules: { /* ... */ },
70
63
  webhooks: {
71
64
  enabled: true,
72
65
  // Future options will be added here
@@ -80,24 +73,20 @@ class MyIntegration extends IntegrationBase {
80
73
  When webhooks are enabled, two routes are automatically created:
81
74
 
82
75
  ### General Webhook
83
-
84
76
  ```
85
77
  POST /api/{integrationName}-integration/webhooks
86
78
  ```
87
-
88
- - No integration ID required
89
- - Useful for system-wide events
90
- - Creates unhydrated integration instance
79
+ - No integration ID required
80
+ - Useful for system-wide events
81
+ - Creates unhydrated integration instance
91
82
 
92
83
  ### Integration-Specific Webhook
93
-
94
84
  ```
95
85
  POST /api/{integrationName}-integration/webhooks/:integrationId
96
86
  ```
97
-
98
- - Includes integration ID in URL
99
- - Worker loads full integration with DB and modules
100
- - Recommended for most use cases
87
+ - Includes integration ID in URL
88
+ - Worker loads full integration with DB and modules
89
+ - Recommended for most use cases
101
90
 
102
91
  ## Event Handlers
103
92
 
@@ -106,7 +95,6 @@ POST /api/{integrationName}-integration/webhooks/:integrationId
106
95
  Triggered when a webhook HTTP request is received (no database connection).
107
96
 
108
97
  #### Default Behavior
109
-
110
98
  Queues the webhook to SQS and responds with `200 OK`:
111
99
 
112
100
  ```javascript
@@ -137,7 +125,7 @@ class MyIntegration extends IntegrationBase {
137
125
  // Verify webhook signature
138
126
  const signature = req.headers['x-webhook-signature'];
139
127
  const expectedSignature = this.calculateSignature(req.body);
140
-
128
+
141
129
  if (signature !== expectedSignature) {
142
130
  return res.status(401).json({ error: 'Invalid signature' });
143
131
  }
@@ -168,7 +156,6 @@ class MyIntegration extends IntegrationBase {
168
156
  Triggered by the queue worker (with database connection and hydrated integration).
169
157
 
170
158
  #### Default Behavior
171
-
172
159
  Logs the webhook data (override this!):
173
160
 
174
161
  ```javascript
@@ -275,26 +262,27 @@ class SlackIntegration extends IntegrationBase {
275
262
  const crypto = require('crypto');
276
263
  const signingSecret = process.env.SLACK_SIGNING_SECRET;
277
264
  const timestamp = req.headers['x-slack-request-timestamp'];
278
-
265
+
279
266
  // Validate timestamp is recent (within 5 minutes)
280
267
  const currentTime = Math.floor(Date.now() / 1000);
281
268
  if (Math.abs(currentTime - parseInt(timestamp)) > 300) {
282
269
  return false; // Request is older than 5 minutes
283
270
  }
284
-
271
+
285
272
  const hmac = crypto.createHmac('sha256', signingSecret);
286
273
  hmac.update(`v0:${timestamp}:${JSON.stringify(req.body)}`);
287
274
  const expected = `v0=${hmac.digest('hex')}`;
288
-
275
+
289
276
  // Check lengths first to avoid errors in timingSafeEqual
290
- const expectedBuffer = Buffer.from(expected);
291
- const signatureBuffer = Buffer.from(signature);
292
-
277
+ const expectedBuffer = Buffer.from(expected)
278
+ const signatureBuffer = Buffer.from(signature)
279
+
293
280
  if (expectedBuffer.length !== signatureBuffer.length) {
294
- return false;
281
+ return false
295
282
  }
283
+
284
+ return crypto.timingSafeEqual(expectedBuffer, signatureBuffer)
296
285
 
297
- return crypto.timingSafeEqual(expectedBuffer, signatureBuffer);
298
286
  }
299
287
  }
300
288
  ```
@@ -457,7 +445,6 @@ describe('MyIntegration Webhooks', () => {
457
445
  ## Best Practices
458
446
 
459
447
  ### 1. Always Verify Signatures
460
-
461
448
  ```javascript
462
449
  async onWebhookReceived({ req, res }) {
463
450
  // Verify before queueing
@@ -470,17 +457,14 @@ async onWebhookReceived({ req, res }) {
470
457
  ```
471
458
 
472
459
  ### 2. Respond Quickly
473
-
474
460
  The `WEBHOOK_RECEIVED` handler should complete in < 3 seconds:
475
-
476
- - Verify signature
477
- - Queue message
478
- - Return 200 OK
461
+ - Verify signature
462
+ - Queue message
463
+ - Return 200 OK
479
464
 
480
465
  Heavy processing goes in `ON_WEBHOOK`.
481
466
 
482
467
  ### 3. Handle Idempotency
483
-
484
468
  ```javascript
485
469
  async onWebhook({ data }) {
486
470
  const { body } = data;
@@ -500,7 +484,6 @@ async onWebhook({ data }) {
500
484
  ```
501
485
 
502
486
  ### 4. Error Handling
503
-
504
487
  ```javascript
505
488
  async onWebhook({ data }) {
506
489
  try {
@@ -508,7 +491,7 @@ async onWebhook({ data }) {
508
491
  } catch (error) {
509
492
  // Log error - message will go to DLQ after retries
510
493
  console.error('Webhook processing failed:', error);
511
-
494
+
512
495
  // Update integration status if needed
513
496
  await this.updateIntegrationMessages.execute(
514
497
  this.id,
@@ -517,7 +500,7 @@ async onWebhook({ data }) {
517
500
  error.message,
518
501
  Date.now()
519
502
  );
520
-
503
+
521
504
  throw error; // Re-throw for retry/DLQ
522
505
  }
523
506
  }
@@ -530,20 +513,18 @@ async onWebhook({ data }) {
530
513
  When `webhooks: true` is set, the Frigg infrastructure automatically creates:
531
514
 
532
515
  1. **HTTP Lambda Function**
533
-
534
- - Handler: `integration-webhook-routers.js`
535
- - No database connection
536
- - Fast cold start
516
+ - Handler: `integration-webhook-routers.js`
517
+ - No database connection
518
+ - Fast cold start
537
519
 
538
520
  2. **Webhook Routes**
521
+ - `POST /api/{name}-integration/webhooks`
522
+ - `POST /api/{name}-integration/webhooks/:integrationId`
539
523
 
540
- - `POST /api/{name}-integration/webhooks`
541
- - `POST /api/{name}-integration/webhooks/:integrationId`
542
-
543
- 3. **Queue Worker**
544
- - Processes from existing integration queue
545
- - Handles `ON_WEBHOOK` events
546
- - Full database access
524
+ 3. **Queue Worker**
525
+ - Processes from existing integration queue
526
+ - Handles `ON_WEBHOOK` events
527
+ - Full database access
547
528
 
548
529
  ### Serverless Configuration (Automatic)
549
530
 
@@ -551,22 +532,22 @@ The following is generated automatically in `serverless.yml`:
551
532
 
552
533
  ```yaml
553
534
  functions:
554
- myintegrationWebhook:
555
- handler: node_modules/@friggframework/core/handlers/routers/integration-webhook-routers.handlers.myintegrationWebhook.handler
556
- events:
557
- - httpApi:
558
- path: /api/myintegration-integration/webhooks
559
- method: POST
560
- - httpApi:
561
- path: /api/myintegration-integration/webhooks/{integrationId}
562
- method: POST
563
-
564
- myintegrationQueueWorker:
565
- handler: node_modules/@friggframework/core/handlers/workers/integration-defined-workers.handlers.myintegration.queueWorker
566
- events:
567
- - sqs:
568
- arn: !GetAtt MyintegrationQueue.Arn
569
- batchSize: 1
535
+ myintegrationWebhook:
536
+ handler: node_modules/@friggframework/core/handlers/routers/integration-webhook-routers.handlers.myintegrationWebhook.handler
537
+ events:
538
+ - httpApi:
539
+ path: /api/myintegration-integration/webhooks
540
+ method: POST
541
+ - httpApi:
542
+ path: /api/myintegration-integration/webhooks/{integrationId}
543
+ method: POST
544
+
545
+ myintegrationQueueWorker:
546
+ handler: node_modules/@friggframework/core/handlers/workers/integration-defined-workers.handlers.myintegration.queueWorker
547
+ events:
548
+ - sqs:
549
+ arn: !GetAtt MyintegrationQueue.Arn
550
+ batchSize: 1
570
551
  ```
571
552
 
572
553
  ## Event Handler Reference
@@ -579,14 +560,13 @@ functions:
579
560
  **Must:** Respond to `res` with status code
580
561
 
581
562
  **Parameters:**
582
-
583
- - `req` - Express request object
584
- - `req.body` - Webhook payload
585
- - `req.params.integrationId` - Integration ID (if in URL)
586
- - `req.headers` - HTTP headers
587
- - `req.query` - Query parameters
588
- - `res` - Express response object
589
- - Call `res.status(code).json(data)` to respond
563
+ - `req` - Express request object
564
+ - `req.body` - Webhook payload
565
+ - `req.params.integrationId` - Integration ID (if in URL)
566
+ - `req.headers` - HTTP headers
567
+ - `req.query` - Query parameters
568
+ - `res` - Express response object
569
+ - Call `res.status(code).json(data)` to respond
590
570
 
591
571
  ### onWebhook({ data, context })
592
572
 
@@ -596,13 +576,12 @@ functions:
596
576
  **Can:** Use `this.modules`, `this.config`, DB operations
597
577
 
598
578
  **Parameters:**
599
-
600
- - `data` - Queued webhook data
601
- - `data.integrationId` - Integration ID (if provided)
602
- - `data.body` - Original webhook payload
603
- - `data.headers` - Original HTTP headers
604
- - `data.query` - Original query parameters
605
- - `context` - Lambda context object
579
+ - `data` - Queued webhook data
580
+ - `data.integrationId` - Integration ID (if provided)
581
+ - `data.body` - Original webhook payload
582
+ - `data.headers` - Original HTTP headers
583
+ - `data.query` - Original query parameters
584
+ - `context` - Lambda context object
606
585
 
607
586
  ## Queue Helper
608
587
 
@@ -629,7 +608,6 @@ Automatically uses the correct SQS queue URL based on integration name.
629
608
  **Error:** `Queue URL not found for {NAME}_QUEUE_URL`
630
609
 
631
610
  **Solution:** Ensure environment variable is set:
632
-
633
611
  ```bash
634
612
  export MY_INTEGRATION_QUEUE_URL=https://sqs.us-east-1.amazonaws.com/...
635
613
  ```
@@ -637,7 +615,6 @@ export MY_INTEGRATION_QUEUE_URL=https://sqs.us-east-1.amazonaws.com/...
637
615
  ### Webhook Not Responding
638
616
 
639
617
  **Check:**
640
-
641
618
  1. Is `webhooks: true` in Definition?
642
619
  2. Is webhook endpoint deployed?
643
620
  3. Are you sending POST requests?
@@ -646,7 +623,6 @@ export MY_INTEGRATION_QUEUE_URL=https://sqs.us-east-1.amazonaws.com/...
646
623
  ### Worker Not Processing
647
624
 
648
625
  **Check:**
649
-
650
626
  1. Is SQS queue receiving messages?
651
627
  2. Is queue worker Lambda function deployed?
652
628
  3. Check CloudWatch logs for worker errors
@@ -662,15 +638,16 @@ export MY_INTEGRATION_QUEUE_URL=https://sqs.us-east-1.amazonaws.com/...
662
638
 
663
639
  ## Performance
664
640
 
665
- - **HTTP Response:** < 100ms (signature check + queue)
666
- - **Worker Processing:** Based on your logic
667
- - **Concurrency:** Controlled by SQS worker `reservedConcurrency: 5`
668
- - **Burst Handling:** Unlimited HTTP, throttled processing
641
+ - **HTTP Response:** < 100ms (signature check + queue)
642
+ - **Worker Processing:** Based on your logic
643
+ - **Concurrency:** Controlled by SQS worker `reservedConcurrency: 5`
644
+ - **Burst Handling:** Unlimited HTTP, throttled processing
669
645
 
670
646
  ## Related Files
671
647
 
672
- - `packages/core/integrations/integration-base.js` - Event definitions and default handlers
673
- - `packages/core/handlers/routers/integration-webhook-routers.js` - HTTP webhook routes
674
- - `packages/core/handlers/backend-utils.js` - Queue worker with hydration logic
675
- - `packages/core/handlers/integration-event-dispatcher.js` - Event dispatching
676
- - `packages/devtools/infrastructure/serverless-template.js` - Automatic infrastructure generation
648
+ - `packages/core/integrations/integration-base.js` - Event definitions and default handlers
649
+ - `packages/core/handlers/routers/integration-webhook-routers.js` - HTTP webhook routes
650
+ - `packages/core/handlers/backend-utils.js` - Queue worker with hydration logic
651
+ - `packages/core/handlers/integration-event-dispatcher.js` - Event dispatching
652
+ - `packages/devtools/infrastructure/serverless-template.js` - Automatic infrastructure generation
653
+
@@ -35,4 +35,4 @@ function loadAppDefinition() {
35
35
 
36
36
  module.exports = {
37
37
  loadAppDefinition,
38
- };
38
+ };
@@ -3,7 +3,6 @@ const express = require('express');
3
3
  const bodyParser = require('body-parser');
4
4
  const cors = require('cors');
5
5
  const Boom = require('@hapi/boom');
6
- const loadUserManager = require('./routers/middleware/loadUser');
7
6
  const serverlessHttp = require('serverless-http');
8
7
 
9
8
  const createApp = (applyMiddleware) => {
@@ -20,8 +19,6 @@ const createApp = (applyMiddleware) => {
20
19
  })
21
20
  );
22
21
 
23
- app.use(loadUserManager);
24
-
25
22
  if (applyMiddleware) applyMiddleware(app);
26
23
 
27
24
  // Handle sending error response and logging server errors to console
@@ -42,18 +39,9 @@ const createApp = (applyMiddleware) => {
42
39
  return app;
43
40
  };
44
41
 
45
- function createAppHandler(
46
- eventName,
47
- router,
48
- shouldUseDatabase = true,
49
- basePath = null
50
- ) {
42
+ function createAppHandler(eventName, router, shouldUseDatabase = true) {
51
43
  const app = createApp((app) => {
52
- if (basePath) {
53
- app.use(basePath, router);
54
- } else {
55
- app.use(router);
56
- }
44
+ app.use(router);
57
45
  });
58
46
  return createHandler({
59
47
  eventName,
@@ -101,6 +101,7 @@ const loadIntegrationForWebhook = async (integrationId) => {
101
101
  };
102
102
 
103
103
  const loadIntegrationForProcess = async (processId, integrationClass) => {
104
+
104
105
  const { processRepository, integrationRepository, moduleRepository } =
105
106
  initializeRepositories();
106
107
 
@@ -1,24 +1,24 @@
1
1
  /**
2
2
  * Database Migration Handler for AWS Lambda
3
- *
3
+ *
4
4
  * Executes Prisma migrations in a Lambda environment.
5
5
  * Based on AWS best practices for running migrations in serverless environments.
6
- *
6
+ *
7
7
  * Supported Commands:
8
8
  * - deploy: Apply pending migrations to the database (production-safe)
9
9
  * - reset: Reset database and apply all migrations (DANGEROUS - dev only)
10
- *
10
+ *
11
11
  * Usage:
12
12
  * // Via Lambda invoke
13
13
  * {
14
14
  * "command": "deploy" // or "reset"
15
15
  * }
16
- *
16
+ *
17
17
  * Requirements:
18
18
  * - Prisma CLI must be included in deployment or Lambda layer
19
19
  * - DATABASE_URL environment variable must be set
20
20
  * - VPC configuration for Aurora access
21
- *
21
+ *
22
22
  * Reference: https://www.prisma.io/docs/guides/deployment/deployment-guides/deploying-to-aws-lambda
23
23
  */
24
24
 
@@ -27,7 +27,7 @@ const path = require('path');
27
27
 
28
28
  /**
29
29
  * Execute Prisma migration command
30
- *
30
+ *
31
31
  * @param {string} command - Migration command ('deploy' or 'reset')
32
32
  * @param {string} schemaPath - Path to Prisma schema file
33
33
  * @returns {Promise<number>} Exit code
@@ -35,18 +35,16 @@ const path = require('path');
35
35
  async function executePrismaMigration(command, schemaPath) {
36
36
  console.log(`Executing Prisma migration: ${command}`);
37
37
  console.log(`Schema path: ${schemaPath}`);
38
- console.log(
39
- `Database URL: ${process.env.DATABASE_URL ? '[SET]' : '[NOT SET]'}`
40
- );
38
+ console.log(`Database URL: ${process.env.DATABASE_URL ? '[SET]' : '[NOT SET]'}`);
41
39
 
42
40
  return new Promise((resolve, reject) => {
43
41
  // Build command arguments
44
42
  const args = ['migrate', command];
45
-
43
+
46
44
  // Add command-specific options
47
45
  if (command === 'reset') {
48
- args.push('--force'); // Skip confirmation prompt
49
- args.push('--skip-generate'); // Skip client generation (already done in layer)
46
+ args.push('--force'); // Skip confirmation prompt
47
+ args.push('--skip-generate'); // Skip client generation (already done in layer)
50
48
  }
51
49
 
52
50
  // Add schema path if provided
@@ -55,7 +53,7 @@ async function executePrismaMigration(command, schemaPath) {
55
53
  }
56
54
 
57
55
  console.log(`Running: prisma ${args.join(' ')}`);
58
-
56
+
59
57
  // Execute Prisma CLI
60
58
  execFile(
61
59
  path.resolve('./node_modules/prisma/build/index.js'),
@@ -65,7 +63,7 @@ async function executePrismaMigration(command, schemaPath) {
65
63
  ...process.env,
66
64
  // Ensure Prisma uses the correct binary target
67
65
  PRISMA_CLI_BINARY_TARGETS: 'rhel-openssl-3.0.x',
68
- },
66
+ }
69
67
  },
70
68
  (error, stdout, stderr) => {
71
69
  // Log all output
@@ -77,10 +75,7 @@ async function executePrismaMigration(command, schemaPath) {
77
75
  }
78
76
 
79
77
  if (error) {
80
- console.error(
81
- `Migration ${command} exited with error:`,
82
- error.message
83
- );
78
+ console.error(`Migration ${command} exited with error:`, error.message);
84
79
  console.error(`Exit code: ${error.code || 1}`);
85
80
  resolve(error.code || 1);
86
81
  } else {
@@ -97,11 +92,11 @@ async function executePrismaMigration(command, schemaPath) {
97
92
  */
98
93
  function validateCommand(command) {
99
94
  const validCommands = ['deploy', 'reset'];
100
-
95
+
101
96
  if (!validCommands.includes(command)) {
102
97
  throw new Error(
103
98
  `Invalid migration command: "${command}". ` +
104
- `Valid commands are: ${validCommands.join(', ')}`
99
+ `Valid commands are: ${validCommands.join(', ')}`
105
100
  );
106
101
  }
107
102
 
@@ -111,12 +106,10 @@ function validateCommand(command) {
111
106
  if (stage === 'production' || stage === 'prod') {
112
107
  throw new Error(
113
108
  'BLOCKED: "reset" command is not allowed in production environment. ' +
114
- 'This command would delete all data. Use "deploy" instead.'
109
+ 'This command would delete all data. Use "deploy" instead.'
115
110
  );
116
111
  }
117
- console.warn(
118
- '⚠️ WARNING: "reset" will DELETE all data and reset the database!'
119
- );
112
+ console.warn('⚠️ WARNING: "reset" will DELETE all data and reset the database!');
120
113
  }
121
114
  }
122
115
 
@@ -126,17 +119,14 @@ function validateCommand(command) {
126
119
  function getSchemaPath() {
127
120
  // In Lambda, schemas are in @friggframework/core/generated/
128
121
  const baseSchemaPath = './node_modules/@friggframework/core/generated';
129
-
122
+
130
123
  // Check if Postgres is enabled
131
- if (
132
- process.env.DATABASE_URL?.includes('postgresql') ||
133
- process.env.DATABASE_URL?.includes('postgres')
134
- ) {
124
+ if (process.env.DATABASE_URL?.includes('postgresql') || process.env.DATABASE_URL?.includes('postgres')) {
135
125
  const schemaPath = `${baseSchemaPath}/prisma-postgresql/schema.prisma`;
136
126
  console.log(`Using PostgreSQL schema: ${schemaPath}`);
137
127
  return schemaPath;
138
128
  }
139
-
129
+
140
130
  // Check if MongoDB is enabled
141
131
  if (process.env.DATABASE_URL?.includes('mongodb')) {
142
132
  const schemaPath = `${baseSchemaPath}/prisma-mongodb/schema.prisma`;
@@ -145,15 +135,13 @@ function getSchemaPath() {
145
135
  }
146
136
 
147
137
  // Default to PostgreSQL
148
- console.log(
149
- 'DATABASE_URL not set or database type unknown, defaulting to PostgreSQL'
150
- );
138
+ console.log('DATABASE_URL not set or database type unknown, defaulting to PostgreSQL');
151
139
  return `${baseSchemaPath}/prisma-postgresql/schema.prisma`;
152
140
  }
153
141
 
154
142
  /**
155
143
  * Lambda handler for database migrations
156
- *
144
+ *
157
145
  * @param {Object} event - Lambda event
158
146
  * @param {string} event.command - Migration command ('deploy' or 'reset')
159
147
  * @param {Object} context - Lambda context
@@ -161,48 +149,41 @@ function getSchemaPath() {
161
149
  */
162
150
  exports.handler = async (event, context) => {
163
151
  const startTime = Date.now();
164
-
152
+
165
153
  console.log('='.repeat(60));
166
154
  console.log('Database Migration Handler');
167
155
  console.log('='.repeat(60));
168
156
  console.log('Event:', JSON.stringify(event, null, 2));
169
- console.log(
170
- 'Context:',
171
- JSON.stringify(
172
- {
173
- functionName: context.functionName,
174
- functionVersion: context.functionVersion,
175
- memoryLimitInMB: context.memoryLimitInMB,
176
- logGroupName: context.logGroupName,
177
- },
178
- null,
179
- 2
180
- )
181
- );
182
-
157
+ console.log('Context:', JSON.stringify({
158
+ functionName: context.functionName,
159
+ functionVersion: context.functionVersion,
160
+ memoryLimitInMB: context.memoryLimitInMB,
161
+ logGroupName: context.logGroupName,
162
+ }, null, 2));
163
+
183
164
  try {
184
165
  // Get migration command (default to 'deploy')
185
166
  const command = event.command || 'deploy';
186
-
167
+
187
168
  // Validate command
188
169
  validateCommand(command);
189
-
170
+
190
171
  // Check required environment variables
191
172
  if (!process.env.DATABASE_URL) {
192
173
  throw new Error(
193
174
  'DATABASE_URL environment variable is not set. ' +
194
- 'Cannot connect to database for migrations.'
175
+ 'Cannot connect to database for migrations.'
195
176
  );
196
177
  }
197
-
178
+
198
179
  // Determine schema path
199
180
  const schemaPath = getSchemaPath();
200
-
181
+
201
182
  // Execute migration
202
183
  const exitCode = await executePrismaMigration(command, schemaPath);
203
-
184
+
204
185
  const duration = Date.now() - startTime;
205
-
186
+
206
187
  if (exitCode === 0) {
207
188
  const result = {
208
189
  success: true,
@@ -211,27 +192,26 @@ exports.handler = async (event, context) => {
211
192
  duration: `${duration}ms`,
212
193
  timestamp: new Date().toISOString(),
213
194
  };
214
-
195
+
215
196
  console.log('='.repeat(60));
216
197
  console.log('Migration completed successfully');
217
198
  console.log(JSON.stringify(result, null, 2));
218
199
  console.log('='.repeat(60));
219
-
200
+
220
201
  return result;
221
202
  } else {
222
- throw new Error(
223
- `Migration ${command} failed with exit code ${exitCode}`
224
- );
203
+ throw new Error(`Migration ${command} failed with exit code ${exitCode}`);
225
204
  }
205
+
226
206
  } catch (error) {
227
207
  const duration = Date.now() - startTime;
228
-
208
+
229
209
  console.error('='.repeat(60));
230
210
  console.error('Migration failed');
231
211
  console.error('Error:', error.message);
232
212
  console.error('Stack:', error.stack);
233
213
  console.error('='.repeat(60));
234
-
214
+
235
215
  const errorResult = {
236
216
  success: false,
237
217
  command: event.command || 'unknown',
@@ -239,8 +219,9 @@ exports.handler = async (event, context) => {
239
219
  duration: `${duration}ms`,
240
220
  timestamp: new Date().toISOString(),
241
221
  };
242
-
222
+
243
223
  // Return error (don't throw) so Lambda doesn't retry
244
224
  return errorResult;
245
225
  }
246
226
  };
227
+