@friggframework/core 2.0.0-next.8 → 2.0.0-next.81

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 (305) hide show
  1. package/CLAUDE.md +702 -0
  2. package/README.md +959 -50
  3. package/application/commands/README.md +451 -0
  4. package/application/commands/credential-commands.js +245 -0
  5. package/application/commands/entity-commands.js +336 -0
  6. package/application/commands/integration-commands.js +210 -0
  7. package/application/commands/scheduler-commands.js +263 -0
  8. package/application/commands/user-commands.js +283 -0
  9. package/application/index.js +73 -0
  10. package/assertions/index.js +0 -3
  11. package/core/CLAUDE.md +690 -0
  12. package/core/Worker.js +60 -24
  13. package/core/create-handler.js +79 -8
  14. package/credential/repositories/credential-repository-documentdb.js +304 -0
  15. package/credential/repositories/credential-repository-factory.js +54 -0
  16. package/credential/repositories/credential-repository-interface.js +98 -0
  17. package/credential/repositories/credential-repository-mongo.js +269 -0
  18. package/credential/repositories/credential-repository-postgres.js +287 -0
  19. package/credential/repositories/credential-repository.js +300 -0
  20. package/credential/use-cases/get-credential-for-user.js +25 -0
  21. package/credential/use-cases/update-authentication-status.js +15 -0
  22. package/database/MONGODB_TRANSACTION_FIX.md +198 -0
  23. package/database/adapters/lambda-invoker.js +97 -0
  24. package/database/config.js +154 -0
  25. package/database/documentdb-encryption-service.js +330 -0
  26. package/database/documentdb-utils.js +136 -0
  27. package/database/encryption/README.md +839 -0
  28. package/database/encryption/documentdb-encryption-service.md +3575 -0
  29. package/database/encryption/encryption-schema-registry.js +268 -0
  30. package/database/encryption/field-encryption-service.js +226 -0
  31. package/database/encryption/logger.js +79 -0
  32. package/database/encryption/prisma-encryption-extension.js +222 -0
  33. package/database/index.js +21 -21
  34. package/database/prisma.js +182 -0
  35. package/database/repositories/health-check-repository-documentdb.js +138 -0
  36. package/database/repositories/health-check-repository-factory.js +48 -0
  37. package/database/repositories/health-check-repository-interface.js +82 -0
  38. package/database/repositories/health-check-repository-mongodb.js +89 -0
  39. package/database/repositories/health-check-repository-postgres.js +82 -0
  40. package/database/repositories/migration-status-repository-s3.js +137 -0
  41. package/database/use-cases/check-database-health-use-case.js +29 -0
  42. package/database/use-cases/check-database-state-use-case.js +81 -0
  43. package/database/use-cases/check-encryption-health-use-case.js +83 -0
  44. package/database/use-cases/get-database-state-via-worker-use-case.js +61 -0
  45. package/database/use-cases/get-migration-status-use-case.js +93 -0
  46. package/database/use-cases/run-database-migration-use-case.js +139 -0
  47. package/database/use-cases/test-encryption-use-case.js +253 -0
  48. package/database/use-cases/trigger-database-migration-use-case.js +157 -0
  49. package/database/utils/mongodb-collection-utils.js +94 -0
  50. package/database/utils/mongodb-schema-init.js +108 -0
  51. package/database/utils/prisma-runner.js +477 -0
  52. package/database/utils/prisma-schema-parser.js +182 -0
  53. package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +517 -0
  54. package/encrypt/Cryptor.js +34 -168
  55. package/encrypt/index.js +1 -2
  56. package/errors/client-safe-error.js +26 -0
  57. package/errors/fetch-error.js +15 -7
  58. package/errors/index.js +2 -0
  59. package/generated/prisma-mongodb/client.d.ts +1 -0
  60. package/generated/prisma-mongodb/client.js +4 -0
  61. package/generated/prisma-mongodb/default.d.ts +1 -0
  62. package/generated/prisma-mongodb/default.js +4 -0
  63. package/generated/prisma-mongodb/edge.d.ts +1 -0
  64. package/generated/prisma-mongodb/edge.js +335 -0
  65. package/generated/prisma-mongodb/index-browser.js +317 -0
  66. package/generated/prisma-mongodb/index.d.ts +22955 -0
  67. package/generated/prisma-mongodb/index.js +360 -0
  68. package/generated/prisma-mongodb/libquery_engine-debian-openssl-3.0.x.so.node +0 -0
  69. package/generated/prisma-mongodb/libquery_engine-rhel-openssl-3.0.x.so.node +0 -0
  70. package/generated/prisma-mongodb/package.json +183 -0
  71. package/generated/prisma-mongodb/runtime/edge-esm.js +34 -0
  72. package/generated/prisma-mongodb/runtime/edge.js +34 -0
  73. package/generated/prisma-mongodb/runtime/index-browser.d.ts +370 -0
  74. package/generated/prisma-mongodb/runtime/index-browser.js +16 -0
  75. package/generated/prisma-mongodb/runtime/library.d.ts +3977 -0
  76. package/generated/prisma-mongodb/runtime/library.js +146 -0
  77. package/generated/prisma-mongodb/runtime/react-native.js +83 -0
  78. package/generated/prisma-mongodb/runtime/wasm-compiler-edge.js +84 -0
  79. package/generated/prisma-mongodb/runtime/wasm-engine-edge.js +36 -0
  80. package/generated/prisma-mongodb/schema.prisma +368 -0
  81. package/generated/prisma-mongodb/wasm-edge-light-loader.mjs +4 -0
  82. package/generated/prisma-mongodb/wasm-worker-loader.mjs +4 -0
  83. package/generated/prisma-mongodb/wasm.d.ts +1 -0
  84. package/generated/prisma-mongodb/wasm.js +342 -0
  85. package/generated/prisma-postgresql/client.d.ts +1 -0
  86. package/generated/prisma-postgresql/client.js +4 -0
  87. package/generated/prisma-postgresql/default.d.ts +1 -0
  88. package/generated/prisma-postgresql/default.js +4 -0
  89. package/generated/prisma-postgresql/edge.d.ts +1 -0
  90. package/generated/prisma-postgresql/edge.js +357 -0
  91. package/generated/prisma-postgresql/index-browser.js +339 -0
  92. package/generated/prisma-postgresql/index.d.ts +25135 -0
  93. package/generated/prisma-postgresql/index.js +382 -0
  94. package/generated/prisma-postgresql/libquery_engine-debian-openssl-3.0.x.so.node +0 -0
  95. package/generated/prisma-postgresql/libquery_engine-rhel-openssl-3.0.x.so.node +0 -0
  96. package/generated/prisma-postgresql/package.json +183 -0
  97. package/generated/prisma-postgresql/query_engine_bg.js +2 -0
  98. package/generated/prisma-postgresql/query_engine_bg.wasm +0 -0
  99. package/generated/prisma-postgresql/runtime/edge-esm.js +34 -0
  100. package/generated/prisma-postgresql/runtime/edge.js +34 -0
  101. package/generated/prisma-postgresql/runtime/index-browser.d.ts +370 -0
  102. package/generated/prisma-postgresql/runtime/index-browser.js +16 -0
  103. package/generated/prisma-postgresql/runtime/library.d.ts +3977 -0
  104. package/generated/prisma-postgresql/runtime/library.js +146 -0
  105. package/generated/prisma-postgresql/runtime/react-native.js +83 -0
  106. package/generated/prisma-postgresql/runtime/wasm-compiler-edge.js +84 -0
  107. package/generated/prisma-postgresql/runtime/wasm-engine-edge.js +36 -0
  108. package/generated/prisma-postgresql/schema.prisma +351 -0
  109. package/generated/prisma-postgresql/wasm-edge-light-loader.mjs +4 -0
  110. package/generated/prisma-postgresql/wasm-worker-loader.mjs +4 -0
  111. package/generated/prisma-postgresql/wasm.d.ts +1 -0
  112. package/generated/prisma-postgresql/wasm.js +364 -0
  113. package/handlers/WEBHOOKS.md +653 -0
  114. package/handlers/app-definition-loader.js +38 -0
  115. package/handlers/app-handler-helpers.js +57 -0
  116. package/handlers/backend-utils.js +262 -0
  117. package/handlers/database-migration-handler.js +227 -0
  118. package/handlers/integration-event-dispatcher.js +54 -0
  119. package/handlers/routers/HEALTHCHECK.md +342 -0
  120. package/handlers/routers/auth.js +15 -0
  121. package/handlers/routers/db-migration.handler.js +29 -0
  122. package/handlers/routers/db-migration.js +326 -0
  123. package/handlers/routers/health.js +516 -0
  124. package/handlers/routers/integration-defined-routers.js +45 -0
  125. package/handlers/routers/integration-webhook-routers.js +67 -0
  126. package/handlers/routers/user.js +63 -0
  127. package/handlers/routers/websocket.js +57 -0
  128. package/handlers/use-cases/check-external-apis-health-use-case.js +81 -0
  129. package/handlers/use-cases/check-integrations-health-use-case.js +44 -0
  130. package/handlers/workers/db-migration.js +352 -0
  131. package/handlers/workers/dlq-processor.js +63 -0
  132. package/handlers/workers/integration-defined-workers.js +23 -0
  133. package/index.js +82 -46
  134. package/infrastructure/scheduler/eventbridge-scheduler-adapter.js +184 -0
  135. package/infrastructure/scheduler/index.js +33 -0
  136. package/infrastructure/scheduler/mock-scheduler-adapter.js +143 -0
  137. package/infrastructure/scheduler/scheduler-service-factory.js +73 -0
  138. package/infrastructure/scheduler/scheduler-service-interface.js +47 -0
  139. package/integrations/WEBHOOK-QUICKSTART.md +151 -0
  140. package/integrations/index.js +12 -10
  141. package/integrations/integration-base.js +364 -55
  142. package/integrations/integration-router.js +376 -179
  143. package/integrations/options.js +1 -1
  144. package/integrations/repositories/integration-mapping-repository-documentdb.js +280 -0
  145. package/integrations/repositories/integration-mapping-repository-factory.js +57 -0
  146. package/integrations/repositories/integration-mapping-repository-interface.js +106 -0
  147. package/integrations/repositories/integration-mapping-repository-mongo.js +161 -0
  148. package/integrations/repositories/integration-mapping-repository-postgres.js +227 -0
  149. package/integrations/repositories/integration-mapping-repository.js +156 -0
  150. package/integrations/repositories/integration-repository-documentdb.js +219 -0
  151. package/integrations/repositories/integration-repository-factory.js +51 -0
  152. package/integrations/repositories/integration-repository-interface.js +144 -0
  153. package/integrations/repositories/integration-repository-mongo.js +330 -0
  154. package/integrations/repositories/integration-repository-postgres.js +385 -0
  155. package/integrations/repositories/process-repository-documentdb.js +311 -0
  156. package/integrations/repositories/process-repository-factory.js +53 -0
  157. package/integrations/repositories/process-repository-interface.js +136 -0
  158. package/integrations/repositories/process-repository-mongo.js +262 -0
  159. package/integrations/repositories/process-repository-postgres.js +380 -0
  160. package/integrations/repositories/process-update-ops-shared.js +112 -0
  161. package/integrations/tests/doubles/config-capturing-integration.js +81 -0
  162. package/integrations/tests/doubles/dummy-integration-class.js +105 -0
  163. package/integrations/tests/doubles/test-integration-repository.js +112 -0
  164. package/integrations/use-cases/create-integration.js +83 -0
  165. package/integrations/use-cases/create-process.js +128 -0
  166. package/integrations/use-cases/delete-integration-for-user.js +101 -0
  167. package/integrations/use-cases/find-integration-context-by-external-entity-id.js +72 -0
  168. package/integrations/use-cases/get-integration-for-user.js +78 -0
  169. package/integrations/use-cases/get-integration-instance-by-definition.js +67 -0
  170. package/integrations/use-cases/get-integration-instance.js +83 -0
  171. package/integrations/use-cases/get-integrations-for-user.js +88 -0
  172. package/integrations/use-cases/get-possible-integrations.js +27 -0
  173. package/integrations/use-cases/get-process.js +87 -0
  174. package/integrations/use-cases/index.js +19 -0
  175. package/integrations/use-cases/load-integration-context.js +71 -0
  176. package/integrations/use-cases/update-integration-messages.js +44 -0
  177. package/integrations/use-cases/update-integration-status.js +32 -0
  178. package/integrations/use-cases/update-integration.js +92 -0
  179. package/integrations/use-cases/update-process-metrics.js +205 -0
  180. package/integrations/use-cases/update-process-state.js +158 -0
  181. package/integrations/utils/map-integration-dto.js +37 -0
  182. package/jest-global-setup-noop.js +3 -0
  183. package/jest-global-teardown-noop.js +3 -0
  184. package/logs/logger.js +0 -4
  185. package/{module-plugin → modules}/index.js +0 -10
  186. package/modules/module-factory.js +56 -0
  187. package/modules/module.js +258 -0
  188. package/modules/repositories/module-repository-documentdb.js +335 -0
  189. package/modules/repositories/module-repository-factory.js +40 -0
  190. package/modules/repositories/module-repository-interface.js +129 -0
  191. package/modules/repositories/module-repository-mongo.js +408 -0
  192. package/modules/repositories/module-repository-postgres.js +453 -0
  193. package/modules/repositories/module-repository.js +345 -0
  194. package/modules/requester/api-key.js +52 -0
  195. package/modules/requester/oauth-2.js +396 -0
  196. package/modules/requester/requester.js +275 -0
  197. package/{module-plugin → modules}/test/mock-api/api.js +8 -3
  198. package/{module-plugin → modules}/test/mock-api/definition.js +14 -10
  199. package/modules/tests/doubles/test-module-factory.js +16 -0
  200. package/modules/tests/doubles/test-module-repository.js +39 -0
  201. package/modules/use-cases/get-entities-for-user.js +32 -0
  202. package/modules/use-cases/get-entity-options-by-id.js +71 -0
  203. package/modules/use-cases/get-entity-options-by-type.js +34 -0
  204. package/modules/use-cases/get-module-instance-from-type.js +34 -0
  205. package/modules/use-cases/get-module.js +74 -0
  206. package/modules/use-cases/process-authorization-callback.js +177 -0
  207. package/modules/use-cases/refresh-entity-options.js +72 -0
  208. package/modules/use-cases/test-module-auth.js +72 -0
  209. package/modules/utils/map-module-dto.js +18 -0
  210. package/package.json +82 -50
  211. package/prisma-mongodb/schema.prisma +368 -0
  212. package/prisma-postgresql/migrations/20250930193005_init/migration.sql +315 -0
  213. package/prisma-postgresql/migrations/20251006135218_init/migration.sql +9 -0
  214. package/prisma-postgresql/migrations/20251010000000_remove_unused_entity_reference_map/migration.sql +3 -0
  215. package/prisma-postgresql/migrations/20251112195422_update_user_unique_constraints/migration.sql +25 -0
  216. package/prisma-postgresql/migrations/20260422120000_add_entity_data_column/migration.sql +10 -0
  217. package/prisma-postgresql/migrations/20260422120001_create_process_table/migration.sql +48 -0
  218. package/prisma-postgresql/migrations/migration_lock.toml +3 -0
  219. package/prisma-postgresql/schema.prisma +351 -0
  220. package/queues/queuer-util.js +103 -21
  221. package/syncs/manager.js +468 -443
  222. package/syncs/repositories/sync-repository-documentdb.js +240 -0
  223. package/syncs/repositories/sync-repository-factory.js +43 -0
  224. package/syncs/repositories/sync-repository-interface.js +109 -0
  225. package/syncs/repositories/sync-repository-mongo.js +239 -0
  226. package/syncs/repositories/sync-repository-postgres.js +319 -0
  227. package/syncs/sync.js +0 -1
  228. package/token/repositories/token-repository-documentdb.js +137 -0
  229. package/token/repositories/token-repository-factory.js +40 -0
  230. package/token/repositories/token-repository-interface.js +131 -0
  231. package/token/repositories/token-repository-mongo.js +219 -0
  232. package/token/repositories/token-repository-postgres.js +264 -0
  233. package/token/repositories/token-repository.js +219 -0
  234. package/types/associations/index.d.ts +0 -17
  235. package/types/core/index.d.ts +12 -4
  236. package/types/database/index.d.ts +10 -2
  237. package/types/encrypt/index.d.ts +5 -3
  238. package/types/integrations/index.d.ts +3 -8
  239. package/types/module-plugin/index.d.ts +17 -69
  240. package/types/syncs/index.d.ts +0 -17
  241. package/user/repositories/user-repository-documentdb.js +441 -0
  242. package/user/repositories/user-repository-factory.js +52 -0
  243. package/user/repositories/user-repository-interface.js +201 -0
  244. package/user/repositories/user-repository-mongo.js +308 -0
  245. package/user/repositories/user-repository-postgres.js +360 -0
  246. package/user/tests/doubles/test-user-repository.js +72 -0
  247. package/user/use-cases/authenticate-user.js +127 -0
  248. package/user/use-cases/authenticate-with-shared-secret.js +48 -0
  249. package/user/use-cases/create-individual-user.js +61 -0
  250. package/user/use-cases/create-organization-user.js +47 -0
  251. package/user/use-cases/create-token-for-user-id.js +30 -0
  252. package/user/use-cases/get-user-from-adopter-jwt.js +149 -0
  253. package/user/use-cases/get-user-from-bearer-token.js +77 -0
  254. package/user/use-cases/get-user-from-x-frigg-headers.js +132 -0
  255. package/user/use-cases/login-user.js +122 -0
  256. package/user/user.js +125 -0
  257. package/utils/backend-path.js +38 -0
  258. package/utils/index.js +6 -0
  259. package/websocket/repositories/websocket-connection-repository-documentdb.js +119 -0
  260. package/websocket/repositories/websocket-connection-repository-factory.js +44 -0
  261. package/websocket/repositories/websocket-connection-repository-interface.js +106 -0
  262. package/websocket/repositories/websocket-connection-repository-mongo.js +156 -0
  263. package/websocket/repositories/websocket-connection-repository-postgres.js +196 -0
  264. package/websocket/repositories/websocket-connection-repository.js +161 -0
  265. package/assertions/is-equal.js +0 -17
  266. package/associations/model.js +0 -54
  267. package/database/models/IndividualUser.js +0 -76
  268. package/database/models/OrganizationUser.js +0 -29
  269. package/database/models/State.js +0 -9
  270. package/database/models/Token.js +0 -70
  271. package/database/models/UserModel.js +0 -7
  272. package/database/models/WebsocketConnection.js +0 -49
  273. package/database/mongo.js +0 -45
  274. package/database/mongoose.js +0 -5
  275. package/encrypt/Cryptor.test.js +0 -32
  276. package/encrypt/encrypt.js +0 -132
  277. package/encrypt/encrypt.test.js +0 -1069
  278. package/encrypt/test-encrypt.js +0 -107
  279. package/errors/base-error.test.js +0 -32
  280. package/errors/fetch-error.test.js +0 -79
  281. package/errors/halt-error.test.js +0 -11
  282. package/errors/validation-errors.test.js +0 -120
  283. package/integrations/create-frigg-backend.js +0 -31
  284. package/integrations/integration-factory.js +0 -251
  285. package/integrations/integration-mapping.js +0 -43
  286. package/integrations/integration-model.js +0 -46
  287. package/integrations/integration-user.js +0 -144
  288. package/integrations/test/integration-base.test.js +0 -144
  289. package/lambda/TimeoutCatcher.test.js +0 -68
  290. package/logs/logger.test.js +0 -76
  291. package/module-plugin/auther.js +0 -393
  292. package/module-plugin/credential.js +0 -22
  293. package/module-plugin/entity-manager.js +0 -70
  294. package/module-plugin/entity.js +0 -46
  295. package/module-plugin/manager.js +0 -169
  296. package/module-plugin/module-factory.js +0 -61
  297. package/module-plugin/requester/api-key.js +0 -36
  298. package/module-plugin/requester/oauth-2.js +0 -219
  299. package/module-plugin/requester/requester.js +0 -165
  300. package/module-plugin/requester/requester.test.js +0 -28
  301. package/module-plugin/test/auther.test.js +0 -97
  302. package/syncs/model.js +0 -62
  303. /package/{module-plugin → modules}/ModuleConstants.js +0 -0
  304. /package/{module-plugin → modules}/requester/basic.js +0 -0
  305. /package/{module-plugin → modules}/test/mock-api/mocks/hubspot.js +0 -0
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @param {import('../module').Module} moduleInstance
3
+ * Convert a Module domain instance to a plain DTO suitable for JSON responses.
4
+ */
5
+ function mapModuleClassToModuleDTO(moduleInstance) {
6
+ if (!moduleInstance) return null;
7
+
8
+ return {
9
+ id: moduleInstance.entity.id,
10
+ name: moduleInstance.name,
11
+ userId: moduleInstance.userId,
12
+ entity: moduleInstance.entity,
13
+ credentialId: moduleInstance.credential?._id?.toString(),
14
+ type: moduleInstance.getName()
15
+ };
16
+ }
17
+
18
+ module.exports = { mapModuleClassToModuleDTO };
package/package.json CHANGED
@@ -1,52 +1,84 @@
1
1
  {
2
- "name": "@friggframework/core",
3
- "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0-next.8",
5
- "dependencies": {
6
- "@hapi/boom": "^10.0.1",
7
- "aws-sdk": "^2.1200.0",
8
- "bcryptjs": "^2.4.3",
9
- "common-tags": "^1.8.2",
10
- "express": "^4.18.2",
11
- "express-async-handler": "^1.2.0",
12
- "lodash": "^4.17.21",
13
- "lodash.get": "^4.4.2",
14
- "mongoose": "6.11.6",
15
- "node-fetch": "^2.6.7"
16
- },
17
- "devDependencies": {
18
- "@friggframework/eslint-config": "2.0.0-next.8",
19
- "@friggframework/prettier-config": "2.0.0-next.8",
20
- "@friggframework/test": "2.0.0-next.8",
21
- "@types/lodash": "^4.14.191",
22
- "@typescript-eslint/eslint-plugin": "^8.0.0",
23
- "chai": "^4.3.6",
24
- "eslint": "^8.22.0",
25
- "eslint-plugin-import": "^2.29.1",
26
- "eslint-plugin-n": "^17.10.2",
27
- "eslint-plugin-promise": "^7.0.0",
28
- "jest": "^29.7.0",
29
- "jest-runner-groups": "^2.2.0",
30
- "mongodb-memory-server": "^8.9.0",
31
- "prettier": "^2.8.5",
32
- "sinon": "^16.1.1",
33
- "typescript": "^5.0.2"
34
- },
35
- "scripts": {
36
- "lint:fix": "prettier --write --loglevel error . && eslint . --fix",
37
- "test": "jest --passWithNoTests # TODO"
38
- },
39
- "author": "",
40
- "license": "MIT",
41
- "main": "index.js",
42
- "repository": {
43
- "type": "git",
44
- "url": "git+https://github.com/friggframework/frigg.git"
45
- },
46
- "bugs": {
47
- "url": "https://github.com/friggframework/frigg/issues"
48
- },
49
- "homepage": "https://github.com/friggframework/frigg#readme",
50
- "description": "",
51
- "gitHead": "60b7a6f92954ad165186861a35fba66e40f60a42"
2
+ "name": "@friggframework/core",
3
+ "prettier": "@friggframework/prettier-config",
4
+ "version": "2.0.0-next.81",
5
+ "dependencies": {
6
+ "@aws-sdk/client-apigatewaymanagementapi": "^3.588.0",
7
+ "@aws-sdk/client-kms": "^3.588.0",
8
+ "@aws-sdk/client-lambda": "^3.714.0",
9
+ "@aws-sdk/client-sqs": "^3.588.0",
10
+ "@hapi/boom": "^10.0.1",
11
+ "bcryptjs": "^2.4.3",
12
+ "body-parser": "^1.20.2",
13
+ "bson": "^4.7.2",
14
+ "chalk": "^4.1.2",
15
+ "common-tags": "^1.8.2",
16
+ "cors": "^2.8.5",
17
+ "dotenv": "^16.4.7",
18
+ "express": "^4.19.2",
19
+ "express-async-handler": "^1.2.0",
20
+ "form-data": "^4.0.0",
21
+ "fs-extra": "^11.2.0",
22
+ "lodash": "4.17.21",
23
+ "lodash.get": "^4.4.2",
24
+ "node-fetch": "^2.6.7",
25
+ "serverless-http": "^2.7.0",
26
+ "uuid": "^9.0.1"
27
+ },
28
+ "peerDependencies": {
29
+ "@prisma/client": "^6.16.3",
30
+ "prisma": "^6.16.3"
31
+ },
32
+ "peerDependenciesMeta": {
33
+ "@prisma/client": {
34
+ "optional": true
35
+ },
36
+ "prisma": {
37
+ "optional": true
38
+ }
39
+ },
40
+ "devDependencies": {
41
+ "@friggframework/eslint-config": "2.0.0-next.81",
42
+ "@friggframework/prettier-config": "2.0.0-next.81",
43
+ "@friggframework/test": "2.0.0-next.81",
44
+ "@prisma/client": "^6.17.0",
45
+ "@types/lodash": "4.17.15",
46
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
47
+ "chai": "^4.3.6",
48
+ "eslint": "^8.22.0",
49
+ "eslint-plugin-import": "^2.29.1",
50
+ "eslint-plugin-n": "^17.10.2",
51
+ "eslint-plugin-promise": "^7.0.0",
52
+ "jest": "^29.7.0",
53
+ "prettier": "^2.7.1",
54
+ "prisma": "^6.17.0",
55
+ "sinon": "^16.1.1",
56
+ "typescript": "^5.0.2"
57
+ },
58
+ "scripts": {
59
+ "lint:fix": "prettier --write --loglevel error . && eslint . --fix",
60
+ "test": "jest --passWithNoTests # TODO",
61
+ "prisma:generate:mongo": "npx prisma generate --schema ./prisma-mongodb/schema.prisma",
62
+ "prisma:generate:postgres": "npx prisma generate --schema ./prisma-postgresql/schema.prisma",
63
+ "prisma:generate": "npm run prisma:generate:mongo && npm run prisma:generate:postgres",
64
+ "prisma:push:mongo": "npx prisma db push --schema ./prisma-mongodb/schema.prisma",
65
+ "prisma:migrate:postgres": "npx prisma migrate dev --schema ./prisma-postgresql/schema.prisma",
66
+ "prepublishOnly": "npm run prisma:generate"
67
+ },
68
+ "author": "",
69
+ "license": "MIT",
70
+ "main": "index.js",
71
+ "repository": {
72
+ "type": "git",
73
+ "url": "git+https://github.com/friggframework/frigg.git"
74
+ },
75
+ "bugs": {
76
+ "url": "https://github.com/friggframework/frigg/issues"
77
+ },
78
+ "homepage": "https://github.com/friggframework/frigg#readme",
79
+ "description": "",
80
+ "publishConfig": {
81
+ "access": "public"
82
+ },
83
+ "gitHead": "f928679326fe06cc56ac46e97cf268fe8f8e823e"
52
84
  }
@@ -0,0 +1,368 @@
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
+ // Library engine (default since Prisma 3.x): Rust query engine loads as a
10
+ // Node-API addon inside the same process. The binary engine forks a child
11
+ // query-engine subprocess and communicates over a local HTTP/IPC pipe with
12
+ // NO client-side timeout — a zombied child wedges the Node process until
13
+ // Lambda's 900s cap. Switching to library eliminates that entire class of
14
+ // silent hangs. See friggframework/frigg#580 for the investigation.
15
+ engineType = "library"
16
+ }
17
+
18
+ datasource db {
19
+ provider = "mongodb"
20
+ url = env("DATABASE_URL")
21
+ }
22
+
23
+ // ============================================================================
24
+ // USER MODELS
25
+ // ============================================================================
26
+
27
+ /// User model with discriminator pattern support
28
+ /// Replaces Mongoose discriminators (IndividualUser, OrganizationUser)
29
+ model User {
30
+ id String @id @default(auto()) @map("_id") @db.ObjectId
31
+ type UserType
32
+
33
+ // Timestamps
34
+ createdAt DateTime @default(now())
35
+ updatedAt DateTime @updatedAt
36
+
37
+ // IndividualUser fields (nullable for organizations)
38
+ email String?
39
+ username String?
40
+ hashword String? // Bcrypt hashed password (handled in application layer)
41
+ appUserId String?
42
+ organizationId String? @db.ObjectId
43
+
44
+ // Self-referential relation for organization membership
45
+ organization User? @relation("OrgMembers", fields: [organizationId], references: [id], onDelete: NoAction, onUpdate: NoAction)
46
+ members User[] @relation("OrgMembers")
47
+
48
+ // OrganizationUser fields (nullable for individuals)
49
+ appOrgId String?
50
+ name String?
51
+
52
+ // Relations
53
+ tokens Token[]
54
+ credentials Credential[]
55
+ entities Entity[]
56
+ integrations Integration[]
57
+ processes Process[]
58
+
59
+ @@unique([username, appUserId])
60
+ @@index([type])
61
+ @@index([appUserId])
62
+ @@map("User")
63
+ }
64
+
65
+ enum UserType {
66
+ INDIVIDUAL
67
+ ORGANIZATION
68
+ }
69
+
70
+ // ============================================================================
71
+ // AUTHENTICATION MODELS
72
+ // ============================================================================
73
+
74
+ /// Authentication tokens with expiration
75
+ /// Bcrypt hashed tokens stored (handled in application layer)
76
+ model Token {
77
+ id String @id @default(auto()) @map("_id") @db.ObjectId
78
+ token String // Bcrypt hashed
79
+ created DateTime @default(now())
80
+ expires DateTime?
81
+ userId String @db.ObjectId
82
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
83
+
84
+ @@index([userId])
85
+ @@index([expires])
86
+ @@map("Token")
87
+ }
88
+
89
+ // ============================================================================
90
+ // CREDENTIAL & ENTITY MODELS
91
+ // ============================================================================
92
+
93
+ /// OAuth credentials and API tokens
94
+ /// All sensitive data encrypted with KMS at rest
95
+ model Credential {
96
+ id String @id @default(auto()) @map("_id") @db.ObjectId
97
+ userId String? @db.ObjectId
98
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
99
+ authIsValid Boolean?
100
+ externalId String?
101
+
102
+ // Dynamic OAuth fields stored as JSON (encrypted via Prisma middleware)
103
+ // Contains: access_token, refresh_token, domain, expires_in, token_type, etc.
104
+ data Json @default("{}")
105
+
106
+ createdAt DateTime @default(now())
107
+ updatedAt DateTime @updatedAt
108
+
109
+ // Relations
110
+ entities Entity[]
111
+
112
+ @@index([userId])
113
+ @@index([externalId])
114
+ @@map("Credential")
115
+ }
116
+
117
+ /// External service entities (API connections)
118
+ model Entity {
119
+ id String @id @default(auto()) @map("_id") @db.ObjectId
120
+ credentialId String? @db.ObjectId
121
+ credential Credential? @relation(fields: [credentialId], references: [id], onDelete: SetNull)
122
+ userId String? @db.ObjectId
123
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
124
+ name String?
125
+ moduleName String?
126
+ externalId String?
127
+
128
+ data Json @default("{}")
129
+
130
+ createdAt DateTime @default(now())
131
+ updatedAt DateTime @updatedAt
132
+
133
+ // Relations - many-to-many with scalar lists
134
+ integrations Integration[] @relation("IntegrationEntities", fields: [integrationIds], references: [id])
135
+ integrationIds String[] @db.ObjectId
136
+
137
+ syncs Sync[] @relation("SyncEntities", fields: [syncIds], references: [id])
138
+ syncIds String[] @db.ObjectId
139
+
140
+ dataIdentifiers DataIdentifier[]
141
+ associationObjects AssociationObject[]
142
+
143
+ @@index([userId])
144
+ @@index([externalId])
145
+ @@index([moduleName])
146
+ @@index([credentialId])
147
+ @@map("Entity")
148
+ }
149
+
150
+ // ============================================================================
151
+ // INTEGRATION MODELS
152
+ // ============================================================================
153
+
154
+ /// Main integration configuration and state
155
+ model Integration {
156
+ id String @id @default(auto()) @map("_id") @db.ObjectId
157
+ userId String? @db.ObjectId
158
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
159
+ status IntegrationStatus @default(ENABLED)
160
+
161
+ // Configuration and version
162
+ config Json? // Integration configuration object
163
+ version String?
164
+
165
+ // Entity references (many-to-many via explicit scalar list)
166
+ entities Entity[] @relation("IntegrationEntities", fields: [entityIds], references: [id])
167
+ entityIds String[] @db.ObjectId
168
+
169
+ // Message arrays (stored as JSON)
170
+ errors Json @default("[]")
171
+ warnings Json @default("[]")
172
+ info Json @default("[]")
173
+ logs Json @default("[]")
174
+
175
+ createdAt DateTime @default(now())
176
+ updatedAt DateTime @updatedAt
177
+
178
+ // Relations
179
+ associations Association[]
180
+ syncs Sync[]
181
+ mappings IntegrationMapping[]
182
+ processes Process[]
183
+
184
+ @@index([userId])
185
+ @@index([status])
186
+ @@map("Integration")
187
+ }
188
+
189
+ enum IntegrationStatus {
190
+ ENABLED
191
+ NEEDS_CONFIG
192
+ PROCESSING
193
+ DISABLED
194
+ ERROR
195
+ }
196
+
197
+ /// Integration-specific data mappings
198
+ /// All mapping data encrypted with KMS
199
+ model IntegrationMapping {
200
+ id String @id @default(auto()) @map("_id") @db.ObjectId
201
+ integrationId String @db.ObjectId
202
+ integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
203
+ sourceId String?
204
+
205
+ // Encrypted mapping data (handled via Prisma middleware)
206
+ mapping Json?
207
+
208
+ createdAt DateTime @default(now())
209
+ updatedAt DateTime @updatedAt
210
+
211
+ @@unique([integrationId, sourceId])
212
+ @@index([integrationId])
213
+ @@index([sourceId])
214
+ @@map("IntegrationMapping")
215
+ }
216
+
217
+ // ============================================================================
218
+ // PROCESS MODELS
219
+ // ============================================================================
220
+
221
+ /// Generic Process Model - tracks any long-running operation
222
+ /// Used for: CRM syncs, data migrations, bulk operations, etc.
223
+ model Process {
224
+ id String @id @default(auto()) @map("_id") @db.ObjectId
225
+
226
+ // Core references
227
+ userId String @db.ObjectId
228
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
229
+ integrationId String @db.ObjectId
230
+ integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
231
+
232
+ // Process identification
233
+ name String // e.g., "zoho-crm-contact-sync", "pipedrive-lead-sync"
234
+ type String // e.g., "CRM_SYNC", "DATA_MIGRATION", "BULK_OPERATION"
235
+
236
+ // State machine
237
+ state String // Current state (integration-defined states)
238
+
239
+ // Flexible storage
240
+ context Json @default("{}") // Process-specific data (pagination, metadata, etc.)
241
+ results Json @default("{}") // Process results and metrics
242
+
243
+ // Hierarchy support
244
+ childProcesses String[] @db.ObjectId
245
+ parentProcessId String? @db.ObjectId
246
+
247
+ // Timestamps
248
+ createdAt DateTime @default(now())
249
+ updatedAt DateTime @updatedAt
250
+
251
+ @@index([userId])
252
+ @@index([integrationId])
253
+ @@index([type])
254
+ @@index([state])
255
+ @@index([name])
256
+ @@map("Process")
257
+ }
258
+
259
+ // ============================================================================
260
+ // SYNC MODELS
261
+ // ============================================================================
262
+
263
+ /// Bidirectional data synchronization tracking
264
+ model Sync {
265
+ id String @id @default(auto()) @map("_id") @db.ObjectId
266
+ integrationId String? @db.ObjectId
267
+ integration Integration? @relation(fields: [integrationId], references: [id], onDelete: Cascade)
268
+
269
+ // Entity references (many-to-many via explicit scalar list)
270
+ entities Entity[] @relation("SyncEntities", fields: [entityIds], references: [id])
271
+ entityIds String[] @db.ObjectId
272
+
273
+ hash String
274
+ name String
275
+
276
+ // Data identifiers (extracted to separate model)
277
+ dataIdentifiers DataIdentifier[]
278
+
279
+ @@index([integrationId])
280
+ @@index([hash])
281
+ @@index([name])
282
+ @@map("Sync")
283
+ }
284
+
285
+ /// Data identifier for sync operations
286
+ /// Replaces nested array structure in Mongoose
287
+ model DataIdentifier {
288
+ id String @id @default(auto()) @map("_id") @db.ObjectId
289
+ syncId String? @db.ObjectId
290
+ sync Sync? @relation(fields: [syncId], references: [id], onDelete: Cascade)
291
+ entityId String @db.ObjectId
292
+ entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
293
+
294
+ // Identifier data (can be any structure)
295
+ idData Json
296
+
297
+ hash String
298
+
299
+ @@index([syncId])
300
+ @@index([entityId])
301
+ @@index([hash])
302
+ @@map("DataIdentifier")
303
+ }
304
+
305
+ // ============================================================================
306
+ // ASSOCIATION MODELS
307
+ // ============================================================================
308
+
309
+ /// Entity associations with cardinality tracking
310
+ model Association {
311
+ id String @id @default(auto()) @map("_id") @db.ObjectId
312
+ integrationId String @db.ObjectId
313
+ integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
314
+ name String
315
+ type AssociationType
316
+ primaryObject String
317
+
318
+ // Associated objects (extracted to separate model)
319
+ objects AssociationObject[]
320
+
321
+ @@index([integrationId])
322
+ @@index([name])
323
+ @@map("Association")
324
+ }
325
+
326
+ /// Association object entry
327
+ /// Replaces nested array structure in Mongoose
328
+ model AssociationObject {
329
+ id String @id @default(auto()) @map("_id") @db.ObjectId
330
+ associationId String @db.ObjectId
331
+ association Association @relation(fields: [associationId], references: [id], onDelete: Cascade)
332
+ entityId String @db.ObjectId
333
+ entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
334
+ objectType String
335
+ objId String
336
+ metadata Json? // Optional metadata
337
+
338
+ @@index([associationId])
339
+ @@index([entityId])
340
+ @@map("AssociationObject")
341
+ }
342
+
343
+ enum AssociationType {
344
+ ONE_TO_MANY
345
+ ONE_TO_ONE
346
+ MANY_TO_ONE
347
+ }
348
+
349
+ // ============================================================================
350
+ // UTILITY MODELS
351
+ // ============================================================================
352
+
353
+ /// Generic state storage
354
+ model State {
355
+ id String @id @default(auto()) @map("_id") @db.ObjectId
356
+ state Json?
357
+
358
+ @@map("State")
359
+ }
360
+
361
+ /// AWS API Gateway WebSocket connection tracking
362
+ model WebsocketConnection {
363
+ id String @id @default(auto()) @map("_id") @db.ObjectId
364
+ connectionId String?
365
+
366
+ @@index([connectionId])
367
+ @@map("WebsocketConnection")
368
+ }