@friggframework/core 2.0.0-next.10 → 2.0.0-next.100
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 +702 -0
- package/README.md +959 -50
- package/admin-scripts/index.js +52 -0
- package/admin-scripts/repositories/admin-script-execution-repository-documentdb.js +21 -0
- package/admin-scripts/repositories/admin-script-execution-repository-factory.js +51 -0
- package/admin-scripts/repositories/admin-script-execution-repository-interface.js +166 -0
- package/admin-scripts/repositories/admin-script-execution-repository-mongo.js +228 -0
- package/admin-scripts/repositories/admin-script-execution-repository-postgres.js +268 -0
- package/admin-scripts/repositories/script-schedule-repository-documentdb.js +21 -0
- package/admin-scripts/repositories/script-schedule-repository-factory.js +51 -0
- package/admin-scripts/repositories/script-schedule-repository-interface.js +108 -0
- package/admin-scripts/repositories/script-schedule-repository-mongo.js +179 -0
- package/admin-scripts/repositories/script-schedule-repository-postgres.js +210 -0
- package/application/commands/README.md +451 -0
- package/application/commands/admin-script-commands.js +358 -0
- package/application/commands/credential-commands.js +245 -0
- package/application/commands/entity-commands.js +336 -0
- package/application/commands/integration-commands.js +343 -0
- package/application/commands/process-commands.js +135 -0
- package/application/commands/scheduler-commands.js +263 -0
- package/application/commands/user-commands.js +312 -0
- package/application/index.js +82 -0
- package/assertions/index.js +0 -3
- package/core/CLAUDE.md +690 -0
- package/core/Worker.js +60 -24
- package/core/create-handler.js +84 -6
- package/credential/repositories/credential-repository-documentdb.js +304 -0
- package/credential/repositories/credential-repository-factory.js +54 -0
- package/credential/repositories/credential-repository-interface.js +98 -0
- package/credential/repositories/credential-repository-mongo.js +269 -0
- package/credential/repositories/credential-repository-postgres.js +287 -0
- package/credential/repositories/credential-repository.js +300 -0
- package/credential/use-cases/get-credential-for-user.js +25 -0
- package/credential/use-cases/update-authentication-status.js +15 -0
- package/database/MONGODB_TRANSACTION_FIX.md +198 -0
- package/database/adapters/lambda-invoker.js +97 -0
- package/database/config.js +154 -0
- package/database/documentdb-encryption-service.js +330 -0
- package/database/documentdb-utils.js +136 -0
- package/database/encryption/README.md +839 -0
- package/database/encryption/documentdb-encryption-service.md +3575 -0
- package/database/encryption/encryption-schema-registry.js +401 -0
- package/database/encryption/field-encryption-service.js +254 -0
- package/database/encryption/logger.js +79 -0
- package/database/encryption/prisma-encryption-extension.js +230 -0
- package/database/index.js +21 -21
- package/database/prisma.js +182 -0
- package/database/repositories/health-check-repository-documentdb.js +138 -0
- package/database/repositories/health-check-repository-factory.js +48 -0
- package/database/repositories/health-check-repository-interface.js +82 -0
- package/database/repositories/health-check-repository-mongodb.js +89 -0
- package/database/repositories/health-check-repository-postgres.js +82 -0
- package/database/repositories/migration-status-repository-s3.js +137 -0
- package/database/use-cases/check-database-health-use-case.js +29 -0
- package/database/use-cases/check-database-state-use-case.js +81 -0
- package/database/use-cases/check-encryption-health-use-case.js +83 -0
- package/database/use-cases/get-database-state-via-worker-use-case.js +61 -0
- package/database/use-cases/get-migration-status-use-case.js +93 -0
- package/database/use-cases/run-database-migration-use-case.js +139 -0
- package/database/use-cases/test-encryption-use-case.js +253 -0
- package/database/use-cases/trigger-database-migration-use-case.js +157 -0
- package/database/utils/mongodb-collection-utils.js +94 -0
- package/database/utils/mongodb-schema-init.js +108 -0
- package/database/utils/prisma-runner.js +477 -0
- package/database/utils/prisma-schema-parser.js +182 -0
- package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +517 -0
- package/encrypt/Cryptor.js +34 -168
- package/encrypt/index.js +1 -2
- package/errors/client-safe-error.js +26 -0
- package/errors/fetch-error.js +15 -7
- package/errors/index.js +2 -0
- package/generated/prisma-mongodb/client.d.ts +1 -0
- package/generated/prisma-mongodb/client.js +5 -0
- package/generated/prisma-mongodb/default.d.ts +1 -0
- package/generated/prisma-mongodb/default.js +5 -0
- package/generated/prisma-mongodb/edge.d.ts +1 -0
- package/generated/prisma-mongodb/edge.js +374 -0
- package/generated/prisma-mongodb/index-browser.js +356 -0
- package/generated/prisma-mongodb/index.d.ts +25667 -0
- package/generated/prisma-mongodb/index.js +399 -0
- package/generated/prisma-mongodb/libquery_engine-debian-openssl-3.0.x.so.node +0 -0
- package/generated/prisma-mongodb/libquery_engine-rhel-openssl-3.0.x.so.node +0 -0
- package/generated/prisma-mongodb/package.json +183 -0
- package/generated/prisma-mongodb/runtime/edge-esm.js +35 -0
- package/generated/prisma-mongodb/runtime/edge.js +35 -0
- package/generated/prisma-mongodb/runtime/index-browser.d.ts +370 -0
- package/generated/prisma-mongodb/runtime/index-browser.js +17 -0
- package/generated/prisma-mongodb/runtime/library.d.ts +3982 -0
- package/generated/prisma-mongodb/runtime/library.js +147 -0
- package/generated/prisma-mongodb/runtime/react-native.js +84 -0
- package/generated/prisma-mongodb/runtime/wasm-compiler-edge.js +85 -0
- package/generated/prisma-mongodb/runtime/wasm-engine-edge.js +38 -0
- package/generated/prisma-mongodb/schema.prisma +432 -0
- package/generated/prisma-mongodb/wasm-edge-light-loader.mjs +5 -0
- package/generated/prisma-mongodb/wasm-worker-loader.mjs +5 -0
- package/generated/prisma-mongodb/wasm.d.ts +1 -0
- package/generated/prisma-mongodb/wasm.js +381 -0
- package/generated/prisma-postgresql/client.d.ts +1 -0
- package/generated/prisma-postgresql/client.js +5 -0
- package/generated/prisma-postgresql/default.d.ts +1 -0
- package/generated/prisma-postgresql/default.js +5 -0
- package/generated/prisma-postgresql/edge.d.ts +1 -0
- package/generated/prisma-postgresql/edge.js +395 -0
- package/generated/prisma-postgresql/index-browser.js +377 -0
- package/generated/prisma-postgresql/index.d.ts +28455 -0
- package/generated/prisma-postgresql/index.js +420 -0
- package/generated/prisma-postgresql/libquery_engine-debian-openssl-3.0.x.so.node +0 -0
- package/generated/prisma-postgresql/libquery_engine-rhel-openssl-3.0.x.so.node +0 -0
- package/generated/prisma-postgresql/package.json +183 -0
- package/generated/prisma-postgresql/query_engine_bg.js +2 -0
- package/generated/prisma-postgresql/query_engine_bg.wasm +0 -0
- package/generated/prisma-postgresql/runtime/edge-esm.js +35 -0
- package/generated/prisma-postgresql/runtime/edge.js +35 -0
- package/generated/prisma-postgresql/runtime/index-browser.d.ts +370 -0
- package/generated/prisma-postgresql/runtime/index-browser.js +17 -0
- package/generated/prisma-postgresql/runtime/library.d.ts +3982 -0
- package/generated/prisma-postgresql/runtime/library.js +147 -0
- package/generated/prisma-postgresql/runtime/react-native.js +84 -0
- package/generated/prisma-postgresql/runtime/wasm-compiler-edge.js +85 -0
- package/generated/prisma-postgresql/runtime/wasm-engine-edge.js +38 -0
- package/generated/prisma-postgresql/schema.prisma +414 -0
- package/generated/prisma-postgresql/wasm-edge-light-loader.mjs +5 -0
- package/generated/prisma-postgresql/wasm-worker-loader.mjs +5 -0
- package/generated/prisma-postgresql/wasm.d.ts +1 -0
- package/generated/prisma-postgresql/wasm.js +402 -0
- package/handlers/WEBHOOKS.md +653 -0
- package/handlers/app-definition-loader.js +43 -0
- package/handlers/app-handler-helpers.js +3 -3
- package/handlers/backend-utils.js +271 -42
- package/handlers/database-migration-handler.js +227 -0
- package/handlers/integration-event-dispatcher.js +54 -0
- package/handlers/middleware/admin-auth.js +73 -0
- package/handlers/routers/HEALTHCHECK.md +342 -0
- package/handlers/routers/auth.js +4 -15
- package/handlers/routers/db-migration.handler.js +29 -0
- package/handlers/routers/db-migration.js +311 -0
- package/handlers/routers/health.js +518 -0
- package/handlers/routers/integration-defined-routers.js +85 -10
- package/handlers/routers/integration-webhook-routers.js +67 -0
- package/handlers/routers/reporting.js +9 -0
- package/handlers/routers/user.js +27 -5
- package/handlers/routers/websocket.js +5 -3
- package/handlers/use-cases/check-external-apis-health-use-case.js +81 -0
- package/handlers/use-cases/check-integrations-health-use-case.js +44 -0
- package/handlers/workers/db-migration.js +352 -0
- package/handlers/workers/dlq-processor.js +63 -0
- package/handlers/workers/integration-defined-workers.js +13 -7
- package/index.js +91 -46
- package/infrastructure/scheduler/eventbridge-scheduler-adapter.js +184 -0
- package/infrastructure/scheduler/index.js +33 -0
- package/infrastructure/scheduler/mock-scheduler-adapter.js +143 -0
- package/infrastructure/scheduler/scheduler-service-factory.js +73 -0
- package/infrastructure/scheduler/scheduler-service-interface.js +47 -0
- package/integrations/EXTENSIONS.md +240 -0
- package/integrations/WEBHOOK-QUICKSTART.md +151 -0
- package/integrations/extension.js +254 -0
- package/integrations/index.js +20 -10
- package/integrations/integration-base.js +619 -72
- package/integrations/integration-router.js +398 -180
- package/integrations/options.js +1 -1
- package/integrations/repositories/config-patch-shared.js +43 -0
- package/integrations/repositories/integration-mapping-repository-documentdb.js +280 -0
- package/integrations/repositories/integration-mapping-repository-factory.js +57 -0
- package/integrations/repositories/integration-mapping-repository-interface.js +106 -0
- package/integrations/repositories/integration-mapping-repository-mongo.js +161 -0
- package/integrations/repositories/integration-mapping-repository-postgres.js +227 -0
- package/integrations/repositories/integration-mapping-repository.js +156 -0
- package/integrations/repositories/integration-repository-documentdb.js +284 -0
- package/integrations/repositories/integration-repository-factory.js +51 -0
- package/integrations/repositories/integration-repository-interface.js +173 -0
- package/integrations/repositories/integration-repository-mongo.js +414 -0
- package/integrations/repositories/integration-repository-postgres.js +452 -0
- package/integrations/repositories/process-repository-documentdb.js +311 -0
- package/integrations/repositories/process-repository-factory.js +53 -0
- package/integrations/repositories/process-repository-interface.js +136 -0
- package/integrations/repositories/process-repository-mongo.js +262 -0
- package/integrations/repositories/process-repository-postgres.js +380 -0
- package/integrations/repositories/process-update-ops-shared.js +112 -0
- package/integrations/tests/doubles/config-capturing-integration.js +81 -0
- package/integrations/tests/doubles/dummy-integration-class.js +113 -0
- package/integrations/tests/doubles/test-integration-repository.js +146 -0
- package/integrations/use-cases/create-integration.js +215 -0
- package/integrations/use-cases/create-process.js +130 -0
- package/integrations/use-cases/delete-integration-for-user.js +119 -0
- package/integrations/use-cases/find-integration-by-entity-external-id.js +74 -0
- package/integrations/use-cases/find-integration-context-by-external-entity-id.js +76 -0
- package/integrations/use-cases/get-integration-for-user.js +78 -0
- package/integrations/use-cases/get-integration-instance-by-definition.js +67 -0
- package/integrations/use-cases/get-integration-instance.js +83 -0
- package/integrations/use-cases/get-integrations-for-user.js +88 -0
- package/integrations/use-cases/get-possible-integrations.js +27 -0
- package/integrations/use-cases/get-process.js +89 -0
- package/integrations/use-cases/index.js +19 -0
- package/integrations/use-cases/list-integrations-by-entity-external-id.js +46 -0
- package/integrations/use-cases/load-integration-context.js +71 -0
- package/integrations/use-cases/patch-integration-config.js +39 -0
- package/integrations/use-cases/process-errors.js +28 -0
- package/integrations/use-cases/update-integration-config.js +32 -0
- package/integrations/use-cases/update-integration-messages.js +44 -0
- package/integrations/use-cases/update-integration-status.js +32 -0
- package/integrations/use-cases/update-integration.js +92 -0
- package/integrations/use-cases/update-process-metrics.js +216 -0
- package/integrations/use-cases/update-process-state.js +163 -0
- package/integrations/utils/map-integration-dto.js +37 -0
- package/jest-global-setup-noop.js +3 -0
- package/jest-global-teardown-noop.js +3 -0
- package/logs/logger.js +0 -4
- package/{module-plugin → modules}/index.js +0 -10
- package/modules/module-factory.js +56 -0
- package/modules/module.js +274 -0
- package/modules/repositories/module-repository-documentdb.js +350 -0
- package/modules/repositories/module-repository-factory.js +40 -0
- package/modules/repositories/module-repository-interface.js +145 -0
- package/modules/repositories/module-repository-mongo.js +436 -0
- package/modules/repositories/module-repository-postgres.js +481 -0
- package/modules/repositories/module-repository.js +369 -0
- package/modules/requester/api-key.js +52 -0
- package/modules/requester/oauth-2.js +396 -0
- package/modules/requester/requester.js +285 -0
- package/{module-plugin → modules}/test/mock-api/api.js +8 -3
- package/{module-plugin → modules}/test/mock-api/definition.js +14 -10
- package/modules/tests/doubles/test-module-factory.js +16 -0
- package/modules/tests/doubles/test-module-repository.js +39 -0
- package/modules/use-cases/get-entities-for-user.js +32 -0
- package/modules/use-cases/get-entity-options-by-id.js +71 -0
- package/modules/use-cases/get-entity-options-by-type.js +34 -0
- package/modules/use-cases/get-module-instance-from-type.js +34 -0
- package/modules/use-cases/get-module.js +74 -0
- package/modules/use-cases/process-authorization-callback.js +243 -0
- package/modules/use-cases/refresh-entity-options.js +72 -0
- package/modules/use-cases/test-module-auth.js +72 -0
- package/modules/utils/map-module-dto.js +18 -0
- package/package.json +82 -50
- package/prisma-mongodb/schema.prisma +432 -0
- package/prisma-postgresql/migrations/20250930193005_init/migration.sql +315 -0
- package/prisma-postgresql/migrations/20251006135218_init/migration.sql +9 -0
- package/prisma-postgresql/migrations/20251010000000_remove_unused_entity_reference_map/migration.sql +3 -0
- package/prisma-postgresql/migrations/20251112195422_update_user_unique_constraints/migration.sql +25 -0
- package/prisma-postgresql/migrations/20260422120000_add_entity_data_column/migration.sql +10 -0
- package/prisma-postgresql/migrations/20260422120001_create_process_table/migration.sql +48 -0
- package/prisma-postgresql/migrations/20260625000000_add_user_organization_id_index/migration.sql +2 -0
- package/prisma-postgresql/migrations/20260703000000_add_integration_status_in_creation_in_deletion/migration.sql +11 -0
- package/prisma-postgresql/migrations/20260703000001_integration_status_default_in_creation/migration.sql +8 -0
- package/prisma-postgresql/migrations/20260706000000_add_admin_script_execution_and_schedule/migration.sql +61 -0
- package/prisma-postgresql/migrations/migration_lock.toml +3 -0
- package/prisma-postgresql/schema.prisma +414 -0
- package/queues/queuer-util.js +103 -21
- package/reporting/README.md +86 -0
- package/reporting/index.js +17 -0
- package/reporting/reporting-router.js +77 -0
- package/reporting/repositories/reporting-repository-documentdb.js +127 -0
- package/reporting/repositories/reporting-repository-factory.js +35 -0
- package/reporting/repositories/reporting-repository-interface.js +16 -0
- package/reporting/repositories/reporting-repository-mongo.js +54 -0
- package/reporting/repositories/reporting-repository-postgres.js +70 -0
- package/reporting/use-cases/index.js +6 -0
- package/reporting/use-cases/list-integrations-report.js +142 -0
- package/syncs/manager.js +468 -443
- package/syncs/repositories/sync-repository-documentdb.js +240 -0
- package/syncs/repositories/sync-repository-factory.js +43 -0
- package/syncs/repositories/sync-repository-interface.js +109 -0
- package/syncs/repositories/sync-repository-mongo.js +239 -0
- package/syncs/repositories/sync-repository-postgres.js +319 -0
- package/syncs/sync.js +0 -1
- package/token/repositories/token-repository-documentdb.js +137 -0
- package/token/repositories/token-repository-factory.js +40 -0
- package/token/repositories/token-repository-interface.js +131 -0
- package/token/repositories/token-repository-mongo.js +219 -0
- package/token/repositories/token-repository-postgres.js +264 -0
- package/token/repositories/token-repository.js +219 -0
- package/types/associations/index.d.ts +0 -17
- package/types/core/index.d.ts +12 -4
- package/types/database/index.d.ts +10 -2
- package/types/encrypt/index.d.ts +5 -3
- package/types/integrations/index.d.ts +3 -8
- package/types/module-plugin/index.d.ts +17 -69
- package/types/syncs/index.d.ts +0 -17
- package/user/repositories/user-repository-documentdb.js +458 -0
- package/user/repositories/user-repository-factory.js +52 -0
- package/user/repositories/user-repository-interface.js +214 -0
- package/user/repositories/user-repository-mongo.js +323 -0
- package/user/repositories/user-repository-postgres.js +377 -0
- package/user/tests/doubles/test-user-repository.js +72 -0
- package/user/use-cases/authenticate-user.js +127 -0
- package/user/use-cases/authenticate-with-shared-secret.js +48 -0
- package/user/use-cases/create-individual-user.js +61 -0
- package/user/use-cases/create-organization-user.js +47 -0
- package/user/use-cases/create-token-for-user-id.js +30 -0
- package/user/use-cases/get-user-from-adopter-jwt.js +149 -0
- package/user/use-cases/get-user-from-bearer-token.js +77 -0
- package/user/use-cases/get-user-from-x-frigg-headers.js +132 -0
- package/user/use-cases/login-user.js +122 -0
- package/user/user.js +125 -0
- package/utils/backend-path.js +38 -0
- package/utils/index.js +6 -0
- package/websocket/repositories/websocket-connection-repository-documentdb.js +119 -0
- package/websocket/repositories/websocket-connection-repository-factory.js +44 -0
- package/websocket/repositories/websocket-connection-repository-interface.js +106 -0
- package/websocket/repositories/websocket-connection-repository-mongo.js +156 -0
- package/websocket/repositories/websocket-connection-repository-postgres.js +196 -0
- package/websocket/repositories/websocket-connection-repository.js +161 -0
- package/assertions/is-equal.js +0 -17
- package/associations/model.js +0 -54
- package/database/models/IndividualUser.js +0 -76
- package/database/models/OrganizationUser.js +0 -29
- package/database/models/State.js +0 -9
- package/database/models/Token.js +0 -70
- package/database/models/UserModel.js +0 -7
- package/database/models/WebsocketConnection.js +0 -49
- package/database/mongo.js +0 -45
- package/database/mongoose.js +0 -5
- package/encrypt/Cryptor.test.js +0 -32
- package/encrypt/encrypt.js +0 -132
- package/encrypt/encrypt.test.js +0 -1069
- package/encrypt/test-encrypt.js +0 -107
- package/errors/base-error.test.js +0 -32
- package/errors/fetch-error.test.js +0 -79
- package/errors/halt-error.test.js +0 -11
- package/errors/validation-errors.test.js +0 -120
- package/handlers/routers/middleware/loadUser.js +0 -15
- package/handlers/routers/middleware/requireLoggedInUser.js +0 -12
- package/integrations/create-frigg-backend.js +0 -31
- package/integrations/integration-factory.js +0 -251
- package/integrations/integration-mapping.js +0 -43
- package/integrations/integration-model.js +0 -46
- package/integrations/integration-user.js +0 -144
- package/integrations/test/integration-base.test.js +0 -144
- package/lambda/TimeoutCatcher.test.js +0 -68
- package/logs/logger.test.js +0 -76
- package/module-plugin/auther.js +0 -393
- package/module-plugin/credential.js +0 -22
- package/module-plugin/entity-manager.js +0 -70
- package/module-plugin/entity.js +0 -46
- package/module-plugin/manager.js +0 -169
- package/module-plugin/module-factory.js +0 -61
- package/module-plugin/requester/api-key.js +0 -36
- package/module-plugin/requester/oauth-2.js +0 -219
- package/module-plugin/requester/requester.js +0 -165
- package/module-plugin/requester/requester.test.js +0 -28
- package/module-plugin/test/auther.test.js +0 -97
- package/syncs/model.js +0 -62
- /package/{module-plugin → modules}/ModuleConstants.js +0 -0
- /package/{module-plugin → modules}/requester/basic.js +0 -0
- /package/{module-plugin → modules}/test/mock-api/mocks/hubspot.js +0 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
const { prisma } = require('../../database/prisma');
|
|
2
|
+
const {
|
|
3
|
+
AdminScriptExecutionRepositoryInterface,
|
|
4
|
+
} = require('./admin-script-execution-repository-interface');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* PostgreSQL Admin Process Repository Adapter
|
|
8
|
+
* Handles admin process 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
|
+
* - context and results are Json objects
|
|
15
|
+
*/
|
|
16
|
+
class AdminScriptExecutionRepositoryPostgres extends AdminScriptExecutionRepositoryInterface {
|
|
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 process object IDs to strings
|
|
40
|
+
* @private
|
|
41
|
+
* @param {Object|null} process - Process object from database
|
|
42
|
+
* @returns {Object|null} Process with string IDs
|
|
43
|
+
*/
|
|
44
|
+
_convertExecutionIds(process) {
|
|
45
|
+
if (!process) return process;
|
|
46
|
+
return {
|
|
47
|
+
...process,
|
|
48
|
+
id: process.id?.toString(),
|
|
49
|
+
parentExecutionId: process.parentExecutionId?.toString(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Create a new admin process record
|
|
55
|
+
*
|
|
56
|
+
* @param {Object} params - Process creation parameters
|
|
57
|
+
* @param {string} params.name - Name of the process
|
|
58
|
+
* @param {string} params.type - Type of process (e.g., 'ADMIN_SCRIPT', 'DB_MIGRATION')
|
|
59
|
+
* @param {Object} [params.context] - Context data
|
|
60
|
+
* @returns {Promise<Object>} The created process record with string ID
|
|
61
|
+
*/
|
|
62
|
+
async createExecution({ name, type, context = {}, parentExecutionId }) {
|
|
63
|
+
const data = {
|
|
64
|
+
name,
|
|
65
|
+
type,
|
|
66
|
+
context,
|
|
67
|
+
results: { logs: [] },
|
|
68
|
+
...(parentExecutionId != null && {
|
|
69
|
+
parentExecutionId: this._convertId(parentExecutionId),
|
|
70
|
+
}),
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const process = await this.prisma.adminScriptExecution.create({
|
|
74
|
+
data,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return this._convertExecutionIds(process);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Find a process by its ID
|
|
82
|
+
*
|
|
83
|
+
* @param {string|number} id - The process ID
|
|
84
|
+
* @returns {Promise<Object|null>} The process record with string ID or null if not found
|
|
85
|
+
*/
|
|
86
|
+
async findExecutionById(id) {
|
|
87
|
+
const intId = this._convertId(id);
|
|
88
|
+
const process = await this.prisma.adminScriptExecution.findUnique({
|
|
89
|
+
where: { id: intId },
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return this._convertExecutionIds(process);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Find all processes with a specific name
|
|
97
|
+
*
|
|
98
|
+
* @param {string} name - The process name to filter by
|
|
99
|
+
* @param {Object} [options] - Query options
|
|
100
|
+
* @param {number} [options.limit] - Maximum number of results
|
|
101
|
+
* @param {number} [options.offset] - Number of results to skip
|
|
102
|
+
* @param {string} [options.sortBy] - Field to sort by
|
|
103
|
+
* @param {string} [options.sortOrder] - Sort order ('asc' or 'desc')
|
|
104
|
+
* @returns {Promise<Array>} Array of process records with string IDs
|
|
105
|
+
*/
|
|
106
|
+
async findExecutionsByName(name, options = {}) {
|
|
107
|
+
const {
|
|
108
|
+
limit,
|
|
109
|
+
offset,
|
|
110
|
+
sortBy = 'createdAt',
|
|
111
|
+
sortOrder = 'desc',
|
|
112
|
+
state,
|
|
113
|
+
} = options;
|
|
114
|
+
|
|
115
|
+
const where = { name };
|
|
116
|
+
if (state) where.state = state;
|
|
117
|
+
|
|
118
|
+
const processes = await this.prisma.adminScriptExecution.findMany({
|
|
119
|
+
where,
|
|
120
|
+
orderBy: { [sortBy]: sortOrder },
|
|
121
|
+
take: limit,
|
|
122
|
+
skip: offset,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return processes.map((process) => this._convertExecutionIds(process));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Find all processes with a specific state
|
|
130
|
+
*
|
|
131
|
+
* @param {string} state - State to filter by
|
|
132
|
+
* @param {Object} [options] - Query options
|
|
133
|
+
* @param {number} [options.limit] - Maximum number of results
|
|
134
|
+
* @param {number} [options.offset] - Number of results to skip
|
|
135
|
+
* @param {string} [options.sortBy] - Field to sort by
|
|
136
|
+
* @param {string} [options.sortOrder] - Sort order ('asc' or 'desc')
|
|
137
|
+
* @returns {Promise<Array>} Array of process records with string IDs
|
|
138
|
+
*/
|
|
139
|
+
async findExecutionsByState(state, options = {}) {
|
|
140
|
+
const {
|
|
141
|
+
limit,
|
|
142
|
+
offset,
|
|
143
|
+
sortBy = 'createdAt',
|
|
144
|
+
sortOrder = 'desc',
|
|
145
|
+
} = options;
|
|
146
|
+
|
|
147
|
+
const processes = await this.prisma.adminScriptExecution.findMany({
|
|
148
|
+
where: { state },
|
|
149
|
+
orderBy: { [sortBy]: sortOrder },
|
|
150
|
+
take: limit,
|
|
151
|
+
skip: offset,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
return processes.map((process) => this._convertExecutionIds(process));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Update the state of a process
|
|
159
|
+
*
|
|
160
|
+
* @param {string|number} id - The process ID
|
|
161
|
+
* @param {string} state - New state value
|
|
162
|
+
* @returns {Promise<Object>} Updated process record with string ID
|
|
163
|
+
*/
|
|
164
|
+
async updateExecutionState(id, state) {
|
|
165
|
+
const intId = this._convertId(id);
|
|
166
|
+
const process = await this.prisma.adminScriptExecution.update({
|
|
167
|
+
where: { id: intId },
|
|
168
|
+
data: { state },
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
return this._convertExecutionIds(process);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Update the results of a process
|
|
176
|
+
* Merges new results with existing results
|
|
177
|
+
*
|
|
178
|
+
* @param {string|number} id - The process ID
|
|
179
|
+
* @param {Object} results - Results data to merge
|
|
180
|
+
* @returns {Promise<Object>} Updated process record with string ID
|
|
181
|
+
*/
|
|
182
|
+
async updateExecutionResults(id, results) {
|
|
183
|
+
const intId = this._convertId(id);
|
|
184
|
+
|
|
185
|
+
// Get current process to merge results
|
|
186
|
+
const currentProcess = await this.prisma.adminScriptExecution.findUnique({
|
|
187
|
+
where: { id: intId },
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
if (!currentProcess) {
|
|
191
|
+
throw new Error(`AdminScriptExecution ${id} not found`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Merge new results with existing results
|
|
195
|
+
const mergedResults = {
|
|
196
|
+
...(currentProcess.results || {}),
|
|
197
|
+
...results,
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const process = await this.prisma.adminScriptExecution.update({
|
|
201
|
+
where: { id: intId },
|
|
202
|
+
data: { results: mergedResults },
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
return this._convertExecutionIds(process);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Append a log entry to a process's log array in results
|
|
210
|
+
*
|
|
211
|
+
* @param {string|number} id - The process ID
|
|
212
|
+
* @param {Object} logEntry - Log entry to append
|
|
213
|
+
* @param {string} logEntry.level - Log level ('debug', 'info', 'warn', 'error')
|
|
214
|
+
* @param {string} logEntry.message - Log message
|
|
215
|
+
* @param {Object} [logEntry.data] - Additional log data
|
|
216
|
+
* @param {string} logEntry.timestamp - ISO timestamp
|
|
217
|
+
* @returns {Promise<Object>} Updated process record with string ID
|
|
218
|
+
*/
|
|
219
|
+
async appendExecutionLog(id, logEntry) {
|
|
220
|
+
const intId = this._convertId(id);
|
|
221
|
+
|
|
222
|
+
// Get current process
|
|
223
|
+
const process = await this.prisma.adminScriptExecution.findUnique({
|
|
224
|
+
where: { id: intId },
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
if (!process) {
|
|
228
|
+
throw new Error(`AdminScriptExecution ${id} not found`);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Get current results and logs
|
|
232
|
+
const results = process.results || {};
|
|
233
|
+
const logs = Array.isArray(results.logs) ? [...results.logs] : [];
|
|
234
|
+
logs.push(logEntry);
|
|
235
|
+
|
|
236
|
+
// Update with new logs array in results
|
|
237
|
+
const updated = await this.prisma.adminScriptExecution.update({
|
|
238
|
+
where: { id: intId },
|
|
239
|
+
data: { results: { ...results, logs } },
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
return this._convertExecutionIds(updated);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Delete all processes older than a specific date
|
|
247
|
+
* Used for cleanup and retention policies
|
|
248
|
+
*
|
|
249
|
+
* @param {Date} date - Delete processes older than this date
|
|
250
|
+
* @returns {Promise<Object>} Deletion result with count
|
|
251
|
+
*/
|
|
252
|
+
async deleteExecutionsOlderThan(date) {
|
|
253
|
+
const result = await this.prisma.adminScriptExecution.deleteMany({
|
|
254
|
+
where: {
|
|
255
|
+
createdAt: {
|
|
256
|
+
lt: date,
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
return {
|
|
262
|
+
acknowledged: true,
|
|
263
|
+
deletedCount: result.count,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
module.exports = { AdminScriptExecutionRepositoryPostgres };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const {
|
|
2
|
+
ScriptScheduleRepositoryMongo,
|
|
3
|
+
} = require('./script-schedule-repository-mongo');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* DocumentDB Script Schedule Repository Adapter
|
|
7
|
+
* Handles script schedule persistence using Prisma with AWS DocumentDB
|
|
8
|
+
*
|
|
9
|
+
* DocumentDB is MongoDB-compatible with some limitations:
|
|
10
|
+
* - Uses MongoDB wire protocol
|
|
11
|
+
* - Same Prisma schema as MongoDB
|
|
12
|
+
* - Inherits all MongoDB repository methods
|
|
13
|
+
*
|
|
14
|
+
* For schedule operations, DocumentDB and MongoDB behavior is identical.
|
|
15
|
+
*/
|
|
16
|
+
class ScriptScheduleRepositoryDocumentDB extends ScriptScheduleRepositoryMongo {
|
|
17
|
+
// Inherits all methods from MongoDB implementation
|
|
18
|
+
// DocumentDB is MongoDB-compatible for these operations
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = { ScriptScheduleRepositoryDocumentDB };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const { ScriptScheduleRepositoryMongo } = require('./script-schedule-repository-mongo');
|
|
2
|
+
const { ScriptScheduleRepositoryPostgres } = require('./script-schedule-repository-postgres');
|
|
3
|
+
const {
|
|
4
|
+
ScriptScheduleRepositoryDocumentDB,
|
|
5
|
+
} = require('./script-schedule-repository-documentdb');
|
|
6
|
+
const config = require('../../database/config');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Script Schedule Repository Factory
|
|
10
|
+
* Creates the appropriate repository adapter based on database type
|
|
11
|
+
*
|
|
12
|
+
* This implements the Factory pattern for Hexagonal Architecture:
|
|
13
|
+
* - Reads database type from app definition (backend/index.js)
|
|
14
|
+
* - Returns correct adapter (MongoDB, DocumentDB, or PostgreSQL)
|
|
15
|
+
* - Provides clear error for unsupported databases
|
|
16
|
+
*
|
|
17
|
+
* Usage:
|
|
18
|
+
* ```javascript
|
|
19
|
+
* const repository = createScriptScheduleRepository();
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @returns {ScriptScheduleRepositoryInterface} Configured repository adapter
|
|
23
|
+
* @throws {Error} If database type is not supported
|
|
24
|
+
*/
|
|
25
|
+
function createScriptScheduleRepository() {
|
|
26
|
+
const dbType = config.DB_TYPE;
|
|
27
|
+
|
|
28
|
+
switch (dbType) {
|
|
29
|
+
case 'mongodb':
|
|
30
|
+
return new ScriptScheduleRepositoryMongo();
|
|
31
|
+
|
|
32
|
+
case 'postgresql':
|
|
33
|
+
return new ScriptScheduleRepositoryPostgres();
|
|
34
|
+
|
|
35
|
+
case 'documentdb':
|
|
36
|
+
return new ScriptScheduleRepositoryDocumentDB();
|
|
37
|
+
|
|
38
|
+
default:
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Unsupported database type: ${dbType}. Supported values: 'mongodb', 'documentdb', 'postgresql'`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = {
|
|
46
|
+
createScriptScheduleRepository,
|
|
47
|
+
// Export adapters for direct testing
|
|
48
|
+
ScriptScheduleRepositoryMongo,
|
|
49
|
+
ScriptScheduleRepositoryPostgres,
|
|
50
|
+
ScriptScheduleRepositoryDocumentDB,
|
|
51
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Script Schedule Repository Interface
|
|
3
|
+
* Abstract base class defining the contract for script schedule 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 schedules support Phase 2 hybrid scheduling:
|
|
11
|
+
* - Database overrides take precedence over Definition defaults
|
|
12
|
+
* - EventBridge rules provisioned for enabled schedules
|
|
13
|
+
* - lastTriggeredAt and nextTriggerAt for monitoring
|
|
14
|
+
*
|
|
15
|
+
* @abstract
|
|
16
|
+
*/
|
|
17
|
+
class ScriptScheduleRepositoryInterface {
|
|
18
|
+
/**
|
|
19
|
+
* Find a schedule by script name
|
|
20
|
+
*
|
|
21
|
+
* @param {string} scriptName - The script name
|
|
22
|
+
* @returns {Promise<Object|null>} Schedule record or null if not found
|
|
23
|
+
* @abstract
|
|
24
|
+
*/
|
|
25
|
+
async findScheduleByScriptName(scriptName) {
|
|
26
|
+
throw new Error('Method findScheduleByScriptName must be implemented by subclass');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Create or update a schedule (upsert)
|
|
31
|
+
*
|
|
32
|
+
* @param {Object} params - Schedule parameters
|
|
33
|
+
* @param {string} params.scriptName - Name of the script
|
|
34
|
+
* @param {boolean} params.enabled - Whether schedule is enabled
|
|
35
|
+
* @param {string} params.cronExpression - Cron expression
|
|
36
|
+
* @param {string} [params.timezone] - Timezone (default 'UTC')
|
|
37
|
+
* @param {string} [params.externalScheduleId] - External scheduler ID (e.g., AWS ARN)
|
|
38
|
+
* @param {string} [params.externalScheduleName] - External scheduler name
|
|
39
|
+
* @returns {Promise<Object>} Created or updated schedule record
|
|
40
|
+
* @abstract
|
|
41
|
+
*/
|
|
42
|
+
async upsertSchedule({ scriptName, enabled, cronExpression, timezone, externalScheduleId, externalScheduleName }) {
|
|
43
|
+
throw new Error('Method upsertSchedule must be implemented by subclass');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Delete a schedule by script name
|
|
48
|
+
*
|
|
49
|
+
* @param {string} scriptName - The script name
|
|
50
|
+
* @returns {Promise<Object>} Deletion result
|
|
51
|
+
* @abstract
|
|
52
|
+
*/
|
|
53
|
+
async deleteSchedule(scriptName) {
|
|
54
|
+
throw new Error('Method deleteSchedule must be implemented by subclass');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Update external scheduler information
|
|
59
|
+
*
|
|
60
|
+
* @param {string} scriptName - The script name
|
|
61
|
+
* @param {Object} externalInfo - External schedule information
|
|
62
|
+
* @param {string} [externalInfo.externalScheduleId] - External scheduler ID (e.g., AWS ARN)
|
|
63
|
+
* @param {string} [externalInfo.externalScheduleName] - External scheduler name
|
|
64
|
+
* @returns {Promise<Object>} Updated schedule record
|
|
65
|
+
* @abstract
|
|
66
|
+
*/
|
|
67
|
+
async updateScheduleExternalInfo(scriptName, { externalScheduleId, externalScheduleName }) {
|
|
68
|
+
throw new Error('Method updateScheduleExternalInfo must be implemented by subclass');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Update last triggered timestamp
|
|
73
|
+
*
|
|
74
|
+
* @param {string} scriptName - The script name
|
|
75
|
+
* @param {Date} [timestamp] - Trigger timestamp (default: now)
|
|
76
|
+
* @returns {Promise<Object>} Updated schedule record
|
|
77
|
+
* @abstract
|
|
78
|
+
*/
|
|
79
|
+
async updateScheduleLastTriggered(scriptName, timestamp) {
|
|
80
|
+
throw new Error('Method updateScheduleLastTriggered must be implemented by subclass');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Update next trigger timestamp
|
|
85
|
+
*
|
|
86
|
+
* @param {string} scriptName - The script name
|
|
87
|
+
* @param {Date} timestamp - Next trigger timestamp
|
|
88
|
+
* @returns {Promise<Object>} Updated schedule record
|
|
89
|
+
* @abstract
|
|
90
|
+
*/
|
|
91
|
+
async updateScheduleNextTrigger(scriptName, timestamp) {
|
|
92
|
+
throw new Error('Method updateScheduleNextTrigger must be implemented by subclass');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* List all schedules
|
|
97
|
+
*
|
|
98
|
+
* @param {Object} [options] - Query options
|
|
99
|
+
* @param {boolean} [options.enabledOnly] - Only return enabled schedules
|
|
100
|
+
* @returns {Promise<Array>} Array of schedule records
|
|
101
|
+
* @abstract
|
|
102
|
+
*/
|
|
103
|
+
async listSchedules(options = {}) {
|
|
104
|
+
throw new Error('Method listSchedules must be implemented by subclass');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
module.exports = { ScriptScheduleRepositoryInterface };
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
const { prisma } = require('../../database/prisma');
|
|
2
|
+
const {
|
|
3
|
+
ScriptScheduleRepositoryInterface,
|
|
4
|
+
} = require('./script-schedule-repository-interface');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* MongoDB Script Schedule Repository Adapter
|
|
8
|
+
* Handles script schedule persistence using Prisma with MongoDB
|
|
9
|
+
*
|
|
10
|
+
* MongoDB-specific characteristics:
|
|
11
|
+
* - IDs are strings with @db.ObjectId
|
|
12
|
+
* - scriptName has unique index
|
|
13
|
+
* - Supports upsert operations natively
|
|
14
|
+
*/
|
|
15
|
+
class ScriptScheduleRepositoryMongo extends ScriptScheduleRepositoryInterface {
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
this.prisma = prisma;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Find a schedule by script name
|
|
23
|
+
*
|
|
24
|
+
* @param {string} scriptName - The script name
|
|
25
|
+
* @returns {Promise<Object|null>} Schedule record or null if not found
|
|
26
|
+
*/
|
|
27
|
+
async findScheduleByScriptName(scriptName) {
|
|
28
|
+
const schedule = await this.prisma.scriptSchedule.findUnique({
|
|
29
|
+
where: { scriptName },
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return schedule;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Create or update a schedule (upsert)
|
|
37
|
+
*
|
|
38
|
+
* @param {Object} params - Schedule parameters
|
|
39
|
+
* @param {string} params.scriptName - Name of the script
|
|
40
|
+
* @param {boolean} params.enabled - Whether schedule is enabled
|
|
41
|
+
* @param {string} params.cronExpression - Cron expression
|
|
42
|
+
* @param {string} [params.timezone] - Timezone (default 'UTC')
|
|
43
|
+
* @param {string} [params.externalScheduleId] - External scheduler ID (e.g., AWS ARN)
|
|
44
|
+
* @param {string} [params.externalScheduleName] - External scheduler name
|
|
45
|
+
* @returns {Promise<Object>} Created or updated schedule record
|
|
46
|
+
*/
|
|
47
|
+
async upsertSchedule({ scriptName, enabled, cronExpression, timezone, externalScheduleId, externalScheduleName }) {
|
|
48
|
+
const data = {
|
|
49
|
+
enabled,
|
|
50
|
+
cronExpression,
|
|
51
|
+
timezone: timezone || 'UTC',
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Only set external scheduler fields if provided
|
|
55
|
+
if (externalScheduleId !== undefined) data.externalScheduleId = externalScheduleId;
|
|
56
|
+
if (externalScheduleName !== undefined) data.externalScheduleName = externalScheduleName;
|
|
57
|
+
|
|
58
|
+
const schedule = await this.prisma.scriptSchedule.upsert({
|
|
59
|
+
where: { scriptName },
|
|
60
|
+
update: data,
|
|
61
|
+
create: {
|
|
62
|
+
scriptName,
|
|
63
|
+
...data,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return schedule;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Delete a schedule by script name
|
|
72
|
+
*
|
|
73
|
+
* @param {string} scriptName - The script name
|
|
74
|
+
* @returns {Promise<Object>} Deletion result
|
|
75
|
+
*/
|
|
76
|
+
async deleteSchedule(scriptName) {
|
|
77
|
+
try {
|
|
78
|
+
const schedule = await this.prisma.scriptSchedule.delete({
|
|
79
|
+
where: { scriptName },
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
acknowledged: true,
|
|
84
|
+
deletedCount: 1,
|
|
85
|
+
deleted: schedule,
|
|
86
|
+
};
|
|
87
|
+
} catch (error) {
|
|
88
|
+
// Return 0 count if not found
|
|
89
|
+
if (error.code === 'P2025') {
|
|
90
|
+
return {
|
|
91
|
+
acknowledged: true,
|
|
92
|
+
deletedCount: 0,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Update external scheduler information
|
|
101
|
+
*
|
|
102
|
+
* @param {string} scriptName - The script name
|
|
103
|
+
* @param {Object} externalInfo - External schedule information
|
|
104
|
+
* @param {string} [externalInfo.externalScheduleId] - External scheduler ID (e.g., AWS ARN)
|
|
105
|
+
* @param {string} [externalInfo.externalScheduleName] - External scheduler name
|
|
106
|
+
* @returns {Promise<Object>} Updated schedule record
|
|
107
|
+
*/
|
|
108
|
+
async updateScheduleExternalInfo(scriptName, { externalScheduleId, externalScheduleName }) {
|
|
109
|
+
const data = {};
|
|
110
|
+
if (externalScheduleId !== undefined) data.externalScheduleId = externalScheduleId;
|
|
111
|
+
if (externalScheduleName !== undefined) data.externalScheduleName = externalScheduleName;
|
|
112
|
+
|
|
113
|
+
const schedule = await this.prisma.scriptSchedule.update({
|
|
114
|
+
where: { scriptName },
|
|
115
|
+
data,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return schedule;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Update last triggered timestamp
|
|
123
|
+
*
|
|
124
|
+
* @param {string} scriptName - The script name
|
|
125
|
+
* @param {Date} [timestamp] - Trigger timestamp (default: now)
|
|
126
|
+
* @returns {Promise<Object>} Updated schedule record
|
|
127
|
+
*/
|
|
128
|
+
async updateScheduleLastTriggered(scriptName, timestamp) {
|
|
129
|
+
const schedule = await this.prisma.scriptSchedule.update({
|
|
130
|
+
where: { scriptName },
|
|
131
|
+
data: {
|
|
132
|
+
lastTriggeredAt: timestamp || new Date(),
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
return schedule;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Update next trigger timestamp
|
|
141
|
+
*
|
|
142
|
+
* @param {string} scriptName - The script name
|
|
143
|
+
* @param {Date} timestamp - Next trigger timestamp
|
|
144
|
+
* @returns {Promise<Object>} Updated schedule record
|
|
145
|
+
*/
|
|
146
|
+
async updateScheduleNextTrigger(scriptName, timestamp) {
|
|
147
|
+
const schedule = await this.prisma.scriptSchedule.update({
|
|
148
|
+
where: { scriptName },
|
|
149
|
+
data: {
|
|
150
|
+
nextTriggerAt: timestamp,
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
return schedule;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* List all schedules
|
|
159
|
+
*
|
|
160
|
+
* @param {Object} [options] - Query options
|
|
161
|
+
* @param {boolean} [options.enabledOnly] - Only return enabled schedules
|
|
162
|
+
* @returns {Promise<Array>} Array of schedule records
|
|
163
|
+
*/
|
|
164
|
+
async listSchedules(options = {}) {
|
|
165
|
+
const where = {};
|
|
166
|
+
if (options.enabledOnly) {
|
|
167
|
+
where.enabled = true;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const schedules = await this.prisma.scriptSchedule.findMany({
|
|
171
|
+
where,
|
|
172
|
+
orderBy: { scriptName: 'asc' },
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
return schedules;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
module.exports = { ScriptScheduleRepositoryMongo };
|