@friggframework/core 2.0.0-next.6 → 2.0.0-next.60
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.
- package/CLAUDE.md +694 -0
- package/README.md +959 -50
- package/application/commands/README.md +451 -0
- package/application/commands/credential-commands.js +245 -0
- package/application/commands/entity-commands.js +336 -0
- package/application/commands/integration-commands.js +210 -0
- package/application/commands/user-commands.js +283 -0
- package/application/index.js +69 -0
- package/core/CLAUDE.md +690 -0
- package/core/Worker.js +8 -21
- package/core/create-handler.js +14 -7
- package/credential/repositories/credential-repository-documentdb.js +304 -0
- package/credential/repositories/credential-repository-factory.js +54 -0
- package/credential/repositories/credential-repository-interface.js +98 -0
- package/credential/repositories/credential-repository-mongo.js +269 -0
- package/credential/repositories/credential-repository-postgres.js +291 -0
- package/credential/repositories/credential-repository.js +302 -0
- package/credential/use-cases/get-credential-for-user.js +25 -0
- package/credential/use-cases/update-authentication-status.js +15 -0
- package/database/MONGODB_TRANSACTION_FIX.md +198 -0
- package/database/adapters/lambda-invoker.js +97 -0
- package/database/config.js +154 -0
- package/database/documentdb-encryption-service.js +330 -0
- package/database/documentdb-utils.js +136 -0
- package/database/encryption/README.md +839 -0
- package/database/encryption/documentdb-encryption-service.md +3575 -0
- package/database/encryption/encryption-schema-registry.js +268 -0
- package/database/encryption/field-encryption-service.js +226 -0
- package/database/encryption/logger.js +79 -0
- package/database/encryption/prisma-encryption-extension.js +222 -0
- package/database/index.js +61 -21
- package/database/models/WebsocketConnection.js +16 -10
- package/database/models/readme.md +1 -0
- package/database/prisma.js +182 -0
- package/database/repositories/health-check-repository-documentdb.js +134 -0
- package/database/repositories/health-check-repository-factory.js +48 -0
- package/database/repositories/health-check-repository-interface.js +82 -0
- package/database/repositories/health-check-repository-mongodb.js +89 -0
- package/database/repositories/health-check-repository-postgres.js +82 -0
- package/database/repositories/health-check-repository.js +108 -0
- package/database/repositories/migration-status-repository-s3.js +137 -0
- package/database/use-cases/check-database-health-use-case.js +29 -0
- package/database/use-cases/check-database-state-use-case.js +81 -0
- package/database/use-cases/check-encryption-health-use-case.js +83 -0
- package/database/use-cases/get-database-state-via-worker-use-case.js +61 -0
- package/database/use-cases/get-migration-status-use-case.js +93 -0
- package/database/use-cases/run-database-migration-use-case.js +139 -0
- package/database/use-cases/test-encryption-use-case.js +253 -0
- package/database/use-cases/trigger-database-migration-use-case.js +157 -0
- package/database/utils/mongodb-collection-utils.js +91 -0
- package/database/utils/mongodb-schema-init.js +106 -0
- package/database/utils/prisma-runner.js +477 -0
- package/database/utils/prisma-schema-parser.js +182 -0
- package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +517 -0
- package/encrypt/Cryptor.js +34 -168
- package/encrypt/index.js +1 -2
- package/encrypt/test-encrypt.js +0 -2
- package/errors/client-safe-error.js +26 -0
- package/errors/fetch-error.js +2 -1
- package/errors/index.js +2 -0
- package/generated/prisma-mongodb/client.d.ts +1 -0
- package/generated/prisma-mongodb/client.js +4 -0
- package/generated/prisma-mongodb/default.d.ts +1 -0
- package/generated/prisma-mongodb/default.js +4 -0
- package/generated/prisma-mongodb/edge.d.ts +1 -0
- package/generated/prisma-mongodb/edge.js +334 -0
- package/generated/prisma-mongodb/index-browser.js +316 -0
- package/generated/prisma-mongodb/index.d.ts +22903 -0
- package/generated/prisma-mongodb/index.js +359 -0
- package/generated/prisma-mongodb/package.json +183 -0
- package/generated/prisma-mongodb/query-engine-debian-openssl-3.0.x +0 -0
- package/generated/prisma-mongodb/query-engine-rhel-openssl-3.0.x +0 -0
- package/generated/prisma-mongodb/runtime/binary.d.ts +1 -0
- package/generated/prisma-mongodb/runtime/binary.js +289 -0
- package/generated/prisma-mongodb/runtime/edge-esm.js +34 -0
- package/generated/prisma-mongodb/runtime/edge.js +34 -0
- package/generated/prisma-mongodb/runtime/index-browser.d.ts +370 -0
- package/generated/prisma-mongodb/runtime/index-browser.js +16 -0
- package/generated/prisma-mongodb/runtime/library.d.ts +3977 -0
- package/generated/prisma-mongodb/runtime/react-native.js +83 -0
- package/generated/prisma-mongodb/runtime/wasm-compiler-edge.js +84 -0
- package/generated/prisma-mongodb/runtime/wasm-engine-edge.js +36 -0
- package/generated/prisma-mongodb/schema.prisma +360 -0
- package/generated/prisma-mongodb/wasm-edge-light-loader.mjs +4 -0
- package/generated/prisma-mongodb/wasm-worker-loader.mjs +4 -0
- package/generated/prisma-mongodb/wasm.d.ts +1 -0
- package/generated/prisma-mongodb/wasm.js +341 -0
- package/generated/prisma-postgresql/client.d.ts +1 -0
- package/generated/prisma-postgresql/client.js +4 -0
- package/generated/prisma-postgresql/default.d.ts +1 -0
- package/generated/prisma-postgresql/default.js +4 -0
- package/generated/prisma-postgresql/edge.d.ts +1 -0
- package/generated/prisma-postgresql/edge.js +356 -0
- package/generated/prisma-postgresql/index-browser.js +338 -0
- package/generated/prisma-postgresql/index.d.ts +25077 -0
- package/generated/prisma-postgresql/index.js +381 -0
- package/generated/prisma-postgresql/package.json +183 -0
- package/generated/prisma-postgresql/query-engine-debian-openssl-3.0.x +0 -0
- package/generated/prisma-postgresql/query-engine-rhel-openssl-3.0.x +0 -0
- package/generated/prisma-postgresql/query_engine_bg.js +2 -0
- package/generated/prisma-postgresql/query_engine_bg.wasm +0 -0
- package/generated/prisma-postgresql/runtime/binary.d.ts +1 -0
- package/generated/prisma-postgresql/runtime/binary.js +289 -0
- package/generated/prisma-postgresql/runtime/edge-esm.js +34 -0
- package/generated/prisma-postgresql/runtime/edge.js +34 -0
- package/generated/prisma-postgresql/runtime/index-browser.d.ts +370 -0
- package/generated/prisma-postgresql/runtime/index-browser.js +16 -0
- package/generated/prisma-postgresql/runtime/library.d.ts +3977 -0
- package/generated/prisma-postgresql/runtime/react-native.js +83 -0
- package/generated/prisma-postgresql/runtime/wasm-compiler-edge.js +84 -0
- package/generated/prisma-postgresql/runtime/wasm-engine-edge.js +36 -0
- package/generated/prisma-postgresql/schema.prisma +343 -0
- package/generated/prisma-postgresql/wasm-edge-light-loader.mjs +4 -0
- package/generated/prisma-postgresql/wasm-worker-loader.mjs +4 -0
- package/generated/prisma-postgresql/wasm.d.ts +1 -0
- package/generated/prisma-postgresql/wasm.js +363 -0
- package/handlers/WEBHOOKS.md +653 -0
- package/handlers/app-definition-loader.js +38 -0
- package/handlers/app-handler-helpers.js +56 -0
- package/handlers/backend-utils.js +186 -0
- package/handlers/database-migration-handler.js +227 -0
- package/handlers/integration-event-dispatcher.js +54 -0
- package/handlers/routers/HEALTHCHECK.md +342 -0
- package/handlers/routers/auth.js +15 -0
- package/handlers/routers/db-migration.handler.js +29 -0
- package/handlers/routers/db-migration.js +326 -0
- package/handlers/routers/health.js +516 -0
- package/handlers/routers/integration-defined-routers.js +45 -0
- package/handlers/routers/integration-webhook-routers.js +67 -0
- package/handlers/routers/user.js +63 -0
- package/handlers/routers/websocket.js +57 -0
- package/handlers/use-cases/check-external-apis-health-use-case.js +81 -0
- package/handlers/use-cases/check-integrations-health-use-case.js +44 -0
- package/handlers/workers/db-migration.js +352 -0
- package/handlers/workers/integration-defined-workers.js +27 -0
- package/index.js +77 -22
- package/integrations/WEBHOOK-QUICKSTART.md +151 -0
- package/integrations/index.js +12 -10
- package/integrations/integration-base.js +326 -55
- package/integrations/integration-router.js +374 -179
- package/integrations/options.js +1 -1
- package/integrations/repositories/integration-mapping-repository-documentdb.js +280 -0
- package/integrations/repositories/integration-mapping-repository-factory.js +57 -0
- package/integrations/repositories/integration-mapping-repository-interface.js +106 -0
- package/integrations/repositories/integration-mapping-repository-mongo.js +161 -0
- package/integrations/repositories/integration-mapping-repository-postgres.js +227 -0
- package/integrations/repositories/integration-mapping-repository.js +156 -0
- package/integrations/repositories/integration-repository-documentdb.js +210 -0
- package/integrations/repositories/integration-repository-factory.js +51 -0
- package/integrations/repositories/integration-repository-interface.js +127 -0
- package/integrations/repositories/integration-repository-mongo.js +303 -0
- package/integrations/repositories/integration-repository-postgres.js +352 -0
- package/integrations/repositories/process-repository-documentdb.js +243 -0
- package/integrations/repositories/process-repository-factory.js +53 -0
- package/integrations/repositories/process-repository-interface.js +90 -0
- package/integrations/repositories/process-repository-mongo.js +190 -0
- package/integrations/repositories/process-repository-postgres.js +217 -0
- package/integrations/tests/doubles/dummy-integration-class.js +83 -0
- package/integrations/tests/doubles/test-integration-repository.js +99 -0
- package/integrations/use-cases/create-integration.js +83 -0
- package/integrations/use-cases/create-process.js +128 -0
- package/integrations/use-cases/delete-integration-for-user.js +101 -0
- package/integrations/use-cases/find-integration-context-by-external-entity-id.js +72 -0
- package/integrations/use-cases/get-integration-for-user.js +78 -0
- package/integrations/use-cases/get-integration-instance-by-definition.js +67 -0
- package/integrations/use-cases/get-integration-instance.js +83 -0
- package/integrations/use-cases/get-integrations-for-user.js +88 -0
- package/integrations/use-cases/get-possible-integrations.js +27 -0
- package/integrations/use-cases/get-process.js +87 -0
- package/integrations/use-cases/index.js +19 -0
- package/integrations/use-cases/load-integration-context.js +71 -0
- package/integrations/use-cases/update-integration-messages.js +44 -0
- package/integrations/use-cases/update-integration-status.js +32 -0
- package/integrations/use-cases/update-integration.js +93 -0
- package/integrations/use-cases/update-process-metrics.js +201 -0
- package/integrations/use-cases/update-process-state.js +119 -0
- package/integrations/utils/map-integration-dto.js +37 -0
- package/jest-global-setup-noop.js +3 -0
- package/jest-global-teardown-noop.js +3 -0
- package/logs/logger.js +0 -4
- package/{module-plugin → modules}/entity.js +1 -1
- package/{module-plugin → modules}/index.js +0 -8
- package/modules/module-factory.js +56 -0
- package/modules/module.js +221 -0
- package/modules/repositories/module-repository-documentdb.js +307 -0
- package/modules/repositories/module-repository-factory.js +40 -0
- package/modules/repositories/module-repository-interface.js +129 -0
- package/modules/repositories/module-repository-mongo.js +377 -0
- package/modules/repositories/module-repository-postgres.js +426 -0
- package/modules/repositories/module-repository.js +316 -0
- package/modules/requester/api-key.js +52 -0
- package/{module-plugin → modules}/requester/requester.js +1 -0
- package/{module-plugin → modules}/test/mock-api/api.js +8 -3
- package/{module-plugin → modules}/test/mock-api/definition.js +12 -8
- package/modules/tests/doubles/test-module-factory.js +16 -0
- package/modules/tests/doubles/test-module-repository.js +39 -0
- package/modules/use-cases/get-entities-for-user.js +32 -0
- package/modules/use-cases/get-entity-options-by-id.js +71 -0
- package/modules/use-cases/get-entity-options-by-type.js +34 -0
- package/modules/use-cases/get-module-instance-from-type.js +31 -0
- package/modules/use-cases/get-module.js +74 -0
- package/modules/use-cases/process-authorization-callback.js +133 -0
- package/modules/use-cases/refresh-entity-options.js +72 -0
- package/modules/use-cases/test-module-auth.js +72 -0
- package/modules/utils/map-module-dto.js +18 -0
- package/package.json +82 -50
- package/prisma-mongodb/schema.prisma +360 -0
- package/prisma-postgresql/migrations/20250930193005_init/migration.sql +315 -0
- package/prisma-postgresql/migrations/20251006135218_init/migration.sql +9 -0
- package/prisma-postgresql/migrations/20251010000000_remove_unused_entity_reference_map/migration.sql +3 -0
- package/prisma-postgresql/migrations/20251112195422_update_user_unique_constraints/migration.sql +25 -0
- package/prisma-postgresql/migrations/migration_lock.toml +3 -0
- package/prisma-postgresql/schema.prisma +343 -0
- package/queues/queuer-util.js +27 -22
- package/syncs/manager.js +468 -443
- package/syncs/repositories/sync-repository-documentdb.js +240 -0
- package/syncs/repositories/sync-repository-factory.js +43 -0
- package/syncs/repositories/sync-repository-interface.js +109 -0
- package/syncs/repositories/sync-repository-mongo.js +239 -0
- package/syncs/repositories/sync-repository-postgres.js +319 -0
- package/syncs/sync.js +0 -1
- package/token/repositories/token-repository-documentdb.js +137 -0
- package/token/repositories/token-repository-factory.js +40 -0
- package/token/repositories/token-repository-interface.js +131 -0
- package/token/repositories/token-repository-mongo.js +219 -0
- package/token/repositories/token-repository-postgres.js +264 -0
- package/token/repositories/token-repository.js +219 -0
- package/types/core/index.d.ts +2 -2
- package/types/integrations/index.d.ts +2 -6
- package/types/module-plugin/index.d.ts +5 -59
- package/types/syncs/index.d.ts +0 -2
- package/user/repositories/user-repository-documentdb.js +441 -0
- package/user/repositories/user-repository-factory.js +52 -0
- package/user/repositories/user-repository-interface.js +201 -0
- package/user/repositories/user-repository-mongo.js +308 -0
- package/user/repositories/user-repository-postgres.js +360 -0
- package/user/tests/doubles/test-user-repository.js +72 -0
- package/user/use-cases/authenticate-user.js +127 -0
- package/user/use-cases/authenticate-with-shared-secret.js +48 -0
- package/user/use-cases/create-individual-user.js +61 -0
- package/user/use-cases/create-organization-user.js +47 -0
- package/user/use-cases/create-token-for-user-id.js +30 -0
- package/user/use-cases/get-user-from-adopter-jwt.js +149 -0
- package/user/use-cases/get-user-from-bearer-token.js +77 -0
- package/user/use-cases/get-user-from-x-frigg-headers.js +132 -0
- package/user/use-cases/login-user.js +122 -0
- package/user/user.js +125 -0
- package/utils/backend-path.js +38 -0
- package/utils/index.js +6 -0
- package/websocket/repositories/websocket-connection-repository-documentdb.js +119 -0
- package/websocket/repositories/websocket-connection-repository-factory.js +44 -0
- package/websocket/repositories/websocket-connection-repository-interface.js +106 -0
- package/websocket/repositories/websocket-connection-repository-mongo.js +156 -0
- package/websocket/repositories/websocket-connection-repository-postgres.js +196 -0
- package/websocket/repositories/websocket-connection-repository.js +161 -0
- package/database/models/State.js +0 -9
- package/database/models/Token.js +0 -70
- package/database/mongo.js +0 -45
- package/encrypt/Cryptor.test.js +0 -32
- package/encrypt/encrypt.js +0 -132
- package/encrypt/encrypt.test.js +0 -1069
- package/errors/base-error.test.js +0 -32
- package/errors/fetch-error.test.js +0 -79
- package/errors/halt-error.test.js +0 -11
- package/errors/validation-errors.test.js +0 -120
- package/integrations/create-frigg-backend.js +0 -31
- package/integrations/integration-factory.js +0 -251
- package/integrations/integration-mapping.js +0 -43
- package/integrations/integration-model.js +0 -46
- package/integrations/integration-user.js +0 -144
- package/integrations/test/integration-base.test.js +0 -144
- package/lambda/TimeoutCatcher.test.js +0 -68
- package/logs/logger.test.js +0 -76
- package/module-plugin/auther.js +0 -393
- package/module-plugin/credential.js +0 -22
- package/module-plugin/entity-manager.js +0 -70
- package/module-plugin/manager.js +0 -169
- package/module-plugin/module-factory.js +0 -61
- package/module-plugin/requester/api-key.js +0 -36
- package/module-plugin/requester/requester.test.js +0 -28
- package/module-plugin/test/auther.test.js +0 -97
- /package/{module-plugin → modules}/ModuleConstants.js +0 -0
- /package/{module-plugin → modules}/requester/basic.js +0 -0
- /package/{module-plugin → modules}/requester/oauth-2.js +0 -0
- /package/{module-plugin → modules}/test/mock-api/mocks/hubspot.js +0 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
const { prisma } = require('../../database/prisma');
|
|
2
|
+
const {
|
|
3
|
+
IntegrationMappingRepositoryInterface,
|
|
4
|
+
} = require('./integration-mapping-repository-interface');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* PostgreSQL Integration Mapping Repository Adapter
|
|
8
|
+
* Handles persistence of integration mappings used for data transformation
|
|
9
|
+
*
|
|
10
|
+
* PostgreSQL-specific characteristics:
|
|
11
|
+
* - Uses Int IDs with autoincrement
|
|
12
|
+
* - Requires ID conversion: String (app layer) ↔ Int (database)
|
|
13
|
+
* - All returned IDs are converted to strings for application layer consistency
|
|
14
|
+
*/
|
|
15
|
+
class IntegrationMappingRepositoryPostgres extends IntegrationMappingRepositoryInterface {
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
this.prisma = prisma;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Convert string ID to integer for PostgreSQL queries
|
|
23
|
+
* @private
|
|
24
|
+
* @param {string|number|null|undefined} id - ID to convert
|
|
25
|
+
* @returns {number|null|undefined} Integer ID or null/undefined
|
|
26
|
+
* @throws {Error} If ID cannot be converted to integer
|
|
27
|
+
*/
|
|
28
|
+
_stringToInt(id) {
|
|
29
|
+
if (id === null || id === undefined) return id;
|
|
30
|
+
const parsed = parseInt(id, 10);
|
|
31
|
+
if (isNaN(parsed)) {
|
|
32
|
+
throw new Error(`Invalid ID: ${id} cannot be converted to integer`);
|
|
33
|
+
}
|
|
34
|
+
return parsed;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Convert any value to string (handles null/undefined)
|
|
39
|
+
* @private
|
|
40
|
+
* @param {*} value - Value to convert
|
|
41
|
+
* @returns {string|null|undefined} String value or null/undefined
|
|
42
|
+
*/
|
|
43
|
+
_toString(value) {
|
|
44
|
+
if (value === null || value === undefined) return value;
|
|
45
|
+
return String(value);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Convert integer to string for application layer
|
|
50
|
+
* @private
|
|
51
|
+
* @param {number|null|undefined} id - Integer ID from database
|
|
52
|
+
* @returns {string|null|undefined} String ID or null/undefined
|
|
53
|
+
*/
|
|
54
|
+
_intToString(id) {
|
|
55
|
+
if (id === null || id === undefined) return id;
|
|
56
|
+
return id.toString();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Legacy alias for _stringToInt (for backward compatibility)
|
|
61
|
+
* @private
|
|
62
|
+
*/
|
|
63
|
+
_convertId(id) {
|
|
64
|
+
return this._stringToInt(id);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Convert mapping object IDs to strings
|
|
69
|
+
* @private
|
|
70
|
+
* @param {Object|null} mapping - Mapping object from database
|
|
71
|
+
* @returns {Object|null} Mapping with string IDs
|
|
72
|
+
*/
|
|
73
|
+
_convertMappingIds(mapping) {
|
|
74
|
+
if (!mapping) return mapping;
|
|
75
|
+
return {
|
|
76
|
+
...mapping,
|
|
77
|
+
id: this._intToString(mapping.id),
|
|
78
|
+
integrationId: this._intToString(mapping.integrationId),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Find mapping by integration ID and source ID
|
|
84
|
+
* Replaces: IntegrationMapping.findBy(integrationId, sourceId)
|
|
85
|
+
*
|
|
86
|
+
* @param {string} integrationId - The integration ID (string from application layer)
|
|
87
|
+
* @param {string} sourceId - The source ID for lookup
|
|
88
|
+
* @returns {Promise<Object|null>} The mapping object with string IDs or null
|
|
89
|
+
*/
|
|
90
|
+
async findMappingBy(integrationId, sourceId) {
|
|
91
|
+
const mapping = await this.prisma.integrationMapping.findFirst({
|
|
92
|
+
where: {
|
|
93
|
+
integrationId: this._stringToInt(integrationId),
|
|
94
|
+
sourceId: this._toString(sourceId),
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
return this._convertMappingIds(mapping);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Create or update a mapping
|
|
102
|
+
* Replaces: IntegrationMapping.upsert(integrationId, sourceId, mapping)
|
|
103
|
+
*
|
|
104
|
+
* @param {string} integrationId - The integration ID (string from application layer)
|
|
105
|
+
* @param {string} sourceId - The source ID for lookup
|
|
106
|
+
* @param {Object} mapping - The mapping data
|
|
107
|
+
* @returns {Promise<Object>} The created or updated mapping document with string IDs
|
|
108
|
+
*/
|
|
109
|
+
async upsertMapping(integrationId, sourceId, mapping) {
|
|
110
|
+
const result = await this.prisma.integrationMapping.upsert({
|
|
111
|
+
where: {
|
|
112
|
+
integrationId_sourceId: {
|
|
113
|
+
integrationId: this._stringToInt(integrationId),
|
|
114
|
+
sourceId: this._toString(sourceId),
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
update: {
|
|
118
|
+
mapping,
|
|
119
|
+
},
|
|
120
|
+
create: {
|
|
121
|
+
integrationId: this._stringToInt(integrationId),
|
|
122
|
+
sourceId: this._toString(sourceId),
|
|
123
|
+
mapping,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
return this._convertMappingIds(result);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Find all mappings for an integration
|
|
131
|
+
* Replaces: IntegrationMapping.find({ integration: integrationId })
|
|
132
|
+
*
|
|
133
|
+
* @param {string} integrationId - The integration ID (string from application layer)
|
|
134
|
+
* @returns {Promise<Array>} Array of mapping documents with string IDs
|
|
135
|
+
*/
|
|
136
|
+
async findMappingsByIntegration(integrationId) {
|
|
137
|
+
const intIntegrationId = this._convertId(integrationId);
|
|
138
|
+
const mappings = await this.prisma.integrationMapping.findMany({
|
|
139
|
+
where: { integrationId: intIntegrationId },
|
|
140
|
+
});
|
|
141
|
+
return mappings.map((m) => this._convertMappingIds(m));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Delete a mapping by integration and source ID
|
|
146
|
+
* Replaces: IntegrationMapping.deleteOne({ integration, sourceId })
|
|
147
|
+
*
|
|
148
|
+
* @param {string} integrationId - The integration ID (string from application layer)
|
|
149
|
+
* @param {string} sourceId - The source ID
|
|
150
|
+
* @returns {Promise<Object>} The deletion result
|
|
151
|
+
*/
|
|
152
|
+
async deleteMapping(integrationId, sourceId) {
|
|
153
|
+
try {
|
|
154
|
+
await this.prisma.integrationMapping.delete({
|
|
155
|
+
where: {
|
|
156
|
+
integrationId_sourceId: {
|
|
157
|
+
integrationId: this._stringToInt(integrationId),
|
|
158
|
+
sourceId: this._toString(sourceId),
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
return { acknowledged: true, deletedCount: 1 };
|
|
163
|
+
} catch (error) {
|
|
164
|
+
if (error.code === 'P2025') {
|
|
165
|
+
// Record not found
|
|
166
|
+
return { acknowledged: true, deletedCount: 0 };
|
|
167
|
+
}
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Delete all mappings for an integration
|
|
174
|
+
* Replaces: IntegrationMapping.deleteMany({ integration: integrationId })
|
|
175
|
+
*
|
|
176
|
+
* @param {string} integrationId - The integration ID (string from application layer)
|
|
177
|
+
* @returns {Promise<Object>} The deletion result
|
|
178
|
+
*/
|
|
179
|
+
async deleteMappingsByIntegration(integrationId) {
|
|
180
|
+
const intIntegrationId = this._convertId(integrationId);
|
|
181
|
+
const result = await this.prisma.integrationMapping.deleteMany({
|
|
182
|
+
where: { integrationId: intIntegrationId },
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
acknowledged: true,
|
|
187
|
+
deletedCount: result.count,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Find mapping by ID
|
|
193
|
+
* @param {string} id - Mapping ID (string from application layer)
|
|
194
|
+
* @returns {Promise<Object|null>} Mapping object with string IDs or null
|
|
195
|
+
*/
|
|
196
|
+
async findMappingById(id) {
|
|
197
|
+
const intId = this._convertId(id);
|
|
198
|
+
const mapping = await this.prisma.integrationMapping.findUnique({
|
|
199
|
+
where: { id: intId },
|
|
200
|
+
});
|
|
201
|
+
return this._convertMappingIds(mapping);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Update mapping by ID
|
|
206
|
+
* @param {string} id - Mapping ID (string from application layer)
|
|
207
|
+
* @param {Object} updates - Fields to update (with string IDs from application layer)
|
|
208
|
+
* @returns {Promise<Object>} Updated mapping object with string IDs
|
|
209
|
+
*/
|
|
210
|
+
async updateMapping(id, updates) {
|
|
211
|
+
const intId = this._convertId(id);
|
|
212
|
+
|
|
213
|
+
// Convert integrationId if present in updates
|
|
214
|
+
const data = { ...updates };
|
|
215
|
+
if (data.integrationId !== undefined) {
|
|
216
|
+
data.integrationId = this._convertId(data.integrationId);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const mapping = await this.prisma.integrationMapping.update({
|
|
220
|
+
where: { id: intId },
|
|
221
|
+
data,
|
|
222
|
+
});
|
|
223
|
+
return this._convertMappingIds(mapping);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
module.exports = { IntegrationMappingRepositoryPostgres };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
const { prisma } = require('../../database/prisma');
|
|
2
|
+
const {
|
|
3
|
+
IntegrationMappingRepositoryInterface,
|
|
4
|
+
} = require('./integration-mapping-repository-interface');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Prisma-based Integration Mapping Repository
|
|
8
|
+
* Handles persistence of integration mappings used for data transformation
|
|
9
|
+
*
|
|
10
|
+
* Works identically for both MongoDB and PostgreSQL:
|
|
11
|
+
* - MongoDB: String IDs with @db.ObjectId
|
|
12
|
+
* - PostgreSQL: Integer IDs with auto-increment
|
|
13
|
+
* - Both use same query patterns (no many-to-many differences)
|
|
14
|
+
*
|
|
15
|
+
* Migration from Mongoose:
|
|
16
|
+
* - Constructor injection of Prisma client
|
|
17
|
+
* - IntegrationMapping.findBy() → findFirst with where clause
|
|
18
|
+
* - IntegrationMapping.upsert() → Prisma upsert with unique constraint
|
|
19
|
+
* - mapping data stored in JSON field
|
|
20
|
+
*/
|
|
21
|
+
class IntegrationMappingRepository extends IntegrationMappingRepositoryInterface {
|
|
22
|
+
constructor(prismaClient = prisma) {
|
|
23
|
+
super();
|
|
24
|
+
this.prisma = prismaClient; // Allow injection for testing
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Find mapping by integration ID and source ID
|
|
29
|
+
* Replaces: IntegrationMapping.findBy(integrationId, sourceId)
|
|
30
|
+
*
|
|
31
|
+
* @param {string} integrationId - The integration ID
|
|
32
|
+
* @param {string} sourceId - The source ID for lookup
|
|
33
|
+
* @returns {Promise<Object|null>} The mapping object or null
|
|
34
|
+
*/
|
|
35
|
+
async findMappingBy(integrationId, sourceId) {
|
|
36
|
+
return await this.prisma.integrationMapping.findFirst({
|
|
37
|
+
where: {
|
|
38
|
+
integrationId,
|
|
39
|
+
sourceId,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Create or update a mapping
|
|
46
|
+
* Replaces: IntegrationMapping.upsert(integrationId, sourceId, mapping)
|
|
47
|
+
*
|
|
48
|
+
* @param {string} integrationId - The integration ID
|
|
49
|
+
* @param {string} sourceId - The source ID for lookup
|
|
50
|
+
* @param {Object} mapping - The mapping data
|
|
51
|
+
* @returns {Promise<Object>} The created or updated mapping document
|
|
52
|
+
*/
|
|
53
|
+
async upsertMapping(integrationId, sourceId, mapping) {
|
|
54
|
+
return await this.prisma.integrationMapping.upsert({
|
|
55
|
+
where: {
|
|
56
|
+
integrationId_sourceId: {
|
|
57
|
+
integrationId,
|
|
58
|
+
sourceId,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
update: {
|
|
62
|
+
mapping,
|
|
63
|
+
},
|
|
64
|
+
create: {
|
|
65
|
+
integrationId,
|
|
66
|
+
sourceId,
|
|
67
|
+
mapping,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Find all mappings for an integration
|
|
74
|
+
* Replaces: IntegrationMapping.find({ integration: integrationId })
|
|
75
|
+
*
|
|
76
|
+
* @param {string} integrationId - The integration ID
|
|
77
|
+
* @returns {Promise<Array>} Array of mapping documents
|
|
78
|
+
*/
|
|
79
|
+
async findMappingsByIntegration(integrationId) {
|
|
80
|
+
return await this.prisma.integrationMapping.findMany({
|
|
81
|
+
where: { integrationId },
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Delete a mapping by integration and source ID
|
|
87
|
+
* Replaces: IntegrationMapping.deleteOne({ integration, sourceId })
|
|
88
|
+
*
|
|
89
|
+
* @param {string} integrationId - The integration ID
|
|
90
|
+
* @param {string} sourceId - The source ID
|
|
91
|
+
* @returns {Promise<Object>} The deletion result
|
|
92
|
+
*/
|
|
93
|
+
async deleteMapping(integrationId, sourceId) {
|
|
94
|
+
try {
|
|
95
|
+
await this.prisma.integrationMapping.delete({
|
|
96
|
+
where: {
|
|
97
|
+
integrationId_sourceId: {
|
|
98
|
+
integrationId,
|
|
99
|
+
sourceId,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
return { acknowledged: true, deletedCount: 1 };
|
|
104
|
+
} catch (error) {
|
|
105
|
+
if (error.code === 'P2025') {
|
|
106
|
+
// Record not found
|
|
107
|
+
return { acknowledged: true, deletedCount: 0 };
|
|
108
|
+
}
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Delete all mappings for an integration
|
|
115
|
+
* Replaces: IntegrationMapping.deleteMany({ integration: integrationId })
|
|
116
|
+
*
|
|
117
|
+
* @param {string} integrationId - The integration ID
|
|
118
|
+
* @returns {Promise<Object>} The deletion result
|
|
119
|
+
*/
|
|
120
|
+
async deleteMappingsByIntegration(integrationId) {
|
|
121
|
+
const result = await this.prisma.integrationMapping.deleteMany({
|
|
122
|
+
where: { integrationId },
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
acknowledged: true,
|
|
127
|
+
deletedCount: result.count,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Find mapping by ID
|
|
133
|
+
* @param {string} id - Mapping ID
|
|
134
|
+
* @returns {Promise<Object|null>} Mapping object or null
|
|
135
|
+
*/
|
|
136
|
+
async findMappingById(id) {
|
|
137
|
+
return await this.prisma.integrationMapping.findUnique({
|
|
138
|
+
where: { id },
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Update mapping by ID
|
|
144
|
+
* @param {string} id - Mapping ID
|
|
145
|
+
* @param {Object} updates - Fields to update
|
|
146
|
+
* @returns {Promise<Object>} Updated mapping object
|
|
147
|
+
*/
|
|
148
|
+
async updateMapping(id, updates) {
|
|
149
|
+
return await this.prisma.integrationMapping.update({
|
|
150
|
+
where: { id },
|
|
151
|
+
data: updates,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
module.exports = { IntegrationMappingRepository };
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
const { prisma } = require('../../database/prisma');
|
|
2
|
+
const {
|
|
3
|
+
toObjectId,
|
|
4
|
+
toObjectIdArray,
|
|
5
|
+
fromObjectId,
|
|
6
|
+
findMany,
|
|
7
|
+
findOne,
|
|
8
|
+
insertOne,
|
|
9
|
+
updateOne,
|
|
10
|
+
deleteOne,
|
|
11
|
+
} = require('../../database/documentdb-utils');
|
|
12
|
+
const {
|
|
13
|
+
IntegrationRepositoryInterface,
|
|
14
|
+
} = require('./integration-repository-interface');
|
|
15
|
+
|
|
16
|
+
class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
this.prisma = prisma;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async findIntegrationsByUserId(userId) {
|
|
23
|
+
const objectId = toObjectId(userId);
|
|
24
|
+
const filter = objectId ? { userId: objectId } : {};
|
|
25
|
+
const records = await findMany(this.prisma, 'Integration', filter);
|
|
26
|
+
return records.map((doc) => this._mapIntegration(doc));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async deleteIntegrationById(integrationId) {
|
|
30
|
+
const objectId = toObjectId(integrationId);
|
|
31
|
+
if (!objectId) return { acknowledged: true, deletedCount: 0 };
|
|
32
|
+
const result = await deleteOne(this.prisma, 'Integration', { _id: objectId });
|
|
33
|
+
const deleted = result?.n ?? 0;
|
|
34
|
+
return { acknowledged: true, deletedCount: deleted };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async findIntegrationByName(name) {
|
|
38
|
+
const doc = await findOne(this.prisma, 'Integration', { 'config.type': name });
|
|
39
|
+
if (!doc) {
|
|
40
|
+
throw new Error(`Integration with name ${name} not found`);
|
|
41
|
+
}
|
|
42
|
+
return this._mapIntegration(doc);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async findIntegrationById(id) {
|
|
46
|
+
const objectId = toObjectId(id);
|
|
47
|
+
if (!objectId) {
|
|
48
|
+
throw new Error(`Integration with id ${id} not found`);
|
|
49
|
+
}
|
|
50
|
+
const doc = await findOne(this.prisma, 'Integration', { _id: objectId });
|
|
51
|
+
if (!doc) {
|
|
52
|
+
throw new Error(`Integration with id ${id} not found`);
|
|
53
|
+
}
|
|
54
|
+
return this._mapIntegration(doc);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async updateIntegrationStatus(integrationId, status) {
|
|
58
|
+
const objectId = toObjectId(integrationId);
|
|
59
|
+
if (!objectId) return false;
|
|
60
|
+
await updateOne(
|
|
61
|
+
this.prisma,
|
|
62
|
+
'Integration',
|
|
63
|
+
{ _id: objectId },
|
|
64
|
+
{
|
|
65
|
+
$set: { status, updatedAt: new Date() },
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async updateIntegrationMessages(
|
|
72
|
+
integrationId,
|
|
73
|
+
messageType,
|
|
74
|
+
messageTitle,
|
|
75
|
+
messageBody,
|
|
76
|
+
messageTimestamp
|
|
77
|
+
) {
|
|
78
|
+
const objectId = toObjectId(integrationId);
|
|
79
|
+
if (!objectId) {
|
|
80
|
+
throw new Error(`Integration ${integrationId} not found`);
|
|
81
|
+
}
|
|
82
|
+
const existing = await findOne(this.prisma, 'Integration', { _id: objectId });
|
|
83
|
+
if (!existing) {
|
|
84
|
+
throw new Error(`Integration ${integrationId} not found`);
|
|
85
|
+
}
|
|
86
|
+
const messages = this._extractMessages(existing);
|
|
87
|
+
const list = Array.isArray(messages[messageType]) ? [...messages[messageType]] : [];
|
|
88
|
+
list.push({
|
|
89
|
+
title: messageTitle ?? null,
|
|
90
|
+
message: messageBody,
|
|
91
|
+
timestamp: messageTimestamp,
|
|
92
|
+
});
|
|
93
|
+
const updatedMessages = { ...messages, [messageType]: list };
|
|
94
|
+
await updateOne(
|
|
95
|
+
this.prisma,
|
|
96
|
+
'Integration',
|
|
97
|
+
{ _id: objectId },
|
|
98
|
+
{
|
|
99
|
+
$set: {
|
|
100
|
+
messages: updatedMessages,
|
|
101
|
+
errors: updatedMessages.errors ?? [],
|
|
102
|
+
warnings: updatedMessages.warnings ?? [],
|
|
103
|
+
info: updatedMessages.info ?? [],
|
|
104
|
+
logs: updatedMessages.logs ?? [],
|
|
105
|
+
updatedAt: new Date(),
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async createIntegration(entities, userId, config) {
|
|
113
|
+
const now = new Date();
|
|
114
|
+
const document = {
|
|
115
|
+
userId: toObjectId(userId) || null,
|
|
116
|
+
config,
|
|
117
|
+
version: '0.0.0',
|
|
118
|
+
status: 'ENABLED',
|
|
119
|
+
entityIds: toObjectIdArray(entities),
|
|
120
|
+
messages: { errors: [], warnings: [], info: [], logs: [] },
|
|
121
|
+
errors: [],
|
|
122
|
+
warnings: [],
|
|
123
|
+
info: [],
|
|
124
|
+
logs: [],
|
|
125
|
+
createdAt: now,
|
|
126
|
+
updatedAt: now,
|
|
127
|
+
};
|
|
128
|
+
const insertedId = await insertOne(this.prisma, 'Integration', document);
|
|
129
|
+
const created = await findOne(this.prisma, 'Integration', { _id: insertedId });
|
|
130
|
+
if (!created) {
|
|
131
|
+
console.error('[IntegrationRepositoryDocumentDB] Integration not found after insert', {
|
|
132
|
+
insertedId: fromObjectId(insertedId),
|
|
133
|
+
userId,
|
|
134
|
+
config,
|
|
135
|
+
});
|
|
136
|
+
throw new Error(
|
|
137
|
+
'Failed to create integration: Document not found after insert. ' +
|
|
138
|
+
'This indicates a database consistency issue.'
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
return this._mapIntegration(created);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async findIntegrationByUserId(userId) {
|
|
145
|
+
const objectId = toObjectId(userId);
|
|
146
|
+
if (!objectId) return null;
|
|
147
|
+
const doc = await findOne(this.prisma, 'Integration', { userId: objectId });
|
|
148
|
+
return doc ? this._mapIntegration(doc) : null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async updateIntegrationConfig(integrationId, config) {
|
|
152
|
+
if (config === null || config === undefined) {
|
|
153
|
+
throw new Error('Config parameter is required');
|
|
154
|
+
}
|
|
155
|
+
const objectId = toObjectId(integrationId);
|
|
156
|
+
if (!objectId) {
|
|
157
|
+
throw new Error(`Integration with id ${integrationId} not found`);
|
|
158
|
+
}
|
|
159
|
+
await updateOne(
|
|
160
|
+
this.prisma,
|
|
161
|
+
'Integration',
|
|
162
|
+
{ _id: objectId },
|
|
163
|
+
{
|
|
164
|
+
$set: {
|
|
165
|
+
config,
|
|
166
|
+
updatedAt: new Date(),
|
|
167
|
+
},
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
const updated = await findOne(this.prisma, 'Integration', { _id: objectId });
|
|
171
|
+
if (!updated) {
|
|
172
|
+
console.error('[IntegrationRepositoryDocumentDB] Integration not found after update', {
|
|
173
|
+
integrationId: fromObjectId(objectId),
|
|
174
|
+
config,
|
|
175
|
+
});
|
|
176
|
+
throw new Error(
|
|
177
|
+
'Failed to update integration: Document not found after update. ' +
|
|
178
|
+
'This indicates a database consistency issue.'
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
return this._mapIntegration(updated);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
_mapIntegration(doc) {
|
|
185
|
+
const messages = this._extractMessages(doc);
|
|
186
|
+
return {
|
|
187
|
+
id: fromObjectId(doc?._id),
|
|
188
|
+
entitiesIds: (doc?.entityIds || []).map((value) => fromObjectId(value)),
|
|
189
|
+
userId: fromObjectId(doc?.userId),
|
|
190
|
+
config: doc?.config ?? null,
|
|
191
|
+
version: doc?.version ?? null,
|
|
192
|
+
status: doc?.status ?? null,
|
|
193
|
+
messages,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
_extractMessages(doc) {
|
|
198
|
+
const base = doc?.messages && typeof doc.messages === 'object' ? doc.messages : {};
|
|
199
|
+
return {
|
|
200
|
+
errors: base.errors ?? doc?.errors ?? [],
|
|
201
|
+
warnings: base.warnings ?? doc?.warnings ?? [],
|
|
202
|
+
info: base.info ?? doc?.info ?? [],
|
|
203
|
+
logs: base.logs ?? doc?.logs ?? [],
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
module.exports = { IntegrationRepositoryDocumentDB };
|
|
209
|
+
|
|
210
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const { IntegrationRepositoryMongo } = require('./integration-repository-mongo');
|
|
2
|
+
const { IntegrationRepositoryPostgres } = require('./integration-repository-postgres');
|
|
3
|
+
const {
|
|
4
|
+
IntegrationRepositoryDocumentDB,
|
|
5
|
+
} = require('./integration-repository-documentdb');
|
|
6
|
+
const config = require('../../database/config');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Integration Repository Factory
|
|
10
|
+
* Creates the appropriate repository adapter based on database type
|
|
11
|
+
*
|
|
12
|
+
* This implements the Factory pattern for Hexagonal Architecture:
|
|
13
|
+
* - Reads database type from app definition (backend/index.js)
|
|
14
|
+
* - Returns correct adapter (MongoDB or PostgreSQL)
|
|
15
|
+
* - Provides clear error for unsupported databases
|
|
16
|
+
*
|
|
17
|
+
* Usage:
|
|
18
|
+
* ```javascript
|
|
19
|
+
* const repository = createIntegrationRepository();
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @returns {IntegrationRepositoryInterface} Configured repository adapter
|
|
23
|
+
* @throws {Error} If database type is not supported
|
|
24
|
+
*/
|
|
25
|
+
function createIntegrationRepository() {
|
|
26
|
+
const dbType = config.DB_TYPE;
|
|
27
|
+
|
|
28
|
+
switch (dbType) {
|
|
29
|
+
case 'mongodb':
|
|
30
|
+
return new IntegrationRepositoryMongo();
|
|
31
|
+
|
|
32
|
+
case 'postgresql':
|
|
33
|
+
return new IntegrationRepositoryPostgres();
|
|
34
|
+
|
|
35
|
+
case 'documentdb':
|
|
36
|
+
return new IntegrationRepositoryDocumentDB();
|
|
37
|
+
|
|
38
|
+
default:
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Unsupported database type: ${dbType}. Supported values: 'mongodb', 'documentdb', 'postgresql'`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = {
|
|
46
|
+
createIntegrationRepository,
|
|
47
|
+
// Export adapters for direct testing
|
|
48
|
+
IntegrationRepositoryMongo,
|
|
49
|
+
IntegrationRepositoryPostgres,
|
|
50
|
+
IntegrationRepositoryDocumentDB,
|
|
51
|
+
};
|