@friggframework/core 2.0.0-next.41 → 2.0.0-next.42
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 +693 -0
- package/README.md +931 -50
- package/application/commands/README.md +421 -0
- package/application/commands/credential-commands.js +224 -0
- package/application/commands/entity-commands.js +315 -0
- package/application/commands/integration-commands.js +160 -0
- package/application/commands/integration-commands.test.js +123 -0
- package/application/commands/user-commands.js +213 -0
- package/application/index.js +69 -0
- package/core/CLAUDE.md +690 -0
- package/core/create-handler.js +0 -6
- package/credential/repositories/credential-repository-factory.js +47 -0
- package/credential/repositories/credential-repository-interface.js +98 -0
- package/credential/repositories/credential-repository-mongo.js +301 -0
- package/credential/repositories/credential-repository-postgres.js +307 -0
- package/credential/repositories/credential-repository.js +307 -0
- package/credential/use-cases/get-credential-for-user.js +21 -0
- package/credential/use-cases/update-authentication-status.js +15 -0
- package/database/config.js +117 -0
- package/database/encryption/README.md +683 -0
- package/database/encryption/encryption-integration.test.js +553 -0
- package/database/encryption/encryption-schema-registry.js +141 -0
- package/database/encryption/encryption-schema-registry.test.js +392 -0
- package/database/encryption/field-encryption-service.js +226 -0
- package/database/encryption/field-encryption-service.test.js +525 -0
- package/database/encryption/logger.js +79 -0
- package/database/encryption/mongo-decryption-fix-verification.test.js +348 -0
- package/database/encryption/postgres-decryption-fix-verification.test.js +371 -0
- package/database/encryption/postgres-relation-decryption.test.js +245 -0
- package/database/encryption/prisma-encryption-extension.js +222 -0
- package/database/encryption/prisma-encryption-extension.test.js +439 -0
- package/database/index.js +25 -12
- package/database/models/readme.md +1 -0
- package/database/prisma.js +162 -0
- package/database/repositories/health-check-repository-factory.js +38 -0
- package/database/repositories/health-check-repository-interface.js +86 -0
- package/database/repositories/health-check-repository-mongodb.js +72 -0
- package/database/repositories/health-check-repository-postgres.js +75 -0
- package/database/repositories/health-check-repository.js +108 -0
- package/database/use-cases/check-database-health-use-case.js +34 -0
- package/database/use-cases/check-encryption-health-use-case.js +82 -0
- package/database/use-cases/test-encryption-use-case.js +252 -0
- package/encrypt/Cryptor.js +20 -152
- package/encrypt/index.js +1 -2
- package/encrypt/test-encrypt.js +0 -2
- package/handlers/app-definition-loader.js +38 -0
- package/handlers/app-handler-helpers.js +0 -3
- package/handlers/auth-flow.integration.test.js +147 -0
- package/handlers/backend-utils.js +25 -45
- package/handlers/integration-event-dispatcher.js +54 -0
- package/handlers/integration-event-dispatcher.test.js +141 -0
- package/handlers/routers/HEALTHCHECK.md +103 -1
- package/handlers/routers/auth.js +3 -14
- package/handlers/routers/health.js +63 -424
- package/handlers/routers/health.test.js +7 -0
- package/handlers/routers/integration-defined-routers.js +8 -5
- package/handlers/routers/user.js +25 -5
- package/handlers/routers/websocket.js +5 -3
- package/handlers/use-cases/check-external-apis-health-use-case.js +81 -0
- package/handlers/use-cases/check-integrations-health-use-case.js +32 -0
- package/handlers/workers/integration-defined-workers.js +6 -3
- package/index.js +45 -22
- package/integrations/index.js +12 -10
- package/integrations/integration-base.js +224 -53
- package/integrations/integration-router.js +386 -178
- package/integrations/options.js +1 -1
- package/integrations/repositories/integration-mapping-repository-factory.js +50 -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-factory.js +44 -0
- package/integrations/repositories/integration-repository-interface.js +115 -0
- package/integrations/repositories/integration-repository-mongo.js +271 -0
- package/integrations/repositories/integration-repository-postgres.js +319 -0
- package/integrations/tests/doubles/dummy-integration-class.js +90 -0
- package/integrations/tests/doubles/test-integration-repository.js +99 -0
- package/integrations/tests/use-cases/create-integration.test.js +131 -0
- package/integrations/tests/use-cases/delete-integration-for-user.test.js +150 -0
- package/integrations/tests/use-cases/find-integration-context-by-external-entity-id.test.js +92 -0
- package/integrations/tests/use-cases/get-integration-for-user.test.js +150 -0
- package/integrations/tests/use-cases/get-integration-instance.test.js +176 -0
- package/integrations/tests/use-cases/get-integrations-for-user.test.js +176 -0
- package/integrations/tests/use-cases/get-possible-integrations.test.js +188 -0
- package/integrations/tests/use-cases/update-integration-messages.test.js +142 -0
- package/integrations/tests/use-cases/update-integration-status.test.js +103 -0
- package/integrations/tests/use-cases/update-integration.test.js +141 -0
- package/integrations/use-cases/create-integration.js +83 -0
- package/integrations/use-cases/delete-integration-for-user.js +73 -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 +87 -0
- package/integrations/use-cases/get-possible-integrations.js +27 -0
- package/integrations/use-cases/index.js +11 -0
- package/integrations/use-cases/load-integration-context-full.test.js +329 -0
- package/integrations/use-cases/load-integration-context.js +71 -0
- package/integrations/use-cases/load-integration-context.test.js +114 -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/utils/map-integration-dto.js +36 -0
- package/jest-global-setup-noop.js +3 -0
- package/jest-global-teardown-noop.js +3 -0
- package/{module-plugin → modules}/entity.js +1 -0
- package/{module-plugin → modules}/index.js +0 -8
- package/modules/module-factory.js +56 -0
- package/modules/module-hydration.test.js +205 -0
- package/modules/module.js +221 -0
- package/modules/repositories/module-repository-factory.js +33 -0
- package/modules/repositories/module-repository-interface.js +129 -0
- package/modules/repositories/module-repository-mongo.js +386 -0
- package/modules/repositories/module-repository-postgres.js +437 -0
- package/modules/repositories/module-repository.js +327 -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 +59 -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 +56 -0
- package/modules/use-cases/process-authorization-callback.js +121 -0
- package/modules/use-cases/refresh-entity-options.js +59 -0
- package/modules/use-cases/test-module-auth.js +55 -0
- package/modules/utils/map-module-dto.js +18 -0
- package/package.json +14 -6
- package/prisma-mongodb/schema.prisma +321 -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/migration_lock.toml +3 -0
- package/prisma-postgresql/schema.prisma +303 -0
- package/syncs/manager.js +468 -443
- package/syncs/repositories/sync-repository-factory.js +38 -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-factory.js +33 -0
- package/token/repositories/token-repository-interface.js +131 -0
- package/token/repositories/token-repository-mongo.js +212 -0
- package/token/repositories/token-repository-postgres.js +257 -0
- package/token/repositories/token-repository.js +219 -0
- package/types/integrations/index.d.ts +2 -6
- package/types/module-plugin/index.d.ts +5 -57
- package/types/syncs/index.d.ts +0 -2
- package/user/repositories/user-repository-factory.js +46 -0
- package/user/repositories/user-repository-interface.js +198 -0
- package/user/repositories/user-repository-mongo.js +250 -0
- package/user/repositories/user-repository-postgres.js +311 -0
- package/user/tests/doubles/test-user-repository.js +72 -0
- package/user/tests/use-cases/create-individual-user.test.js +24 -0
- package/user/tests/use-cases/create-organization-user.test.js +28 -0
- package/user/tests/use-cases/create-token-for-user-id.test.js +19 -0
- package/user/tests/use-cases/get-user-from-bearer-token.test.js +64 -0
- package/user/tests/use-cases/login-user.test.js +140 -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-bearer-token.js +77 -0
- package/user/use-cases/login-user.js +122 -0
- package/user/user.js +77 -0
- package/websocket/repositories/websocket-connection-repository-factory.js +37 -0
- package/websocket/repositories/websocket-connection-repository-interface.js +106 -0
- package/websocket/repositories/websocket-connection-repository-mongo.js +155 -0
- package/websocket/repositories/websocket-connection-repository-postgres.js +195 -0
- package/websocket/repositories/websocket-connection-repository.js +160 -0
- package/database/models/State.js +0 -9
- package/database/models/Token.js +0 -70
- package/database/mongo.js +0 -171
- package/encrypt/Cryptor.test.js +0 -32
- package/encrypt/encrypt.js +0 -104
- package/encrypt/encrypt.test.js +0 -1069
- package/handlers/routers/middleware/loadUser.js +0 -15
- package/handlers/routers/middleware/requireLoggedInUser.js +0 -12
- 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/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/test/auther.test.js +0 -97
- /package/{module-plugin → modules}/ModuleConstants.js +0 -0
- /package/{module-plugin → modules}/requester/api-key.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}/requester/requester.js +0 -0
- /package/{module-plugin → modules}/requester/requester.test.js +0 -0
- /package/{module-plugin → modules}/test/mock-api/mocks/hubspot.js +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const { IntegrationRepositoryMongo } = require('./integration-repository-mongo');
|
|
2
|
+
const { IntegrationRepositoryPostgres } = require('./integration-repository-postgres');
|
|
3
|
+
const config = require('../../database/config');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Integration Repository Factory
|
|
7
|
+
* Creates the appropriate repository adapter based on database type
|
|
8
|
+
*
|
|
9
|
+
* This implements the Factory pattern for Hexagonal Architecture:
|
|
10
|
+
* - Reads database type from app definition (backend/index.js)
|
|
11
|
+
* - Returns correct adapter (MongoDB or PostgreSQL)
|
|
12
|
+
* - Provides clear error for unsupported databases
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* ```javascript
|
|
16
|
+
* const repository = createIntegrationRepository();
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @returns {IntegrationRepositoryInterface} Configured repository adapter
|
|
20
|
+
* @throws {Error} If database type is not supported
|
|
21
|
+
*/
|
|
22
|
+
function createIntegrationRepository() {
|
|
23
|
+
const dbType = config.DB_TYPE;
|
|
24
|
+
|
|
25
|
+
switch (dbType) {
|
|
26
|
+
case 'mongodb':
|
|
27
|
+
return new IntegrationRepositoryMongo();
|
|
28
|
+
|
|
29
|
+
case 'postgresql':
|
|
30
|
+
return new IntegrationRepositoryPostgres();
|
|
31
|
+
|
|
32
|
+
default:
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Unsupported database type: ${dbType}. Supported values: 'mongodb', 'postgresql'`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
createIntegrationRepository,
|
|
41
|
+
// Export adapters for direct testing
|
|
42
|
+
IntegrationRepositoryMongo,
|
|
43
|
+
IntegrationRepositoryPostgres,
|
|
44
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration Repository Interface
|
|
3
|
+
* Abstract base class defining the contract for integration persistence adapters
|
|
4
|
+
*
|
|
5
|
+
* This follows the Port in Hexagonal Architecture:
|
|
6
|
+
* - Domain layer depends on this abstraction
|
|
7
|
+
* - Concrete adapters (MongoDB, PostgreSQL) implement this interface
|
|
8
|
+
* - Use cases receive repositories via dependency injection
|
|
9
|
+
*
|
|
10
|
+
* @abstract
|
|
11
|
+
*/
|
|
12
|
+
class IntegrationRepositoryInterface {
|
|
13
|
+
/**
|
|
14
|
+
* Find all integrations for a user
|
|
15
|
+
*
|
|
16
|
+
* @param {string|number} userId - User ID
|
|
17
|
+
* @returns {Promise<Array>} Array of integration objects
|
|
18
|
+
* @abstract
|
|
19
|
+
*/
|
|
20
|
+
async findIntegrationsByUserId(userId) {
|
|
21
|
+
throw new Error('Method findIntegrationsByUserId must be implemented by subclass');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Delete integration by ID
|
|
26
|
+
*
|
|
27
|
+
* @param {string|number} integrationId - Integration ID
|
|
28
|
+
* @returns {Promise<Object>} Deletion result
|
|
29
|
+
* @abstract
|
|
30
|
+
*/
|
|
31
|
+
async deleteIntegrationById(integrationId) {
|
|
32
|
+
throw new Error('Method deleteIntegrationById must be implemented by subclass');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Find integration by name
|
|
37
|
+
*
|
|
38
|
+
* @param {string} name - Integration type name
|
|
39
|
+
* @returns {Promise<Object>} Integration object
|
|
40
|
+
* @abstract
|
|
41
|
+
*/
|
|
42
|
+
async findIntegrationByName(name) {
|
|
43
|
+
throw new Error('Method findIntegrationByName must be implemented by subclass');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Find integration by ID
|
|
48
|
+
*
|
|
49
|
+
* @param {string|number} id - Integration ID
|
|
50
|
+
* @returns {Promise<Object>} Integration object
|
|
51
|
+
* @abstract
|
|
52
|
+
*/
|
|
53
|
+
async findIntegrationById(id) {
|
|
54
|
+
throw new Error('Method findIntegrationById must be implemented by subclass');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Update integration status
|
|
59
|
+
*
|
|
60
|
+
* @param {string|number} integrationId - Integration ID
|
|
61
|
+
* @param {string} status - New status
|
|
62
|
+
* @returns {Promise<boolean>} Success indicator
|
|
63
|
+
* @abstract
|
|
64
|
+
*/
|
|
65
|
+
async updateIntegrationStatus(integrationId, status) {
|
|
66
|
+
throw new Error('Method updateIntegrationStatus must be implemented by subclass');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Update integration messages
|
|
71
|
+
*
|
|
72
|
+
* @param {string|number} integrationId - Integration ID
|
|
73
|
+
* @param {string} messageType - Type of message (errors, warnings, info, logs)
|
|
74
|
+
* @param {string} messageTitle - Message title
|
|
75
|
+
* @param {string} messageBody - Message body
|
|
76
|
+
* @param {Date} messageTimestamp - Message timestamp
|
|
77
|
+
* @returns {Promise<boolean>} Success indicator
|
|
78
|
+
* @abstract
|
|
79
|
+
*/
|
|
80
|
+
async updateIntegrationMessages(
|
|
81
|
+
integrationId,
|
|
82
|
+
messageType,
|
|
83
|
+
messageTitle,
|
|
84
|
+
messageBody,
|
|
85
|
+
messageTimestamp
|
|
86
|
+
) {
|
|
87
|
+
throw new Error('Method updateIntegrationMessages must be implemented by subclass');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Create a new integration
|
|
92
|
+
*
|
|
93
|
+
* @param {Array<string|number>} entities - Array of entity IDs
|
|
94
|
+
* @param {string|number} userId - User ID
|
|
95
|
+
* @param {Object} config - Integration configuration
|
|
96
|
+
* @returns {Promise<Object>} Created integration object
|
|
97
|
+
* @abstract
|
|
98
|
+
*/
|
|
99
|
+
async createIntegration(entities, userId, config) {
|
|
100
|
+
throw new Error('Method createIntegration must be implemented by subclass');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Find integration by user ID (returns single integration)
|
|
105
|
+
*
|
|
106
|
+
* @param {string|number} userId - User ID
|
|
107
|
+
* @returns {Promise<Object|null>} Integration object or null
|
|
108
|
+
* @abstract
|
|
109
|
+
*/
|
|
110
|
+
async findIntegrationByUserId(userId) {
|
|
111
|
+
throw new Error('Method findIntegrationByUserId must be implemented by subclass');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = { IntegrationRepositoryInterface };
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
const { prisma } = require('../../database/prisma');
|
|
2
|
+
const {
|
|
3
|
+
IntegrationRepositoryInterface,
|
|
4
|
+
} = require('./integration-repository-interface');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* MongoDB Integration Repository Adapter
|
|
8
|
+
* Handles integration persistence using Prisma with MongoDB
|
|
9
|
+
*
|
|
10
|
+
* MongoDB-specific characteristics:
|
|
11
|
+
* - Uses scalar fields for relations (userId, entityIds)
|
|
12
|
+
* - IDs are strings with @db.ObjectId
|
|
13
|
+
* - Arrays used for many-to-many relationships
|
|
14
|
+
*
|
|
15
|
+
* Migration from Mongoose:
|
|
16
|
+
* - Constructor injection of Prisma client
|
|
17
|
+
* - populate() → include in Prisma queries
|
|
18
|
+
* - lean: true → No longer needed (Prisma returns plain objects)
|
|
19
|
+
* - toString() conversions → Done automatically by Prisma
|
|
20
|
+
*/
|
|
21
|
+
class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
22
|
+
constructor() {
|
|
23
|
+
super();
|
|
24
|
+
this.prisma = prisma;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Find all integrations for a user
|
|
29
|
+
* Replaces: IntegrationModel.find({ user: userId }).populate('entities')
|
|
30
|
+
*
|
|
31
|
+
* @param {string} userId - User ID (MongoDB ObjectId as string)
|
|
32
|
+
* @returns {Promise<Array>} Array of integration objects
|
|
33
|
+
*/
|
|
34
|
+
async findIntegrationsByUserId(userId) {
|
|
35
|
+
const integrations = await this.prisma.integration.findMany({
|
|
36
|
+
where: { userId },
|
|
37
|
+
include: {
|
|
38
|
+
entities: true,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Map to domain objects (maintains same API)
|
|
43
|
+
return integrations.map((integration) => ({
|
|
44
|
+
id: integration.id,
|
|
45
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
46
|
+
userId: integration.userId,
|
|
47
|
+
config: integration.config,
|
|
48
|
+
version: integration.version,
|
|
49
|
+
status: integration.status,
|
|
50
|
+
messages: integration.messages,
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Delete integration by ID
|
|
56
|
+
* Replaces: IntegrationModel.deleteOne({ _id: integrationId })
|
|
57
|
+
*
|
|
58
|
+
* @param {string} integrationId - Integration ID
|
|
59
|
+
* @returns {Promise<Object>} Deletion result
|
|
60
|
+
*/
|
|
61
|
+
async deleteIntegrationById(integrationId) {
|
|
62
|
+
await this.prisma.integration.delete({
|
|
63
|
+
where: { id: integrationId },
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Return Mongoose-compatible result
|
|
67
|
+
return { acknowledged: true, deletedCount: 1 };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Find integration by name
|
|
72
|
+
* Replaces: IntegrationModel.findOne({ 'config.type': name }).populate('entities')
|
|
73
|
+
*
|
|
74
|
+
* @param {string} name - Integration type name
|
|
75
|
+
* @returns {Promise<Object>} Integration object
|
|
76
|
+
*/
|
|
77
|
+
async findIntegrationByName(name) {
|
|
78
|
+
const integration = await this.prisma.integration.findFirst({
|
|
79
|
+
where: {
|
|
80
|
+
config: {
|
|
81
|
+
path: ['type'],
|
|
82
|
+
equals: name,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
include: {
|
|
86
|
+
entities: true,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
if (!integration) {
|
|
91
|
+
throw new Error(`Integration with name ${name} not found`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
id: integration.id,
|
|
96
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
97
|
+
userId: integration.userId,
|
|
98
|
+
config: integration.config,
|
|
99
|
+
version: integration.version,
|
|
100
|
+
status: integration.status,
|
|
101
|
+
messages: integration.messages,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Find integration by ID
|
|
107
|
+
* Replaces: IntegrationModel.findById(id).populate('entities')
|
|
108
|
+
*
|
|
109
|
+
* @param {string} id - Integration ID
|
|
110
|
+
* @returns {Promise<Object>} Integration object
|
|
111
|
+
*/
|
|
112
|
+
async findIntegrationById(id) {
|
|
113
|
+
const integration = await this.prisma.integration.findUnique({
|
|
114
|
+
where: { id },
|
|
115
|
+
include: {
|
|
116
|
+
entities: true,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (!integration) {
|
|
121
|
+
throw new Error(`Integration with id ${id} not found`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
id: integration.id,
|
|
126
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
127
|
+
userId: integration.userId,
|
|
128
|
+
config: integration.config,
|
|
129
|
+
version: integration.version,
|
|
130
|
+
status: integration.status,
|
|
131
|
+
messages: integration.messages,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Update integration status
|
|
137
|
+
* Replaces: IntegrationModel.updateOne({ _id: integrationId }, { status })
|
|
138
|
+
*
|
|
139
|
+
* @param {string} integrationId - Integration ID
|
|
140
|
+
* @param {string} status - New status
|
|
141
|
+
* @returns {Promise<boolean>} Success indicator
|
|
142
|
+
*/
|
|
143
|
+
async updateIntegrationStatus(integrationId, status) {
|
|
144
|
+
await this.prisma.integration.update({
|
|
145
|
+
where: { id: integrationId },
|
|
146
|
+
data: { status },
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
return true; // Mongoose compatibility
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Update integration messages
|
|
154
|
+
* Replaces: IntegrationModel.updateOne with $push operator
|
|
155
|
+
*
|
|
156
|
+
* @param {string} integrationId - Integration ID
|
|
157
|
+
* @param {string} messageType - Type of message (errors, warnings, info, logs)
|
|
158
|
+
* @param {string} messageTitle - Message title
|
|
159
|
+
* @param {string} messageBody - Message body
|
|
160
|
+
* @param {Date} messageTimestamp - Message timestamp
|
|
161
|
+
* @returns {Promise<boolean>} Success indicator
|
|
162
|
+
*/
|
|
163
|
+
async updateIntegrationMessages(
|
|
164
|
+
integrationId,
|
|
165
|
+
messageType,
|
|
166
|
+
messageTitle,
|
|
167
|
+
messageBody,
|
|
168
|
+
messageTimestamp
|
|
169
|
+
) {
|
|
170
|
+
// Get current integration
|
|
171
|
+
const integration = await this.prisma.integration.findUnique({
|
|
172
|
+
where: { id: integrationId },
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
if (!integration) {
|
|
176
|
+
throw new Error(`Integration ${integrationId} not found`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Parse existing messages (JSON field)
|
|
180
|
+
const messages = integration.messages || {};
|
|
181
|
+
const messageArray = Array.isArray(messages[messageType])
|
|
182
|
+
? messages[messageType]
|
|
183
|
+
: [];
|
|
184
|
+
|
|
185
|
+
// Add new message
|
|
186
|
+
messageArray.push({
|
|
187
|
+
title: messageTitle,
|
|
188
|
+
message: messageBody,
|
|
189
|
+
timestamp: messageTimestamp,
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Update messages
|
|
193
|
+
await this.prisma.integration.update({
|
|
194
|
+
where: { id: integrationId },
|
|
195
|
+
data: {
|
|
196
|
+
[messageType]: messageArray,
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
return true; // Mongoose compatibility
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Create a new integration
|
|
205
|
+
* Replaces: IntegrationModel.create({ entities, user, config })
|
|
206
|
+
*
|
|
207
|
+
* MongoDB-specific: Uses scalar fields for relations
|
|
208
|
+
*
|
|
209
|
+
* @param {Array<string>} entities - Array of entity IDs (MongoDB ObjectIds)
|
|
210
|
+
* @param {string} userId - User ID (MongoDB ObjectId)
|
|
211
|
+
* @param {Object} config - Integration configuration
|
|
212
|
+
* @returns {Promise<Object>} Created integration object
|
|
213
|
+
*/
|
|
214
|
+
async createIntegration(entities, userId, config) {
|
|
215
|
+
const data = {
|
|
216
|
+
config,
|
|
217
|
+
version: '0.0.0',
|
|
218
|
+
userId: userId,
|
|
219
|
+
entityIds: entities,
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
const integration = await this.prisma.integration.create({
|
|
223
|
+
data,
|
|
224
|
+
include: {
|
|
225
|
+
entities: true,
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
return {
|
|
230
|
+
id: integration.id,
|
|
231
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
232
|
+
userId: integration.userId,
|
|
233
|
+
config: integration.config,
|
|
234
|
+
version: integration.version,
|
|
235
|
+
status: integration.status,
|
|
236
|
+
messages: integration.messages,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Find integration by user ID (returns single integration)
|
|
242
|
+
* Replaces: IntegrationModel.findOne({ user: userId }).populate('entities')
|
|
243
|
+
*
|
|
244
|
+
* @param {string} userId - User ID
|
|
245
|
+
* @returns {Promise<Object|null>} Integration object or null
|
|
246
|
+
*/
|
|
247
|
+
async findIntegrationByUserId(userId) {
|
|
248
|
+
const integration = await this.prisma.integration.findFirst({
|
|
249
|
+
where: { userId },
|
|
250
|
+
include: {
|
|
251
|
+
entities: true,
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
if (!integration) {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return {
|
|
260
|
+
id: integration.id,
|
|
261
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
262
|
+
userId: integration.userId,
|
|
263
|
+
config: integration.config,
|
|
264
|
+
version: integration.version,
|
|
265
|
+
status: integration.status,
|
|
266
|
+
messages: integration.messages,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
module.exports = { IntegrationRepositoryMongo };
|