@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,12 +1,6 @@
|
|
|
1
|
-
const bcrypt = require('bcryptjs');
|
|
2
|
-
const { v4: uuid } = require('uuid');
|
|
3
|
-
|
|
4
1
|
const ERROR_CODE_MAP = {
|
|
5
|
-
INVALID_API_KEY: 401,
|
|
6
|
-
EXPIRED_API_KEY: 401,
|
|
7
2
|
SCRIPT_NOT_FOUND: 404,
|
|
8
3
|
EXECUTION_NOT_FOUND: 404,
|
|
9
|
-
UNAUTHORIZED_SCOPE: 403,
|
|
10
4
|
};
|
|
11
5
|
|
|
12
6
|
function mapErrorToResponse(error) {
|
|
@@ -23,166 +17,50 @@ function mapErrorToResponse(error) {
|
|
|
23
17
|
* - Maps errors to HTTP-friendly responses
|
|
24
18
|
* - Returns data or error objects (never throws)
|
|
25
19
|
*
|
|
20
|
+
* WHY SEPARATE FROM integration-commands.js:
|
|
21
|
+
* These commands are intentionally separate because they serve different domains:
|
|
22
|
+
* - integration-commands: User-context operations on integrations
|
|
23
|
+
* - Requires integrationClass constructor parameter
|
|
24
|
+
* - Works with userId, entityIds, integration contexts
|
|
25
|
+
* - Uses IntegrationRepository, ModuleRepository
|
|
26
|
+
* - admin-script-commands: System/admin operations without user context
|
|
27
|
+
* - No user context required
|
|
28
|
+
* - Works with AdminProcess, ScriptSchedule
|
|
29
|
+
* - Uses AdminProcessRepository, ScriptScheduleRepository
|
|
30
|
+
*
|
|
31
|
+
* Merging them would violate SRP and create coupling between
|
|
32
|
+
* user-facing integration code and admin/system code.
|
|
33
|
+
*
|
|
34
|
+
* Authentication:
|
|
35
|
+
* - Uses ENV-based ADMIN_API_KEY (see handlers/middleware/admin-auth.js)
|
|
36
|
+
* - No database-backed API keys (simplified from original design)
|
|
37
|
+
*
|
|
26
38
|
* @returns {Object} Command methods for admin scripts
|
|
27
39
|
*/
|
|
28
40
|
function createAdminScriptCommands() {
|
|
29
41
|
// Lazy-load repository factories to avoid circular dependencies
|
|
30
|
-
const {
|
|
31
|
-
|
|
32
|
-
} = require('../../admin-scripts/repositories/admin-api-key-repository-factory');
|
|
33
|
-
const {
|
|
34
|
-
createScriptExecutionRepository,
|
|
35
|
-
} = require('../../admin-scripts/repositories/script-execution-repository-factory');
|
|
36
|
-
const {
|
|
37
|
-
createScriptScheduleRepository,
|
|
38
|
-
} = require('../../admin-scripts/repositories/script-schedule-repository-factory');
|
|
42
|
+
const { createAdminProcessRepository } = require('../../admin-scripts/repositories/admin-process-repository-factory');
|
|
43
|
+
const { createScriptScheduleRepository } = require('../../admin-scripts/repositories/script-schedule-repository-factory');
|
|
39
44
|
|
|
40
|
-
const
|
|
41
|
-
const executionRepository = createScriptExecutionRepository();
|
|
45
|
+
const adminProcessRepository = createAdminProcessRepository();
|
|
42
46
|
const scheduleRepository = createScriptScheduleRepository();
|
|
43
47
|
|
|
44
48
|
return {
|
|
45
|
-
// ====================
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Create a new admin API key
|
|
49
|
-
* Generates a UUID, hashes it with bcrypt, stores in database
|
|
50
|
-
*
|
|
51
|
-
* @param {Object} params - Key creation parameters
|
|
52
|
-
* @param {string} params.name - Human-readable name for the key
|
|
53
|
-
* @param {string[]} params.scopes - Permission scopes (e.g., ['scripts:execute'])
|
|
54
|
-
* @param {Date} [params.expiresAt] - Optional expiration date
|
|
55
|
-
* @param {string} [params.createdBy] - Optional creator identifier
|
|
56
|
-
* @returns {Promise<Object>} Created key with rawKey (only returned once!)
|
|
57
|
-
*/
|
|
58
|
-
async createAdminApiKey({ name, scopes, expiresAt, createdBy }) {
|
|
59
|
-
try {
|
|
60
|
-
// Generate raw key (UUID format)
|
|
61
|
-
const rawKey = uuid();
|
|
62
|
-
|
|
63
|
-
// Hash with bcrypt (cost factor 10)
|
|
64
|
-
const keyHash = await bcrypt.hash(rawKey, 10);
|
|
65
|
-
|
|
66
|
-
// Store last 4 characters for display
|
|
67
|
-
const keyLast4 = rawKey.slice(-4);
|
|
68
|
-
|
|
69
|
-
// Create via repository
|
|
70
|
-
const record = await apiKeyRepository.createApiKey({
|
|
71
|
-
name,
|
|
72
|
-
keyHash,
|
|
73
|
-
keyLast4,
|
|
74
|
-
scopes,
|
|
75
|
-
expiresAt,
|
|
76
|
-
createdBy,
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// Return record with rawKey (ONLY TIME IT'S RETURNED!)
|
|
80
|
-
return {
|
|
81
|
-
id: record.id,
|
|
82
|
-
rawKey, // User must save this - we never show it again
|
|
83
|
-
name: record.name,
|
|
84
|
-
keyLast4: record.keyLast4,
|
|
85
|
-
scopes: record.scopes,
|
|
86
|
-
expiresAt: record.expiresAt,
|
|
87
|
-
};
|
|
88
|
-
} catch (error) {
|
|
89
|
-
return mapErrorToResponse(error);
|
|
90
|
-
}
|
|
91
|
-
},
|
|
49
|
+
// ==================== Admin Process Management Commands ====================
|
|
92
50
|
|
|
93
51
|
/**
|
|
94
|
-
*
|
|
95
|
-
* Compares bcrypt hash, checks expiration, updates lastUsedAt
|
|
52
|
+
* Create a new admin process record
|
|
96
53
|
*
|
|
97
|
-
* @param {
|
|
98
|
-
* @returns {Promise<Object>} { valid: true, apiKey } or error response
|
|
99
|
-
*/
|
|
100
|
-
async validateAdminApiKey(rawKey) {
|
|
101
|
-
try {
|
|
102
|
-
// Find all active keys
|
|
103
|
-
const activeKeys = await apiKeyRepository.findActiveApiKeys();
|
|
104
|
-
|
|
105
|
-
// Compare bcrypt hash for each key
|
|
106
|
-
for (const key of activeKeys) {
|
|
107
|
-
const isMatch = await bcrypt.compare(rawKey, key.keyHash);
|
|
108
|
-
if (isMatch) {
|
|
109
|
-
// Check expiration
|
|
110
|
-
if (
|
|
111
|
-
key.expiresAt &&
|
|
112
|
-
new Date(key.expiresAt) < new Date()
|
|
113
|
-
) {
|
|
114
|
-
const error = new Error('API key has expired');
|
|
115
|
-
error.code = 'EXPIRED_API_KEY';
|
|
116
|
-
return mapErrorToResponse(error);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Update lastUsedAt on success
|
|
120
|
-
await apiKeyRepository.updateApiKeyLastUsed(key.id);
|
|
121
|
-
|
|
122
|
-
return { valid: true, apiKey: key };
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// No match found
|
|
127
|
-
const error = new Error('Invalid API key');
|
|
128
|
-
error.code = 'INVALID_API_KEY';
|
|
129
|
-
return mapErrorToResponse(error);
|
|
130
|
-
} catch (error) {
|
|
131
|
-
return mapErrorToResponse(error);
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* List all active admin API keys
|
|
137
|
-
* Returns keys without keyHash (security)
|
|
138
|
-
*
|
|
139
|
-
* @returns {Promise<Array>} Array of API key records (without keyHash)
|
|
140
|
-
*/
|
|
141
|
-
async listAdminApiKeys() {
|
|
142
|
-
try {
|
|
143
|
-
const keys = await apiKeyRepository.findActiveApiKeys();
|
|
144
|
-
|
|
145
|
-
// Remove keyHash from response (security)
|
|
146
|
-
return keys.map((key) => {
|
|
147
|
-
const { keyHash, ...safeKey } = key;
|
|
148
|
-
return safeKey;
|
|
149
|
-
});
|
|
150
|
-
} catch (error) {
|
|
151
|
-
return mapErrorToResponse(error);
|
|
152
|
-
}
|
|
153
|
-
},
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Deactivate an admin API key
|
|
157
|
-
* Soft delete - sets isActive to false
|
|
158
|
-
*
|
|
159
|
-
* @param {string|number} id - The API key ID
|
|
160
|
-
* @returns {Promise<Object>} Updated record or error
|
|
161
|
-
*/
|
|
162
|
-
async deactivateAdminApiKey(id) {
|
|
163
|
-
try {
|
|
164
|
-
const result = await apiKeyRepository.deactivateApiKey(id);
|
|
165
|
-
return result;
|
|
166
|
-
} catch (error) {
|
|
167
|
-
return mapErrorToResponse(error);
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
|
|
171
|
-
// ==================== Execution Management Commands ====================
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Create a new script execution record
|
|
175
|
-
*
|
|
176
|
-
* @param {Object} params - Execution creation parameters
|
|
54
|
+
* @param {Object} params - Process creation parameters
|
|
177
55
|
* @param {string} params.scriptName - Name of script being executed
|
|
178
56
|
* @param {string} [params.scriptVersion] - Script version
|
|
179
57
|
* @param {string} params.trigger - Trigger type ('MANUAL', 'SCHEDULED', 'QUEUE', 'WEBHOOK')
|
|
180
58
|
* @param {string} [params.mode] - Execution mode ('sync' or 'async', default 'async')
|
|
181
59
|
* @param {Object} [params.input] - Input parameters
|
|
182
60
|
* @param {Object} [params.audit] - Audit information (apiKeyName, apiKeyLast4, ipAddress)
|
|
183
|
-
* @returns {Promise<Object>} Created
|
|
61
|
+
* @returns {Promise<Object>} Created admin process record
|
|
184
62
|
*/
|
|
185
|
-
async
|
|
63
|
+
async createAdminProcess({
|
|
186
64
|
scriptName,
|
|
187
65
|
scriptVersion,
|
|
188
66
|
trigger,
|
|
@@ -191,7 +69,7 @@ function createAdminScriptCommands() {
|
|
|
191
69
|
audit,
|
|
192
70
|
}) {
|
|
193
71
|
try {
|
|
194
|
-
const
|
|
72
|
+
const process = await adminProcessRepository.createAdminProcess({
|
|
195
73
|
scriptName,
|
|
196
74
|
scriptVersion,
|
|
197
75
|
trigger,
|
|
@@ -199,51 +77,46 @@ function createAdminScriptCommands() {
|
|
|
199
77
|
input,
|
|
200
78
|
audit,
|
|
201
79
|
});
|
|
202
|
-
return
|
|
80
|
+
return process;
|
|
203
81
|
} catch (error) {
|
|
204
82
|
return mapErrorToResponse(error);
|
|
205
83
|
}
|
|
206
84
|
},
|
|
207
85
|
|
|
208
86
|
/**
|
|
209
|
-
* Find
|
|
87
|
+
* Find an admin process by ID
|
|
210
88
|
*
|
|
211
|
-
* @param {string|number}
|
|
212
|
-
* @returns {Promise<Object>}
|
|
89
|
+
* @param {string|number} processId - The admin process ID
|
|
90
|
+
* @returns {Promise<Object>} Admin process record or error
|
|
213
91
|
*/
|
|
214
|
-
async
|
|
92
|
+
async findAdminProcessById(processId) {
|
|
215
93
|
try {
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (!execution) {
|
|
220
|
-
const error = new Error(
|
|
221
|
-
`Execution ${executionId} not found`
|
|
222
|
-
);
|
|
94
|
+
const process = await adminProcessRepository.findAdminProcessById(processId);
|
|
95
|
+
if (!process) {
|
|
96
|
+
const error = new Error(`Execution ${processId} not found`);
|
|
223
97
|
error.code = 'EXECUTION_NOT_FOUND';
|
|
224
98
|
return mapErrorToResponse(error);
|
|
225
99
|
}
|
|
226
|
-
return
|
|
100
|
+
return process;
|
|
227
101
|
} catch (error) {
|
|
228
102
|
return mapErrorToResponse(error);
|
|
229
103
|
}
|
|
230
104
|
},
|
|
231
105
|
|
|
232
106
|
/**
|
|
233
|
-
* Find all
|
|
107
|
+
* Find all admin processes for a specific script
|
|
234
108
|
*
|
|
235
109
|
* @param {string} scriptName - Script name to filter by
|
|
236
110
|
* @param {Object} [options] - Query options (limit, offset, sortBy, sortOrder)
|
|
237
|
-
* @returns {Promise<Array>} Array of
|
|
111
|
+
* @returns {Promise<Array>} Array of admin process records
|
|
238
112
|
*/
|
|
239
|
-
async
|
|
113
|
+
async findAdminProcessesByName(scriptName, options = {}) {
|
|
240
114
|
try {
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return executions;
|
|
115
|
+
const processes = await adminProcessRepository.findAdminProcessesByName(
|
|
116
|
+
scriptName,
|
|
117
|
+
options
|
|
118
|
+
);
|
|
119
|
+
return processes;
|
|
247
120
|
} catch (error) {
|
|
248
121
|
// Return empty array on error (non-critical)
|
|
249
122
|
return [];
|
|
@@ -251,17 +124,17 @@ function createAdminScriptCommands() {
|
|
|
251
124
|
},
|
|
252
125
|
|
|
253
126
|
/**
|
|
254
|
-
* Update
|
|
127
|
+
* Update admin process state
|
|
255
128
|
*
|
|
256
|
-
* @param {string|number}
|
|
257
|
-
* @param {string}
|
|
258
|
-
* @returns {Promise<Object>} Updated
|
|
129
|
+
* @param {string|number} processId - The admin process ID
|
|
130
|
+
* @param {string} state - New state ('PENDING', 'RUNNING', 'COMPLETED', 'FAILED')
|
|
131
|
+
* @returns {Promise<Object>} Updated admin process record
|
|
259
132
|
*/
|
|
260
|
-
async
|
|
133
|
+
async updateAdminProcessState(processId, state) {
|
|
261
134
|
try {
|
|
262
|
-
const updated = await
|
|
263
|
-
|
|
264
|
-
|
|
135
|
+
const updated = await adminProcessRepository.updateAdminProcessState(
|
|
136
|
+
processId,
|
|
137
|
+
state
|
|
265
138
|
);
|
|
266
139
|
return updated;
|
|
267
140
|
} catch (error) {
|
|
@@ -270,16 +143,16 @@ function createAdminScriptCommands() {
|
|
|
270
143
|
},
|
|
271
144
|
|
|
272
145
|
/**
|
|
273
|
-
* Append a log entry to an
|
|
146
|
+
* Append a log entry to an admin process's results.logs array
|
|
274
147
|
*
|
|
275
|
-
* @param {string|number}
|
|
148
|
+
* @param {string|number} processId - The admin process ID
|
|
276
149
|
* @param {Object} logEntry - Log entry { level, message, data, timestamp }
|
|
277
|
-
* @returns {Promise<Object>} Updated
|
|
150
|
+
* @returns {Promise<Object>} Updated admin process record
|
|
278
151
|
*/
|
|
279
|
-
async
|
|
152
|
+
async appendAdminProcessLog(processId, logEntry) {
|
|
280
153
|
try {
|
|
281
|
-
const updated = await
|
|
282
|
-
|
|
154
|
+
const updated = await adminProcessRepository.appendAdminProcessLog(
|
|
155
|
+
processId,
|
|
283
156
|
logEntry
|
|
284
157
|
);
|
|
285
158
|
return updated;
|
|
@@ -289,46 +162,31 @@ function createAdminScriptCommands() {
|
|
|
289
162
|
},
|
|
290
163
|
|
|
291
164
|
/**
|
|
292
|
-
* Complete
|
|
293
|
-
* Updates
|
|
165
|
+
* Complete an admin process
|
|
166
|
+
* Updates state, output, error, and metrics
|
|
294
167
|
*
|
|
295
|
-
* @param {string|number}
|
|
168
|
+
* @param {string|number} processId - The admin process ID
|
|
296
169
|
* @param {Object} params - Completion parameters
|
|
297
|
-
* @param {string} [params.
|
|
298
|
-
* @param {Object} [params.output] - Script output/result
|
|
299
|
-
* @param {Object} [params.error] - Error details { name, message, stack }
|
|
300
|
-
* @param {Object} [params.metrics] - Performance metrics { startTime, endTime, durationMs }
|
|
170
|
+
* @param {string} [params.state] - Final state ('COMPLETED', 'FAILED')
|
|
171
|
+
* @param {Object} [params.output] - Script output/result (stored in results.output)
|
|
172
|
+
* @param {Object} [params.error] - Error details { name, message, stack } (stored in results.error)
|
|
173
|
+
* @param {Object} [params.metrics] - Performance metrics { startTime, endTime, durationMs } (stored in results.metrics)
|
|
301
174
|
* @returns {Promise<Object>} { success: true } or error
|
|
302
175
|
*/
|
|
303
|
-
async
|
|
304
|
-
executionId,
|
|
305
|
-
{ status, output, error, metrics }
|
|
306
|
-
) {
|
|
176
|
+
async completeAdminProcess(processId, { state, output, error, metrics }) {
|
|
307
177
|
try {
|
|
308
178
|
// Update each field independently (partial updates allowed)
|
|
309
|
-
if (
|
|
310
|
-
await
|
|
311
|
-
executionId,
|
|
312
|
-
status
|
|
313
|
-
);
|
|
179
|
+
if (state) {
|
|
180
|
+
await adminProcessRepository.updateAdminProcessState(processId, state);
|
|
314
181
|
}
|
|
315
182
|
if (output !== undefined) {
|
|
316
|
-
await
|
|
317
|
-
executionId,
|
|
318
|
-
output
|
|
319
|
-
);
|
|
183
|
+
await adminProcessRepository.updateAdminProcessOutput(processId, output);
|
|
320
184
|
}
|
|
321
185
|
if (error) {
|
|
322
|
-
await
|
|
323
|
-
executionId,
|
|
324
|
-
error
|
|
325
|
-
);
|
|
186
|
+
await adminProcessRepository.updateAdminProcessError(processId, error);
|
|
326
187
|
}
|
|
327
188
|
if (metrics) {
|
|
328
|
-
await
|
|
329
|
-
executionId,
|
|
330
|
-
metrics
|
|
331
|
-
);
|
|
189
|
+
await adminProcessRepository.updateAdminProcessMetrics(processId, metrics);
|
|
332
190
|
}
|
|
333
191
|
|
|
334
192
|
return { success: true };
|
|
@@ -338,32 +196,29 @@ function createAdminScriptCommands() {
|
|
|
338
196
|
},
|
|
339
197
|
|
|
340
198
|
/**
|
|
341
|
-
* Find recent
|
|
199
|
+
* Find recent admin processes across all scripts
|
|
342
200
|
*
|
|
343
201
|
* @param {Object} [options] - Query options
|
|
344
202
|
* @param {number} [options.limit] - Maximum results (default 20)
|
|
345
|
-
* @param {string} [options.
|
|
203
|
+
* @param {string} [options.state] - Filter by state
|
|
346
204
|
* @param {Date} [options.since] - Filter by created date
|
|
347
|
-
* @returns {Promise<Array>} Array of recent
|
|
205
|
+
* @returns {Promise<Array>} Array of recent admin processes
|
|
348
206
|
*/
|
|
349
|
-
async
|
|
207
|
+
async findRecentAdminProcesses(options = {}) {
|
|
350
208
|
try {
|
|
351
|
-
const { limit = 20,
|
|
352
|
-
|
|
353
|
-
// If
|
|
354
|
-
if (
|
|
355
|
-
return await
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
sortOrder: 'desc',
|
|
361
|
-
}
|
|
362
|
-
);
|
|
209
|
+
const { limit = 20, state, since } = options;
|
|
210
|
+
|
|
211
|
+
// If state filter provided, use state query
|
|
212
|
+
if (state) {
|
|
213
|
+
return await adminProcessRepository.findAdminProcessesByState(state, {
|
|
214
|
+
limit,
|
|
215
|
+
sortBy: 'createdAt',
|
|
216
|
+
sortOrder: 'desc',
|
|
217
|
+
});
|
|
363
218
|
}
|
|
364
219
|
|
|
365
220
|
// Otherwise, use generic recent query (would need to be added to interface)
|
|
366
|
-
// For now, fall back to empty array if no
|
|
221
|
+
// For now, fall back to empty array if no state filter
|
|
367
222
|
return [];
|
|
368
223
|
} catch (error) {
|
|
369
224
|
return [];
|
|
@@ -381,10 +236,7 @@ function createAdminScriptCommands() {
|
|
|
381
236
|
*/
|
|
382
237
|
async getScheduleByScriptName(scriptName) {
|
|
383
238
|
try {
|
|
384
|
-
const schedule =
|
|
385
|
-
await scheduleRepository.findScheduleByScriptName(
|
|
386
|
-
scriptName
|
|
387
|
-
);
|
|
239
|
+
const schedule = await scheduleRepository.findScheduleByScriptName(scriptName);
|
|
388
240
|
return schedule;
|
|
389
241
|
} catch (error) {
|
|
390
242
|
return mapErrorToResponse(error);
|
|
@@ -401,12 +253,7 @@ function createAdminScriptCommands() {
|
|
|
401
253
|
* @param {string} [params.timezone] - Timezone (default 'UTC')
|
|
402
254
|
* @returns {Promise<Object>} Created or updated schedule
|
|
403
255
|
*/
|
|
404
|
-
async upsertSchedule({
|
|
405
|
-
scriptName,
|
|
406
|
-
enabled,
|
|
407
|
-
cronExpression,
|
|
408
|
-
timezone,
|
|
409
|
-
}) {
|
|
256
|
+
async upsertSchedule({ scriptName, enabled, cronExpression, timezone }) {
|
|
410
257
|
try {
|
|
411
258
|
const schedule = await scheduleRepository.upsertSchedule({
|
|
412
259
|
scriptName,
|
|
@@ -428,9 +275,7 @@ function createAdminScriptCommands() {
|
|
|
428
275
|
*/
|
|
429
276
|
async deleteSchedule(scriptName) {
|
|
430
277
|
try {
|
|
431
|
-
const result = await scheduleRepository.deleteSchedule(
|
|
432
|
-
scriptName
|
|
433
|
-
);
|
|
278
|
+
const result = await scheduleRepository.deleteSchedule(scriptName);
|
|
434
279
|
return result;
|
|
435
280
|
} catch (error) {
|
|
436
281
|
return mapErrorToResponse(error);
|
|
@@ -438,26 +283,20 @@ function createAdminScriptCommands() {
|
|
|
438
283
|
},
|
|
439
284
|
|
|
440
285
|
/**
|
|
441
|
-
* Update
|
|
286
|
+
* Update external scheduler information
|
|
442
287
|
*
|
|
443
288
|
* @param {string} scriptName - The script name
|
|
444
|
-
* @param {Object}
|
|
445
|
-
* @param {string} [
|
|
446
|
-
* @param {string} [
|
|
289
|
+
* @param {Object} externalInfo - External schedule information
|
|
290
|
+
* @param {string} [externalInfo.externalScheduleId] - External scheduler ID (e.g., AWS ARN)
|
|
291
|
+
* @param {string} [externalInfo.externalScheduleName] - External scheduler name
|
|
447
292
|
* @returns {Promise<Object>} Updated schedule
|
|
448
293
|
*/
|
|
449
|
-
async
|
|
450
|
-
scriptName,
|
|
451
|
-
{ awsScheduleArn, awsScheduleName }
|
|
452
|
-
) {
|
|
294
|
+
async updateScheduleExternalInfo(scriptName, { externalScheduleId, externalScheduleName }) {
|
|
453
295
|
try {
|
|
454
|
-
const schedule = await scheduleRepository.
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
awsScheduleName,
|
|
459
|
-
}
|
|
460
|
-
);
|
|
296
|
+
const schedule = await scheduleRepository.updateScheduleExternalInfo(scriptName, {
|
|
297
|
+
externalScheduleId,
|
|
298
|
+
externalScheduleName,
|
|
299
|
+
});
|
|
461
300
|
return schedule;
|
|
462
301
|
} catch (error) {
|
|
463
302
|
return mapErrorToResponse(error);
|
|
@@ -474,11 +313,10 @@ function createAdminScriptCommands() {
|
|
|
474
313
|
*/
|
|
475
314
|
async updateScheduleLastTriggered(scriptName, timestamp) {
|
|
476
315
|
try {
|
|
477
|
-
const schedule =
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
);
|
|
316
|
+
const schedule = await scheduleRepository.updateScheduleLastTriggered(
|
|
317
|
+
scriptName,
|
|
318
|
+
timestamp
|
|
319
|
+
);
|
|
482
320
|
return schedule;
|
|
483
321
|
} catch (error) {
|
|
484
322
|
return mapErrorToResponse(error);
|
|
@@ -494,9 +332,7 @@ function createAdminScriptCommands() {
|
|
|
494
332
|
*/
|
|
495
333
|
async listSchedules(options = {}) {
|
|
496
334
|
try {
|
|
497
|
-
const schedules = await scheduleRepository.listSchedules(
|
|
498
|
-
options
|
|
499
|
-
);
|
|
335
|
+
const schedules = await scheduleRepository.listSchedules(options);
|
|
500
336
|
return schedules;
|
|
501
337
|
} catch (error) {
|
|
502
338
|
return [];
|
|
@@ -152,11 +152,10 @@ function createIntegrationCommands({ integrationClass }) {
|
|
|
152
152
|
*/
|
|
153
153
|
async updateIntegrationConfig({ integrationId, config }) {
|
|
154
154
|
try {
|
|
155
|
-
const integration =
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
);
|
|
155
|
+
const integration = await integrationRepository.updateIntegrationConfig(
|
|
156
|
+
integrationId,
|
|
157
|
+
config
|
|
158
|
+
);
|
|
160
159
|
return integration;
|
|
161
160
|
} catch (error) {
|
|
162
161
|
return mapErrorToResponse(error);
|
|
@@ -176,15 +175,10 @@ function createIntegrationCommands({ integrationClass }) {
|
|
|
176
175
|
throw error;
|
|
177
176
|
}
|
|
178
177
|
|
|
179
|
-
const deleted =
|
|
180
|
-
await integrationRepository.deleteIntegrationById(
|
|
181
|
-
integrationId
|
|
182
|
-
);
|
|
178
|
+
const deleted = await integrationRepository.deleteIntegrationById(integrationId);
|
|
183
179
|
|
|
184
180
|
if (!deleted) {
|
|
185
|
-
const error = new Error(
|
|
186
|
-
`Integration ${integrationId} not found`
|
|
187
|
-
);
|
|
181
|
+
const error = new Error(`Integration ${integrationId} not found`);
|
|
188
182
|
error.code = 'INTEGRATION_NOT_FOUND';
|
|
189
183
|
return mapErrorToResponse(error);
|
|
190
184
|
}
|
package/application/index.js
CHANGED
|
@@ -4,7 +4,9 @@ const {
|
|
|
4
4
|
} = require('./commands/integration-commands');
|
|
5
5
|
const { createUserCommands } = require('./commands/user-commands');
|
|
6
6
|
const { createEntityCommands } = require('./commands/entity-commands');
|
|
7
|
-
const {
|
|
7
|
+
const {
|
|
8
|
+
createCredentialCommands,
|
|
9
|
+
} = require('./commands/credential-commands');
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Create a unified command factory with all CRUD operations
|
package/assertions/get.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
const lodashGet = require('lodash.get');
|
|
2
|
-
const {
|
|
2
|
+
const {
|
|
3
|
+
RequiredPropertyError,
|
|
4
|
+
ParameterTypeError,
|
|
5
|
+
} = require('../errors');
|
|
3
6
|
|
|
4
7
|
const get = (o, key, defaultValue) => {
|
|
5
8
|
const value = lodashGet(o, key, defaultValue);
|