@friggframework/core 2.0.0-next.5 → 2.0.0-next.51

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 (267) hide show
  1. package/CLAUDE.md +693 -0
  2. package/README.md +959 -50
  3. package/application/commands/README.md +421 -0
  4. package/application/commands/credential-commands.js +224 -0
  5. package/application/commands/entity-commands.js +315 -0
  6. package/application/commands/integration-commands.js +179 -0
  7. package/application/commands/user-commands.js +213 -0
  8. package/application/index.js +69 -0
  9. package/core/CLAUDE.md +690 -0
  10. package/core/Worker.js +8 -21
  11. package/core/create-handler.js +2 -7
  12. package/credential/repositories/credential-repository-factory.js +47 -0
  13. package/credential/repositories/credential-repository-interface.js +98 -0
  14. package/credential/repositories/credential-repository-mongo.js +307 -0
  15. package/credential/repositories/credential-repository-postgres.js +313 -0
  16. package/credential/repositories/credential-repository.js +302 -0
  17. package/credential/use-cases/get-credential-for-user.js +21 -0
  18. package/credential/use-cases/update-authentication-status.js +15 -0
  19. package/database/MONGODB_TRANSACTION_FIX.md +198 -0
  20. package/database/adapters/lambda-invoker.js +97 -0
  21. package/database/config.js +154 -0
  22. package/database/encryption/README.md +684 -0
  23. package/database/encryption/encryption-schema-registry.js +141 -0
  24. package/database/encryption/field-encryption-service.js +226 -0
  25. package/database/encryption/logger.js +79 -0
  26. package/database/encryption/prisma-encryption-extension.js +222 -0
  27. package/database/index.js +25 -12
  28. package/database/models/WebsocketConnection.js +16 -10
  29. package/database/models/readme.md +1 -0
  30. package/database/prisma.js +222 -0
  31. package/database/repositories/health-check-repository-factory.js +43 -0
  32. package/database/repositories/health-check-repository-interface.js +87 -0
  33. package/database/repositories/health-check-repository-mongodb.js +91 -0
  34. package/database/repositories/health-check-repository-postgres.js +82 -0
  35. package/database/repositories/health-check-repository.js +108 -0
  36. package/database/repositories/migration-status-repository-s3.js +137 -0
  37. package/database/use-cases/check-database-health-use-case.js +29 -0
  38. package/database/use-cases/check-database-state-use-case.js +81 -0
  39. package/database/use-cases/check-encryption-health-use-case.js +83 -0
  40. package/database/use-cases/get-database-state-via-worker-use-case.js +61 -0
  41. package/database/use-cases/get-migration-status-use-case.js +93 -0
  42. package/database/use-cases/run-database-migration-use-case.js +137 -0
  43. package/database/use-cases/test-encryption-use-case.js +253 -0
  44. package/database/use-cases/trigger-database-migration-use-case.js +157 -0
  45. package/database/utils/mongodb-collection-utils.js +91 -0
  46. package/database/utils/mongodb-schema-init.js +106 -0
  47. package/database/utils/prisma-runner.js +400 -0
  48. package/database/utils/prisma-schema-parser.js +182 -0
  49. package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +517 -0
  50. package/encrypt/Cryptor.js +34 -168
  51. package/encrypt/index.js +1 -2
  52. package/encrypt/test-encrypt.js +0 -2
  53. package/generated/prisma-mongodb/client.d.ts +1 -0
  54. package/generated/prisma-mongodb/client.js +4 -0
  55. package/generated/prisma-mongodb/default.d.ts +1 -0
  56. package/generated/prisma-mongodb/default.js +4 -0
  57. package/generated/prisma-mongodb/edge.d.ts +1 -0
  58. package/generated/prisma-mongodb/edge.js +334 -0
  59. package/generated/prisma-mongodb/index-browser.js +316 -0
  60. package/generated/prisma-mongodb/index.d.ts +22898 -0
  61. package/generated/prisma-mongodb/index.js +359 -0
  62. package/generated/prisma-mongodb/package.json +183 -0
  63. package/generated/prisma-mongodb/query-engine-debian-openssl-3.0.x +0 -0
  64. package/generated/prisma-mongodb/query-engine-rhel-openssl-3.0.x +0 -0
  65. package/generated/prisma-mongodb/runtime/binary.d.ts +1 -0
  66. package/generated/prisma-mongodb/runtime/binary.js +289 -0
  67. package/generated/prisma-mongodb/runtime/edge-esm.js +34 -0
  68. package/generated/prisma-mongodb/runtime/edge.js +34 -0
  69. package/generated/prisma-mongodb/runtime/index-browser.d.ts +370 -0
  70. package/generated/prisma-mongodb/runtime/index-browser.js +16 -0
  71. package/generated/prisma-mongodb/runtime/library.d.ts +3982 -0
  72. package/generated/prisma-mongodb/runtime/react-native.js +83 -0
  73. package/generated/prisma-mongodb/runtime/wasm-compiler-edge.js +84 -0
  74. package/generated/prisma-mongodb/runtime/wasm-engine-edge.js +36 -0
  75. package/generated/prisma-mongodb/schema.prisma +362 -0
  76. package/generated/prisma-mongodb/wasm-edge-light-loader.mjs +4 -0
  77. package/generated/prisma-mongodb/wasm-worker-loader.mjs +4 -0
  78. package/generated/prisma-mongodb/wasm.d.ts +1 -0
  79. package/generated/prisma-mongodb/wasm.js +341 -0
  80. package/generated/prisma-postgresql/client.d.ts +1 -0
  81. package/generated/prisma-postgresql/client.js +4 -0
  82. package/generated/prisma-postgresql/default.d.ts +1 -0
  83. package/generated/prisma-postgresql/default.js +4 -0
  84. package/generated/prisma-postgresql/edge.d.ts +1 -0
  85. package/generated/prisma-postgresql/edge.js +356 -0
  86. package/generated/prisma-postgresql/index-browser.js +338 -0
  87. package/generated/prisma-postgresql/index.d.ts +25072 -0
  88. package/generated/prisma-postgresql/index.js +381 -0
  89. package/generated/prisma-postgresql/package.json +183 -0
  90. package/generated/prisma-postgresql/query-engine-debian-openssl-3.0.x +0 -0
  91. package/generated/prisma-postgresql/query-engine-rhel-openssl-3.0.x +0 -0
  92. package/generated/prisma-postgresql/query_engine_bg.js +2 -0
  93. package/generated/prisma-postgresql/query_engine_bg.wasm +0 -0
  94. package/generated/prisma-postgresql/runtime/binary.d.ts +1 -0
  95. package/generated/prisma-postgresql/runtime/binary.js +289 -0
  96. package/generated/prisma-postgresql/runtime/edge-esm.js +34 -0
  97. package/generated/prisma-postgresql/runtime/edge.js +34 -0
  98. package/generated/prisma-postgresql/runtime/index-browser.d.ts +370 -0
  99. package/generated/prisma-postgresql/runtime/index-browser.js +16 -0
  100. package/generated/prisma-postgresql/runtime/library.d.ts +3982 -0
  101. package/generated/prisma-postgresql/runtime/react-native.js +83 -0
  102. package/generated/prisma-postgresql/runtime/wasm-compiler-edge.js +84 -0
  103. package/generated/prisma-postgresql/runtime/wasm-engine-edge.js +36 -0
  104. package/generated/prisma-postgresql/schema.prisma +345 -0
  105. package/generated/prisma-postgresql/wasm-edge-light-loader.mjs +4 -0
  106. package/generated/prisma-postgresql/wasm-worker-loader.mjs +4 -0
  107. package/generated/prisma-postgresql/wasm.d.ts +1 -0
  108. package/generated/prisma-postgresql/wasm.js +363 -0
  109. package/handlers/WEBHOOKS.md +653 -0
  110. package/handlers/app-definition-loader.js +38 -0
  111. package/handlers/app-handler-helpers.js +56 -0
  112. package/handlers/backend-utils.js +180 -0
  113. package/handlers/database-migration-handler.js +227 -0
  114. package/handlers/integration-event-dispatcher.js +54 -0
  115. package/handlers/routers/HEALTHCHECK.md +342 -0
  116. package/handlers/routers/auth.js +15 -0
  117. package/handlers/routers/db-migration.handler.js +29 -0
  118. package/handlers/routers/db-migration.js +256 -0
  119. package/handlers/routers/health.js +519 -0
  120. package/handlers/routers/integration-defined-routers.js +45 -0
  121. package/handlers/routers/integration-webhook-routers.js +67 -0
  122. package/handlers/routers/user.js +63 -0
  123. package/handlers/routers/websocket.js +57 -0
  124. package/handlers/use-cases/check-external-apis-health-use-case.js +81 -0
  125. package/handlers/use-cases/check-integrations-health-use-case.js +44 -0
  126. package/handlers/workers/db-migration.js +352 -0
  127. package/handlers/workers/integration-defined-workers.js +27 -0
  128. package/index.js +77 -22
  129. package/integrations/WEBHOOK-QUICKSTART.md +151 -0
  130. package/integrations/index.js +12 -10
  131. package/integrations/integration-base.js +296 -54
  132. package/integrations/integration-router.js +381 -182
  133. package/integrations/options.js +1 -1
  134. package/integrations/repositories/integration-mapping-repository-factory.js +50 -0
  135. package/integrations/repositories/integration-mapping-repository-interface.js +106 -0
  136. package/integrations/repositories/integration-mapping-repository-mongo.js +161 -0
  137. package/integrations/repositories/integration-mapping-repository-postgres.js +227 -0
  138. package/integrations/repositories/integration-mapping-repository.js +156 -0
  139. package/integrations/repositories/integration-repository-factory.js +44 -0
  140. package/integrations/repositories/integration-repository-interface.js +127 -0
  141. package/integrations/repositories/integration-repository-mongo.js +303 -0
  142. package/integrations/repositories/integration-repository-postgres.js +352 -0
  143. package/integrations/repositories/process-repository-factory.js +46 -0
  144. package/integrations/repositories/process-repository-interface.js +90 -0
  145. package/integrations/repositories/process-repository-mongo.js +190 -0
  146. package/integrations/repositories/process-repository-postgres.js +217 -0
  147. package/integrations/tests/doubles/dummy-integration-class.js +83 -0
  148. package/integrations/tests/doubles/test-integration-repository.js +99 -0
  149. package/integrations/use-cases/create-integration.js +83 -0
  150. package/integrations/use-cases/create-process.js +128 -0
  151. package/integrations/use-cases/delete-integration-for-user.js +101 -0
  152. package/integrations/use-cases/find-integration-context-by-external-entity-id.js +72 -0
  153. package/integrations/use-cases/get-integration-for-user.js +78 -0
  154. package/integrations/use-cases/get-integration-instance-by-definition.js +67 -0
  155. package/integrations/use-cases/get-integration-instance.js +83 -0
  156. package/integrations/use-cases/get-integrations-for-user.js +88 -0
  157. package/integrations/use-cases/get-possible-integrations.js +27 -0
  158. package/integrations/use-cases/get-process.js +87 -0
  159. package/integrations/use-cases/index.js +19 -0
  160. package/integrations/use-cases/load-integration-context.js +71 -0
  161. package/integrations/use-cases/update-integration-messages.js +44 -0
  162. package/integrations/use-cases/update-integration-status.js +32 -0
  163. package/integrations/use-cases/update-integration.js +93 -0
  164. package/integrations/use-cases/update-process-metrics.js +201 -0
  165. package/integrations/use-cases/update-process-state.js +119 -0
  166. package/integrations/utils/map-integration-dto.js +37 -0
  167. package/jest-global-setup-noop.js +3 -0
  168. package/jest-global-teardown-noop.js +3 -0
  169. package/logs/logger.js +0 -4
  170. package/{module-plugin → modules}/entity.js +1 -1
  171. package/{module-plugin → modules}/index.js +0 -8
  172. package/modules/module-factory.js +56 -0
  173. package/modules/module.js +221 -0
  174. package/modules/repositories/module-repository-factory.js +33 -0
  175. package/modules/repositories/module-repository-interface.js +129 -0
  176. package/modules/repositories/module-repository-mongo.js +377 -0
  177. package/modules/repositories/module-repository-postgres.js +426 -0
  178. package/modules/repositories/module-repository.js +316 -0
  179. package/{module-plugin → modules}/requester/requester.js +1 -0
  180. package/{module-plugin → modules}/test/mock-api/api.js +8 -3
  181. package/{module-plugin → modules}/test/mock-api/definition.js +12 -8
  182. package/modules/tests/doubles/test-module-factory.js +16 -0
  183. package/modules/tests/doubles/test-module-repository.js +39 -0
  184. package/modules/use-cases/get-entities-for-user.js +32 -0
  185. package/modules/use-cases/get-entity-options-by-id.js +59 -0
  186. package/modules/use-cases/get-entity-options-by-type.js +34 -0
  187. package/modules/use-cases/get-module-instance-from-type.js +31 -0
  188. package/modules/use-cases/get-module.js +55 -0
  189. package/modules/use-cases/process-authorization-callback.js +122 -0
  190. package/modules/use-cases/refresh-entity-options.js +59 -0
  191. package/modules/use-cases/test-module-auth.js +55 -0
  192. package/modules/utils/map-module-dto.js +18 -0
  193. package/package.json +82 -50
  194. package/prisma-mongodb/schema.prisma +362 -0
  195. package/prisma-postgresql/migrations/20250930193005_init/migration.sql +315 -0
  196. package/prisma-postgresql/migrations/20251006135218_init/migration.sql +9 -0
  197. package/prisma-postgresql/migrations/20251010000000_remove_unused_entity_reference_map/migration.sql +3 -0
  198. package/prisma-postgresql/migrations/migration_lock.toml +3 -0
  199. package/prisma-postgresql/schema.prisma +345 -0
  200. package/queues/queuer-util.js +28 -15
  201. package/syncs/manager.js +468 -443
  202. package/syncs/repositories/sync-repository-factory.js +38 -0
  203. package/syncs/repositories/sync-repository-interface.js +109 -0
  204. package/syncs/repositories/sync-repository-mongo.js +239 -0
  205. package/syncs/repositories/sync-repository-postgres.js +319 -0
  206. package/syncs/sync.js +0 -1
  207. package/token/repositories/token-repository-factory.js +33 -0
  208. package/token/repositories/token-repository-interface.js +131 -0
  209. package/token/repositories/token-repository-mongo.js +212 -0
  210. package/token/repositories/token-repository-postgres.js +257 -0
  211. package/token/repositories/token-repository.js +219 -0
  212. package/types/core/index.d.ts +2 -2
  213. package/types/integrations/index.d.ts +2 -6
  214. package/types/module-plugin/index.d.ts +5 -59
  215. package/types/syncs/index.d.ts +0 -2
  216. package/user/repositories/user-repository-factory.js +46 -0
  217. package/user/repositories/user-repository-interface.js +198 -0
  218. package/user/repositories/user-repository-mongo.js +291 -0
  219. package/user/repositories/user-repository-postgres.js +350 -0
  220. package/user/tests/doubles/test-user-repository.js +72 -0
  221. package/user/use-cases/authenticate-user.js +127 -0
  222. package/user/use-cases/authenticate-with-shared-secret.js +48 -0
  223. package/user/use-cases/create-individual-user.js +61 -0
  224. package/user/use-cases/create-organization-user.js +47 -0
  225. package/user/use-cases/create-token-for-user-id.js +30 -0
  226. package/user/use-cases/get-user-from-adopter-jwt.js +149 -0
  227. package/user/use-cases/get-user-from-bearer-token.js +77 -0
  228. package/user/use-cases/get-user-from-x-frigg-headers.js +106 -0
  229. package/user/use-cases/login-user.js +122 -0
  230. package/user/user.js +93 -0
  231. package/utils/backend-path.js +38 -0
  232. package/utils/index.js +6 -0
  233. package/websocket/repositories/websocket-connection-repository-factory.js +37 -0
  234. package/websocket/repositories/websocket-connection-repository-interface.js +106 -0
  235. package/websocket/repositories/websocket-connection-repository-mongo.js +156 -0
  236. package/websocket/repositories/websocket-connection-repository-postgres.js +196 -0
  237. package/websocket/repositories/websocket-connection-repository.js +161 -0
  238. package/database/models/State.js +0 -9
  239. package/database/models/Token.js +0 -70
  240. package/database/mongo.js +0 -45
  241. package/encrypt/Cryptor.test.js +0 -32
  242. package/encrypt/encrypt.js +0 -132
  243. package/encrypt/encrypt.test.js +0 -1069
  244. package/errors/base-error.test.js +0 -32
  245. package/errors/fetch-error.test.js +0 -79
  246. package/errors/halt-error.test.js +0 -11
  247. package/errors/validation-errors.test.js +0 -120
  248. package/integrations/create-frigg-backend.js +0 -31
  249. package/integrations/integration-factory.js +0 -251
  250. package/integrations/integration-mapping.js +0 -43
  251. package/integrations/integration-model.js +0 -46
  252. package/integrations/integration-user.js +0 -144
  253. package/integrations/test/integration-base.test.js +0 -144
  254. package/lambda/TimeoutCatcher.test.js +0 -68
  255. package/logs/logger.test.js +0 -76
  256. package/module-plugin/auther.js +0 -393
  257. package/module-plugin/credential.js +0 -22
  258. package/module-plugin/entity-manager.js +0 -70
  259. package/module-plugin/manager.js +0 -169
  260. package/module-plugin/module-factory.js +0 -61
  261. package/module-plugin/requester/requester.test.js +0 -28
  262. package/module-plugin/test/auther.test.js +0 -97
  263. /package/{module-plugin → modules}/ModuleConstants.js +0 -0
  264. /package/{module-plugin → modules}/requester/api-key.js +0 -0
  265. /package/{module-plugin → modules}/requester/basic.js +0 -0
  266. /package/{module-plugin → modules}/requester/oauth-2.js +0 -0
  267. /package/{module-plugin → modules}/test/mock-api/mocks/hubspot.js +0 -0
@@ -0,0 +1,362 @@
1
+ // Frigg Framework - Prisma Schema
2
+ // MongoDB database schema for enterprise integration platform
3
+ // Migration from Mongoose ODM to Prisma ORM
4
+
5
+ generator client {
6
+ provider = "prisma-client-js"
7
+ output = "../generated/prisma-mongodb"
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 = "mongodb"
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 String @id @default(auto()) @map("_id") @db.ObjectId
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 String? @db.ObjectId
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
+ @@map("User")
59
+ }
60
+
61
+ enum UserType {
62
+ INDIVIDUAL
63
+ ORGANIZATION
64
+ }
65
+
66
+ // ============================================================================
67
+ // AUTHENTICATION MODELS
68
+ // ============================================================================
69
+
70
+ /// Authentication tokens with expiration
71
+ /// Bcrypt hashed tokens stored (handled in application layer)
72
+ model Token {
73
+ id String @id @default(auto()) @map("_id") @db.ObjectId
74
+ token String // Bcrypt hashed
75
+ created DateTime @default(now())
76
+ expires DateTime?
77
+ userId String @db.ObjectId
78
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
79
+
80
+ @@index([userId])
81
+ @@index([expires])
82
+ @@map("Token")
83
+ }
84
+
85
+ // ============================================================================
86
+ // CREDENTIAL & ENTITY MODELS
87
+ // ============================================================================
88
+
89
+ /// OAuth credentials and API tokens
90
+ /// All sensitive data encrypted with KMS at rest
91
+ model Credential {
92
+ id String @id @default(auto()) @map("_id") @db.ObjectId
93
+ userId String? @db.ObjectId
94
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
95
+ authIsValid Boolean?
96
+ externalId String?
97
+
98
+ // Dynamic OAuth fields stored as JSON (encrypted via Prisma middleware)
99
+ // Contains: access_token, refresh_token, domain, expires_in, token_type, etc.
100
+ data Json @default("{}")
101
+
102
+ createdAt DateTime @default(now())
103
+ updatedAt DateTime @updatedAt
104
+
105
+ // Relations
106
+ entities Entity[]
107
+
108
+ @@index([userId])
109
+ @@index([externalId])
110
+ @@map("Credential")
111
+ }
112
+
113
+ /// External service entities (API connections)
114
+ model Entity {
115
+ id String @id @default(auto()) @map("_id") @db.ObjectId
116
+ credentialId String? @db.ObjectId
117
+ credential Credential? @relation(fields: [credentialId], references: [id], onDelete: SetNull)
118
+ userId String? @db.ObjectId
119
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
120
+ name String?
121
+ moduleName String?
122
+ externalId String?
123
+
124
+ createdAt DateTime @default(now())
125
+ updatedAt DateTime @updatedAt
126
+
127
+ // Relations - many-to-many with scalar lists
128
+ integrations Integration[] @relation("IntegrationEntities", fields: [integrationIds], references: [id])
129
+ integrationIds String[] @db.ObjectId
130
+
131
+ syncs Sync[] @relation("SyncEntities", fields: [syncIds], references: [id])
132
+ syncIds String[] @db.ObjectId
133
+
134
+ dataIdentifiers DataIdentifier[]
135
+ associationObjects AssociationObject[]
136
+
137
+ @@index([userId])
138
+ @@index([externalId])
139
+ @@index([moduleName])
140
+ @@index([credentialId])
141
+ @@map("Entity")
142
+ }
143
+
144
+ // ============================================================================
145
+ // INTEGRATION MODELS
146
+ // ============================================================================
147
+
148
+ /// Main integration configuration and state
149
+ model Integration {
150
+ id String @id @default(auto()) @map("_id") @db.ObjectId
151
+ userId String? @db.ObjectId
152
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
153
+ status IntegrationStatus @default(ENABLED)
154
+
155
+ // Configuration and version
156
+ config Json? // Integration configuration object
157
+ version String?
158
+
159
+ // Entity references (many-to-many via explicit scalar list)
160
+ entities Entity[] @relation("IntegrationEntities", fields: [entityIds], references: [id])
161
+ entityIds String[] @db.ObjectId
162
+
163
+ // Message arrays (stored as JSON)
164
+ errors Json @default("[]")
165
+ warnings Json @default("[]")
166
+ info Json @default("[]")
167
+ logs Json @default("[]")
168
+
169
+ createdAt DateTime @default(now())
170
+ updatedAt DateTime @updatedAt
171
+
172
+ // Relations
173
+ associations Association[]
174
+ syncs Sync[]
175
+ mappings IntegrationMapping[]
176
+ processes Process[]
177
+
178
+ @@index([userId])
179
+ @@index([status])
180
+ @@map("Integration")
181
+ }
182
+
183
+ enum IntegrationStatus {
184
+ ENABLED
185
+ NEEDS_CONFIG
186
+ PROCESSING
187
+ DISABLED
188
+ ERROR
189
+ }
190
+
191
+ /// Integration-specific data mappings
192
+ /// All mapping data encrypted with KMS
193
+ model IntegrationMapping {
194
+ id String @id @default(auto()) @map("_id") @db.ObjectId
195
+ integrationId String @db.ObjectId
196
+ integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
197
+ sourceId String?
198
+
199
+ // Encrypted mapping data (handled via Prisma middleware)
200
+ mapping Json?
201
+
202
+ createdAt DateTime @default(now())
203
+ updatedAt DateTime @updatedAt
204
+
205
+ @@unique([integrationId, sourceId])
206
+ @@index([integrationId])
207
+ @@index([sourceId])
208
+ @@map("IntegrationMapping")
209
+ }
210
+
211
+ // ============================================================================
212
+ // PROCESS MODELS
213
+ // ============================================================================
214
+
215
+ /// Generic Process Model - tracks any long-running operation
216
+ /// Used for: CRM syncs, data migrations, bulk operations, etc.
217
+ model Process {
218
+ id String @id @default(auto()) @map("_id") @db.ObjectId
219
+
220
+ // Core references
221
+ userId String @db.ObjectId
222
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
223
+ integrationId String @db.ObjectId
224
+ integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
225
+
226
+ // Process identification
227
+ name String // e.g., "zoho-crm-contact-sync", "pipedrive-lead-sync"
228
+ type String // e.g., "CRM_SYNC", "DATA_MIGRATION", "BULK_OPERATION"
229
+
230
+ // State machine
231
+ state String // Current state (integration-defined states)
232
+
233
+ // Flexible storage
234
+ context Json @default("{}") // Process-specific data (pagination, metadata, etc.)
235
+ results Json @default("{}") // Process results and metrics
236
+
237
+ // Hierarchy support
238
+ childProcesses String[] @db.ObjectId
239
+ parentProcessId String? @db.ObjectId
240
+
241
+ // Timestamps
242
+ createdAt DateTime @default(now())
243
+ updatedAt DateTime @updatedAt
244
+
245
+ @@index([userId])
246
+ @@index([integrationId])
247
+ @@index([type])
248
+ @@index([state])
249
+ @@index([name])
250
+ @@map("Process")
251
+ }
252
+
253
+ // ============================================================================
254
+ // SYNC MODELS
255
+ // ============================================================================
256
+
257
+ /// Bidirectional data synchronization tracking
258
+ model Sync {
259
+ id String @id @default(auto()) @map("_id") @db.ObjectId
260
+ integrationId String? @db.ObjectId
261
+ integration Integration? @relation(fields: [integrationId], references: [id], onDelete: Cascade)
262
+
263
+ // Entity references (many-to-many via explicit scalar list)
264
+ entities Entity[] @relation("SyncEntities", fields: [entityIds], references: [id])
265
+ entityIds String[] @db.ObjectId
266
+
267
+ hash String
268
+ name String
269
+
270
+ // Data identifiers (extracted to separate model)
271
+ dataIdentifiers DataIdentifier[]
272
+
273
+ @@index([integrationId])
274
+ @@index([hash])
275
+ @@index([name])
276
+ @@map("Sync")
277
+ }
278
+
279
+ /// Data identifier for sync operations
280
+ /// Replaces nested array structure in Mongoose
281
+ model DataIdentifier {
282
+ id String @id @default(auto()) @map("_id") @db.ObjectId
283
+ syncId String? @db.ObjectId
284
+ sync Sync? @relation(fields: [syncId], references: [id], onDelete: Cascade)
285
+ entityId String @db.ObjectId
286
+ entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
287
+
288
+ // Identifier data (can be any structure)
289
+ idData Json
290
+
291
+ hash String
292
+
293
+ @@index([syncId])
294
+ @@index([entityId])
295
+ @@index([hash])
296
+ @@map("DataIdentifier")
297
+ }
298
+
299
+ // ============================================================================
300
+ // ASSOCIATION MODELS
301
+ // ============================================================================
302
+
303
+ /// Entity associations with cardinality tracking
304
+ model Association {
305
+ id String @id @default(auto()) @map("_id") @db.ObjectId
306
+ integrationId String @db.ObjectId
307
+ integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
308
+ name String
309
+ type AssociationType
310
+ primaryObject String
311
+
312
+ // Associated objects (extracted to separate model)
313
+ objects AssociationObject[]
314
+
315
+ @@index([integrationId])
316
+ @@index([name])
317
+ @@map("Association")
318
+ }
319
+
320
+ /// Association object entry
321
+ /// Replaces nested array structure in Mongoose
322
+ model AssociationObject {
323
+ id String @id @default(auto()) @map("_id") @db.ObjectId
324
+ associationId String @db.ObjectId
325
+ association Association @relation(fields: [associationId], references: [id], onDelete: Cascade)
326
+ entityId String @db.ObjectId
327
+ entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
328
+ objectType String
329
+ objId String
330
+ metadata Json? // Optional metadata
331
+
332
+ @@index([associationId])
333
+ @@index([entityId])
334
+ @@map("AssociationObject")
335
+ }
336
+
337
+ enum AssociationType {
338
+ ONE_TO_MANY
339
+ ONE_TO_ONE
340
+ MANY_TO_ONE
341
+ }
342
+
343
+ // ============================================================================
344
+ // UTILITY MODELS
345
+ // ============================================================================
346
+
347
+ /// Generic state storage
348
+ model State {
349
+ id String @id @default(auto()) @map("_id") @db.ObjectId
350
+ state Json?
351
+
352
+ @@map("State")
353
+ }
354
+
355
+ /// AWS API Gateway WebSocket connection tracking
356
+ model WebsocketConnection {
357
+ id String @id @default(auto()) @map("_id") @db.ObjectId
358
+ connectionId String?
359
+
360
+ @@index([connectionId])
361
+ @@map("WebsocketConnection")
362
+ }
@@ -0,0 +1,315 @@
1
+ -- CreateEnum
2
+ CREATE TYPE "UserType" AS ENUM ('INDIVIDUAL', 'ORGANIZATION');
3
+
4
+ -- CreateEnum
5
+ CREATE TYPE "IntegrationStatus" AS ENUM ('ENABLED', 'NEEDS_CONFIG', 'PROCESSING', 'DISABLED', 'ERROR');
6
+
7
+ -- CreateEnum
8
+ CREATE TYPE "AssociationType" AS ENUM ('ONE_TO_MANY', 'ONE_TO_ONE', 'MANY_TO_ONE');
9
+
10
+ -- CreateTable
11
+ CREATE TABLE "User" (
12
+ "id" SERIAL NOT NULL,
13
+ "type" "UserType" NOT NULL,
14
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
15
+ "updatedAt" TIMESTAMP(3) NOT NULL,
16
+ "email" TEXT,
17
+ "username" TEXT,
18
+ "hashword" TEXT,
19
+ "appUserId" TEXT,
20
+ "organizationId" INTEGER,
21
+ "appOrgId" TEXT,
22
+ "name" TEXT,
23
+
24
+ CONSTRAINT "User_pkey" PRIMARY KEY ("id")
25
+ );
26
+
27
+ -- CreateTable
28
+ CREATE TABLE "Token" (
29
+ "id" SERIAL NOT NULL,
30
+ "token" TEXT NOT NULL,
31
+ "created" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
32
+ "expires" TIMESTAMP(3),
33
+ "userId" INTEGER NOT NULL,
34
+
35
+ CONSTRAINT "Token_pkey" PRIMARY KEY ("id")
36
+ );
37
+
38
+ -- CreateTable
39
+ CREATE TABLE "Credential" (
40
+ "id" SERIAL NOT NULL,
41
+ "userId" INTEGER,
42
+ "subType" TEXT,
43
+ "auth_is_valid" BOOLEAN,
44
+ "externalId" TEXT,
45
+ "data" JSONB NOT NULL DEFAULT '{}',
46
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
47
+ "updatedAt" TIMESTAMP(3) NOT NULL,
48
+
49
+ CONSTRAINT "Credential_pkey" PRIMARY KEY ("id")
50
+ );
51
+
52
+ -- CreateTable
53
+ CREATE TABLE "Entity" (
54
+ "id" SERIAL NOT NULL,
55
+ "credentialId" INTEGER,
56
+ "subType" TEXT,
57
+ "userId" INTEGER,
58
+ "name" TEXT,
59
+ "moduleName" TEXT,
60
+ "externalId" TEXT,
61
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
62
+ "updatedAt" TIMESTAMP(3) NOT NULL,
63
+
64
+ CONSTRAINT "Entity_pkey" PRIMARY KEY ("id")
65
+ );
66
+
67
+ -- CreateTable
68
+ CREATE TABLE "Integration" (
69
+ "id" SERIAL NOT NULL,
70
+ "userId" INTEGER,
71
+ "status" "IntegrationStatus" NOT NULL DEFAULT 'ENABLED',
72
+ "config" JSONB,
73
+ "version" TEXT,
74
+ "entityReferenceMap" JSONB DEFAULT '{}',
75
+ "errors" JSONB NOT NULL DEFAULT '[]',
76
+ "warnings" JSONB NOT NULL DEFAULT '[]',
77
+ "info" JSONB NOT NULL DEFAULT '[]',
78
+ "logs" JSONB NOT NULL DEFAULT '[]',
79
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
80
+ "updatedAt" TIMESTAMP(3) NOT NULL,
81
+
82
+ CONSTRAINT "Integration_pkey" PRIMARY KEY ("id")
83
+ );
84
+
85
+ -- CreateTable
86
+ CREATE TABLE "IntegrationMapping" (
87
+ "id" SERIAL NOT NULL,
88
+ "integrationId" INTEGER NOT NULL,
89
+ "sourceId" TEXT,
90
+ "mapping" JSONB,
91
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
92
+ "updatedAt" TIMESTAMP(3) NOT NULL,
93
+
94
+ CONSTRAINT "IntegrationMapping_pkey" PRIMARY KEY ("id")
95
+ );
96
+
97
+ -- CreateTable
98
+ CREATE TABLE "Sync" (
99
+ "id" SERIAL NOT NULL,
100
+ "integrationId" INTEGER,
101
+ "hash" TEXT NOT NULL,
102
+ "name" TEXT NOT NULL,
103
+
104
+ CONSTRAINT "Sync_pkey" PRIMARY KEY ("id")
105
+ );
106
+
107
+ -- CreateTable
108
+ CREATE TABLE "DataIdentifier" (
109
+ "id" SERIAL NOT NULL,
110
+ "syncId" INTEGER,
111
+ "entityId" INTEGER NOT NULL,
112
+ "idData" JSONB NOT NULL,
113
+ "hash" TEXT NOT NULL,
114
+
115
+ CONSTRAINT "DataIdentifier_pkey" PRIMARY KEY ("id")
116
+ );
117
+
118
+ -- CreateTable
119
+ CREATE TABLE "Association" (
120
+ "id" SERIAL NOT NULL,
121
+ "integrationId" INTEGER NOT NULL,
122
+ "name" TEXT NOT NULL,
123
+ "type" "AssociationType" NOT NULL,
124
+ "primaryObject" TEXT NOT NULL,
125
+
126
+ CONSTRAINT "Association_pkey" PRIMARY KEY ("id")
127
+ );
128
+
129
+ -- CreateTable
130
+ CREATE TABLE "AssociationObject" (
131
+ "id" SERIAL NOT NULL,
132
+ "associationId" INTEGER NOT NULL,
133
+ "entityId" INTEGER NOT NULL,
134
+ "objectType" TEXT NOT NULL,
135
+ "objId" TEXT NOT NULL,
136
+ "metadata" JSONB,
137
+
138
+ CONSTRAINT "AssociationObject_pkey" PRIMARY KEY ("id")
139
+ );
140
+
141
+ -- CreateTable
142
+ CREATE TABLE "State" (
143
+ "id" SERIAL NOT NULL,
144
+ "state" JSONB,
145
+
146
+ CONSTRAINT "State_pkey" PRIMARY KEY ("id")
147
+ );
148
+
149
+ -- CreateTable
150
+ CREATE TABLE "WebsocketConnection" (
151
+ "id" SERIAL NOT NULL,
152
+ "connectionId" TEXT,
153
+
154
+ CONSTRAINT "WebsocketConnection_pkey" PRIMARY KEY ("id")
155
+ );
156
+
157
+ -- CreateTable
158
+ CREATE TABLE "_EntityToIntegration" (
159
+ "A" INTEGER NOT NULL,
160
+ "B" INTEGER NOT NULL,
161
+
162
+ CONSTRAINT "_EntityToIntegration_AB_pkey" PRIMARY KEY ("A","B")
163
+ );
164
+
165
+ -- CreateTable
166
+ CREATE TABLE "_EntityToSync" (
167
+ "A" INTEGER NOT NULL,
168
+ "B" INTEGER NOT NULL,
169
+
170
+ CONSTRAINT "_EntityToSync_AB_pkey" PRIMARY KEY ("A","B")
171
+ );
172
+
173
+ -- CreateIndex
174
+ CREATE INDEX "User_type_idx" ON "User"("type");
175
+
176
+ -- CreateIndex
177
+ CREATE INDEX "User_appUserId_idx" ON "User"("appUserId");
178
+
179
+ -- CreateIndex
180
+ CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
181
+
182
+ -- CreateIndex
183
+ CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
184
+
185
+ -- CreateIndex
186
+ CREATE UNIQUE INDEX "User_appOrgId_key" ON "User"("appOrgId");
187
+
188
+ -- CreateIndex
189
+ CREATE INDEX "Token_userId_idx" ON "Token"("userId");
190
+
191
+ -- CreateIndex
192
+ CREATE INDEX "Token_expires_idx" ON "Token"("expires");
193
+
194
+ -- CreateIndex
195
+ CREATE INDEX "Credential_userId_idx" ON "Credential"("userId");
196
+
197
+ -- CreateIndex
198
+ CREATE INDEX "Credential_externalId_idx" ON "Credential"("externalId");
199
+
200
+ -- CreateIndex
201
+ CREATE INDEX "Entity_userId_idx" ON "Entity"("userId");
202
+
203
+ -- CreateIndex
204
+ CREATE INDEX "Entity_externalId_idx" ON "Entity"("externalId");
205
+
206
+ -- CreateIndex
207
+ CREATE INDEX "Entity_moduleName_idx" ON "Entity"("moduleName");
208
+
209
+ -- CreateIndex
210
+ CREATE INDEX "Entity_credentialId_idx" ON "Entity"("credentialId");
211
+
212
+ -- CreateIndex
213
+ CREATE INDEX "Integration_userId_idx" ON "Integration"("userId");
214
+
215
+ -- CreateIndex
216
+ CREATE INDEX "Integration_status_idx" ON "Integration"("status");
217
+
218
+ -- CreateIndex
219
+ CREATE INDEX "IntegrationMapping_integrationId_idx" ON "IntegrationMapping"("integrationId");
220
+
221
+ -- CreateIndex
222
+ CREATE INDEX "IntegrationMapping_sourceId_idx" ON "IntegrationMapping"("sourceId");
223
+
224
+ -- CreateIndex
225
+ CREATE UNIQUE INDEX "IntegrationMapping_integrationId_sourceId_key" ON "IntegrationMapping"("integrationId", "sourceId");
226
+
227
+ -- CreateIndex
228
+ CREATE INDEX "Sync_integrationId_idx" ON "Sync"("integrationId");
229
+
230
+ -- CreateIndex
231
+ CREATE INDEX "Sync_hash_idx" ON "Sync"("hash");
232
+
233
+ -- CreateIndex
234
+ CREATE INDEX "Sync_name_idx" ON "Sync"("name");
235
+
236
+ -- CreateIndex
237
+ CREATE INDEX "DataIdentifier_syncId_idx" ON "DataIdentifier"("syncId");
238
+
239
+ -- CreateIndex
240
+ CREATE INDEX "DataIdentifier_entityId_idx" ON "DataIdentifier"("entityId");
241
+
242
+ -- CreateIndex
243
+ CREATE INDEX "DataIdentifier_hash_idx" ON "DataIdentifier"("hash");
244
+
245
+ -- CreateIndex
246
+ CREATE INDEX "Association_integrationId_idx" ON "Association"("integrationId");
247
+
248
+ -- CreateIndex
249
+ CREATE INDEX "Association_name_idx" ON "Association"("name");
250
+
251
+ -- CreateIndex
252
+ CREATE INDEX "AssociationObject_associationId_idx" ON "AssociationObject"("associationId");
253
+
254
+ -- CreateIndex
255
+ CREATE INDEX "AssociationObject_entityId_idx" ON "AssociationObject"("entityId");
256
+
257
+ -- CreateIndex
258
+ CREATE INDEX "WebsocketConnection_connectionId_idx" ON "WebsocketConnection"("connectionId");
259
+
260
+ -- CreateIndex
261
+ CREATE INDEX "_EntityToIntegration_B_index" ON "_EntityToIntegration"("B");
262
+
263
+ -- CreateIndex
264
+ CREATE INDEX "_EntityToSync_B_index" ON "_EntityToSync"("B");
265
+
266
+ -- AddForeignKey
267
+ ALTER TABLE "User" ADD CONSTRAINT "User_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "User"("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
268
+
269
+ -- AddForeignKey
270
+ ALTER TABLE "Token" ADD CONSTRAINT "Token_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
271
+
272
+ -- AddForeignKey
273
+ ALTER TABLE "Credential" ADD CONSTRAINT "Credential_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
274
+
275
+ -- AddForeignKey
276
+ ALTER TABLE "Entity" ADD CONSTRAINT "Entity_credentialId_fkey" FOREIGN KEY ("credentialId") REFERENCES "Credential"("id") ON DELETE SET NULL ON UPDATE CASCADE;
277
+
278
+ -- AddForeignKey
279
+ ALTER TABLE "Entity" ADD CONSTRAINT "Entity_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
280
+
281
+ -- AddForeignKey
282
+ ALTER TABLE "Integration" ADD CONSTRAINT "Integration_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
283
+
284
+ -- AddForeignKey
285
+ ALTER TABLE "IntegrationMapping" ADD CONSTRAINT "IntegrationMapping_integrationId_fkey" FOREIGN KEY ("integrationId") REFERENCES "Integration"("id") ON DELETE CASCADE ON UPDATE CASCADE;
286
+
287
+ -- AddForeignKey
288
+ ALTER TABLE "Sync" ADD CONSTRAINT "Sync_integrationId_fkey" FOREIGN KEY ("integrationId") REFERENCES "Integration"("id") ON DELETE CASCADE ON UPDATE CASCADE;
289
+
290
+ -- AddForeignKey
291
+ ALTER TABLE "DataIdentifier" ADD CONSTRAINT "DataIdentifier_syncId_fkey" FOREIGN KEY ("syncId") REFERENCES "Sync"("id") ON DELETE CASCADE ON UPDATE CASCADE;
292
+
293
+ -- AddForeignKey
294
+ ALTER TABLE "DataIdentifier" ADD CONSTRAINT "DataIdentifier_entityId_fkey" FOREIGN KEY ("entityId") REFERENCES "Entity"("id") ON DELETE CASCADE ON UPDATE CASCADE;
295
+
296
+ -- AddForeignKey
297
+ ALTER TABLE "Association" ADD CONSTRAINT "Association_integrationId_fkey" FOREIGN KEY ("integrationId") REFERENCES "Integration"("id") ON DELETE CASCADE ON UPDATE CASCADE;
298
+
299
+ -- AddForeignKey
300
+ ALTER TABLE "AssociationObject" ADD CONSTRAINT "AssociationObject_associationId_fkey" FOREIGN KEY ("associationId") REFERENCES "Association"("id") ON DELETE CASCADE ON UPDATE CASCADE;
301
+
302
+ -- AddForeignKey
303
+ ALTER TABLE "AssociationObject" ADD CONSTRAINT "AssociationObject_entityId_fkey" FOREIGN KEY ("entityId") REFERENCES "Entity"("id") ON DELETE CASCADE ON UPDATE CASCADE;
304
+
305
+ -- AddForeignKey
306
+ ALTER TABLE "_EntityToIntegration" ADD CONSTRAINT "_EntityToIntegration_A_fkey" FOREIGN KEY ("A") REFERENCES "Entity"("id") ON DELETE CASCADE ON UPDATE CASCADE;
307
+
308
+ -- AddForeignKey
309
+ ALTER TABLE "_EntityToIntegration" ADD CONSTRAINT "_EntityToIntegration_B_fkey" FOREIGN KEY ("B") REFERENCES "Integration"("id") ON DELETE CASCADE ON UPDATE CASCADE;
310
+
311
+ -- AddForeignKey
312
+ ALTER TABLE "_EntityToSync" ADD CONSTRAINT "_EntityToSync_A_fkey" FOREIGN KEY ("A") REFERENCES "Entity"("id") ON DELETE CASCADE ON UPDATE CASCADE;
313
+
314
+ -- AddForeignKey
315
+ ALTER TABLE "_EntityToSync" ADD CONSTRAINT "_EntityToSync_B_fkey" FOREIGN KEY ("B") REFERENCES "Sync"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,9 @@
1
+ /*
2
+ Warnings:
3
+
4
+ - You are about to drop the column `auth_is_valid` on the `Credential` table. All the data in the column will be lost.
5
+
6
+ */
7
+ -- AlterTable
8
+ ALTER TABLE "Credential" DROP COLUMN "auth_is_valid",
9
+ ADD COLUMN "authIsValid" BOOLEAN;
@@ -0,0 +1,3 @@
1
+ -- AlterTable
2
+ -- Remove unused entityReferenceMap field from Integration table
3
+ ALTER TABLE "Integration" DROP COLUMN "entityReferenceMap";
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "postgresql"