@friggframework/core 2.0.0--canary.522.cbd3d5a.0 → 2.0.0--canary.517.35ee143.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/CHANGELOG.md +67 -66
- package/CLAUDE.md +124 -148
- package/README.md +130 -165
- package/admin-scripts/index.js +16 -30
- package/admin-scripts/repositories/{admin-api-key-repository-documentdb.js → admin-process-repository-documentdb.js} +5 -5
- package/admin-scripts/repositories/{admin-api-key-repository-factory.js → admin-process-repository-factory.js} +15 -19
- package/admin-scripts/repositories/admin-process-repository-interface.js +150 -0
- package/admin-scripts/repositories/admin-process-repository-mongo.js +213 -0
- package/admin-scripts/repositories/admin-process-repository-postgres.js +251 -0
- package/admin-scripts/repositories/script-schedule-repository-factory.js +2 -6
- package/admin-scripts/repositories/script-schedule-repository-interface.js +14 -36
- package/admin-scripts/repositories/script-schedule-repository-mongo.js +13 -25
- package/admin-scripts/repositories/script-schedule-repository-postgres.js +13 -25
- package/application/commands/admin-script-commands.js +102 -266
- package/application/commands/integration-commands.js +6 -12
- package/application/index.js +3 -1
- package/assertions/get.js +4 -1
- package/associations/association.js +57 -59
- package/associations/model.js +41 -41
- package/core/CLAUDE.md +156 -222
- package/core/Worker.js +1 -5
- package/credential/repositories/credential-repository-documentdb.js +1 -71
- package/credential/repositories/credential-repository-interface.js +2 -8
- package/credential/repositories/credential-repository-mongo.js +4 -45
- package/credential/repositories/credential-repository-postgres.js +3 -44
- package/credential/repositories/credential-repository.js +4 -6
- package/credential/use-cases/get-credential-for-user.js +3 -21
- package/credential/use-cases/update-authentication-status.js +2 -5
- package/database/MONGODB_TRANSACTION_FIX.md +52 -72
- package/database/adapters/lambda-invoker.js +7 -8
- package/database/config.js +13 -15
- package/database/documentdb-encryption-service.js +13 -29
- package/database/documentdb-utils.js +12 -21
- package/database/encryption/README.md +36 -53
- package/database/encryption/encryption-schema-registry.js +9 -21
- package/database/encryption/field-encryption-service.js +4 -15
- package/database/encryption/logger.js +2 -3
- package/database/encryption/prisma-encryption-extension.js +8 -5
- package/database/index.js +2 -4
- package/database/models/IndividualUser.js +15 -15
- package/database/models/OrganizationUser.js +4 -6
- package/database/models/UserModel.js +2 -2
- package/database/models/WebsocketConnection.js +1 -4
- package/database/mongoose.js +2 -2
- package/database/prisma.js +14 -22
- package/database/repositories/health-check-repository-documentdb.js +7 -22
- package/database/repositories/health-check-repository-factory.js +3 -9
- package/database/repositories/health-check-repository-interface.js +5 -15
- package/database/repositories/health-check-repository-mongodb.js +6 -9
- package/database/repositories/health-check-repository-postgres.js +1 -1
- package/database/repositories/migration-status-repository-s3.js +5 -10
- package/database/use-cases/check-database-health-use-case.js +2 -3
- package/database/use-cases/check-database-state-use-case.js +7 -9
- package/database/use-cases/get-database-state-via-worker-use-case.js +12 -15
- package/database/use-cases/get-migration-status-use-case.js +2 -4
- package/database/use-cases/run-database-migration-use-case.js +9 -41
- package/database/use-cases/test-encryption-use-case.js +5 -4
- package/database/use-cases/trigger-database-migration-use-case.js +8 -9
- package/database/utils/mongodb-collection-utils.js +3 -11
- package/database/utils/mongodb-schema-init.js +4 -10
- package/database/utils/prisma-runner.js +74 -144
- package/database/utils/prisma-schema-parser.js +2 -2
- package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +80 -135
- package/encrypt/Cryptor.js +2 -8
- package/errors/fetch-error.js +1 -1
- package/generated/prisma-mongodb/edge.js +16 -59
- package/generated/prisma-mongodb/index-browser.js +12 -62
- package/generated/prisma-mongodb/index.d.ts +4850 -8136
- package/generated/prisma-mongodb/index.js +16 -59
- package/generated/prisma-mongodb/package.json +1 -1
- package/generated/prisma-mongodb/schema.prisma +33 -75
- package/generated/prisma-mongodb/wasm.js +16 -59
- package/generated/prisma-postgresql/edge.js +15 -59
- package/generated/prisma-postgresql/index-browser.js +11 -62
- package/generated/prisma-postgresql/index.d.ts +5963 -8930
- package/generated/prisma-postgresql/index.js +15 -59
- package/generated/prisma-postgresql/package.json +1 -1
- package/generated/prisma-postgresql/schema.prisma +33 -73
- package/generated/prisma-postgresql/wasm.js +15 -59
- package/handlers/WEBHOOKS.md +81 -104
- package/handlers/app-definition-loader.js +1 -1
- package/handlers/app-handler-helpers.js +2 -14
- package/handlers/backend-utils.js +1 -0
- package/handlers/database-migration-handler.js +45 -64
- package/handlers/middleware/admin-auth.js +53 -0
- package/handlers/routers/HEALTHCHECK.md +135 -170
- package/handlers/routers/auth.js +2 -23
- package/handlers/routers/db-migration.handler.js +3 -2
- package/handlers/routers/db-migration.js +33 -69
- package/handlers/routers/health.js +8 -23
- package/handlers/routers/integration-defined-routers.js +4 -4
- package/handlers/routers/integration-webhook-routers.js +7 -17
- package/handlers/routers/websocket.js +3 -9
- package/handlers/use-cases/check-integrations-health-use-case.js +6 -13
- package/handlers/workers/db-migration.js +26 -54
- package/index.js +9 -5
- package/integrations/WEBHOOK-QUICKSTART.md +14 -21
- package/integrations/index.js +0 -4
- package/integrations/integration-base.js +6 -9
- package/integrations/integration-router.js +146 -1817
- package/integrations/options.js +20 -47
- package/integrations/repositories/integration-repository-documentdb.js +24 -53
- package/integrations/repositories/integration-repository-factory.js +2 -6
- package/integrations/repositories/integration-repository-interface.js +9 -27
- package/integrations/repositories/integration-repository-postgres.js +3 -3
- package/integrations/repositories/process-repository-factory.js +1 -0
- package/integrations/repositories/process-repository-interface.js +5 -9
- package/integrations/repositories/process-repository-mongo.js +3 -7
- package/integrations/repositories/process-repository-postgres.js +2 -2
- package/integrations/tests/doubles/config-capturing-integration.js +8 -9
- package/integrations/tests/doubles/dummy-integration-class.js +8 -81
- package/integrations/tests/doubles/test-integration-repository.js +11 -51
- package/integrations/use-cases/create-integration.js +32 -36
- package/integrations/use-cases/create-process.js +9 -20
- package/integrations/use-cases/delete-integration-for-user.js +4 -5
- package/integrations/use-cases/get-integration-for-user.js +10 -25
- package/integrations/use-cases/get-integration-instance-by-definition.js +7 -13
- package/integrations/use-cases/get-integrations-for-user.js +1 -4
- package/integrations/use-cases/get-possible-integrations.js +1 -1
- package/integrations/use-cases/get-process.js +6 -5
- package/integrations/use-cases/index.js +1 -3
- package/integrations/use-cases/load-integration-context.js +5 -1
- package/integrations/use-cases/update-process-state.js +8 -10
- package/integrations/utils/map-integration-dto.js +3 -9
- package/jest-setup.js +1 -1
- package/jest-teardown.js +1 -1
- package/lambda/TimeoutCatcher.js +30 -32
- package/lambda/index.js +1 -1
- package/logs/index.js +3 -3
- package/modules/module.js +1 -3
- package/modules/repositories/module-repository-documentdb.js +48 -114
- package/modules/repositories/module-repository-interface.js +0 -13
- package/modules/repositories/module-repository-mongo.js +6 -46
- package/modules/repositories/module-repository-postgres.js +6 -48
- package/modules/repositories/module-repository.js +1 -34
- package/modules/requester/api-key.js +2 -0
- package/modules/requester/basic.js +1 -0
- package/modules/requester/oauth-2.js +2 -3
- package/modules/test/mock-api/definition.js +10 -15
- package/modules/test/mock-api/mocks/hubspot.js +36 -36
- package/modules/tests/doubles/test-module-factory.js +4 -10
- package/modules/tests/doubles/test-module-repository.js +1 -1
- package/modules/use-cases/get-entities-for-user.js +1 -1
- package/modules/use-cases/get-entity-options-by-id.js +6 -8
- package/modules/use-cases/get-module.js +9 -12
- package/modules/use-cases/process-authorization-callback.js +6 -12
- package/modules/use-cases/refresh-entity-options.js +6 -8
- package/modules/use-cases/test-module-auth.js +6 -8
- package/modules/utils/map-module-dto.js +2 -2
- package/package.json +5 -7
- package/prisma-mongodb/schema.prisma +33 -75
- package/prisma-postgresql/schema.prisma +33 -73
- package/queues/queuer-util.js +1 -5
- package/syncs/model.js +51 -51
- package/syncs/repositories/sync-repository-documentdb.js +19 -39
- package/syncs/repositories/sync-repository-interface.js +2 -6
- package/syncs/repositories/sync-repository-postgres.js +13 -19
- package/syncs/sync.js +100 -104
- package/token/repositories/token-repository-factory.js +3 -1
- package/types/assertions/index.d.ts +72 -72
- package/types/associations/index.d.ts +57 -57
- package/types/core/index.d.ts +53 -59
- package/types/database/index.d.ts +2 -2
- package/types/encrypt/index.d.ts +3 -3
- package/types/errors/index.d.ts +54 -61
- package/types/eslint-config/index.d.ts +40 -40
- package/types/integrations/index.d.ts +183 -185
- package/types/lambda/index.d.ts +26 -26
- package/types/logs/index.d.ts +4 -4
- package/types/module-plugin/index.d.ts +237 -239
- package/types/prettier-config/index.d.ts +5 -5
- package/types/syncs/index.d.ts +108 -102
- package/types/test-environment/index.d.ts +14 -14
- package/types/tsconfig.json +93 -95
- package/user/tests/doubles/test-user-repository.js +2 -5
- package/user/use-cases/authenticate-user.js +4 -2
- package/user/use-cases/authenticate-with-shared-secret.js +1 -1
- package/user/use-cases/create-individual-user.js +7 -8
- package/user/use-cases/create-organization-user.js +1 -1
- package/user/use-cases/create-token-for-user-id.js +1 -1
- package/user/use-cases/get-user-from-adopter-jwt.js +2 -0
- package/user/use-cases/get-user-from-bearer-token.js +3 -7
- package/user/use-cases/get-user-from-x-frigg-headers.js +11 -14
- package/user/use-cases/login-user.js +8 -8
- package/user/user.js +4 -18
- package/utils/backend-path.js +2 -2
- package/utils/index.js +1 -4
- package/websocket/repositories/websocket-connection-repository-documentdb.js +8 -21
- package/websocket/repositories/websocket-connection-repository-mongo.js +4 -8
- package/websocket/repositories/websocket-connection-repository-postgres.js +4 -8
- package/websocket/repositories/websocket-connection-repository.js +4 -8
- package/admin-scripts/repositories/admin-api-key-repository-interface.js +0 -121
- package/admin-scripts/repositories/admin-api-key-repository-mongo.js +0 -155
- package/admin-scripts/repositories/admin-api-key-repository-postgres.js +0 -189
- package/admin-scripts/repositories/script-execution-repository-documentdb.js +0 -21
- package/admin-scripts/repositories/script-execution-repository-factory.js +0 -55
- package/admin-scripts/repositories/script-execution-repository-interface.js +0 -193
- package/admin-scripts/repositories/script-execution-repository-mongo.js +0 -278
- package/admin-scripts/repositories/script-execution-repository-postgres.js +0 -320
- package/credential/credential-router.js +0 -262
- package/credential/use-cases/delete-credential-for-user.js +0 -50
- package/credential/use-cases/list-credentials-for-user.js +0 -31
- package/credential/use-cases/reauthorize-credential.js +0 -103
- package/handlers/routers/admin.js +0 -450
- package/handlers/routers/docs.js +0 -180
- package/handlers/routers/middleware/loadUser.js +0 -39
- package/handlers/routers/middleware/requireAdmin.js +0 -41
- package/handlers/routers/middleware/requireLoggedInUser.js +0 -19
- package/integrations/use-cases/execute-proxy-request.js +0 -564
- package/modules/domain/entities/AuthorizationSession.js +0 -131
- package/modules/domain/entities/index.js +0 -10
- package/modules/repositories/authorization-session-repository-factory.js +0 -55
- package/modules/repositories/authorization-session-repository-interface.js +0 -75
- package/modules/repositories/authorization-session-repository-mongo.js +0 -169
- package/modules/repositories/authorization-session-repository-postgres.js +0 -170
- package/modules/use-cases/delete-module-entity.js +0 -23
- package/modules/use-cases/get-authorization-requirements.js +0 -110
- package/modules/use-cases/get-module-entity-by-id.js +0 -16
- package/modules/use-cases/process-authorization-step.js +0 -160
- package/modules/use-cases/start-authorization-session.js +0 -86
- package/modules/use-cases/update-module-entity.js +0 -27
- package/openapi/openapi-spec-generator.js +0 -370
- package/openapi/openapi-v1.yaml +0 -1360
- package/openapi/openapi-v2.yaml +0 -1535
- package/user/use-cases/delete-user.js +0 -47
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
const { prisma } = require('../../database/prisma');
|
|
2
|
-
const {
|
|
3
|
-
AdminApiKeyRepositoryInterface,
|
|
4
|
-
} = require('./admin-api-key-repository-interface');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* PostgreSQL Admin API Key Repository Adapter
|
|
8
|
-
* Handles admin API key persistence using Prisma with PostgreSQL
|
|
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 AdminApiKeyRepositoryPostgres extends AdminApiKeyRepositoryInterface {
|
|
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
|
-
_convertId(id) {
|
|
29
|
-
if (id === null || id === undefined) return id;
|
|
30
|
-
const parsed = Number.parseInt(id, 10);
|
|
31
|
-
if (Number.isNaN(parsed)) {
|
|
32
|
-
throw new Error(`Invalid ID: ${id} cannot be converted to integer`);
|
|
33
|
-
}
|
|
34
|
-
return parsed;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Convert API key object IDs to strings
|
|
39
|
-
* @private
|
|
40
|
-
* @param {Object|null} apiKey - API key object from database
|
|
41
|
-
* @returns {Object|null} API key with string IDs
|
|
42
|
-
*/
|
|
43
|
-
_convertApiKeyIds(apiKey) {
|
|
44
|
-
if (!apiKey) return apiKey;
|
|
45
|
-
return {
|
|
46
|
-
...apiKey,
|
|
47
|
-
id: apiKey.id?.toString(),
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Create a new admin API key
|
|
53
|
-
*
|
|
54
|
-
* @param {Object} params - API key creation parameters
|
|
55
|
-
* @param {string} params.name - Human-readable name for the key
|
|
56
|
-
* @param {string} params.keyHash - bcrypt hash of the raw key
|
|
57
|
-
* @param {string} params.keyLast4 - Last 4 characters of key (for display)
|
|
58
|
-
* @param {string[]} params.scopes - Array of permission scopes
|
|
59
|
-
* @param {Date} [params.expiresAt] - Optional expiration date
|
|
60
|
-
* @param {string} [params.createdBy] - Optional identifier of creator
|
|
61
|
-
* @returns {Promise<Object>} The created API key record with string ID
|
|
62
|
-
*/
|
|
63
|
-
async createApiKey({
|
|
64
|
-
name,
|
|
65
|
-
keyHash,
|
|
66
|
-
keyLast4,
|
|
67
|
-
scopes,
|
|
68
|
-
expiresAt,
|
|
69
|
-
createdBy,
|
|
70
|
-
}) {
|
|
71
|
-
const apiKey = await this.prisma.adminApiKey.create({
|
|
72
|
-
data: {
|
|
73
|
-
name,
|
|
74
|
-
keyHash,
|
|
75
|
-
keyLast4,
|
|
76
|
-
scopes,
|
|
77
|
-
expiresAt,
|
|
78
|
-
createdBy,
|
|
79
|
-
},
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
return this._convertApiKeyIds(apiKey);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Find an API key by its bcrypt hash
|
|
87
|
-
* Used during authentication to validate incoming keys
|
|
88
|
-
*
|
|
89
|
-
* @param {string} keyHash - The bcrypt hash to search for
|
|
90
|
-
* @returns {Promise<Object|null>} The API key record with string ID or null if not found
|
|
91
|
-
*/
|
|
92
|
-
async findApiKeyByHash(keyHash) {
|
|
93
|
-
const apiKey = await this.prisma.adminApiKey.findUnique({
|
|
94
|
-
where: { keyHash },
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
return this._convertApiKeyIds(apiKey);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Find an API key by its ID
|
|
102
|
-
*
|
|
103
|
-
* @param {string|number} id - The API key ID
|
|
104
|
-
* @returns {Promise<Object|null>} The API key record with string ID or null if not found
|
|
105
|
-
*/
|
|
106
|
-
async findApiKeyById(id) {
|
|
107
|
-
const intId = this._convertId(id);
|
|
108
|
-
const apiKey = await this.prisma.adminApiKey.findUnique({
|
|
109
|
-
where: { id: intId },
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
return this._convertApiKeyIds(apiKey);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Find all active (non-expired, non-deactivated) API keys
|
|
117
|
-
* Used during authentication to check all valid keys
|
|
118
|
-
*
|
|
119
|
-
* @returns {Promise<Array>} Array of active API key records with string IDs
|
|
120
|
-
*/
|
|
121
|
-
async findActiveApiKeys() {
|
|
122
|
-
const now = new Date();
|
|
123
|
-
const apiKeys = await this.prisma.adminApiKey.findMany({
|
|
124
|
-
where: {
|
|
125
|
-
isActive: true,
|
|
126
|
-
OR: [{ expiresAt: null }, { expiresAt: { gt: now } }],
|
|
127
|
-
},
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
return apiKeys.map((apiKey) => this._convertApiKeyIds(apiKey));
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Update the lastUsedAt timestamp for an API key
|
|
135
|
-
* Called after successful authentication
|
|
136
|
-
*
|
|
137
|
-
* @param {string|number} id - The API key ID
|
|
138
|
-
* @returns {Promise<Object>} Updated API key record with string ID
|
|
139
|
-
*/
|
|
140
|
-
async updateApiKeyLastUsed(id) {
|
|
141
|
-
const intId = this._convertId(id);
|
|
142
|
-
const apiKey = await this.prisma.adminApiKey.update({
|
|
143
|
-
where: { id: intId },
|
|
144
|
-
data: {
|
|
145
|
-
lastUsedAt: new Date(),
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
return this._convertApiKeyIds(apiKey);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Deactivate an API key (soft delete)
|
|
154
|
-
* Sets isActive to false, preventing further use
|
|
155
|
-
*
|
|
156
|
-
* @param {string|number} id - The API key ID
|
|
157
|
-
* @returns {Promise<Object>} Updated API key record with string ID
|
|
158
|
-
*/
|
|
159
|
-
async deactivateApiKey(id) {
|
|
160
|
-
const intId = this._convertId(id);
|
|
161
|
-
const apiKey = await this.prisma.adminApiKey.update({
|
|
162
|
-
where: { id: intId },
|
|
163
|
-
data: {
|
|
164
|
-
isActive: false,
|
|
165
|
-
},
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
return this._convertApiKeyIds(apiKey);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Delete an API key (hard delete)
|
|
173
|
-
* Permanently removes the key from the database
|
|
174
|
-
*
|
|
175
|
-
* @param {string|number} id - The API key ID
|
|
176
|
-
* @returns {Promise<Object>} Deletion result
|
|
177
|
-
*/
|
|
178
|
-
async deleteApiKey(id) {
|
|
179
|
-
const intId = this._convertId(id);
|
|
180
|
-
await this.prisma.adminApiKey.delete({
|
|
181
|
-
where: { id: intId },
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
// Return Mongoose-compatible result
|
|
185
|
-
return { acknowledged: true, deletedCount: 1 };
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
module.exports = { AdminApiKeyRepositoryPostgres };
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
const {
|
|
2
|
-
ScriptExecutionRepositoryMongo,
|
|
3
|
-
} = require('./script-execution-repository-mongo');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* DocumentDB Script Execution Repository Adapter
|
|
7
|
-
* Extends MongoDB implementation since DocumentDB uses the same Prisma client
|
|
8
|
-
*
|
|
9
|
-
* DocumentDB-specific characteristics:
|
|
10
|
-
* - Uses MongoDB-compatible API
|
|
11
|
-
* - Prisma client handles the connection
|
|
12
|
-
* - IDs are strings with ObjectId format
|
|
13
|
-
* - All operations identical to MongoDB implementation
|
|
14
|
-
*/
|
|
15
|
-
class ScriptExecutionRepositoryDocumentDB extends ScriptExecutionRepositoryMongo {
|
|
16
|
-
constructor() {
|
|
17
|
-
super();
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
module.exports = { ScriptExecutionRepositoryDocumentDB };
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
const {
|
|
2
|
-
ScriptExecutionRepositoryMongo,
|
|
3
|
-
} = require('./script-execution-repository-mongo');
|
|
4
|
-
const {
|
|
5
|
-
ScriptExecutionRepositoryPostgres,
|
|
6
|
-
} = require('./script-execution-repository-postgres');
|
|
7
|
-
const {
|
|
8
|
-
ScriptExecutionRepositoryDocumentDB,
|
|
9
|
-
} = require('./script-execution-repository-documentdb');
|
|
10
|
-
const config = require('../../database/config');
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Script Execution Repository Factory
|
|
14
|
-
* Creates the appropriate repository adapter based on database type
|
|
15
|
-
*
|
|
16
|
-
* This implements the Factory pattern for Hexagonal Architecture:
|
|
17
|
-
* - Reads database type from app definition (backend/index.js)
|
|
18
|
-
* - Returns correct adapter (MongoDB, DocumentDB, or PostgreSQL)
|
|
19
|
-
* - Provides clear error for unsupported databases
|
|
20
|
-
*
|
|
21
|
-
* Usage:
|
|
22
|
-
* ```javascript
|
|
23
|
-
* const repository = createScriptExecutionRepository();
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* @returns {ScriptExecutionRepositoryInterface} Configured repository adapter
|
|
27
|
-
* @throws {Error} If database type is not supported
|
|
28
|
-
*/
|
|
29
|
-
function createScriptExecutionRepository() {
|
|
30
|
-
const dbType = config.DB_TYPE;
|
|
31
|
-
|
|
32
|
-
switch (dbType) {
|
|
33
|
-
case 'mongodb':
|
|
34
|
-
return new ScriptExecutionRepositoryMongo();
|
|
35
|
-
|
|
36
|
-
case 'postgresql':
|
|
37
|
-
return new ScriptExecutionRepositoryPostgres();
|
|
38
|
-
|
|
39
|
-
case 'documentdb':
|
|
40
|
-
return new ScriptExecutionRepositoryDocumentDB();
|
|
41
|
-
|
|
42
|
-
default:
|
|
43
|
-
throw new Error(
|
|
44
|
-
`Unsupported database type: ${dbType}. Supported values: 'mongodb', 'documentdb', 'postgresql'`
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
module.exports = {
|
|
50
|
-
createScriptExecutionRepository,
|
|
51
|
-
// Export adapters for direct testing
|
|
52
|
-
ScriptExecutionRepositoryMongo,
|
|
53
|
-
ScriptExecutionRepositoryPostgres,
|
|
54
|
-
ScriptExecutionRepositoryDocumentDB,
|
|
55
|
-
};
|
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Script Execution Repository Interface
|
|
3
|
-
* Abstract base class defining the contract for script execution persistence adapters
|
|
4
|
-
*
|
|
5
|
-
* This follows the Port in Hexagonal Architecture:
|
|
6
|
-
* - Domain layer depends on this abstraction
|
|
7
|
-
* - Concrete adapters implement this interface
|
|
8
|
-
* - Use cases receive repositories via dependency injection
|
|
9
|
-
*
|
|
10
|
-
* Script executions track the lifecycle of admin script runs, including:
|
|
11
|
-
* - Input parameters and output results
|
|
12
|
-
* - Execution status and error details
|
|
13
|
-
* - Performance metrics
|
|
14
|
-
* - Audit trail (who triggered, when, from where)
|
|
15
|
-
* - Real-time logs
|
|
16
|
-
*
|
|
17
|
-
* @abstract
|
|
18
|
-
*/
|
|
19
|
-
class ScriptExecutionRepositoryInterface {
|
|
20
|
-
/**
|
|
21
|
-
* Create a new script execution record
|
|
22
|
-
*
|
|
23
|
-
* @param {Object} params - Execution creation parameters
|
|
24
|
-
* @param {string} params.scriptName - Name of the script being executed
|
|
25
|
-
* @param {string} [params.scriptVersion] - Version of the script
|
|
26
|
-
* @param {string} params.trigger - Trigger type ('MANUAL', 'SCHEDULED', 'QUEUE', 'WEBHOOK')
|
|
27
|
-
* @param {string} [params.mode] - Execution mode ('sync' or 'async', default 'async')
|
|
28
|
-
* @param {Object} [params.input] - Input parameters for the script
|
|
29
|
-
* @param {Object} [params.audit] - Audit information
|
|
30
|
-
* @param {string} [params.audit.apiKeyName] - Name of API key used
|
|
31
|
-
* @param {string} [params.audit.apiKeyLast4] - Last 4 chars of API key
|
|
32
|
-
* @param {string} [params.audit.ipAddress] - IP address of requester
|
|
33
|
-
* @returns {Promise<Object>} The created execution record
|
|
34
|
-
* @abstract
|
|
35
|
-
*/
|
|
36
|
-
async createExecution({
|
|
37
|
-
scriptName,
|
|
38
|
-
scriptVersion,
|
|
39
|
-
trigger,
|
|
40
|
-
mode,
|
|
41
|
-
input,
|
|
42
|
-
audit,
|
|
43
|
-
}) {
|
|
44
|
-
throw new Error(
|
|
45
|
-
'Method createExecution must be implemented by subclass'
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Find an execution by its ID
|
|
51
|
-
*
|
|
52
|
-
* @param {string|number} id - The execution ID
|
|
53
|
-
* @returns {Promise<Object|null>} The execution record or null if not found
|
|
54
|
-
* @abstract
|
|
55
|
-
*/
|
|
56
|
-
async findExecutionById(id) {
|
|
57
|
-
throw new Error(
|
|
58
|
-
'Method findExecutionById must be implemented by subclass'
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Find all executions for a specific script
|
|
64
|
-
*
|
|
65
|
-
* @param {string} scriptName - The script name to filter by
|
|
66
|
-
* @param {Object} [options] - Query options
|
|
67
|
-
* @param {number} [options.limit] - Maximum number of results
|
|
68
|
-
* @param {number} [options.offset] - Number of results to skip
|
|
69
|
-
* @param {string} [options.sortBy] - Field to sort by
|
|
70
|
-
* @param {string} [options.sortOrder] - Sort order ('asc' or 'desc')
|
|
71
|
-
* @returns {Promise<Array>} Array of execution records
|
|
72
|
-
* @abstract
|
|
73
|
-
*/
|
|
74
|
-
async findExecutionsByScriptName(scriptName, options = {}) {
|
|
75
|
-
throw new Error(
|
|
76
|
-
'Method findExecutionsByScriptName must be implemented by subclass'
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Find all executions with a specific status
|
|
82
|
-
*
|
|
83
|
-
* @param {string} status - Status to filter by ('PENDING', 'RUNNING', 'COMPLETED', 'FAILED', 'TIMEOUT', 'CANCELLED')
|
|
84
|
-
* @param {Object} [options] - Query options
|
|
85
|
-
* @param {number} [options.limit] - Maximum number of results
|
|
86
|
-
* @param {number} [options.offset] - Number of results to skip
|
|
87
|
-
* @param {string} [options.sortBy] - Field to sort by
|
|
88
|
-
* @param {string} [options.sortOrder] - Sort order ('asc' or 'desc')
|
|
89
|
-
* @returns {Promise<Array>} Array of execution records
|
|
90
|
-
* @abstract
|
|
91
|
-
*/
|
|
92
|
-
async findExecutionsByStatus(status, options = {}) {
|
|
93
|
-
throw new Error(
|
|
94
|
-
'Method findExecutionsByStatus must be implemented by subclass'
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Update the status of an execution
|
|
100
|
-
*
|
|
101
|
-
* @param {string|number} id - The execution ID
|
|
102
|
-
* @param {string} status - New status value
|
|
103
|
-
* @returns {Promise<Object>} Updated execution record
|
|
104
|
-
* @abstract
|
|
105
|
-
*/
|
|
106
|
-
async updateExecutionStatus(id, status) {
|
|
107
|
-
throw new Error(
|
|
108
|
-
'Method updateExecutionStatus must be implemented by subclass'
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Update the output result of an execution
|
|
114
|
-
*
|
|
115
|
-
* @param {string|number} id - The execution ID
|
|
116
|
-
* @param {Object} output - Output data from the script
|
|
117
|
-
* @returns {Promise<Object>} Updated execution record
|
|
118
|
-
* @abstract
|
|
119
|
-
*/
|
|
120
|
-
async updateExecutionOutput(id, output) {
|
|
121
|
-
throw new Error(
|
|
122
|
-
'Method updateExecutionOutput must be implemented by subclass'
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Update the error details of a failed execution
|
|
128
|
-
*
|
|
129
|
-
* @param {string|number} id - The execution ID
|
|
130
|
-
* @param {Object} error - Error information
|
|
131
|
-
* @param {string} error.name - Error name/type
|
|
132
|
-
* @param {string} error.message - Error message
|
|
133
|
-
* @param {string} [error.stack] - Error stack trace
|
|
134
|
-
* @returns {Promise<Object>} Updated execution record
|
|
135
|
-
* @abstract
|
|
136
|
-
*/
|
|
137
|
-
async updateExecutionError(id, error) {
|
|
138
|
-
throw new Error(
|
|
139
|
-
'Method updateExecutionError must be implemented by subclass'
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Update the performance metrics of an execution
|
|
145
|
-
*
|
|
146
|
-
* @param {string|number} id - The execution ID
|
|
147
|
-
* @param {Object} metrics - Performance metrics
|
|
148
|
-
* @param {Date} [metrics.startTime] - Execution start time
|
|
149
|
-
* @param {Date} [metrics.endTime] - Execution end time
|
|
150
|
-
* @param {number} [metrics.durationMs] - Duration in milliseconds
|
|
151
|
-
* @returns {Promise<Object>} Updated execution record
|
|
152
|
-
* @abstract
|
|
153
|
-
*/
|
|
154
|
-
async updateExecutionMetrics(id, metrics) {
|
|
155
|
-
throw new Error(
|
|
156
|
-
'Method updateExecutionMetrics must be implemented by subclass'
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Append a log entry to an execution's log array
|
|
162
|
-
*
|
|
163
|
-
* @param {string|number} id - The execution ID
|
|
164
|
-
* @param {Object} logEntry - Log entry to append
|
|
165
|
-
* @param {string} logEntry.level - Log level ('debug', 'info', 'warn', 'error')
|
|
166
|
-
* @param {string} logEntry.message - Log message
|
|
167
|
-
* @param {Object} [logEntry.data] - Additional log data
|
|
168
|
-
* @param {string} logEntry.timestamp - ISO timestamp
|
|
169
|
-
* @returns {Promise<Object>} Updated execution record
|
|
170
|
-
* @abstract
|
|
171
|
-
*/
|
|
172
|
-
async appendExecutionLog(id, logEntry) {
|
|
173
|
-
throw new Error(
|
|
174
|
-
'Method appendExecutionLog must be implemented by subclass'
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Delete all executions older than a specific date
|
|
180
|
-
* Used for cleanup and retention policies
|
|
181
|
-
*
|
|
182
|
-
* @param {Date} date - Delete executions older than this date
|
|
183
|
-
* @returns {Promise<Object>} Deletion result with count
|
|
184
|
-
* @abstract
|
|
185
|
-
*/
|
|
186
|
-
async deleteExecutionsOlderThan(date) {
|
|
187
|
-
throw new Error(
|
|
188
|
-
'Method deleteExecutionsOlderThan must be implemented by subclass'
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
module.exports = { ScriptExecutionRepositoryInterface };
|