@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,278 +0,0 @@
|
|
|
1
|
-
const { prisma } = require('../../database/prisma');
|
|
2
|
-
const {
|
|
3
|
-
ScriptExecutionRepositoryInterface,
|
|
4
|
-
} = require('./script-execution-repository-interface');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* MongoDB Script Execution Repository Adapter
|
|
8
|
-
* Handles script execution persistence using Prisma with MongoDB
|
|
9
|
-
*
|
|
10
|
-
* MongoDB-specific characteristics:
|
|
11
|
-
* - IDs are strings with @db.ObjectId
|
|
12
|
-
* - logs field is Json[] - supports push operations
|
|
13
|
-
* - Audit fields stored as separate columns
|
|
14
|
-
*/
|
|
15
|
-
class ScriptExecutionRepositoryMongo extends ScriptExecutionRepositoryInterface {
|
|
16
|
-
constructor() {
|
|
17
|
-
super();
|
|
18
|
-
this.prisma = prisma;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Create a new script execution record
|
|
23
|
-
*
|
|
24
|
-
* @param {Object} params - Execution creation parameters
|
|
25
|
-
* @param {string} params.scriptName - Name of the script being executed
|
|
26
|
-
* @param {string} [params.scriptVersion] - Version of the script
|
|
27
|
-
* @param {string} params.trigger - Trigger type
|
|
28
|
-
* @param {string} [params.mode] - Execution mode ('sync' or 'async', default 'async')
|
|
29
|
-
* @param {Object} [params.input] - Input parameters for the script
|
|
30
|
-
* @param {Object} [params.audit] - Audit information
|
|
31
|
-
* @param {string} [params.audit.apiKeyName] - Name of API key used
|
|
32
|
-
* @param {string} [params.audit.apiKeyLast4] - Last 4 chars of API key
|
|
33
|
-
* @param {string} [params.audit.ipAddress] - IP address of requester
|
|
34
|
-
* @returns {Promise<Object>} The created execution record
|
|
35
|
-
*/
|
|
36
|
-
async createExecution({
|
|
37
|
-
scriptName,
|
|
38
|
-
scriptVersion,
|
|
39
|
-
trigger,
|
|
40
|
-
mode,
|
|
41
|
-
input,
|
|
42
|
-
audit,
|
|
43
|
-
}) {
|
|
44
|
-
const data = {
|
|
45
|
-
scriptName,
|
|
46
|
-
scriptVersion,
|
|
47
|
-
trigger,
|
|
48
|
-
mode: mode || 'async',
|
|
49
|
-
input,
|
|
50
|
-
logs: [],
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// Map audit object to separate fields
|
|
54
|
-
if (audit) {
|
|
55
|
-
if (audit.apiKeyName) data.auditApiKeyName = audit.apiKeyName;
|
|
56
|
-
if (audit.apiKeyLast4) data.auditApiKeyLast4 = audit.apiKeyLast4;
|
|
57
|
-
if (audit.ipAddress) data.auditIpAddress = audit.ipAddress;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const execution = await this.prisma.scriptExecution.create({
|
|
61
|
-
data,
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
return execution;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Find an execution by its ID
|
|
69
|
-
*
|
|
70
|
-
* @param {string} id - The execution ID
|
|
71
|
-
* @returns {Promise<Object|null>} The execution record or null if not found
|
|
72
|
-
*/
|
|
73
|
-
async findExecutionById(id) {
|
|
74
|
-
const execution = await this.prisma.scriptExecution.findUnique({
|
|
75
|
-
where: { id },
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
return execution;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Find all executions for a specific script
|
|
83
|
-
*
|
|
84
|
-
* @param {string} scriptName - The script name to filter by
|
|
85
|
-
* @param {Object} [options] - Query options
|
|
86
|
-
* @param {number} [options.limit] - Maximum number of results
|
|
87
|
-
* @param {number} [options.offset] - Number of results to skip
|
|
88
|
-
* @param {string} [options.sortBy] - Field to sort by
|
|
89
|
-
* @param {string} [options.sortOrder] - Sort order ('asc' or 'desc')
|
|
90
|
-
* @returns {Promise<Array>} Array of execution records
|
|
91
|
-
*/
|
|
92
|
-
async findExecutionsByScriptName(scriptName, options = {}) {
|
|
93
|
-
const {
|
|
94
|
-
limit,
|
|
95
|
-
offset,
|
|
96
|
-
sortBy = 'createdAt',
|
|
97
|
-
sortOrder = 'desc',
|
|
98
|
-
} = options;
|
|
99
|
-
|
|
100
|
-
const executions = await this.prisma.scriptExecution.findMany({
|
|
101
|
-
where: { scriptName },
|
|
102
|
-
orderBy: { [sortBy]: sortOrder },
|
|
103
|
-
take: limit,
|
|
104
|
-
skip: offset,
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
return executions;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Find all executions with a specific status
|
|
112
|
-
*
|
|
113
|
-
* @param {string} status - Status to filter by
|
|
114
|
-
* @param {Object} [options] - Query options
|
|
115
|
-
* @param {number} [options.limit] - Maximum number of results
|
|
116
|
-
* @param {number} [options.offset] - Number of results to skip
|
|
117
|
-
* @param {string} [options.sortBy] - Field to sort by
|
|
118
|
-
* @param {string} [options.sortOrder] - Sort order ('asc' or 'desc')
|
|
119
|
-
* @returns {Promise<Array>} Array of execution records
|
|
120
|
-
*/
|
|
121
|
-
async findExecutionsByStatus(status, options = {}) {
|
|
122
|
-
const {
|
|
123
|
-
limit,
|
|
124
|
-
offset,
|
|
125
|
-
sortBy = 'createdAt',
|
|
126
|
-
sortOrder = 'desc',
|
|
127
|
-
} = options;
|
|
128
|
-
|
|
129
|
-
const executions = await this.prisma.scriptExecution.findMany({
|
|
130
|
-
where: { status },
|
|
131
|
-
orderBy: { [sortBy]: sortOrder },
|
|
132
|
-
take: limit,
|
|
133
|
-
skip: offset,
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
return executions;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Update the status of an execution
|
|
141
|
-
*
|
|
142
|
-
* @param {string} id - The execution ID
|
|
143
|
-
* @param {string} status - New status value
|
|
144
|
-
* @returns {Promise<Object>} Updated execution record
|
|
145
|
-
*/
|
|
146
|
-
async updateExecutionStatus(id, status) {
|
|
147
|
-
const execution = await this.prisma.scriptExecution.update({
|
|
148
|
-
where: { id },
|
|
149
|
-
data: { status },
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
return execution;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Update the output result of an execution
|
|
157
|
-
*
|
|
158
|
-
* @param {string} id - The execution ID
|
|
159
|
-
* @param {Object} output - Output data from the script
|
|
160
|
-
* @returns {Promise<Object>} Updated execution record
|
|
161
|
-
*/
|
|
162
|
-
async updateExecutionOutput(id, output) {
|
|
163
|
-
const execution = await this.prisma.scriptExecution.update({
|
|
164
|
-
where: { id },
|
|
165
|
-
data: { output },
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
return execution;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Update the error details of a failed execution
|
|
173
|
-
*
|
|
174
|
-
* @param {string} id - The execution ID
|
|
175
|
-
* @param {Object} error - Error information
|
|
176
|
-
* @param {string} error.name - Error name/type
|
|
177
|
-
* @param {string} error.message - Error message
|
|
178
|
-
* @param {string} [error.stack] - Error stack trace
|
|
179
|
-
* @returns {Promise<Object>} Updated execution record
|
|
180
|
-
*/
|
|
181
|
-
async updateExecutionError(id, error) {
|
|
182
|
-
const execution = await this.prisma.scriptExecution.update({
|
|
183
|
-
where: { id },
|
|
184
|
-
data: {
|
|
185
|
-
errorName: error.name,
|
|
186
|
-
errorMessage: error.message,
|
|
187
|
-
errorStack: error.stack,
|
|
188
|
-
},
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
return execution;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Update the performance metrics of an execution
|
|
196
|
-
*
|
|
197
|
-
* @param {string} id - The execution ID
|
|
198
|
-
* @param {Object} metrics - Performance metrics
|
|
199
|
-
* @param {Date} [metrics.startTime] - Execution start time
|
|
200
|
-
* @param {Date} [metrics.endTime] - Execution end time
|
|
201
|
-
* @param {number} [metrics.durationMs] - Duration in milliseconds
|
|
202
|
-
* @returns {Promise<Object>} Updated execution record
|
|
203
|
-
*/
|
|
204
|
-
async updateExecutionMetrics(id, metrics) {
|
|
205
|
-
const data = {};
|
|
206
|
-
if (metrics.startTime !== undefined)
|
|
207
|
-
data.metricsStartTime = metrics.startTime;
|
|
208
|
-
if (metrics.endTime !== undefined)
|
|
209
|
-
data.metricsEndTime = metrics.endTime;
|
|
210
|
-
if (metrics.durationMs !== undefined)
|
|
211
|
-
data.metricsDurationMs = metrics.durationMs;
|
|
212
|
-
|
|
213
|
-
const execution = await this.prisma.scriptExecution.update({
|
|
214
|
-
where: { id },
|
|
215
|
-
data,
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
return execution;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Append a log entry to an execution's log array
|
|
223
|
-
*
|
|
224
|
-
* @param {string} id - The execution ID
|
|
225
|
-
* @param {Object} logEntry - Log entry to append
|
|
226
|
-
* @param {string} logEntry.level - Log level ('debug', 'info', 'warn', 'error')
|
|
227
|
-
* @param {string} logEntry.message - Log message
|
|
228
|
-
* @param {Object} [logEntry.data] - Additional log data
|
|
229
|
-
* @param {string} logEntry.timestamp - ISO timestamp
|
|
230
|
-
* @returns {Promise<Object>} Updated execution record
|
|
231
|
-
*/
|
|
232
|
-
async appendExecutionLog(id, logEntry) {
|
|
233
|
-
// Get current execution
|
|
234
|
-
const execution = await this.prisma.scriptExecution.findUnique({
|
|
235
|
-
where: { id },
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
if (!execution) {
|
|
239
|
-
throw new Error(`Execution ${id} not found`);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Append log entry to logs array (copy to avoid mutating original)
|
|
243
|
-
const logs = Array.isArray(execution.logs) ? [...execution.logs] : [];
|
|
244
|
-
logs.push(logEntry);
|
|
245
|
-
|
|
246
|
-
// Update with new logs array
|
|
247
|
-
const updated = await this.prisma.scriptExecution.update({
|
|
248
|
-
where: { id },
|
|
249
|
-
data: { logs },
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
return updated;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Delete all executions older than a specific date
|
|
257
|
-
* Used for cleanup and retention policies
|
|
258
|
-
*
|
|
259
|
-
* @param {Date} date - Delete executions older than this date
|
|
260
|
-
* @returns {Promise<Object>} Deletion result with count
|
|
261
|
-
*/
|
|
262
|
-
async deleteExecutionsOlderThan(date) {
|
|
263
|
-
const result = await this.prisma.scriptExecution.deleteMany({
|
|
264
|
-
where: {
|
|
265
|
-
createdAt: {
|
|
266
|
-
lt: date,
|
|
267
|
-
},
|
|
268
|
-
},
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
return {
|
|
272
|
-
acknowledged: true,
|
|
273
|
-
deletedCount: result.count,
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
module.exports = { ScriptExecutionRepositoryMongo };
|
|
@@ -1,320 +0,0 @@
|
|
|
1
|
-
const { prisma } = require('../../database/prisma');
|
|
2
|
-
const {
|
|
3
|
-
ScriptExecutionRepositoryInterface,
|
|
4
|
-
} = require('./script-execution-repository-interface');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* PostgreSQL Script Execution Repository Adapter
|
|
8
|
-
* Handles script execution 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
|
-
* - logs field is Json[] - supports push operations
|
|
15
|
-
*/
|
|
16
|
-
class ScriptExecutionRepositoryPostgres extends ScriptExecutionRepositoryInterface {
|
|
17
|
-
constructor() {
|
|
18
|
-
super();
|
|
19
|
-
this.prisma = prisma;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Convert string ID to integer for PostgreSQL queries
|
|
24
|
-
* @private
|
|
25
|
-
* @param {string|number|null|undefined} id - ID to convert
|
|
26
|
-
* @returns {number|null|undefined} Integer ID or null/undefined
|
|
27
|
-
* @throws {Error} If ID cannot be converted to integer
|
|
28
|
-
*/
|
|
29
|
-
_convertId(id) {
|
|
30
|
-
if (id === null || id === undefined) return id;
|
|
31
|
-
const parsed = Number.parseInt(id, 10);
|
|
32
|
-
if (Number.isNaN(parsed)) {
|
|
33
|
-
throw new Error(`Invalid ID: ${id} cannot be converted to integer`);
|
|
34
|
-
}
|
|
35
|
-
return parsed;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Convert execution object IDs to strings
|
|
40
|
-
* @private
|
|
41
|
-
* @param {Object|null} execution - Execution object from database
|
|
42
|
-
* @returns {Object|null} Execution with string IDs
|
|
43
|
-
*/
|
|
44
|
-
_convertExecutionIds(execution) {
|
|
45
|
-
if (!execution) return execution;
|
|
46
|
-
return {
|
|
47
|
-
...execution,
|
|
48
|
-
id: execution.id?.toString(),
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Create a new script execution record
|
|
54
|
-
*
|
|
55
|
-
* @param {Object} params - Execution creation parameters
|
|
56
|
-
* @param {string} params.scriptName - Name of the script being executed
|
|
57
|
-
* @param {string} [params.scriptVersion] - Version of the script
|
|
58
|
-
* @param {string} params.trigger - Trigger type
|
|
59
|
-
* @param {string} [params.mode] - Execution mode ('sync' or 'async', default 'async')
|
|
60
|
-
* @param {Object} [params.input] - Input parameters for the script
|
|
61
|
-
* @param {Object} [params.audit] - Audit information
|
|
62
|
-
* @param {string} [params.audit.apiKeyName] - Name of API key used
|
|
63
|
-
* @param {string} [params.audit.apiKeyLast4] - Last 4 chars of API key
|
|
64
|
-
* @param {string} [params.audit.ipAddress] - IP address of requester
|
|
65
|
-
* @returns {Promise<Object>} The created execution record with string ID
|
|
66
|
-
*/
|
|
67
|
-
async createExecution({
|
|
68
|
-
scriptName,
|
|
69
|
-
scriptVersion,
|
|
70
|
-
trigger,
|
|
71
|
-
mode,
|
|
72
|
-
input,
|
|
73
|
-
audit,
|
|
74
|
-
}) {
|
|
75
|
-
const data = {
|
|
76
|
-
scriptName,
|
|
77
|
-
scriptVersion,
|
|
78
|
-
trigger,
|
|
79
|
-
mode: mode || 'async',
|
|
80
|
-
input,
|
|
81
|
-
logs: [],
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
// Map audit object to separate fields
|
|
85
|
-
if (audit) {
|
|
86
|
-
if (audit.apiKeyName) data.auditApiKeyName = audit.apiKeyName;
|
|
87
|
-
if (audit.apiKeyLast4) data.auditApiKeyLast4 = audit.apiKeyLast4;
|
|
88
|
-
if (audit.ipAddress) data.auditIpAddress = audit.ipAddress;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const execution = await this.prisma.scriptExecution.create({
|
|
92
|
-
data,
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
return this._convertExecutionIds(execution);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Find an execution by its ID
|
|
100
|
-
*
|
|
101
|
-
* @param {string|number} id - The execution ID
|
|
102
|
-
* @returns {Promise<Object|null>} The execution record with string ID or null if not found
|
|
103
|
-
*/
|
|
104
|
-
async findExecutionById(id) {
|
|
105
|
-
const intId = this._convertId(id);
|
|
106
|
-
const execution = await this.prisma.scriptExecution.findUnique({
|
|
107
|
-
where: { id: intId },
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
return this._convertExecutionIds(execution);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Find all executions for a specific script
|
|
115
|
-
*
|
|
116
|
-
* @param {string} scriptName - The script name to filter by
|
|
117
|
-
* @param {Object} [options] - Query options
|
|
118
|
-
* @param {number} [options.limit] - Maximum number of results
|
|
119
|
-
* @param {number} [options.offset] - Number of results to skip
|
|
120
|
-
* @param {string} [options.sortBy] - Field to sort by
|
|
121
|
-
* @param {string} [options.sortOrder] - Sort order ('asc' or 'desc')
|
|
122
|
-
* @returns {Promise<Array>} Array of execution records with string IDs
|
|
123
|
-
*/
|
|
124
|
-
async findExecutionsByScriptName(scriptName, options = {}) {
|
|
125
|
-
const {
|
|
126
|
-
limit,
|
|
127
|
-
offset,
|
|
128
|
-
sortBy = 'createdAt',
|
|
129
|
-
sortOrder = 'desc',
|
|
130
|
-
} = options;
|
|
131
|
-
|
|
132
|
-
const executions = await this.prisma.scriptExecution.findMany({
|
|
133
|
-
where: { scriptName },
|
|
134
|
-
orderBy: { [sortBy]: sortOrder },
|
|
135
|
-
take: limit,
|
|
136
|
-
skip: offset,
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
return executions.map((execution) =>
|
|
140
|
-
this._convertExecutionIds(execution)
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Find all executions with a specific status
|
|
146
|
-
*
|
|
147
|
-
* @param {string} status - Status to filter by
|
|
148
|
-
* @param {Object} [options] - Query options
|
|
149
|
-
* @param {number} [options.limit] - Maximum number of results
|
|
150
|
-
* @param {number} [options.offset] - Number of results to skip
|
|
151
|
-
* @param {string} [options.sortBy] - Field to sort by
|
|
152
|
-
* @param {string} [options.sortOrder] - Sort order ('asc' or 'desc')
|
|
153
|
-
* @returns {Promise<Array>} Array of execution records with string IDs
|
|
154
|
-
*/
|
|
155
|
-
async findExecutionsByStatus(status, options = {}) {
|
|
156
|
-
const {
|
|
157
|
-
limit,
|
|
158
|
-
offset,
|
|
159
|
-
sortBy = 'createdAt',
|
|
160
|
-
sortOrder = 'desc',
|
|
161
|
-
} = options;
|
|
162
|
-
|
|
163
|
-
const executions = await this.prisma.scriptExecution.findMany({
|
|
164
|
-
where: { status },
|
|
165
|
-
orderBy: { [sortBy]: sortOrder },
|
|
166
|
-
take: limit,
|
|
167
|
-
skip: offset,
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
return executions.map((execution) =>
|
|
171
|
-
this._convertExecutionIds(execution)
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Update the status of an execution
|
|
177
|
-
*
|
|
178
|
-
* @param {string|number} id - The execution ID
|
|
179
|
-
* @param {string} status - New status value
|
|
180
|
-
* @returns {Promise<Object>} Updated execution record with string ID
|
|
181
|
-
*/
|
|
182
|
-
async updateExecutionStatus(id, status) {
|
|
183
|
-
const intId = this._convertId(id);
|
|
184
|
-
const execution = await this.prisma.scriptExecution.update({
|
|
185
|
-
where: { id: intId },
|
|
186
|
-
data: { status },
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
return this._convertExecutionIds(execution);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Update the output result of an execution
|
|
194
|
-
*
|
|
195
|
-
* @param {string|number} id - The execution ID
|
|
196
|
-
* @param {Object} output - Output data from the script
|
|
197
|
-
* @returns {Promise<Object>} Updated execution record with string ID
|
|
198
|
-
*/
|
|
199
|
-
async updateExecutionOutput(id, output) {
|
|
200
|
-
const intId = this._convertId(id);
|
|
201
|
-
const execution = await this.prisma.scriptExecution.update({
|
|
202
|
-
where: { id: intId },
|
|
203
|
-
data: { output },
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
return this._convertExecutionIds(execution);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Update the error details of a failed execution
|
|
211
|
-
*
|
|
212
|
-
* @param {string|number} id - The execution ID
|
|
213
|
-
* @param {Object} error - Error information
|
|
214
|
-
* @param {string} error.name - Error name/type
|
|
215
|
-
* @param {string} error.message - Error message
|
|
216
|
-
* @param {string} [error.stack] - Error stack trace
|
|
217
|
-
* @returns {Promise<Object>} Updated execution record with string ID
|
|
218
|
-
*/
|
|
219
|
-
async updateExecutionError(id, error) {
|
|
220
|
-
const intId = this._convertId(id);
|
|
221
|
-
const execution = await this.prisma.scriptExecution.update({
|
|
222
|
-
where: { id: intId },
|
|
223
|
-
data: {
|
|
224
|
-
errorName: error.name,
|
|
225
|
-
errorMessage: error.message,
|
|
226
|
-
errorStack: error.stack,
|
|
227
|
-
},
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
return this._convertExecutionIds(execution);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Update the performance metrics of an execution
|
|
235
|
-
*
|
|
236
|
-
* @param {string|number} id - The execution ID
|
|
237
|
-
* @param {Object} metrics - Performance metrics
|
|
238
|
-
* @param {Date} [metrics.startTime] - Execution start time
|
|
239
|
-
* @param {Date} [metrics.endTime] - Execution end time
|
|
240
|
-
* @param {number} [metrics.durationMs] - Duration in milliseconds
|
|
241
|
-
* @returns {Promise<Object>} Updated execution record with string ID
|
|
242
|
-
*/
|
|
243
|
-
async updateExecutionMetrics(id, metrics) {
|
|
244
|
-
const intId = this._convertId(id);
|
|
245
|
-
const data = {};
|
|
246
|
-
if (metrics.startTime !== undefined)
|
|
247
|
-
data.metricsStartTime = metrics.startTime;
|
|
248
|
-
if (metrics.endTime !== undefined)
|
|
249
|
-
data.metricsEndTime = metrics.endTime;
|
|
250
|
-
if (metrics.durationMs !== undefined)
|
|
251
|
-
data.metricsDurationMs = metrics.durationMs;
|
|
252
|
-
|
|
253
|
-
const execution = await this.prisma.scriptExecution.update({
|
|
254
|
-
where: { id: intId },
|
|
255
|
-
data,
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
return this._convertExecutionIds(execution);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Append a log entry to an execution's log array
|
|
263
|
-
*
|
|
264
|
-
* @param {string|number} id - The execution ID
|
|
265
|
-
* @param {Object} logEntry - Log entry to append
|
|
266
|
-
* @param {string} logEntry.level - Log level ('debug', 'info', 'warn', 'error')
|
|
267
|
-
* @param {string} logEntry.message - Log message
|
|
268
|
-
* @param {Object} [logEntry.data] - Additional log data
|
|
269
|
-
* @param {string} logEntry.timestamp - ISO timestamp
|
|
270
|
-
* @returns {Promise<Object>} Updated execution record with string ID
|
|
271
|
-
*/
|
|
272
|
-
async appendExecutionLog(id, logEntry) {
|
|
273
|
-
const intId = this._convertId(id);
|
|
274
|
-
|
|
275
|
-
// Get current execution
|
|
276
|
-
const execution = await this.prisma.scriptExecution.findUnique({
|
|
277
|
-
where: { id: intId },
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
if (!execution) {
|
|
281
|
-
throw new Error(`Execution ${id} not found`);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Append log entry to logs array (copy to avoid mutating original)
|
|
285
|
-
const logs = Array.isArray(execution.logs) ? [...execution.logs] : [];
|
|
286
|
-
logs.push(logEntry);
|
|
287
|
-
|
|
288
|
-
// Update with new logs array
|
|
289
|
-
const updated = await this.prisma.scriptExecution.update({
|
|
290
|
-
where: { id: intId },
|
|
291
|
-
data: { logs },
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
return this._convertExecutionIds(updated);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Delete all executions older than a specific date
|
|
299
|
-
* Used for cleanup and retention policies
|
|
300
|
-
*
|
|
301
|
-
* @param {Date} date - Delete executions older than this date
|
|
302
|
-
* @returns {Promise<Object>} Deletion result with count
|
|
303
|
-
*/
|
|
304
|
-
async deleteExecutionsOlderThan(date) {
|
|
305
|
-
const result = await this.prisma.scriptExecution.deleteMany({
|
|
306
|
-
where: {
|
|
307
|
-
createdAt: {
|
|
308
|
-
lt: date,
|
|
309
|
-
},
|
|
310
|
-
},
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
return {
|
|
314
|
-
acknowledged: true,
|
|
315
|
-
deletedCount: result.count,
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
module.exports = { ScriptExecutionRepositoryPostgres };
|