@memberjunction/server 2.112.0 → 2.113.1
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/dist/agents/skip-agent.d.ts +4 -4
- package/dist/agents/skip-agent.d.ts.map +1 -1
- package/dist/agents/skip-agent.js +951 -808
- package/dist/agents/skip-agent.js.map +1 -1
- package/dist/agents/skip-sdk.d.ts +1 -1
- package/dist/agents/skip-sdk.d.ts.map +1 -1
- package/dist/agents/skip-sdk.js +43 -53
- package/dist/agents/skip-sdk.js.map +1 -1
- package/dist/apolloServer/index.js +1 -1
- package/dist/auth/AuthProviderFactory.d.ts +1 -1
- package/dist/auth/AuthProviderFactory.d.ts.map +1 -1
- package/dist/auth/AuthProviderFactory.js +3 -1
- package/dist/auth/AuthProviderFactory.js.map +1 -1
- package/dist/auth/BaseAuthProvider.d.ts +1 -1
- package/dist/auth/BaseAuthProvider.d.ts.map +1 -1
- package/dist/auth/BaseAuthProvider.js +2 -3
- package/dist/auth/BaseAuthProvider.js.map +1 -1
- package/dist/auth/IAuthProvider.d.ts +1 -1
- package/dist/auth/IAuthProvider.d.ts.map +1 -1
- package/dist/auth/exampleNewUserSubClass.d.ts.map +1 -1
- package/dist/auth/exampleNewUserSubClass.js +1 -1
- package/dist/auth/exampleNewUserSubClass.js.map +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +6 -6
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/initializeProviders.js +1 -1
- package/dist/auth/initializeProviders.js.map +1 -1
- package/dist/auth/newUsers.d.ts +1 -1
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +7 -7
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/auth/providers/Auth0Provider.d.ts +1 -1
- package/dist/auth/providers/Auth0Provider.d.ts.map +1 -1
- package/dist/auth/providers/Auth0Provider.js +1 -1
- package/dist/auth/providers/Auth0Provider.js.map +1 -1
- package/dist/auth/providers/CognitoProvider.d.ts +1 -1
- package/dist/auth/providers/CognitoProvider.d.ts.map +1 -1
- package/dist/auth/providers/CognitoProvider.js +6 -3
- package/dist/auth/providers/CognitoProvider.js.map +1 -1
- package/dist/auth/providers/GoogleProvider.d.ts +1 -1
- package/dist/auth/providers/GoogleProvider.d.ts.map +1 -1
- package/dist/auth/providers/GoogleProvider.js +1 -1
- package/dist/auth/providers/GoogleProvider.js.map +1 -1
- package/dist/auth/providers/MSALProvider.d.ts +1 -1
- package/dist/auth/providers/MSALProvider.d.ts.map +1 -1
- package/dist/auth/providers/MSALProvider.js +1 -1
- package/dist/auth/providers/MSALProvider.js.map +1 -1
- package/dist/auth/providers/OktaProvider.d.ts +1 -1
- package/dist/auth/providers/OktaProvider.d.ts.map +1 -1
- package/dist/auth/providers/OktaProvider.js +1 -1
- package/dist/auth/providers/OktaProvider.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -22
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +7 -9
- package/dist/context.js.map +1 -1
- package/dist/entitySubclasses/entityPermissions.server.d.ts +1 -1
- package/dist/entitySubclasses/entityPermissions.server.d.ts.map +1 -1
- package/dist/entitySubclasses/entityPermissions.server.js +1 -1
- package/dist/entitySubclasses/entityPermissions.server.js.map +1 -1
- package/dist/generated/generated.d.ts +788 -658
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +2050 -3054
- package/dist/generated/generated.js.map +1 -1
- package/dist/generic/KeyInputOutputTypes.d.ts +1 -1
- package/dist/generic/KeyInputOutputTypes.d.ts.map +1 -1
- package/dist/generic/KeyInputOutputTypes.js +1 -1
- package/dist/generic/KeyInputOutputTypes.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +1 -1
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +10 -15
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +1 -1
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +15 -15
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -18
- package/dist/index.js.map +1 -1
- package/dist/resolvers/ActionResolver.d.ts +2 -2
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +30 -28
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/AskSkipResolver.d.ts +2 -2
- package/dist/resolvers/AskSkipResolver.d.ts.map +1 -1
- package/dist/resolvers/AskSkipResolver.js +50 -60
- package/dist/resolvers/AskSkipResolver.js.map +1 -1
- package/dist/resolvers/ComponentRegistryResolver.d.ts.map +1 -1
- package/dist/resolvers/ComponentRegistryResolver.js +38 -36
- package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
- package/dist/resolvers/CreateQueryResolver.d.ts +1 -1
- package/dist/resolvers/CreateQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/CreateQueryResolver.js +40 -43
- package/dist/resolvers/CreateQueryResolver.js.map +1 -1
- package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
- package/dist/resolvers/DatasetResolver.js +1 -1
- package/dist/resolvers/DatasetResolver.js.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts +1 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/EntityResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityResolver.js +1 -1
- package/dist/resolvers/EntityResolver.js.map +1 -1
- package/dist/resolvers/FileCategoryResolver.js +1 -1
- package/dist/resolvers/FileCategoryResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.js +1 -1
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.d.ts +1 -1
- package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js +5 -5
- package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +6 -8
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts +3 -3
- package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.js +3 -3
- package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.d.ts +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.d.ts.map +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.js +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.js.map +1 -1
- package/dist/resolvers/QueryResolver.d.ts.map +1 -1
- package/dist/resolvers/QueryResolver.js +11 -11
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/ReportResolver.js +1 -1
- package/dist/resolvers/ReportResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +28 -27
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.js +31 -31
- package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +9 -9
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +10 -10
- package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +14 -15
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +44 -48
- package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
- package/dist/resolvers/TaskResolver.d.ts.map +1 -1
- package/dist/resolvers/TaskResolver.js +7 -7
- package/dist/resolvers/TaskResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +12 -12
- package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.d.ts +1 -1
- package/dist/resolvers/UserFavoriteResolver.d.ts.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.js +1 -1
- package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
- package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
- package/dist/resolvers/UserViewResolver.js.map +1 -1
- package/dist/rest/EntityCRUDHandler.d.ts +1 -1
- package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
- package/dist/rest/EntityCRUDHandler.js +16 -14
- package/dist/rest/EntityCRUDHandler.js.map +1 -1
- package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
- package/dist/rest/RESTEndpointHandler.js +25 -23
- package/dist/rest/RESTEndpointHandler.js.map +1 -1
- package/dist/rest/ViewOperationsHandler.d.ts +1 -1
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +21 -17
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/scheduler/LearningCycleScheduler.d.ts.map +1 -1
- package/dist/scheduler/LearningCycleScheduler.js.map +1 -1
- package/dist/services/ScheduledJobsService.d.ts.map +1 -1
- package/dist/services/ScheduledJobsService.js +6 -4
- package/dist/services/ScheduledJobsService.js.map +1 -1
- package/dist/services/TaskOrchestrator.d.ts +1 -1
- package/dist/services/TaskOrchestrator.d.ts.map +1 -1
- package/dist/services/TaskOrchestrator.js +30 -30
- package/dist/services/TaskOrchestrator.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/util.d.ts +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +2 -2
- package/dist/util.js.map +1 -1
- package/package.json +39 -36
- package/src/agents/skip-agent.ts +1200 -1067
- package/src/agents/skip-sdk.ts +851 -877
- package/src/apolloServer/index.ts +2 -2
- package/src/auth/AuthProviderFactory.ts +14 -8
- package/src/auth/BaseAuthProvider.ts +4 -5
- package/src/auth/IAuthProvider.ts +2 -2
- package/src/auth/exampleNewUserSubClass.ts +2 -9
- package/src/auth/index.ts +26 -31
- package/src/auth/initializeProviders.ts +3 -3
- package/src/auth/newUsers.ts +134 -166
- package/src/auth/providers/Auth0Provider.ts +5 -5
- package/src/auth/providers/CognitoProvider.ts +10 -7
- package/src/auth/providers/GoogleProvider.ts +5 -4
- package/src/auth/providers/MSALProvider.ts +5 -5
- package/src/auth/providers/OktaProvider.ts +7 -6
- package/src/config.ts +54 -63
- package/src/context.ts +30 -42
- package/src/entitySubclasses/entityPermissions.server.ts +3 -3
- package/src/generated/generated.ts +40442 -48106
- package/src/generic/KeyInputOutputTypes.ts +6 -3
- package/src/generic/ResolverBase.ts +78 -119
- package/src/generic/RunViewResolver.ts +23 -27
- package/src/index.ts +48 -66
- package/src/resolvers/ActionResolver.ts +57 -46
- package/src/resolvers/AskSkipResolver.ts +533 -607
- package/src/resolvers/ComponentRegistryResolver.ts +562 -547
- package/src/resolvers/CreateQueryResolver.ts +655 -683
- package/src/resolvers/DatasetResolver.ts +6 -5
- package/src/resolvers/EntityCommunicationsResolver.ts +1 -1
- package/src/resolvers/EntityRecordNameResolver.ts +5 -9
- package/src/resolvers/EntityResolver.ts +7 -9
- package/src/resolvers/FileCategoryResolver.ts +2 -2
- package/src/resolvers/FileResolver.ts +4 -4
- package/src/resolvers/GetDataContextDataResolver.ts +118 -106
- package/src/resolvers/GetDataResolver.ts +205 -194
- package/src/resolvers/MergeRecordsResolver.ts +5 -5
- package/src/resolvers/PotentialDuplicateRecordResolver.ts +1 -1
- package/src/resolvers/QueryResolver.ts +78 -95
- package/src/resolvers/ReportResolver.ts +2 -2
- package/src/resolvers/RunAIAgentResolver.ts +828 -818
- package/src/resolvers/RunAIPromptResolver.ts +709 -693
- package/src/resolvers/RunTemplateResolver.ts +103 -105
- package/src/resolvers/SqlLoggingConfigResolver.ts +72 -69
- package/src/resolvers/SyncDataResolver.ts +352 -386
- package/src/resolvers/SyncRolesUsersResolver.ts +350 -387
- package/src/resolvers/TaskResolver.ts +115 -110
- package/src/resolvers/TransactionGroupResolver.ts +138 -143
- package/src/resolvers/UserFavoriteResolver.ts +8 -17
- package/src/resolvers/UserViewResolver.ts +12 -17
- package/src/rest/EntityCRUDHandler.ts +268 -291
- package/src/rest/RESTEndpointHandler.ts +776 -782
- package/src/rest/ViewOperationsHandler.ts +195 -191
- package/src/scheduler/LearningCycleScheduler.ts +52 -8
- package/src/services/ScheduledJobsService.ts +132 -129
- package/src/services/TaskOrchestrator.ts +776 -792
- package/src/types.ts +9 -15
- package/src/util.ts +109 -112
|
@@ -1,203 +1,207 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
LogError, Metadata, RunView, RunViewParams,
|
|
3
|
+
RunViewResult, UserInfo
|
|
4
|
+
} from '@memberjunction/core';
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* View Operations Implementation for REST endpoints
|
|
5
8
|
* These functions handle running views through the REST API
|
|
6
9
|
*/
|
|
7
10
|
export class ViewOperationsHandler {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Run multiple views in batch
|
|
48
|
-
*/
|
|
49
|
-
static async runViews(
|
|
50
|
-
paramsArray: RunViewParams[],
|
|
51
|
-
user: UserInfo
|
|
52
|
-
): Promise<{ success: boolean; results?: RunViewResult[]; error?: string }> {
|
|
53
|
-
try {
|
|
54
|
-
// Validate and sanitize each set of parameters
|
|
55
|
-
const md = new Metadata();
|
|
56
|
-
for (const params of paramsArray) {
|
|
57
|
-
// Validate entity exists
|
|
58
|
-
const entity = md.Entities.find((e) => e.Name === params.EntityName);
|
|
59
|
-
if (!entity) {
|
|
60
|
-
return {
|
|
61
|
-
success: false,
|
|
62
|
-
error: `Entity '${params.EntityName}' not found`,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Check read permission
|
|
67
|
-
const permissions = entity.GetUserPermisions(user);
|
|
68
|
-
if (!permissions.CanRead) {
|
|
69
|
-
return {
|
|
70
|
-
success: false,
|
|
71
|
-
error: `User ${user.Name} does not have permission to read ${params.EntityName} records`,
|
|
72
|
-
};
|
|
11
|
+
/**
|
|
12
|
+
* Run a view and return results
|
|
13
|
+
*/
|
|
14
|
+
static async runView(params: RunViewParams, user: UserInfo): Promise<{ success: boolean, result?: RunViewResult, error?: string }> {
|
|
15
|
+
try {
|
|
16
|
+
// Validate entity exists
|
|
17
|
+
const md = new Metadata();
|
|
18
|
+
const entity = md.Entities.find(e => e.Name === params.EntityName);
|
|
19
|
+
if (!entity) {
|
|
20
|
+
return {
|
|
21
|
+
success: false,
|
|
22
|
+
error: `Entity '${params.EntityName}' not found`
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Check read permission
|
|
27
|
+
const permissions = entity.GetUserPermisions(user);
|
|
28
|
+
if (!permissions.CanRead) {
|
|
29
|
+
return {
|
|
30
|
+
success: false,
|
|
31
|
+
error: `User ${user.Name} does not have permission to read ${params.EntityName} records`
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Sanitize and validate parameters
|
|
36
|
+
this.sanitizeRunViewParams(params);
|
|
37
|
+
|
|
38
|
+
// Execute the view
|
|
39
|
+
const runView = new RunView();
|
|
40
|
+
const result = await runView.RunView(params, user);
|
|
41
|
+
|
|
42
|
+
return { success: true, result };
|
|
43
|
+
} catch (error) {
|
|
44
|
+
LogError(error);
|
|
45
|
+
return { success: false, error: (error as Error)?.message || 'Unknown error' };
|
|
73
46
|
}
|
|
74
|
-
|
|
75
|
-
// Sanitize parameters
|
|
76
|
-
this.sanitizeRunViewParams(params);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Execute the views
|
|
80
|
-
const runView = new RunView();
|
|
81
|
-
const results = await runView.RunViews(paramsArray, user);
|
|
82
|
-
|
|
83
|
-
return { success: true, results };
|
|
84
|
-
} catch (error) {
|
|
85
|
-
LogError(error);
|
|
86
|
-
return { success: false, error: (error as Error)?.message || 'Unknown error' };
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* List entities with optional filtering
|
|
92
|
-
*/
|
|
93
|
-
static async listEntities(params: RunViewParams, user: UserInfo): Promise<RunViewResult> {
|
|
94
|
-
try {
|
|
95
|
-
// Check entity exists and user has permission
|
|
96
|
-
const md = new Metadata();
|
|
97
|
-
const entity = md.Entities.find((e) => e.Name === params.EntityName);
|
|
98
|
-
if (!entity) {
|
|
99
|
-
throw new Error(`Entity '${params.EntityName}' not found`);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const permissions = entity.GetUserPermisions(user);
|
|
103
|
-
if (!permissions.CanRead) {
|
|
104
|
-
throw new Error(`User ${user.Name} does not have permission to read ${params.EntityName} records`);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Sanitize and validate parameters
|
|
108
|
-
this.sanitizeRunViewParams(params);
|
|
109
|
-
|
|
110
|
-
// Execute the view
|
|
111
|
-
const runView = new RunView();
|
|
112
|
-
return await runView.RunView(params, user);
|
|
113
|
-
} catch (error) {
|
|
114
|
-
LogError(error);
|
|
115
|
-
throw error;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Get available views for an entity
|
|
121
|
-
*/
|
|
122
|
-
static async getEntityViews(entityName: string, user: UserInfo): Promise<{ success: boolean; views?: any[]; error?: string }> {
|
|
123
|
-
try {
|
|
124
|
-
// Validate entity exists
|
|
125
|
-
const md = new Metadata();
|
|
126
|
-
const entity = md.Entities.find((e) => e.Name === entityName);
|
|
127
|
-
if (!entity) {
|
|
128
|
-
return {
|
|
129
|
-
success: false,
|
|
130
|
-
error: `Entity '${entityName}' not found`,
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Check read permission
|
|
135
|
-
const permissions = entity.GetUserPermisions(user);
|
|
136
|
-
if (!permissions.CanRead) {
|
|
137
|
-
return {
|
|
138
|
-
success: false,
|
|
139
|
-
error: `User ${user.Name} does not have permission to read ${entityName} records`,
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Run a view to get the available views
|
|
144
|
-
const params: RunViewParams = {
|
|
145
|
-
EntityName: 'User Views',
|
|
146
|
-
ExtraFilter: `Entity = '${entityName}'`,
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const runView = new RunView();
|
|
150
|
-
const result = await runView.RunView(params, user);
|
|
151
|
-
|
|
152
|
-
if (!result.Success) {
|
|
153
|
-
return {
|
|
154
|
-
success: false,
|
|
155
|
-
error: result.ErrorMessage || 'Failed to retrieve views',
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Format the view data
|
|
160
|
-
const views = result.Results.map((view) => ({
|
|
161
|
-
ID: view.ID,
|
|
162
|
-
Name: view.Name,
|
|
163
|
-
Description: view.Description,
|
|
164
|
-
IsShared: view.IsShared,
|
|
165
|
-
CreatedAt: view.CreatedAt,
|
|
166
|
-
}));
|
|
167
|
-
|
|
168
|
-
return { success: true, views };
|
|
169
|
-
} catch (error) {
|
|
170
|
-
LogError(error);
|
|
171
|
-
return { success: false, error: (error as Error)?.message || 'Unknown error' };
|
|
172
47
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Run multiple views in batch
|
|
51
|
+
*/
|
|
52
|
+
static async runViews(paramsArray: RunViewParams[], user: UserInfo): Promise<{ success: boolean, results?: RunViewResult[], error?: string }> {
|
|
53
|
+
try {
|
|
54
|
+
// Validate and sanitize each set of parameters
|
|
55
|
+
const md = new Metadata();
|
|
56
|
+
for (const params of paramsArray) {
|
|
57
|
+
// Validate entity exists
|
|
58
|
+
const entity = md.Entities.find(e => e.Name === params.EntityName);
|
|
59
|
+
if (!entity) {
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
error: `Entity '${params.EntityName}' not found`
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Check read permission
|
|
67
|
+
const permissions = entity.GetUserPermisions(user);
|
|
68
|
+
if (!permissions.CanRead) {
|
|
69
|
+
return {
|
|
70
|
+
success: false,
|
|
71
|
+
error: `User ${user.Name} does not have permission to read ${params.EntityName} records`
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Sanitize parameters
|
|
76
|
+
this.sanitizeRunViewParams(params);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Execute the views
|
|
80
|
+
const runView = new RunView();
|
|
81
|
+
const results = await runView.RunViews(paramsArray, user);
|
|
82
|
+
|
|
83
|
+
return { success: true, results };
|
|
84
|
+
} catch (error) {
|
|
85
|
+
LogError(error);
|
|
86
|
+
return { success: false, error: (error as Error)?.message || 'Unknown error' };
|
|
87
|
+
}
|
|
187
88
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* List entities with optional filtering
|
|
92
|
+
*/
|
|
93
|
+
static async listEntities(params: RunViewParams, user: UserInfo): Promise<RunViewResult> {
|
|
94
|
+
try {
|
|
95
|
+
// Check entity exists and user has permission
|
|
96
|
+
const md = new Metadata();
|
|
97
|
+
const entity = md.Entities.find(e => e.Name === params.EntityName);
|
|
98
|
+
if (!entity) {
|
|
99
|
+
throw new Error(`Entity '${params.EntityName}' not found`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const permissions = entity.GetUserPermisions(user);
|
|
103
|
+
if (!permissions.CanRead) {
|
|
104
|
+
throw new Error(`User ${user.Name} does not have permission to read ${params.EntityName} records`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Sanitize and validate parameters
|
|
108
|
+
this.sanitizeRunViewParams(params);
|
|
109
|
+
|
|
110
|
+
// Execute the view
|
|
111
|
+
const runView = new RunView();
|
|
112
|
+
return await runView.RunView(params, user);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
LogError(error);
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
192
117
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Get available views for an entity
|
|
121
|
+
*/
|
|
122
|
+
static async getEntityViews(entityName: string, user: UserInfo): Promise<{ success: boolean, views?: any[], error?: string }> {
|
|
123
|
+
try {
|
|
124
|
+
// Validate entity exists
|
|
125
|
+
const md = new Metadata();
|
|
126
|
+
const entity = md.Entities.find(e => e.Name === entityName);
|
|
127
|
+
if (!entity) {
|
|
128
|
+
return {
|
|
129
|
+
success: false,
|
|
130
|
+
error: `Entity '${entityName}' not found`
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Check read permission
|
|
135
|
+
const permissions = entity.GetUserPermisions(user);
|
|
136
|
+
if (!permissions.CanRead) {
|
|
137
|
+
return {
|
|
138
|
+
success: false,
|
|
139
|
+
error: `User ${user.Name} does not have permission to read ${entityName} records`
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Run a view to get the available views
|
|
144
|
+
const params: RunViewParams = {
|
|
145
|
+
EntityName: 'User Views',
|
|
146
|
+
ExtraFilter: `Entity = '${entityName}'`
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const runView = new RunView();
|
|
150
|
+
const result = await runView.RunView(params, user);
|
|
151
|
+
|
|
152
|
+
if (!result.Success) {
|
|
153
|
+
return {
|
|
154
|
+
success: false,
|
|
155
|
+
error: result.ErrorMessage || 'Failed to retrieve views'
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Format the view data
|
|
160
|
+
const views = result.Results.map(view => ({
|
|
161
|
+
ID: view.ID,
|
|
162
|
+
Name: view.Name,
|
|
163
|
+
Description: view.Description,
|
|
164
|
+
IsShared: view.IsShared,
|
|
165
|
+
CreatedAt: view.CreatedAt
|
|
166
|
+
}));
|
|
167
|
+
|
|
168
|
+
return { success: true, views };
|
|
169
|
+
} catch (error) {
|
|
170
|
+
LogError(error);
|
|
171
|
+
return { success: false, error: (error as Error)?.message || 'Unknown error' };
|
|
172
|
+
}
|
|
196
173
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Sanitize and validate RunViewParams
|
|
177
|
+
*/
|
|
178
|
+
private static sanitizeRunViewParams(params: RunViewParams): void {
|
|
179
|
+
// Ensure EntityName is provided
|
|
180
|
+
if (!params.EntityName) {
|
|
181
|
+
throw new Error('EntityName is required');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Convert string arrays if they came in as comma-separated strings
|
|
185
|
+
if (params.Fields && typeof params.Fields === 'string') {
|
|
186
|
+
params.Fields = (params.Fields as string).split(',');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Sanitize numeric values
|
|
190
|
+
if (params.MaxRows !== undefined) {
|
|
191
|
+
params.MaxRows = typeof params.MaxRows === 'string'
|
|
192
|
+
? parseInt(params.MaxRows as string)
|
|
193
|
+
: params.MaxRows;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (params.StartRow !== undefined) {
|
|
197
|
+
params.StartRow = typeof params.StartRow === 'string'
|
|
198
|
+
? parseInt(params.StartRow as string)
|
|
199
|
+
: params.StartRow;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Default ResultType if not provided
|
|
203
|
+
if (!params.ResultType) {
|
|
204
|
+
params.ResultType = 'simple';
|
|
205
|
+
}
|
|
201
206
|
}
|
|
202
|
-
|
|
203
|
-
}
|
|
207
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LogStatus, LogError } from '@memberjunction/
|
|
1
|
+
import { LogStatus, LogError } from '@memberjunction/core';
|
|
2
2
|
import { SQLServerDataProvider, SQLServerProviderConfigData, UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
3
3
|
import { GetReadWriteDataSource } from '../util.js';
|
|
4
4
|
import { AskSkipResolver } from '../resolvers/AskSkipResolver.js';
|
|
@@ -13,17 +13,22 @@ import { mj_core_schema } from '../config.js';
|
|
|
13
13
|
*/
|
|
14
14
|
export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler> {
|
|
15
15
|
// private intervalId: NodeJS.Timeout | null = null;
|
|
16
|
+
|
|
16
17
|
// // Track executions by organization ID instead of a global flag
|
|
17
18
|
// private runningOrganizations: Map<string, { startTime: Date, learningCycleId: string }> = new Map();
|
|
19
|
+
|
|
18
20
|
// private lastRunTime: Date | null = null;
|
|
19
21
|
// private dataSources: DataSourceInfo[] = [];
|
|
22
|
+
|
|
20
23
|
// // Protected constructor to enforce singleton pattern via BaseSingleton
|
|
21
24
|
// protected constructor() {
|
|
22
25
|
// super();
|
|
23
26
|
// }
|
|
27
|
+
|
|
24
28
|
// public static get Instance(): LearningCycleScheduler {
|
|
25
29
|
// return super.getInstance<LearningCycleScheduler>();
|
|
26
30
|
// }
|
|
31
|
+
|
|
27
32
|
// /**
|
|
28
33
|
// * Set the data sources for the scheduler
|
|
29
34
|
// * @param dataSources Array of data sources
|
|
@@ -31,6 +36,7 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
31
36
|
// public setDataSources(dataSources: DataSourceInfo[]): void {
|
|
32
37
|
// this.dataSources = dataSources;
|
|
33
38
|
// }
|
|
39
|
+
|
|
34
40
|
// /**
|
|
35
41
|
// * Start the scheduler with the specified interval in minutes
|
|
36
42
|
// * @param intervalMinutes The interval in minutes between runs
|
|
@@ -38,16 +44,19 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
38
44
|
// */
|
|
39
45
|
// public start(intervalMinutes: number = 60): void {
|
|
40
46
|
// LogStatus(`Starting learning cycle scheduler with interval of ${intervalMinutes} minutes`);
|
|
47
|
+
|
|
41
48
|
// // Set up the interval for recurring calls
|
|
42
49
|
// const intervalMs = intervalMinutes * 60 * 1000;
|
|
43
50
|
// this.intervalId = setInterval(() => {
|
|
44
51
|
// this.runLearningCycle()
|
|
45
52
|
// .catch(error => LogError(`Error in scheduled learning cycle: ${error}`));
|
|
46
53
|
// }, intervalMs);
|
|
54
|
+
|
|
47
55
|
// // Start learning cycle immediately upon the server start
|
|
48
56
|
// this.runLearningCycle()
|
|
49
57
|
// .catch(error => LogError(`Error in initial learning cycle: ${error}`));
|
|
50
58
|
// }
|
|
59
|
+
|
|
51
60
|
// /**
|
|
52
61
|
// * Stop the scheduler
|
|
53
62
|
// */
|
|
@@ -58,27 +67,33 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
58
67
|
// LogStatus('Learning cycle scheduler stopped');
|
|
59
68
|
// }
|
|
60
69
|
// }
|
|
70
|
+
|
|
61
71
|
// /**
|
|
62
72
|
// * Run the learning cycle if it's not already running
|
|
63
73
|
// * @returns A promise that resolves when the learning cycle completes
|
|
64
74
|
// */
|
|
65
75
|
// public async runLearningCycle(): Promise<boolean> {
|
|
66
76
|
// const startTime = new Date();
|
|
77
|
+
|
|
67
78
|
// try {
|
|
68
79
|
// // Make sure we have data sources
|
|
69
80
|
// if (!this.dataSources || this.dataSources.length === 0) {
|
|
70
81
|
// throw new Error('No data sources available for the learning cycle');
|
|
71
82
|
// }
|
|
83
|
+
|
|
72
84
|
// const dataSource = GetReadWriteDataSource(this.dataSources);
|
|
85
|
+
|
|
73
86
|
// // Get system user for operation
|
|
74
87
|
// const systemUser = await getSystemUser(dataSource);
|
|
75
88
|
// if (!systemUser) {
|
|
76
89
|
// throw new Error('System user not found');
|
|
77
90
|
// }
|
|
91
|
+
|
|
78
92
|
// // Create context for the resolver
|
|
79
93
|
// const config = new SQLServerProviderConfigData(dataSource, mj_core_schema, 0, undefined, undefined, false);
|
|
80
94
|
// const p = new SQLServerDataProvider();
|
|
81
95
|
// await p.Config(config);
|
|
96
|
+
|
|
82
97
|
// const context: AppContext = {
|
|
83
98
|
// dataSource: dataSource,
|
|
84
99
|
// dataSources: this.dataSources,
|
|
@@ -90,15 +105,19 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
90
105
|
// },
|
|
91
106
|
// providers: [{provider: p, type: 'Read-Write'}]
|
|
92
107
|
// };
|
|
108
|
+
|
|
93
109
|
// // Execute the learning cycle
|
|
94
110
|
// const skipResolver = new AskSkipResolver();
|
|
95
111
|
// const result = await skipResolver.ExecuteAskSkipLearningCycle(
|
|
96
112
|
// context,
|
|
97
113
|
// false // forceEntityRefresh
|
|
98
114
|
// );
|
|
115
|
+
|
|
99
116
|
// const endTime = new Date();
|
|
100
117
|
// const elapsedMs = endTime.getTime() - startTime.getTime();
|
|
118
|
+
|
|
101
119
|
// this.lastRunTime = startTime;
|
|
120
|
+
|
|
102
121
|
// if (result.learningCycleSkipped) {
|
|
103
122
|
// // skipped the learning cycle - no messages to process, already logged..
|
|
104
123
|
// return true;
|
|
@@ -106,7 +125,7 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
106
125
|
// else if (result.success) {
|
|
107
126
|
// LogStatus(`Learning cycle completed successfully in ${elapsedMs}ms`);
|
|
108
127
|
// return true;
|
|
109
|
-
// }
|
|
128
|
+
// }
|
|
110
129
|
// else {
|
|
111
130
|
// LogError(`Learning cycle failed after ${elapsedMs}ms: ${result.error}`);
|
|
112
131
|
// return false;
|
|
@@ -114,8 +133,9 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
114
133
|
// } catch (error) {
|
|
115
134
|
// LogError(`Error executing learning cycle: ${error}`);
|
|
116
135
|
// return false;
|
|
117
|
-
// }
|
|
136
|
+
// }
|
|
118
137
|
// }
|
|
138
|
+
|
|
119
139
|
// /**
|
|
120
140
|
// * Get the current status of the scheduler
|
|
121
141
|
// */
|
|
@@ -131,6 +151,7 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
131
151
|
// }))
|
|
132
152
|
// };
|
|
133
153
|
// }
|
|
154
|
+
|
|
134
155
|
// /**
|
|
135
156
|
// * Checks if an organization is currently running a learning cycle
|
|
136
157
|
// * @param organizationId The organization ID to check
|
|
@@ -140,19 +161,23 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
140
161
|
// organizationId: string
|
|
141
162
|
// ): { isRunning: boolean, startTime?: Date, learningCycleId?: string, runningForMinutes?: number } {
|
|
142
163
|
// const runningInfo = this.runningOrganizations.get(organizationId);
|
|
164
|
+
|
|
143
165
|
// if (runningInfo) {
|
|
144
166
|
// // Check if it's been running too long and should be considered stalled
|
|
145
167
|
// const now = new Date();
|
|
146
168
|
// const elapsedMinutes = (now.getTime() - runningInfo.startTime.getTime()) / (1000 * 60);
|
|
147
|
-
|
|
148
|
-
//
|
|
169
|
+
|
|
170
|
+
// return {
|
|
171
|
+
// isRunning: true,
|
|
149
172
|
// startTime: runningInfo.startTime,
|
|
150
173
|
// learningCycleId: runningInfo.learningCycleId,
|
|
151
174
|
// runningForMinutes: elapsedMinutes
|
|
152
175
|
// };
|
|
153
176
|
// }
|
|
177
|
+
|
|
154
178
|
// return { isRunning: false };
|
|
155
179
|
// }
|
|
180
|
+
|
|
156
181
|
// /**
|
|
157
182
|
// * Registers an organization as running a learning cycle
|
|
158
183
|
// * @param organizationId The organization ID to register
|
|
@@ -162,16 +187,20 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
162
187
|
// public registerRunningCycle(organizationId: string, learningCycleId: string): boolean {
|
|
163
188
|
// // First check if already running
|
|
164
189
|
// const { isRunning } = this.isOrganizationRunningCycle(organizationId);
|
|
190
|
+
|
|
165
191
|
// if (isRunning) {
|
|
166
192
|
// return false;
|
|
167
193
|
// }
|
|
194
|
+
|
|
168
195
|
// // Register the organization as running a cycle
|
|
169
196
|
// this.runningOrganizations.set(organizationId, {
|
|
170
197
|
// startTime: new Date(),
|
|
171
198
|
// learningCycleId
|
|
172
199
|
// });
|
|
200
|
+
|
|
173
201
|
// return true;
|
|
174
202
|
// }
|
|
203
|
+
|
|
175
204
|
// /**
|
|
176
205
|
// * Unregisters an organization after its learning cycle completes
|
|
177
206
|
// * @param organizationId The organization ID to unregister
|
|
@@ -182,8 +211,10 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
182
211
|
// this.runningOrganizations.delete(organizationId);
|
|
183
212
|
// return true;
|
|
184
213
|
// }
|
|
214
|
+
|
|
185
215
|
// return false;
|
|
186
216
|
// }
|
|
217
|
+
|
|
187
218
|
// /**
|
|
188
219
|
// * Manually execute a learning cycle run for testing purposes
|
|
189
220
|
// * This is intended for debugging/testing only and will force a run
|
|
@@ -194,16 +225,20 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
194
225
|
// public async manuallyExecuteLearningCycle(organizationId?: string): Promise<boolean> {
|
|
195
226
|
// try {
|
|
196
227
|
// LogStatus('🧪 Manually executing learning cycle for testing...');
|
|
228
|
+
|
|
197
229
|
// // If an organization ID is provided, register it as running
|
|
198
230
|
// const learningCycleId = `manual_${Date.now()}`;
|
|
199
231
|
// let orgRegistered = false;
|
|
232
|
+
|
|
200
233
|
// if (organizationId) {
|
|
201
234
|
// // Check if already running
|
|
202
235
|
// const runningStatus = this.isOrganizationRunningCycle(organizationId);
|
|
236
|
+
|
|
203
237
|
// if (runningStatus.isRunning) {
|
|
204
238
|
// LogError(`Organization ${organizationId} is already running a learning cycle. Cannot start a new one.`);
|
|
205
239
|
// return false;
|
|
206
240
|
// }
|
|
241
|
+
|
|
207
242
|
// // Register this organization
|
|
208
243
|
// orgRegistered = this.registerRunningCycle(organizationId, learningCycleId);
|
|
209
244
|
// if (!orgRegistered) {
|
|
@@ -211,36 +246,42 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
211
246
|
// return false;
|
|
212
247
|
// }
|
|
213
248
|
// }
|
|
249
|
+
|
|
214
250
|
// // Run the learning cycle
|
|
215
251
|
// const result = await this.runLearningCycle();
|
|
216
252
|
// LogStatus(`🧪 Manual learning cycle execution completed with result: ${result ? 'Success' : 'Failed'}`);
|
|
253
|
+
|
|
217
254
|
// // Unregister the organization if it was registered
|
|
218
255
|
// if (organizationId && orgRegistered) {
|
|
219
256
|
// this.unregisterRunningCycle(organizationId);
|
|
220
257
|
// }
|
|
258
|
+
|
|
221
259
|
// return result;
|
|
222
260
|
// } catch (error) {
|
|
223
261
|
// // Make sure to unregister on error
|
|
224
262
|
// if (organizationId && this.runningOrganizations.has(organizationId)) {
|
|
225
263
|
// this.unregisterRunningCycle(organizationId);
|
|
226
264
|
// }
|
|
265
|
+
|
|
227
266
|
// LogError(`Error in manual learning cycle execution: ${error}`);
|
|
228
267
|
// return false;
|
|
229
268
|
// }
|
|
230
269
|
// }
|
|
270
|
+
|
|
231
271
|
// /**
|
|
232
272
|
// * Force stop a running learning cycle for an organization
|
|
233
273
|
// * @param organizationId The organization ID to stop the cycle for
|
|
234
274
|
// * @returns Information about the stopped cycle
|
|
235
275
|
// */
|
|
236
|
-
// public stopLearningCycleForOrganization(organizationId: string): {
|
|
237
|
-
// success: boolean,
|
|
276
|
+
// public stopLearningCycleForOrganization(organizationId: string): {
|
|
277
|
+
// success: boolean,
|
|
238
278
|
// message: string,
|
|
239
279
|
// wasRunning: boolean,
|
|
240
280
|
// cycleDetails?: { learningCycleId: string, startTime: Date, runningForMinutes: number }
|
|
241
281
|
// } {
|
|
242
282
|
// // Check if this organization has a running cycle
|
|
243
283
|
// const runningStatus = this.isOrganizationRunningCycle(organizationId);
|
|
284
|
+
|
|
244
285
|
// if (!runningStatus.isRunning) {
|
|
245
286
|
// return {
|
|
246
287
|
// success: false,
|
|
@@ -248,12 +289,15 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
248
289
|
// wasRunning: false
|
|
249
290
|
// };
|
|
250
291
|
// }
|
|
292
|
+
|
|
251
293
|
// // Capture details before unregistering
|
|
252
294
|
// const startTime = runningStatus.startTime!;
|
|
253
295
|
// const learningCycleId = runningStatus.learningCycleId!;
|
|
254
296
|
// const runningForMinutes = runningStatus.runningForMinutes!;
|
|
297
|
+
|
|
255
298
|
// // Unregister the organization
|
|
256
299
|
// const unregistered = this.unregisterRunningCycle(organizationId);
|
|
300
|
+
|
|
257
301
|
// if (unregistered) {
|
|
258
302
|
// return {
|
|
259
303
|
// success: true,
|
|
@@ -273,4 +317,4 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
|
|
|
273
317
|
// };
|
|
274
318
|
// }
|
|
275
319
|
// }
|
|
276
|
-
}
|
|
320
|
+
}
|