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

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,345 @@
1
+ // Frigg Framework - Prisma Schema (PostgreSQL)
2
+ // PostgreSQL database schema for enterprise integration platform
3
+ // Converted from MongoDB schema for relational database support
4
+
5
+ generator client {
6
+ provider = "prisma-client-js"
7
+ output = "../generated/prisma-postgresql"
8
+ binaryTargets = ["native", "rhel-openssl-3.0.x"] // native for local dev, rhel for Lambda deployment
9
+ engineType = "binary" // Use binary engines (smaller size)
10
+ }
11
+
12
+ datasource db {
13
+ provider = "postgresql"
14
+ url = env("DATABASE_URL")
15
+ }
16
+
17
+ // ============================================================================
18
+ // USER MODELS
19
+ // ============================================================================
20
+
21
+ /// User model with discriminator pattern support
22
+ /// Replaces Mongoose discriminators (IndividualUser, OrganizationUser)
23
+ model User {
24
+ id Int @id @default(autoincrement())
25
+ type UserType
26
+
27
+ // Timestamps
28
+ createdAt DateTime @default(now())
29
+ updatedAt DateTime @updatedAt
30
+
31
+ // IndividualUser fields (nullable for organizations)
32
+ email String?
33
+ username String?
34
+ hashword String? // Bcrypt hashed password (handled in application layer)
35
+ appUserId String?
36
+ organizationId Int?
37
+
38
+ // Self-referential relation for organization membership
39
+ organization User? @relation("OrgMembers", fields: [organizationId], references: [id], onDelete: NoAction, onUpdate: NoAction)
40
+ members User[] @relation("OrgMembers")
41
+
42
+ // OrganizationUser fields (nullable for individuals)
43
+ appOrgId String?
44
+ name String?
45
+
46
+ // Relations
47
+ tokens Token[]
48
+ credentials Credential[]
49
+ entities Entity[]
50
+ integrations Integration[]
51
+ processes Process[]
52
+
53
+ @@unique([email])
54
+ @@unique([username])
55
+ @@unique([appOrgId])
56
+ @@index([type])
57
+ @@index([appUserId])
58
+ }
59
+
60
+ enum UserType {
61
+ INDIVIDUAL
62
+ ORGANIZATION
63
+ }
64
+
65
+ // ============================================================================
66
+ // AUTHENTICATION MODELS
67
+ // ============================================================================
68
+
69
+ /// Authentication tokens with expiration
70
+ /// Bcrypt hashed tokens stored (handled in application layer)
71
+ model Token {
72
+ id Int @id @default(autoincrement())
73
+ token String // Bcrypt hashed
74
+ created DateTime @default(now())
75
+ expires DateTime?
76
+ userId Int
77
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
78
+
79
+ @@index([userId])
80
+ @@index([expires])
81
+ }
82
+
83
+ // ============================================================================
84
+ // CREDENTIAL & ENTITY MODELS
85
+ // ============================================================================
86
+
87
+ /// OAuth credentials and API tokens
88
+ /// All sensitive data encrypted with KMS at rest
89
+ model Credential {
90
+ id Int @id @default(autoincrement())
91
+ userId Int?
92
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
93
+ authIsValid Boolean?
94
+ externalId String?
95
+
96
+ // Dynamic OAuth fields stored as JSON (encrypted via Prisma middleware)
97
+ // Contains: access_token, refresh_token, domain, expires_in, token_type, etc.
98
+ data Json @default("{}")
99
+
100
+ createdAt DateTime @default(now())
101
+ updatedAt DateTime @updatedAt
102
+
103
+ // Relations
104
+ entities Entity[]
105
+
106
+ @@index([userId])
107
+ @@index([externalId])
108
+ }
109
+
110
+ /// External service entities (API connections)
111
+ model Entity {
112
+ id Int @id @default(autoincrement())
113
+ credentialId Int?
114
+ credential Credential? @relation(fields: [credentialId], references: [id], onDelete: SetNull)
115
+ userId Int?
116
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
117
+ name String?
118
+ moduleName String?
119
+ externalId String?
120
+
121
+ createdAt DateTime @default(now())
122
+ updatedAt DateTime @updatedAt
123
+
124
+ // Relations - many-to-many with implicit join tables
125
+ integrations Integration[]
126
+ syncs Sync[]
127
+
128
+ dataIdentifiers DataIdentifier[]
129
+ associationObjects AssociationObject[]
130
+
131
+ @@index([userId])
132
+ @@index([externalId])
133
+ @@index([moduleName])
134
+ @@index([credentialId])
135
+ }
136
+
137
+ // ============================================================================
138
+ // INTEGRATION MODELS
139
+ // ============================================================================
140
+
141
+ /// Main integration configuration and state
142
+ model Integration {
143
+ id Int @id @default(autoincrement())
144
+ userId Int?
145
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
146
+ status IntegrationStatus @default(ENABLED)
147
+
148
+ // Configuration and version
149
+ config Json? // Integration configuration object
150
+ version String?
151
+
152
+ // Entity references (many-to-many via implicit join table)
153
+ entities Entity[]
154
+
155
+ // Message arrays (stored as JSON)
156
+ errors Json @default("[]")
157
+ warnings Json @default("[]")
158
+ info Json @default("[]")
159
+ logs Json @default("[]")
160
+
161
+ createdAt DateTime @default(now())
162
+ updatedAt DateTime @updatedAt
163
+
164
+ // Relations
165
+ associations Association[]
166
+ syncs Sync[]
167
+ mappings IntegrationMapping[]
168
+ processes Process[]
169
+
170
+ @@index([userId])
171
+ @@index([status])
172
+ }
173
+
174
+ enum IntegrationStatus {
175
+ ENABLED
176
+ NEEDS_CONFIG
177
+ PROCESSING
178
+ DISABLED
179
+ ERROR
180
+ }
181
+
182
+ /// Integration-specific data mappings
183
+ /// All mapping data encrypted with KMS
184
+ model IntegrationMapping {
185
+ id Int @id @default(autoincrement())
186
+ integrationId Int
187
+ integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
188
+ sourceId String?
189
+
190
+ // Encrypted mapping data (handled via Prisma middleware)
191
+ mapping Json?
192
+
193
+ createdAt DateTime @default(now())
194
+ updatedAt DateTime @updatedAt
195
+
196
+ @@unique([integrationId, sourceId])
197
+ @@index([integrationId])
198
+ @@index([sourceId])
199
+ }
200
+
201
+ // ============================================================================
202
+ // SYNC MODELS
203
+ // ============================================================================
204
+
205
+ /// Bidirectional data synchronization tracking
206
+ model Sync {
207
+ id Int @id @default(autoincrement())
208
+ integrationId Int?
209
+ integration Integration? @relation(fields: [integrationId], references: [id], onDelete: Cascade)
210
+
211
+ // Entity references (many-to-many via implicit join table)
212
+ entities Entity[]
213
+
214
+ hash String
215
+ name String
216
+
217
+ // Data identifiers (extracted to separate model)
218
+ dataIdentifiers DataIdentifier[]
219
+
220
+ @@index([integrationId])
221
+ @@index([hash])
222
+ @@index([name])
223
+ }
224
+
225
+ /// Data identifier for sync operations
226
+ /// Replaces nested array structure in Mongoose
227
+ model DataIdentifier {
228
+ id Int @id @default(autoincrement())
229
+ syncId Int?
230
+ sync Sync? @relation(fields: [syncId], references: [id], onDelete: Cascade)
231
+ entityId Int
232
+ entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
233
+
234
+ // Identifier data (can be any structure)
235
+ idData Json
236
+
237
+ hash String
238
+
239
+ @@index([syncId])
240
+ @@index([entityId])
241
+ @@index([hash])
242
+ }
243
+
244
+ // ============================================================================
245
+ // ASSOCIATION MODELS
246
+ // ============================================================================
247
+
248
+ /// Entity associations with cardinality tracking
249
+ model Association {
250
+ id Int @id @default(autoincrement())
251
+ integrationId Int
252
+ integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
253
+ name String
254
+ type AssociationType
255
+ primaryObject String
256
+
257
+ // Associated objects (extracted to separate model)
258
+ objects AssociationObject[]
259
+
260
+ @@index([integrationId])
261
+ @@index([name])
262
+ }
263
+
264
+ /// Association object entry
265
+ /// Replaces nested array structure in Mongoose
266
+ model AssociationObject {
267
+ id Int @id @default(autoincrement())
268
+ associationId Int
269
+ association Association @relation(fields: [associationId], references: [id], onDelete: Cascade)
270
+ entityId Int
271
+ entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
272
+ objectType String
273
+ objId String
274
+ metadata Json? // Optional metadata
275
+
276
+ @@index([associationId])
277
+ @@index([entityId])
278
+ }
279
+
280
+ enum AssociationType {
281
+ ONE_TO_MANY
282
+ ONE_TO_ONE
283
+ MANY_TO_ONE
284
+ }
285
+
286
+ // ============================================================================
287
+ // PROCESS MODELS
288
+ // ============================================================================
289
+
290
+ /// Generic Process Model - tracks any long-running operation
291
+ /// Used for: CRM syncs, data migrations, bulk operations, etc.
292
+ model Process {
293
+ id Int @id @default(autoincrement())
294
+
295
+ // Core references
296
+ userId Int
297
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
298
+ integrationId Int
299
+ integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
300
+
301
+ // Process identification
302
+ name String // e.g., "zoho-crm-contact-sync", "pipedrive-lead-sync"
303
+ type String // e.g., "CRM_SYNC", "DATA_MIGRATION", "BULK_OPERATION"
304
+
305
+ // State machine
306
+ state String // Current state (integration-defined states)
307
+
308
+ // Flexible storage
309
+ context Json @default("{}") // Process-specific data (pagination, metadata, etc.)
310
+ results Json @default("{}") // Process results and metrics
311
+
312
+ // Hierarchy support - self-referential relation
313
+ parentProcessId Int?
314
+ parentProcess Process? @relation("ProcessHierarchy", fields: [parentProcessId], references: [id], onDelete: SetNull)
315
+ childProcesses Process[] @relation("ProcessHierarchy")
316
+
317
+ // Timestamps
318
+ createdAt DateTime @default(now())
319
+ updatedAt DateTime @updatedAt
320
+
321
+ @@index([userId])
322
+ @@index([integrationId])
323
+ @@index([type])
324
+ @@index([state])
325
+ @@index([name])
326
+ @@index([parentProcessId])
327
+ }
328
+
329
+ // ============================================================================
330
+ // UTILITY MODELS
331
+ // ============================================================================
332
+
333
+ /// Generic state storage
334
+ model State {
335
+ id Int @id @default(autoincrement())
336
+ state Json?
337
+ }
338
+
339
+ /// AWS API Gateway WebSocket connection tracking
340
+ model WebsocketConnection {
341
+ id Int @id @default(autoincrement())
342
+ connectionId String?
343
+
344
+ @@index([connectionId])
345
+ }
@@ -0,0 +1,4 @@
1
+
2
+ /* !!! This is code generated by Prisma. Do not edit directly. !!!
3
+ /* eslint-disable */
4
+ export default import('./query_engine_bg.wasm?module')
@@ -0,0 +1,4 @@
1
+
2
+ /* !!! This is code generated by Prisma. Do not edit directly. !!!
3
+ /* eslint-disable */
4
+ export default import('./query_engine_bg.wasm')
@@ -0,0 +1 @@
1
+ export * from "./default"