@friggframework/core 2.0.0--canary.690.08cd07e.0 → 2.0.0--canary.694.f66a64a.0
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 +0 -28
- package/README.md +0 -105
- package/application/commands/integration-commands.js +10 -20
- package/application/commands/scheduler-commands.js +7 -11
- package/application/commands/user-commands.js +5 -17
- package/application/index.js +2 -6
- package/core/Worker.js +7 -31
- package/core/create-handler.js +0 -9
- package/credential/repositories/credential-repository-documentdb.js +0 -34
- package/credential/repositories/credential-repository-interface.js +0 -15
- package/credential/repositories/credential-repository-mongo.js +0 -23
- package/credential/repositories/credential-repository-postgres.js +0 -28
- package/database/config.js +24 -48
- package/database/documentdb-utils.js +2 -2
- package/database/encryption/encryption-schema-registry.js +12 -93
- package/database/prisma.js +2 -4
- package/errors/index.js +4 -0
- package/errors/mapping-already-exists-error.js +14 -0
- package/generated/prisma-mongodb/edge.js +38 -33
- package/generated/prisma-mongodb/index-browser.js +35 -30
- package/generated/prisma-mongodb/index.d.ts +1880 -3191
- package/generated/prisma-mongodb/index.js +38 -33
- package/generated/prisma-mongodb/package.json +1 -1
- package/generated/prisma-mongodb/schema.prisma +50 -86
- package/generated/prisma-mongodb/wasm.js +38 -33
- package/generated/prisma-postgresql/edge.js +38 -33
- package/generated/prisma-postgresql/index-browser.js +35 -30
- package/generated/prisma-postgresql/index.d.ts +2050 -3390
- package/generated/prisma-postgresql/index.js +38 -33
- package/generated/prisma-postgresql/package.json +1 -1
- package/generated/prisma-postgresql/schema.prisma +48 -81
- package/generated/prisma-postgresql/wasm.js +38 -33
- package/handlers/WEBHOOKS.md +29 -0
- package/handlers/app-definition-loader.js +19 -128
- package/handlers/app-handler-helpers.js +3 -25
- package/handlers/backend-utils.js +25 -31
- package/handlers/middleware/admin-auth.js +1 -14
- package/handlers/routers/auth.js +10 -46
- package/handlers/routers/health.js +4 -13
- package/handlers/routers/integration-defined-routers.js +92 -144
- package/handlers/routers/integration-webhook-routers.js +64 -102
- package/handlers/workers/integration-defined-workers.js +2 -5
- package/handlers/workers/integration-triggers.js +25 -0
- package/index.js +3 -65
- package/infrastructure/scheduler/index.js +6 -19
- package/infrastructure/scheduler/recurrence.js +204 -0
- package/infrastructure/scheduler/scheduler-service-factory.js +7 -55
- package/integrations/data-defined/README.md +185 -0
- package/integrations/data-defined/canonical.js +11 -0
- package/integrations/data-defined/capabilities/acmeerp.capabilities.json +608 -0
- package/integrations/data-defined/capabilities/asana.capabilities.json +265 -0
- package/integrations/data-defined/capabilities/calendly.capabilities.json +385 -0
- package/integrations/data-defined/capabilities/docusign.capabilities.json +314 -0
- package/integrations/data-defined/capabilities/fathom.capabilities.json +228 -0
- package/integrations/data-defined/capabilities/github.capabilities.json +563 -0
- package/integrations/data-defined/capabilities/hubspot.capabilities.json +715 -0
- package/integrations/data-defined/capabilities/jira.capabilities.json +376 -0
- package/integrations/data-defined/capabilities/klaviyo.capabilities.json +475 -0
- package/integrations/data-defined/capabilities/linear.capabilities.json +324 -0
- package/integrations/data-defined/capabilities/netsuite.capabilities.json +491 -0
- package/integrations/data-defined/capabilities/notion.capabilities.json +208 -0
- package/integrations/data-defined/capabilities/phone.capabilities.json +470 -0
- package/integrations/data-defined/capabilities/pipedrive.capabilities.json +388 -0
- package/integrations/data-defined/capabilities/quickbooks.capabilities.json +615 -0
- package/integrations/data-defined/capabilities/salesforce.capabilities.json +507 -0
- package/integrations/data-defined/capabilities/shopify.capabilities.json +1082 -0
- package/integrations/data-defined/capabilities/slack.capabilities.json +363 -0
- package/integrations/data-defined/capabilities/stripe.capabilities.json +580 -0
- package/integrations/data-defined/capabilities/webflow.capabilities.json +196 -0
- package/integrations/data-defined/capabilities/zendesk.capabilities.json +409 -0
- package/integrations/data-defined/compile.js +80 -0
- package/integrations/data-defined/config-form.js +137 -0
- package/integrations/data-defined/data-defined-integration.js +417 -0
- package/integrations/data-defined/examples/acme-erp-quickbooks.definition.json +467 -0
- package/integrations/data-defined/examples/asana-slack.definition.json +220 -0
- package/integrations/data-defined/examples/calendly-salesforce.definition.json +459 -0
- package/integrations/data-defined/examples/docusign-salesforce.definition.json +305 -0
- package/integrations/data-defined/examples/fathom-hubspot-notion.definition.json +575 -0
- package/integrations/data-defined/examples/github-linear.definition.json +316 -0
- package/integrations/data-defined/examples/hubspot-slack.definition.json +409 -0
- package/integrations/data-defined/examples/klaviyo-hubspot.definition.json +339 -0
- package/integrations/data-defined/examples/phone-hubspot.definition.json +637 -0
- package/integrations/data-defined/examples/pipedrive-hubspot.definition.json +136 -0
- package/integrations/data-defined/examples/pipedrive-phone.definition.json +340 -0
- package/integrations/data-defined/examples/records/phone-hubspot.definition-version.json +652 -0
- package/integrations/data-defined/examples/records/phone-hubspot.integration.json +86 -0
- package/integrations/data-defined/examples/records/phone-hubspot.mappings.json +39 -0
- package/integrations/data-defined/examples/records/phone-hubspot.workflow-run.json +62 -0
- package/integrations/data-defined/examples/shopify-klaviyo.definition.json +488 -0
- package/integrations/data-defined/examples/shopify-netsuite.definition.json +622 -0
- package/integrations/data-defined/examples/stripe-quickbooks.definition.json +476 -0
- package/integrations/data-defined/examples/webflow-hubspot-slack.definition.json +262 -0
- package/integrations/data-defined/examples/zendesk-jira.definition.json +604 -0
- package/integrations/data-defined/expressions.js +225 -0
- package/integrations/data-defined/index.js +39 -0
- package/integrations/data-defined/interpreter.js +89 -0
- package/integrations/data-defined/manifests.js +125 -0
- package/integrations/data-defined/repositories/definition-version-repository.js +67 -0
- package/integrations/data-defined/repositories/workflow-run-repository.js +59 -0
- package/integrations/data-defined/router.js +97 -0
- package/integrations/data-defined/runtime.js +208 -0
- package/integrations/data-defined/schema/capability-manifest.v0.1.schema.json +377 -0
- package/integrations/data-defined/schema/installation.v0.1.schema.json +130 -0
- package/integrations/data-defined/schema/integration-definition.v0.1.schema.json +902 -0
- package/integrations/data-defined/schema/records.md +98 -0
- package/integrations/data-defined/schema-check.js +58 -0
- package/integrations/data-defined/scripts/validate.js +66 -0
- package/integrations/data-defined/steps.js +89 -0
- package/integrations/data-defined/transforms.js +91 -0
- package/integrations/data-defined/use-cases/definition-use-cases.js +187 -0
- package/integrations/data-defined/validate.js +384 -0
- package/integrations/data-defined/versioning.js +176 -0
- package/integrations/data-defined/webhooks.js +119 -0
- package/integrations/index.js +0 -1
- package/integrations/integration-base.js +117 -0
- package/integrations/integration-router.js +101 -131
- package/integrations/repositories/integration-mapping-repository-documentdb.js +50 -0
- package/integrations/repositories/integration-mapping-repository-interface.js +15 -0
- package/integrations/repositories/integration-mapping-repository-mongo.js +29 -0
- package/integrations/repositories/integration-mapping-repository-postgres.js +30 -0
- package/integrations/repositories/integration-mapping-repository.js +29 -0
- package/integrations/repositories/integration-repository-documentdb.js +9 -37
- package/integrations/repositories/integration-repository-interface.js +4 -17
- package/integrations/repositories/integration-repository-mongo.js +96 -64
- package/integrations/repositories/integration-repository-postgres.js +81 -63
- package/integrations/repositories/process-repository-mongo.js +1 -1
- package/integrations/tests/doubles/test-integration-repository.js +1 -12
- package/integrations/triggers.js +244 -0
- package/integrations/use-cases/create-integration.js +20 -55
- package/integrations/use-cases/get-integrations-for-user.js +40 -80
- package/integrations/use-cases/index.js +1 -7
- package/integrations/use-cases/run-trigger-tick.js +132 -0
- package/integrations/use-cases/run-trigger.js +77 -0
- package/integrations/utils/map-integration-dto.js +14 -43
- package/modules/index.js +0 -14
- package/modules/module-factory.js +0 -12
- package/modules/module.js +2 -53
- package/modules/repositories/module-repository-documentdb.js +6 -51
- package/modules/repositories/module-repository-interface.js +2 -19
- package/modules/repositories/module-repository-mongo.js +74 -67
- package/modules/repositories/module-repository-postgres.js +74 -66
- package/modules/repositories/module-repository.js +1 -2
- package/modules/requester/requester.js +5 -35
- package/modules/use-cases/get-entities-for-user.js +13 -26
- package/modules/use-cases/get-entity-options-by-id.js +4 -10
- package/modules/use-cases/get-entity-options-by-type.js +1 -1
- package/modules/use-cases/get-module-instance-from-type.js +1 -1
- package/modules/use-cases/get-module.js +4 -10
- package/modules/use-cases/process-authorization-callback.js +19 -53
- package/modules/use-cases/refresh-entity-options.js +4 -10
- package/modules/use-cases/test-module-auth.js +4 -10
- package/package.json +6 -6
- package/prisma-mongodb/schema.prisma +50 -86
- package/prisma-postgresql/migrations/20261018000000_add_data_defined_integrations/migration.sql +66 -0
- package/prisma-postgresql/schema.prisma +48 -81
- package/queues/index.js +0 -25
- package/queues/queuer-util.js +9 -2
- package/types/index.d.ts +0 -2
- package/user/repositories/user-repository-documentdb.js +2 -27
- package/user/repositories/user-repository-interface.js +0 -18
- package/user/repositories/user-repository-mongo.js +0 -24
- package/user/repositories/user-repository-postgres.js +0 -18
- package/user/use-cases/authenticate-user.js +1 -7
- package/user/use-cases/get-user-from-adopter-jwt.js +124 -95
- package/user/use-cases/get-user-from-x-frigg-headers.js +80 -83
- package/user/user.js +1 -64
- package/credential/use-cases/credential-operations-for-user.js +0 -202
- package/credential/use-cases/reauthorize-credential-for-user.js +0 -73
- package/database/organization-where.js +0 -18
- package/database/unique-violation.js +0 -25
- package/extensions/bootstrap-runner.js +0 -43
- package/extensions/extension-loader.js +0 -187
- package/extensions/index.js +0 -41
- package/extensions/initialize-app.js +0 -123
- package/extensions/route-mounter.js +0 -103
- package/extensions/schema-composer.js +0 -188
- package/infrastructure/scheduler/netlify-scheduler-adapter.js +0 -216
- package/infrastructure/scheduler/scheduled-job-repository.js +0 -118
- package/integrations/repositories/integration-not-found.js +0 -14
- package/integrations/schedule-config.js +0 -80
- package/integrations/use-cases/dispatch-ongoing-syncs.js +0 -100
- package/integrations/use-cases/integration-operations-for-user.js +0 -256
- package/integrations/use-cases/resolve-integration-ownership.js +0 -177
- package/management-api/create-management-api-router.js +0 -49
- package/management-api/error-response.js +0 -116
- package/management-api/management-api-config.js +0 -151
- package/management-api/meta-router.js +0 -76
- package/management-api/openapi/build-openapi.js +0 -144
- package/management-api/openapi/components.js +0 -415
- package/management-api/openapi/v1-operations.js +0 -83
- package/management-api/openapi/v2-operations.js +0 -264
- package/management-api/route-registry.js +0 -411
- package/management-api/test-support/http-client.js +0 -39
- package/management-api/use-cases/get-management-api-meta.js +0 -57
- package/management-api/v1-deprecation.js +0 -120
- package/management-api/v2/create-v2-router.js +0 -85
- package/management-api/v2/dependencies.js +0 -281
- package/management-api/v2/dto.js +0 -143
- package/management-api/v2/handlers/authorization.js +0 -94
- package/management-api/v2/handlers/credentials.js +0 -33
- package/management-api/v2/handlers/entities.js +0 -77
- package/management-api/v2/handlers/integrations.js +0 -128
- package/management-api/v2/handlers/proxy.js +0 -34
- package/management-api/v2/request.js +0 -85
- package/management-api/v2/test-support/fake-dependencies.js +0 -103
- package/modules/domain/authorization-session.js +0 -144
- package/modules/entity-scope.js +0 -15
- package/modules/entity-type-registry.js +0 -311
- package/modules/proxy/proxy-bases.js +0 -169
- package/modules/proxy/proxy-errors.js +0 -31
- package/modules/proxy/proxy-path.js +0 -183
- package/modules/proxy/proxy-policy.js +0 -277
- package/modules/repositories/authorization-session-repository-documentdb.js +0 -112
- package/modules/repositories/authorization-session-repository-factory.js +0 -31
- package/modules/repositories/authorization-session-repository-interface.js +0 -47
- package/modules/repositories/authorization-session-repository-prisma.js +0 -87
- package/modules/repositories/entity-not-found.js +0 -18
- package/modules/requester/proxy-request.js +0 -245
- package/modules/scope-config.js +0 -192
- package/modules/scope-policy.js +0 -112
- package/modules/scope-resolution.js +0 -288
- package/modules/scope-visibility.js +0 -247
- package/modules/tests/doubles/in-memory-authorization-session-repository.js +0 -45
- package/modules/tests/doubles/ownership-matching.js +0 -18
- package/modules/use-cases/authorize-entity-for-user.js +0 -61
- package/modules/use-cases/create-entity-from-credential.js +0 -113
- package/modules/use-cases/entity-operations-for-user.js +0 -162
- package/modules/use-cases/entity-types.js +0 -139
- package/modules/use-cases/execute-entity-proxy-request.js +0 -331
- package/modules/use-cases/get-authorization-requirements.js +0 -100
- package/modules/use-cases/get-entity-module-for-user.js +0 -113
- package/modules/use-cases/manage-access.js +0 -21
- package/modules/use-cases/multi-step-authorization.js +0 -329
- package/prisma-postgresql/migrations/20261003000000_add_authorization_session/migration.sql +0 -28
- package/prisma-postgresql/migrations/20261015000000_add_organization_membership/migration.sql +0 -26
- package/prisma-postgresql/migrations/20261016000000_add_entity_integration_organization/migration.sql +0 -25
- package/prisma-postgresql/migrations/20261017000000_add_scheduled_job/migration.sql +0 -28
- package/providers/index.js +0 -23
- package/providers/resolve-provider.js +0 -93
- package/providers/runtime-detection.js +0 -124
- package/queues/providers/index.js +0 -11
- package/queues/providers/netlify-background-provider.js +0 -150
- package/queues/providers/qstash-queue-provider.js +0 -219
- package/queues/providers/sqs-queue-provider.js +0 -70
- package/queues/queue-client-interface.js +0 -55
- package/queues/queue-message-auth.js +0 -193
- package/queues/queue-provider-factory.js +0 -101
- package/queues/queue-provider.js +0 -65
- package/queues/sqs-queue-client.js +0 -81
- package/types/modules/index.d.ts +0 -214
- package/types/user/index.d.ts +0 -134
- package/user/adopter-jwt-config.js +0 -177
- package/user/adopter-jwt-errors.js +0 -59
- package/user/adopter-token-verifier.js +0 -122
- package/user/app-user-helpers.js +0 -97
- package/user/create-user-authentication.js +0 -64
- package/user/membership.js +0 -51
- package/user/repositories/organization-membership-record.js +0 -19
- package/user/repositories/organization-membership-repository-documentdb.js +0 -106
- package/user/repositories/organization-membership-repository-factory.js +0 -42
- package/user/repositories/organization-membership-repository-interface.js +0 -57
- package/user/repositories/organization-membership-repository-mongo.js +0 -13
- package/user/repositories/organization-membership-repository-postgres.js +0 -29
- package/user/repositories/organization-membership-repository-prisma.js +0 -81
- package/user/tests/doubles/adopter-jwt-fixtures.js +0 -220
- package/user/use-cases/ensure-organization-membership.js +0 -92
- package/user/use-cases/find-individual-users-by-organization.js +0 -54
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { prisma } = require('../../database/prisma');
|
|
2
|
+
const { MappingAlreadyExistsError } = require('../../errors');
|
|
2
3
|
const {
|
|
3
4
|
IntegrationMappingRepositoryInterface,
|
|
4
5
|
} = require('./integration-mapping-repository-interface');
|
|
@@ -69,6 +70,34 @@ class IntegrationMappingRepository extends IntegrationMappingRepositoryInterface
|
|
|
69
70
|
});
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Insert a mapping; fails if (integrationId, sourceId) already exists
|
|
75
|
+
*
|
|
76
|
+
* @param {string} integrationId - The integration ID
|
|
77
|
+
* @param {string} sourceId - The source ID
|
|
78
|
+
* @param {Object} mapping - The mapping data
|
|
79
|
+
* @returns {Promise<Object>} The created mapping document
|
|
80
|
+
* @throws {MappingAlreadyExistsError} If the pair already exists
|
|
81
|
+
*/
|
|
82
|
+
async createMapping(integrationId, sourceId, mapping) {
|
|
83
|
+
try {
|
|
84
|
+
return await this.prisma.integrationMapping.create({
|
|
85
|
+
data: {
|
|
86
|
+
integrationId,
|
|
87
|
+
sourceId,
|
|
88
|
+
mapping,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (error.code === 'P2002') {
|
|
93
|
+
throw new MappingAlreadyExistsError(integrationId, sourceId, {
|
|
94
|
+
cause: error,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
72
101
|
/**
|
|
73
102
|
* Find all mappings for an integration
|
|
74
103
|
* Replaces: IntegrationMapping.find({ integration: integrationId })
|
|
@@ -14,7 +14,6 @@ const {
|
|
|
14
14
|
IntegrationRepositoryInterface,
|
|
15
15
|
} = require('./integration-repository-interface');
|
|
16
16
|
const { validateConfigPatch } = require('./config-patch-shared');
|
|
17
|
-
const { integrationNotFoundError } = require('./integration-not-found');
|
|
18
17
|
|
|
19
18
|
class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
|
|
20
19
|
constructor() {
|
|
@@ -29,29 +28,7 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
|
|
|
29
28
|
return records.map((doc) => this._mapIntegration(doc));
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
* Find integrations matching any of the owner/organization pairs, in one
|
|
34
|
-
* query. `organizationId: null` matches rows with no organization (a raw
|
|
35
|
-
* MongoDB `null` also matches a missing field). The caller (a use case)
|
|
36
|
-
* decides which pairs; this only runs them.
|
|
37
|
-
*
|
|
38
|
-
* @param {Array<{userId: string, organizationId: (string|null)}>} clauses
|
|
39
|
-
* @returns {Promise<Array>}
|
|
40
|
-
*/
|
|
41
|
-
async findIntegrationsByOwnership(clauses) {
|
|
42
|
-
if (!Array.isArray(clauses) || clauses.length === 0) return [];
|
|
43
|
-
// Drained: a list can hold more than the first cursor batch (~101).
|
|
44
|
-
const records = await findManyDrained(this.prisma, 'Integration', {
|
|
45
|
-
$or: clauses.map(({ userId, organizationId }) => ({
|
|
46
|
-
userId: toObjectId(userId),
|
|
47
|
-
organizationId:
|
|
48
|
-
organizationId === null ? null : toObjectId(organizationId),
|
|
49
|
-
})),
|
|
50
|
-
});
|
|
51
|
-
return records.map((doc) => this._mapIntegration(doc));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async findIntegrations({ type, status } = {}) {
|
|
31
|
+
async findIntegrations({ type, status, limit, after } = {}) {
|
|
55
32
|
const filter = {};
|
|
56
33
|
if (type) {
|
|
57
34
|
filter['config.type'] = type;
|
|
@@ -59,7 +36,11 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
|
|
|
59
36
|
if (status) {
|
|
60
37
|
filter.status = status;
|
|
61
38
|
}
|
|
62
|
-
|
|
39
|
+
if (limit && after !== undefined && after !== null) {
|
|
40
|
+
// Extended JSON: $runCommandRaw does not match a BSON ObjectId instance inside an operator.
|
|
41
|
+
filter._id = { $gt: { $oid: fromObjectId(toObjectId(after)) } };
|
|
42
|
+
}
|
|
43
|
+
const records = await findMany(this.prisma, 'Integration', filter, limit ? { sort: { _id: 1 }, limit, batchSize: limit } : {});
|
|
63
44
|
return records.map((doc) => this._mapIntegration(doc));
|
|
64
45
|
}
|
|
65
46
|
|
|
@@ -91,11 +72,11 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
|
|
|
91
72
|
async findIntegrationById(id) {
|
|
92
73
|
const objectId = toObjectId(id);
|
|
93
74
|
if (!objectId) {
|
|
94
|
-
throw
|
|
75
|
+
throw new Error(`Integration with id ${id} not found`);
|
|
95
76
|
}
|
|
96
77
|
const doc = await findOne(this.prisma, 'Integration', { _id: objectId });
|
|
97
78
|
if (!doc) {
|
|
98
|
-
throw
|
|
79
|
+
throw new Error(`Integration with id ${id} not found`);
|
|
99
80
|
}
|
|
100
81
|
return this._mapIntegration(doc);
|
|
101
82
|
}
|
|
@@ -155,18 +136,10 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
|
|
|
155
136
|
return true;
|
|
156
137
|
}
|
|
157
138
|
|
|
158
|
-
|
|
159
|
-
* @param {Array<string>} entities - entity ids
|
|
160
|
-
* @param {string} userId - owner (the person, or the organization's user)
|
|
161
|
-
* @param {Object} config - Integration configuration
|
|
162
|
-
* @param {{organizationId?: (string|null)}} [tenancy] - the organization the
|
|
163
|
-
* integration is created in (ADR-056 §3.6)
|
|
164
|
-
*/
|
|
165
|
-
async createIntegration(entities, userId, config, tenancy = {}) {
|
|
139
|
+
async createIntegration(entities, userId, config) {
|
|
166
140
|
const now = new Date();
|
|
167
141
|
const document = {
|
|
168
142
|
userId: toObjectId(userId) || null,
|
|
169
|
-
organizationId: toObjectId(tenancy.organizationId) || null,
|
|
170
143
|
config,
|
|
171
144
|
version: '0.0.0',
|
|
172
145
|
status: 'IN_CREATION',
|
|
@@ -329,7 +302,6 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
|
|
|
329
302
|
id: fromObjectId(doc?._id),
|
|
330
303
|
entitiesIds: (doc?.entityIds || []).map((value) => fromObjectId(value)),
|
|
331
304
|
userId: fromObjectId(doc?.userId),
|
|
332
|
-
organizationId: fromObjectId(doc?.organizationId) ?? null,
|
|
333
305
|
config: doc?.config ?? null,
|
|
334
306
|
version: doc?.version ?? null,
|
|
335
307
|
status: doc?.status ?? null,
|
|
@@ -10,20 +10,6 @@
|
|
|
10
10
|
* @abstract
|
|
11
11
|
*/
|
|
12
12
|
class IntegrationRepositoryInterface {
|
|
13
|
-
/**
|
|
14
|
-
* Find integrations matching any of the owner/organization pairs, in one
|
|
15
|
-
* query (ADR-056 §3.6). `organizationId: null` matches rows with no
|
|
16
|
-
* organization. Which pairs is decided by the caller
|
|
17
|
-
* (modules/entity-scope.js), not here.
|
|
18
|
-
*
|
|
19
|
-
* @param {Array<{userId: string|number, organizationId: (string|number|null)}>} clauses
|
|
20
|
-
* @returns {Promise<Array>} Array of integration objects
|
|
21
|
-
* @abstract
|
|
22
|
-
*/
|
|
23
|
-
async findIntegrationsByOwnership(clauses) {
|
|
24
|
-
throw new Error('Method findIntegrationsByOwnership must be implemented by subclass');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
13
|
/**
|
|
28
14
|
* Find all integrations for a user
|
|
29
15
|
*
|
|
@@ -42,6 +28,9 @@ class IntegrationRepositoryInterface {
|
|
|
42
28
|
* @param {Object} [filter={}]
|
|
43
29
|
* @param {string} [filter.type] - Integration type (config.type)
|
|
44
30
|
* @param {string} [filter.status] - Integration status
|
|
31
|
+
* @param {number} [filter.limit] - Page size: at most this many rows, in id order
|
|
32
|
+
* @param {string|number} [filter.after] - With limit: only rows whose id sorts after this one (the last id of the
|
|
33
|
+
* previous page), so a caller can page through every row (the trigger tick does, ADR-055)
|
|
45
34
|
* @returns {Promise<Array>} Array of integration objects (possibly empty)
|
|
46
35
|
* @abstract
|
|
47
36
|
*/
|
|
@@ -137,12 +126,10 @@ class IntegrationRepositoryInterface {
|
|
|
137
126
|
* @param {Array<string|number>} entities - Array of entity IDs
|
|
138
127
|
* @param {string|number} userId - User ID
|
|
139
128
|
* @param {Object} config - Integration configuration
|
|
140
|
-
* @param {{organizationId?: (string|number|null)}} [tenancy] - the organization the
|
|
141
|
-
* integration is created in (ADR-056 §3.6)
|
|
142
129
|
* @returns {Promise<Object>} Created integration object
|
|
143
130
|
* @abstract
|
|
144
131
|
*/
|
|
145
|
-
async createIntegration(entities, userId, config
|
|
132
|
+
async createIntegration(entities, userId, config) {
|
|
146
133
|
throw new Error('Method createIntegration must be implemented by subclass');
|
|
147
134
|
}
|
|
148
135
|
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
const { prisma } = require('../../database/prisma');
|
|
2
|
-
const { organizationWhere } = require('../../database/organization-where');
|
|
3
2
|
const {
|
|
4
3
|
IntegrationRepositoryInterface,
|
|
5
4
|
} = require('./integration-repository-interface');
|
|
6
5
|
const { validateConfigPatch } = require('./config-patch-shared');
|
|
7
|
-
const { integrationNotFoundError } = require('./integration-not-found');
|
|
8
6
|
|
|
9
7
|
/**
|
|
10
8
|
* MongoDB Integration Repository Adapter
|
|
@@ -27,25 +25,6 @@ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
|
27
25
|
this.prisma = prisma;
|
|
28
26
|
}
|
|
29
27
|
|
|
30
|
-
/**
|
|
31
|
-
* The one place a integration integration row becomes the record the
|
|
32
|
-
* application sees (ids of its entities, its organization).
|
|
33
|
-
* @private
|
|
34
|
-
*/
|
|
35
|
-
_mapIntegration(integration) {
|
|
36
|
-
return {
|
|
37
|
-
id: integration.id,
|
|
38
|
-
entitiesIds: integration.entities.map((e) => e.id),
|
|
39
|
-
userId: integration.userId,
|
|
40
|
-
organizationId: integration.organizationId ?? null,
|
|
41
|
-
config: integration.config,
|
|
42
|
-
version: integration.version,
|
|
43
|
-
status: integration.status,
|
|
44
|
-
messages: integration.messages,
|
|
45
|
-
createdAt: integration.createdAt,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
28
|
/**
|
|
50
29
|
* Find all integrations for a user
|
|
51
30
|
* Replaces: IntegrationModel.find({ user: userId }).populate('entities')
|
|
@@ -62,32 +41,16 @@ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
|
62
41
|
});
|
|
63
42
|
|
|
64
43
|
// Map to domain objects (maintains same API)
|
|
65
|
-
return integrations.map((integration) => (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
*/
|
|
76
|
-
async findIntegrationsByOwnership(clauses) {
|
|
77
|
-
if (!Array.isArray(clauses) || clauses.length === 0) return [];
|
|
78
|
-
const integrations = await this.prisma.integration.findMany({
|
|
79
|
-
where: {
|
|
80
|
-
OR: clauses.map(({ userId, organizationId }) => ({
|
|
81
|
-
userId,
|
|
82
|
-
...organizationWhere(organizationId),
|
|
83
|
-
})),
|
|
84
|
-
},
|
|
85
|
-
include: {
|
|
86
|
-
entities: true,
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
return integrations.map((integration) => (this._mapIntegration(integration)));
|
|
44
|
+
return integrations.map((integration) => ({
|
|
45
|
+
id: integration.id,
|
|
46
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
47
|
+
userId: integration.userId,
|
|
48
|
+
config: integration.config,
|
|
49
|
+
version: integration.version,
|
|
50
|
+
status: integration.status,
|
|
51
|
+
messages: integration.messages,
|
|
52
|
+
createdAt: integration.createdAt,
|
|
53
|
+
}));
|
|
91
54
|
}
|
|
92
55
|
|
|
93
56
|
/**
|
|
@@ -98,23 +61,47 @@ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
|
98
61
|
* @param {string} [filter.status] - Integration status
|
|
99
62
|
* @returns {Promise<Array>} Array of integration objects (possibly empty)
|
|
100
63
|
*/
|
|
101
|
-
async findIntegrations({ type, status } = {}) {
|
|
64
|
+
async findIntegrations({ type, status, limit, after } = {}) {
|
|
102
65
|
const where = {};
|
|
103
|
-
if (type) {
|
|
104
|
-
where.config = { path: ['type'], equals: type };
|
|
105
|
-
}
|
|
106
66
|
if (status) {
|
|
107
67
|
where.status = status;
|
|
108
68
|
}
|
|
69
|
+
if (limit && after !== undefined && after !== null) {
|
|
70
|
+
where.id = { gt: after };
|
|
71
|
+
}
|
|
72
|
+
if (type) {
|
|
73
|
+
// Prisma's MongoDB connector has no JSON path filter (`config: { path }` is refused), so the ids of the
|
|
74
|
+
// matching rows come from a raw find on config.type, then the rows load as usual.
|
|
75
|
+
const filter = { 'config.type': type };
|
|
76
|
+
if (status) filter.status = status;
|
|
77
|
+
if (where.id) filter._id = { $gt: { $oid: String(after) } };
|
|
78
|
+
const found = await this.prisma.integration.findRaw({
|
|
79
|
+
filter,
|
|
80
|
+
options: { projection: { _id: 1 }, sort: { _id: 1 }, ...(limit ? { limit } : {}) },
|
|
81
|
+
});
|
|
82
|
+
const ids = found.map((doc) => doc._id?.$oid ?? String(doc._id));
|
|
83
|
+
if (!ids.length) return [];
|
|
84
|
+
where.id = { in: ids };
|
|
85
|
+
}
|
|
109
86
|
|
|
110
87
|
const integrations = await this.prisma.integration.findMany({
|
|
111
88
|
where,
|
|
112
89
|
include: {
|
|
113
90
|
entities: true,
|
|
114
91
|
},
|
|
92
|
+
...(limit ? { orderBy: { id: 'asc' }, take: limit } : {}),
|
|
115
93
|
});
|
|
116
94
|
|
|
117
|
-
return integrations.map((integration) => (
|
|
95
|
+
return integrations.map((integration) => ({
|
|
96
|
+
id: integration.id,
|
|
97
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
98
|
+
userId: integration.userId,
|
|
99
|
+
config: integration.config,
|
|
100
|
+
version: integration.version,
|
|
101
|
+
status: integration.status,
|
|
102
|
+
messages: integration.messages,
|
|
103
|
+
createdAt: integration.createdAt,
|
|
104
|
+
}));
|
|
118
105
|
}
|
|
119
106
|
|
|
120
107
|
/**
|
|
@@ -193,7 +180,15 @@ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
|
193
180
|
throw new Error(`Integration with name ${name} not found`);
|
|
194
181
|
}
|
|
195
182
|
|
|
196
|
-
return
|
|
183
|
+
return {
|
|
184
|
+
id: integration.id,
|
|
185
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
186
|
+
userId: integration.userId,
|
|
187
|
+
config: integration.config,
|
|
188
|
+
version: integration.version,
|
|
189
|
+
status: integration.status,
|
|
190
|
+
messages: integration.messages,
|
|
191
|
+
};
|
|
197
192
|
}
|
|
198
193
|
|
|
199
194
|
/**
|
|
@@ -212,10 +207,18 @@ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
|
212
207
|
});
|
|
213
208
|
|
|
214
209
|
if (!integration) {
|
|
215
|
-
throw
|
|
210
|
+
throw new Error(`Integration with id ${id} not found`);
|
|
216
211
|
}
|
|
217
212
|
|
|
218
|
-
return
|
|
213
|
+
return {
|
|
214
|
+
id: integration.id,
|
|
215
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
216
|
+
userId: integration.userId,
|
|
217
|
+
config: integration.config,
|
|
218
|
+
version: integration.version,
|
|
219
|
+
status: integration.status,
|
|
220
|
+
messages: integration.messages,
|
|
221
|
+
};
|
|
219
222
|
}
|
|
220
223
|
|
|
221
224
|
/**
|
|
@@ -302,7 +305,15 @@ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
|
302
305
|
},
|
|
303
306
|
});
|
|
304
307
|
|
|
305
|
-
return integrations.map((integration) => (
|
|
308
|
+
return integrations.map((integration) => ({
|
|
309
|
+
id: integration.id,
|
|
310
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
311
|
+
userId: integration.userId,
|
|
312
|
+
config: integration.config,
|
|
313
|
+
version: integration.version,
|
|
314
|
+
status: integration.status,
|
|
315
|
+
messages: integration.messages,
|
|
316
|
+
}));
|
|
306
317
|
}
|
|
307
318
|
|
|
308
319
|
/**
|
|
@@ -314,16 +325,13 @@ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
|
314
325
|
* @param {Array<string>} entities - Array of entity IDs (MongoDB ObjectIds)
|
|
315
326
|
* @param {string} userId - User ID (MongoDB ObjectId)
|
|
316
327
|
* @param {Object} config - Integration configuration
|
|
317
|
-
* @param {{organizationId?: (string|null)}} [tenancy] - the organization the
|
|
318
|
-
* integration is created in (ADR-056 §3.6)
|
|
319
328
|
* @returns {Promise<Object>} Created integration object
|
|
320
329
|
*/
|
|
321
|
-
async createIntegration(entities, userId, config
|
|
330
|
+
async createIntegration(entities, userId, config) {
|
|
322
331
|
const data = {
|
|
323
332
|
config,
|
|
324
333
|
version: '0.0.0',
|
|
325
334
|
userId: userId,
|
|
326
|
-
organizationId: tenancy.organizationId ?? null,
|
|
327
335
|
entityIds: entities,
|
|
328
336
|
};
|
|
329
337
|
|
|
@@ -334,7 +342,15 @@ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
|
334
342
|
},
|
|
335
343
|
});
|
|
336
344
|
|
|
337
|
-
return
|
|
345
|
+
return {
|
|
346
|
+
id: integration.id,
|
|
347
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
348
|
+
userId: integration.userId,
|
|
349
|
+
config: integration.config,
|
|
350
|
+
version: integration.version,
|
|
351
|
+
status: integration.status,
|
|
352
|
+
messages: integration.messages,
|
|
353
|
+
};
|
|
338
354
|
}
|
|
339
355
|
|
|
340
356
|
/**
|
|
@@ -356,7 +372,15 @@ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
|
356
372
|
return null;
|
|
357
373
|
}
|
|
358
374
|
|
|
359
|
-
return
|
|
375
|
+
return {
|
|
376
|
+
id: integration.id,
|
|
377
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
378
|
+
userId: integration.userId,
|
|
379
|
+
config: integration.config,
|
|
380
|
+
version: integration.version,
|
|
381
|
+
status: integration.status,
|
|
382
|
+
messages: integration.messages,
|
|
383
|
+
};
|
|
360
384
|
}
|
|
361
385
|
|
|
362
386
|
/**
|
|
@@ -380,7 +404,15 @@ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
|
380
404
|
},
|
|
381
405
|
});
|
|
382
406
|
|
|
383
|
-
return
|
|
407
|
+
return {
|
|
408
|
+
id: integration.id,
|
|
409
|
+
entitiesIds: integration.entities.map((e) => e.id),
|
|
410
|
+
userId: integration.userId,
|
|
411
|
+
config: integration.config,
|
|
412
|
+
version: integration.version,
|
|
413
|
+
status: integration.status,
|
|
414
|
+
messages: integration.messages,
|
|
415
|
+
};
|
|
384
416
|
}
|
|
385
417
|
|
|
386
418
|
/**
|
|
@@ -402,7 +434,7 @@ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
|
|
|
402
434
|
for (const [key, value] of Object.entries(patch)) {
|
|
403
435
|
$set[`config.${key}`] = value;
|
|
404
436
|
}
|
|
405
|
-
$set.updatedAt = new Date();
|
|
437
|
+
$set.updatedAt = { $date: new Date().toISOString() };
|
|
406
438
|
|
|
407
439
|
const result = await this.prisma.$runCommandRaw({
|
|
408
440
|
findAndModify: 'Integration',
|
|
@@ -3,7 +3,6 @@ const {
|
|
|
3
3
|
IntegrationRepositoryInterface,
|
|
4
4
|
} = require('./integration-repository-interface');
|
|
5
5
|
const { validateConfigPatch } = require('./config-patch-shared');
|
|
6
|
-
const { integrationNotFoundError } = require('./integration-not-found');
|
|
7
6
|
const { strictIntId } = require('./report-id');
|
|
8
7
|
|
|
9
8
|
/**
|
|
@@ -52,7 +51,6 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
52
51
|
...integration,
|
|
53
52
|
id: integration.id?.toString(),
|
|
54
53
|
userId: integration.userId?.toString(),
|
|
55
|
-
organizationId: integration.organizationId?.toString() ?? null,
|
|
56
54
|
entities: integration.entities?.map(e => ({
|
|
57
55
|
...e,
|
|
58
56
|
id: e.id?.toString(),
|
|
@@ -62,25 +60,6 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
62
60
|
};
|
|
63
61
|
}
|
|
64
62
|
|
|
65
|
-
/**
|
|
66
|
-
* The one place a converted integration row becomes the record the
|
|
67
|
-
* application sees (string ids, ids of its entities, its organization).
|
|
68
|
-
* @private
|
|
69
|
-
*/
|
|
70
|
-
_mapIntegration(converted) {
|
|
71
|
-
return {
|
|
72
|
-
id: converted.id,
|
|
73
|
-
entitiesIds: converted.entities.map((e) => e.id),
|
|
74
|
-
userId: converted.userId,
|
|
75
|
-
organizationId: converted.organizationId,
|
|
76
|
-
config: converted.config,
|
|
77
|
-
version: converted.version,
|
|
78
|
-
status: converted.status,
|
|
79
|
-
messages: converted.messages,
|
|
80
|
-
createdAt: converted.createdAt,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
63
|
/**
|
|
85
64
|
* Find all integrations for a user
|
|
86
65
|
*
|
|
@@ -99,35 +78,16 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
99
78
|
// Map to domain objects with string IDs
|
|
100
79
|
return integrations.map((integration) => {
|
|
101
80
|
const converted = this._convertIntegrationIds(integration);
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
* @returns {Promise<Array>} Array of integration objects with string IDs
|
|
113
|
-
*/
|
|
114
|
-
async findIntegrationsByOwnership(clauses) {
|
|
115
|
-
if (!Array.isArray(clauses) || clauses.length === 0) return [];
|
|
116
|
-
const integrations = await this.prisma.integration.findMany({
|
|
117
|
-
where: {
|
|
118
|
-
OR: clauses.map(({ userId, organizationId }) => ({
|
|
119
|
-
userId: this._convertId(userId),
|
|
120
|
-
organizationId: this._convertId(organizationId),
|
|
121
|
-
})),
|
|
122
|
-
},
|
|
123
|
-
include: {
|
|
124
|
-
entities: true,
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
return integrations.map((integration) => {
|
|
129
|
-
const converted = this._convertIntegrationIds(integration);
|
|
130
|
-
return this._mapIntegration(converted);
|
|
81
|
+
return {
|
|
82
|
+
id: converted.id,
|
|
83
|
+
entitiesIds: converted.entities.map((e) => e.id),
|
|
84
|
+
userId: converted.userId,
|
|
85
|
+
config: converted.config,
|
|
86
|
+
version: converted.version,
|
|
87
|
+
status: converted.status,
|
|
88
|
+
messages: converted.messages,
|
|
89
|
+
createdAt: converted.createdAt,
|
|
90
|
+
};
|
|
131
91
|
});
|
|
132
92
|
}
|
|
133
93
|
|
|
@@ -139,7 +99,7 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
139
99
|
* @param {string} [filter.status] - Integration status
|
|
140
100
|
* @returns {Promise<Array>} Array of integration objects (possibly empty)
|
|
141
101
|
*/
|
|
142
|
-
async findIntegrations({ type, status } = {}) {
|
|
102
|
+
async findIntegrations({ type, status, limit, after } = {}) {
|
|
143
103
|
const where = {};
|
|
144
104
|
if (type) {
|
|
145
105
|
where.config = { path: ['type'], equals: type };
|
|
@@ -147,17 +107,30 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
147
107
|
if (status) {
|
|
148
108
|
where.status = status;
|
|
149
109
|
}
|
|
110
|
+
if (limit && after !== undefined && after !== null) {
|
|
111
|
+
where.id = { gt: this._convertId(after) };
|
|
112
|
+
}
|
|
150
113
|
|
|
151
114
|
const integrations = await this.prisma.integration.findMany({
|
|
152
115
|
where,
|
|
153
116
|
include: {
|
|
154
117
|
entities: true,
|
|
155
118
|
},
|
|
119
|
+
...(limit ? { orderBy: { id: 'asc' }, take: limit } : {}),
|
|
156
120
|
});
|
|
157
121
|
|
|
158
122
|
return integrations.map((integration) => {
|
|
159
123
|
const converted = this._convertIntegrationIds(integration);
|
|
160
|
-
return
|
|
124
|
+
return {
|
|
125
|
+
id: converted.id,
|
|
126
|
+
entitiesIds: converted.entities.map((e) => e.id),
|
|
127
|
+
userId: converted.userId,
|
|
128
|
+
config: converted.config,
|
|
129
|
+
version: converted.version,
|
|
130
|
+
status: converted.status,
|
|
131
|
+
messages: converted.messages,
|
|
132
|
+
createdAt: converted.createdAt,
|
|
133
|
+
};
|
|
161
134
|
});
|
|
162
135
|
}
|
|
163
136
|
|
|
@@ -240,7 +213,15 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
240
213
|
}
|
|
241
214
|
|
|
242
215
|
const converted = this._convertIntegrationIds(integration);
|
|
243
|
-
return
|
|
216
|
+
return {
|
|
217
|
+
id: converted.id,
|
|
218
|
+
entitiesIds: converted.entities.map((e) => e.id),
|
|
219
|
+
userId: converted.userId,
|
|
220
|
+
config: converted.config,
|
|
221
|
+
version: converted.version,
|
|
222
|
+
status: converted.status,
|
|
223
|
+
messages: converted.messages,
|
|
224
|
+
};
|
|
244
225
|
}
|
|
245
226
|
|
|
246
227
|
/**
|
|
@@ -259,11 +240,19 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
259
240
|
});
|
|
260
241
|
|
|
261
242
|
if (!integration) {
|
|
262
|
-
throw
|
|
243
|
+
throw new Error(`Integration with id ${id} not found`);
|
|
263
244
|
}
|
|
264
245
|
|
|
265
246
|
const converted = this._convertIntegrationIds(integration);
|
|
266
|
-
return
|
|
247
|
+
return {
|
|
248
|
+
id: converted.id,
|
|
249
|
+
entitiesIds: converted.entities.map((e) => e.id),
|
|
250
|
+
userId: converted.userId,
|
|
251
|
+
config: converted.config,
|
|
252
|
+
version: converted.version,
|
|
253
|
+
status: converted.status,
|
|
254
|
+
messages: converted.messages,
|
|
255
|
+
};
|
|
267
256
|
}
|
|
268
257
|
|
|
269
258
|
/**
|
|
@@ -343,15 +332,12 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
343
332
|
* @param {Array<string>} entities - Array of entity IDs (strings from application layer)
|
|
344
333
|
* @param {string} userId - User ID (string from application layer)
|
|
345
334
|
* @param {Object} config - Integration configuration
|
|
346
|
-
* @param {{organizationId?: (string|null)}} [tenancy] - the organization the
|
|
347
|
-
* integration is created in (ADR-056 §3.6)
|
|
348
335
|
* @returns {Promise<Object>} Created integration object with string IDs
|
|
349
336
|
*/
|
|
350
|
-
async createIntegration(entities, userId, config
|
|
337
|
+
async createIntegration(entities, userId, config) {
|
|
351
338
|
const data = {
|
|
352
339
|
config,
|
|
353
340
|
version: '0.0.0',
|
|
354
|
-
organizationId: this._convertId(tenancy.organizationId ?? null),
|
|
355
341
|
};
|
|
356
342
|
|
|
357
343
|
// PostgreSQL: use nested relations with ID conversion
|
|
@@ -372,7 +358,15 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
372
358
|
});
|
|
373
359
|
|
|
374
360
|
const converted = this._convertIntegrationIds(integration);
|
|
375
|
-
return
|
|
361
|
+
return {
|
|
362
|
+
id: converted.id,
|
|
363
|
+
entitiesIds: converted.entities.map((e) => e.id),
|
|
364
|
+
userId: converted.userId,
|
|
365
|
+
config: converted.config,
|
|
366
|
+
version: converted.version,
|
|
367
|
+
status: converted.status,
|
|
368
|
+
messages: converted.messages,
|
|
369
|
+
};
|
|
376
370
|
}
|
|
377
371
|
|
|
378
372
|
/**
|
|
@@ -395,7 +389,15 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
395
389
|
}
|
|
396
390
|
|
|
397
391
|
const converted = this._convertIntegrationIds(integration);
|
|
398
|
-
return
|
|
392
|
+
return {
|
|
393
|
+
id: converted.id,
|
|
394
|
+
entitiesIds: converted.entities.map((e) => e.id),
|
|
395
|
+
userId: converted.userId,
|
|
396
|
+
config: converted.config,
|
|
397
|
+
version: converted.version,
|
|
398
|
+
status: converted.status,
|
|
399
|
+
messages: converted.messages,
|
|
400
|
+
};
|
|
399
401
|
}
|
|
400
402
|
|
|
401
403
|
/**
|
|
@@ -420,7 +422,15 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
420
422
|
});
|
|
421
423
|
|
|
422
424
|
const converted = this._convertIntegrationIds(integration);
|
|
423
|
-
return
|
|
425
|
+
return {
|
|
426
|
+
id: converted.id,
|
|
427
|
+
entitiesIds: converted.entities.map((e) => e.id),
|
|
428
|
+
userId: converted.userId,
|
|
429
|
+
config: converted.config,
|
|
430
|
+
version: converted.version,
|
|
431
|
+
status: converted.status,
|
|
432
|
+
messages: converted.messages,
|
|
433
|
+
};
|
|
424
434
|
}
|
|
425
435
|
|
|
426
436
|
/**
|
|
@@ -470,7 +480,15 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
|
|
|
470
480
|
|
|
471
481
|
return integrations.map((integration) => {
|
|
472
482
|
const converted = this._convertIntegrationIds(integration);
|
|
473
|
-
return
|
|
483
|
+
return {
|
|
484
|
+
id: converted.id,
|
|
485
|
+
entitiesIds: converted.entities.map((e) => e.id),
|
|
486
|
+
userId: converted.userId,
|
|
487
|
+
config: converted.config,
|
|
488
|
+
version: converted.version,
|
|
489
|
+
status: converted.status,
|
|
490
|
+
messages: converted.messages,
|
|
491
|
+
};
|
|
474
492
|
});
|
|
475
493
|
}
|
|
476
494
|
}
|