@memberjunction/server 2.76.0 → 2.77.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/README.md +61 -2
- package/dist/apolloServer/index.d.ts.map +1 -1
- package/dist/apolloServer/index.js +1 -3
- package/dist/apolloServer/index.js.map +1 -1
- package/dist/auth/exampleNewUserSubClass.d.ts +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/newUsers.js.map +1 -1
- package/dist/context.d.ts +5 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +34 -3
- package/dist/context.js.map +1 -1
- package/dist/entitySubclasses/entityPermissions.server.d.ts +2 -2
- package/dist/entitySubclasses/entityPermissions.server.d.ts.map +1 -1
- package/dist/entitySubclasses/entityPermissions.server.js +2 -2
- package/dist/entitySubclasses/entityPermissions.server.js.map +1 -1
- package/dist/generated/generated.d.ts +1648 -1648
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +4945 -4419
- package/dist/generated/generated.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +20 -21
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +75 -59
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +8 -8
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +50 -48
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/resolvers/AskSkipResolver.d.ts +6 -6
- package/dist/resolvers/AskSkipResolver.d.ts.map +1 -1
- package/dist/resolvers/AskSkipResolver.js +33 -21
- package/dist/resolvers/AskSkipResolver.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 +15 -9
- package/dist/resolvers/CreateQueryResolver.js.map +1 -1
- package/dist/resolvers/EntityResolver.d.ts +1 -2
- package/dist/resolvers/EntityResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityResolver.js +17 -9
- package/dist/resolvers/EntityResolver.js.map +1 -1
- package/dist/resolvers/FileCategoryResolver.d.ts +1 -1
- package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
- package/dist/resolvers/FileCategoryResolver.js +9 -9
- package/dist/resolvers/FileCategoryResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +3 -1
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.js +2 -1
- package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
- package/dist/resolvers/ReportResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts +8 -8
- package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +19 -19
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts +10 -10
- package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +19 -19
- package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.d.ts +2 -2
- package/dist/resolvers/UserFavoriteResolver.d.ts.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.js +7 -4
- package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
- package/dist/resolvers/UserResolver.d.ts +3 -3
- package/dist/resolvers/UserResolver.d.ts.map +1 -1
- package/dist/resolvers/UserResolver.js +10 -6
- package/dist/resolvers/UserResolver.js.map +1 -1
- package/dist/resolvers/UserViewResolver.d.ts +2 -2
- package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
- package/dist/resolvers/UserViewResolver.js +11 -6
- package/dist/resolvers/UserViewResolver.js.map +1 -1
- package/dist/scheduler/LearningCycleScheduler.d.ts.map +1 -1
- package/dist/scheduler/LearningCycleScheduler.js +7 -1
- package/dist/scheduler/LearningCycleScheduler.js.map +1 -1
- package/dist/types.d.ts +7 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -1
- package/dist/util.d.ts +8 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +28 -0
- package/dist/util.js.map +1 -1
- package/package.json +34 -34
- package/src/apolloServer/index.ts +3 -3
- package/src/auth/exampleNewUserSubClass.ts +3 -2
- package/src/auth/newUsers.ts +1 -1
- package/src/context.ts +49 -9
- package/src/entitySubclasses/entityPermissions.server.ts +3 -3
- package/src/generated/generated.ts +4945 -4419
- package/src/generic/ResolverBase.ts +103 -86
- package/src/generic/RunViewResolver.ts +55 -54
- package/src/index.ts +1 -1
- package/src/resolvers/AskSkipResolver.ts +44 -23
- package/src/resolvers/CreateQueryResolver.ts +19 -11
- package/src/resolvers/EntityResolver.ts +18 -9
- package/src/resolvers/FileCategoryResolver.ts +12 -9
- package/src/resolvers/FileResolver.ts +4 -2
- package/src/resolvers/MergeRecordsResolver.ts +2 -1
- package/src/resolvers/ReportResolver.ts +1 -1
- package/src/resolvers/SyncDataResolver.ts +21 -21
- package/src/resolvers/SyncRolesUsersResolver.ts +24 -21
- package/src/resolvers/TransactionGroupResolver.ts +1 -1
- package/src/resolvers/UserFavoriteResolver.ts +7 -5
- package/src/resolvers/UserResolver.ts +10 -6
- package/src/resolvers/UserViewResolver.ts +13 -7
- package/src/scheduler/LearningCycleScheduler.ts +10 -4
- package/src/types.ts +14 -4
- package/src/util.ts +45 -2
- package/dist/apolloServer/TransactionPlugin.d.ts +0 -4
- package/dist/apolloServer/TransactionPlugin.d.ts.map +0 -1
- package/dist/apolloServer/TransactionPlugin.js +0 -46
- package/dist/apolloServer/TransactionPlugin.js.map +0 -1
- package/src/apolloServer/TransactionPlugin.ts +0 -53
package/src/index.ts
CHANGED
|
@@ -93,7 +93,7 @@ export * from './resolvers/GetDataResolver.js';
|
|
|
93
93
|
export * from './resolvers/GetDataContextDataResolver.js';
|
|
94
94
|
export * from './resolvers/TransactionGroupResolver.js';
|
|
95
95
|
export * from './resolvers/CreateQueryResolver.js';
|
|
96
|
-
export { GetReadOnlyDataSource, GetReadWriteDataSource } from './util.js';
|
|
96
|
+
export { GetReadOnlyDataSource, GetReadWriteDataSource, GetReadWriteProvider, GetReadOnlyProvider } from './util.js';
|
|
97
97
|
|
|
98
98
|
export * from './generated/generated.js';
|
|
99
99
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Arg, Ctx, Field, Mutation, ObjectType, PubSub, PubSubEngine, Query, Resolver } from 'type-graphql';
|
|
2
|
-
import { LogError, LogStatus, Metadata, RunView, UserInfo, CompositeKey, EntityFieldInfo, EntityInfo, EntityRelationshipInfo } from '@memberjunction/core';
|
|
2
|
+
import { LogError, LogStatus, Metadata, RunView, UserInfo, CompositeKey, EntityFieldInfo, EntityInfo, EntityRelationshipInfo, EntitySaveOptions, EntityDeleteOptions } from '@memberjunction/core';
|
|
3
3
|
import { AppContext, UserPayload, MJ_SERVER_EVENT_CODE } from '../types.js';
|
|
4
4
|
import { BehaviorSubject } from 'rxjs';
|
|
5
5
|
import { take } from 'rxjs/operators';
|
|
@@ -390,6 +390,7 @@ export class AskSkipResolver {
|
|
|
390
390
|
const ck = new CompositeKey();
|
|
391
391
|
ck.KeyValuePairs = compositeKey.KeyValuePairs;
|
|
392
392
|
dci.RecordID = ck.Values();
|
|
393
|
+
|
|
393
394
|
let dciSaveResult: boolean = await dci.Save();
|
|
394
395
|
if (!dciSaveResult) {
|
|
395
396
|
LogError(`Error saving DataContextItemEntity for record chat: ${EntityName} ${ck.Values()}`, undefined, dci.LatestResult);
|
|
@@ -415,7 +416,7 @@ export class AskSkipResolver {
|
|
|
415
416
|
conversationDetailID: convoDetailEntity.ID,
|
|
416
417
|
});
|
|
417
418
|
|
|
418
|
-
return this.handleSimpleSkipChatPostRequest(input, convoEntity, convoDetailEntity, true, user);
|
|
419
|
+
return this.handleSimpleSkipChatPostRequest(input, convoEntity, convoDetailEntity, true, user, userPayload);
|
|
419
420
|
}
|
|
420
421
|
|
|
421
422
|
/**
|
|
@@ -536,7 +537,7 @@ export class AskSkipResolver {
|
|
|
536
537
|
}
|
|
537
538
|
else {
|
|
538
539
|
// Make the API request
|
|
539
|
-
const response = await this.handleSimpleSkipLearningPostRequest(input, user, learningCycleId, agentID);
|
|
540
|
+
const response = await this.handleSimpleSkipLearningPostRequest(input, user, learningCycleId, agentID, userPayload);
|
|
540
541
|
|
|
541
542
|
// Update learning cycle to completed
|
|
542
543
|
const endTime = new Date();
|
|
@@ -594,7 +595,8 @@ export class AskSkipResolver {
|
|
|
594
595
|
input: SkipAPILearningCycleRequest,
|
|
595
596
|
user: UserInfo,
|
|
596
597
|
learningCycleId: string,
|
|
597
|
-
agentID: string
|
|
598
|
+
agentID: string,
|
|
599
|
+
userPayload: UserPayload
|
|
598
600
|
): Promise<SkipAPILearningCycleResponse> {
|
|
599
601
|
const skipConfigInfo = configInfo.askSkip;
|
|
600
602
|
LogStatus(` >>> HandleSimpleSkipLearningPostRequest Sending request to Skip API: ${skipConfigInfo.learningCycleURL}`);
|
|
@@ -608,7 +610,7 @@ export class AskSkipResolver {
|
|
|
608
610
|
|
|
609
611
|
// Process any note changes, if any
|
|
610
612
|
if (apiResponse.noteChanges && apiResponse.noteChanges.length > 0) {
|
|
611
|
-
await this.processLearningCycleNoteChanges(apiResponse.noteChanges, agentID, user);
|
|
613
|
+
await this.processLearningCycleNoteChanges(apiResponse.noteChanges, agentID, user, userPayload);
|
|
612
614
|
}
|
|
613
615
|
|
|
614
616
|
// Not yet implemented
|
|
@@ -653,7 +655,8 @@ export class AskSkipResolver {
|
|
|
653
655
|
convoEntity: ConversationEntity = null,
|
|
654
656
|
convoDetailEntity: ConversationDetailEntity = null,
|
|
655
657
|
createAIMessageConversationDetail: boolean = false,
|
|
656
|
-
user: UserInfo = null
|
|
658
|
+
user: UserInfo = null,
|
|
659
|
+
userPayload: UserPayload = null
|
|
657
660
|
): Promise<AskSkipResultType> {
|
|
658
661
|
const skipConfigInfo = configInfo.askSkip;
|
|
659
662
|
LogStatus(` >>> HandleSimpleSkipChatPostRequest Sending request to Skip API: ${skipConfigInfo.chatURL}`);
|
|
@@ -665,7 +668,7 @@ export class AskSkipResolver {
|
|
|
665
668
|
// the last object in the response array is the final response from the Skip API
|
|
666
669
|
const apiResponse = <SkipAPIResponse>response[response.length - 1].value;
|
|
667
670
|
const AIMessageConversationDetailID = createAIMessageConversationDetail && convoEntity
|
|
668
|
-
? await this.CreateAIMessageConversationDetail(apiResponse, convoEntity.ID, user)
|
|
671
|
+
? await this.CreateAIMessageConversationDetail(apiResponse, convoEntity.ID, user, userPayload)
|
|
669
672
|
: '';
|
|
670
673
|
// const apiResponse = <SkipAPIResponse>response.data;
|
|
671
674
|
LogStatus(` Skip API response: ${apiResponse.responsePhase}`);
|
|
@@ -681,7 +684,7 @@ export class AskSkipResolver {
|
|
|
681
684
|
} else {
|
|
682
685
|
// Set conversation status to Available on failure so user can try again (if conversation exists)
|
|
683
686
|
if (convoEntity) {
|
|
684
|
-
await this.setConversationStatus(convoEntity, 'Available');
|
|
687
|
+
await this.setConversationStatus(convoEntity, 'Available', userPayload);
|
|
685
688
|
}
|
|
686
689
|
|
|
687
690
|
return {
|
|
@@ -697,7 +700,7 @@ export class AskSkipResolver {
|
|
|
697
700
|
} catch (error) {
|
|
698
701
|
// Set conversation status to Available on error so user can try again (if conversation exists)
|
|
699
702
|
if (convoEntity) {
|
|
700
|
-
await this.setConversationStatus(convoEntity, 'Available');
|
|
703
|
+
await this.setConversationStatus(convoEntity, 'Available', userPayload);
|
|
701
704
|
}
|
|
702
705
|
|
|
703
706
|
// Log the error for debugging
|
|
@@ -720,7 +723,8 @@ export class AskSkipResolver {
|
|
|
720
723
|
protected async processLearningCycleNoteChanges(
|
|
721
724
|
noteChanges: SkipLearningCycleNoteChange[],
|
|
722
725
|
agentID: string,
|
|
723
|
-
user: UserInfo
|
|
726
|
+
user: UserInfo,
|
|
727
|
+
userPayload: UserPayload
|
|
724
728
|
): Promise<void> {
|
|
725
729
|
const md = new Metadata();
|
|
726
730
|
|
|
@@ -739,9 +743,9 @@ export class AskSkipResolver {
|
|
|
739
743
|
await Promise.all(validNoteChanges.map(async (change) => {
|
|
740
744
|
try {
|
|
741
745
|
if (change.changeType === 'add' || change.changeType === 'update') {
|
|
742
|
-
await this.processAddOrUpdateSkipNote(change, agentID, user);
|
|
746
|
+
await this.processAddOrUpdateSkipNote(change, agentID, user, userPayload);
|
|
743
747
|
} else if (change.changeType === 'delete') {
|
|
744
|
-
await this.processDeleteSkipNote(change, user);
|
|
748
|
+
await this.processDeleteSkipNote(change, user, userPayload);
|
|
745
749
|
}
|
|
746
750
|
} catch (e) {
|
|
747
751
|
LogError(`Error processing note change: ${e}`);
|
|
@@ -758,7 +762,7 @@ export class AskSkipResolver {
|
|
|
758
762
|
* @param user User context for the operation
|
|
759
763
|
* @returns Whether the operation was successful
|
|
760
764
|
*/
|
|
761
|
-
protected async processAddOrUpdateSkipNote(change: SkipLearningCycleNoteChange, agentID: string, user: UserInfo): Promise<boolean> {
|
|
765
|
+
protected async processAddOrUpdateSkipNote(change: SkipLearningCycleNoteChange, agentID: string, user: UserInfo, userPayload: UserPayload): Promise<boolean> {
|
|
762
766
|
try {
|
|
763
767
|
// Get the note entity object
|
|
764
768
|
const md = new Metadata();
|
|
@@ -805,7 +809,7 @@ export class AskSkipResolver {
|
|
|
805
809
|
* @param user User context for the operation
|
|
806
810
|
* @returns Whether the deletion was successful
|
|
807
811
|
*/
|
|
808
|
-
protected async processDeleteSkipNote(change: SkipLearningCycleNoteChange, user: UserInfo): Promise<boolean> {
|
|
812
|
+
protected async processDeleteSkipNote(change: SkipLearningCycleNoteChange, user: UserInfo, userPayload: UserPayload): Promise<boolean> {
|
|
809
813
|
// Get the note entity object
|
|
810
814
|
const md = new Metadata();
|
|
811
815
|
const noteEntity = await md.GetEntityObject<AIAgentNoteEntity>('AI Agent Notes', user);
|
|
@@ -843,7 +847,7 @@ cycle.`);
|
|
|
843
847
|
* @param user User context for the operation
|
|
844
848
|
* @returns ID of the created conversation detail, or empty string if creation failed
|
|
845
849
|
*/
|
|
846
|
-
protected async CreateAIMessageConversationDetail(apiResponse: SkipAPIResponse, conversationID: string, user: UserInfo): Promise<string> {
|
|
850
|
+
protected async CreateAIMessageConversationDetail(apiResponse: SkipAPIResponse, conversationID: string, user: UserInfo, userPayload: UserPayload): Promise<string> {
|
|
847
851
|
const md = new Metadata();
|
|
848
852
|
const convoDetailEntityAI = <ConversationDetailEntity>await md.GetEntityObject('Conversation Details', user);
|
|
849
853
|
convoDetailEntityAI.NewRecord();
|
|
@@ -853,6 +857,7 @@ cycle.`);
|
|
|
853
857
|
const lastSystemMessage = systemMessages[systemMessages.length - 1];
|
|
854
858
|
convoDetailEntityAI.Message = lastSystemMessage?.content;
|
|
855
859
|
convoDetailEntityAI.Role = 'AI';
|
|
860
|
+
|
|
856
861
|
if (await convoDetailEntityAI.Save()) {
|
|
857
862
|
return convoDetailEntityAI.ID;
|
|
858
863
|
} else {
|
|
@@ -1287,7 +1292,7 @@ cycle.`);
|
|
|
1287
1292
|
await dataContext.Load(DataContextId, dataSource, true, false, 0, user);
|
|
1288
1293
|
const input = <SkipAPIRunScriptRequest>await this.buildSkipChatAPIRequest([], '', dataContext, 'run_existing_script', false, false, false, false, user, dataSource, false, false);
|
|
1289
1294
|
input.scriptText = ScriptText;
|
|
1290
|
-
return this.handleSimpleSkipChatPostRequest(input);
|
|
1295
|
+
return this.handleSimpleSkipChatPostRequest(input, undefined, undefined, undefined, userPayload.userRecord, userPayload);
|
|
1291
1296
|
}
|
|
1292
1297
|
|
|
1293
1298
|
/**
|
|
@@ -1366,7 +1371,7 @@ cycle.`);
|
|
|
1366
1371
|
);
|
|
1367
1372
|
|
|
1368
1373
|
// Set the conversation status to 'Processing' when a request is initiated
|
|
1369
|
-
await this.setConversationStatus(convoEntity, 'Processing');
|
|
1374
|
+
await this.setConversationStatus(convoEntity, 'Processing', userPayload);
|
|
1370
1375
|
|
|
1371
1376
|
// now load up the messages. We will load up ALL of the messages for this conversation, and then pass them to the Skip API
|
|
1372
1377
|
const messages: SkipMessage[] = await this.LoadConversationDetailsIntoSkipMessages(
|
|
@@ -1455,7 +1460,19 @@ cycle.`);
|
|
|
1455
1460
|
updatedAt: f.__mj_UpdatedAt,
|
|
1456
1461
|
};
|
|
1457
1462
|
}),
|
|
1458
|
-
|
|
1463
|
+
params: q.Parameters.map((p) => {
|
|
1464
|
+
return {
|
|
1465
|
+
id: p.ID,
|
|
1466
|
+
name: p.Name,
|
|
1467
|
+
description: p.Description,
|
|
1468
|
+
type: p.Type,
|
|
1469
|
+
isRequired: p.IsRequired,
|
|
1470
|
+
defaultValue: p.DefaultValue,
|
|
1471
|
+
createdAt: p.__mj_CreatedAt,
|
|
1472
|
+
updatedAt: p.__mj_UpdatedAt,
|
|
1473
|
+
};
|
|
1474
|
+
})
|
|
1475
|
+
}
|
|
1459
1476
|
});
|
|
1460
1477
|
}
|
|
1461
1478
|
|
|
@@ -1986,6 +2003,7 @@ cycle.`);
|
|
|
1986
2003
|
convoDetailEntity.Message = UserQuestion;
|
|
1987
2004
|
convoDetailEntity.Role = 'User';
|
|
1988
2005
|
convoDetailEntity.HiddenToUser = false;
|
|
2006
|
+
|
|
1989
2007
|
let convoDetailSaveResult: boolean = await convoDetailEntity.Save();
|
|
1990
2008
|
if (!convoDetailSaveResult) {
|
|
1991
2009
|
LogError(`Error saving conversation detail entity for user message: ${UserQuestion}`, undefined, convoDetailEntity.LatestResult);
|
|
@@ -2162,7 +2180,7 @@ cycle.`);
|
|
|
2162
2180
|
|
|
2163
2181
|
if (conversationDetailCount > 10) {
|
|
2164
2182
|
// Set status of conversation to Available since we still want to allow the user to ask questions
|
|
2165
|
-
await this.setConversationStatus(convoEntity, 'Available');
|
|
2183
|
+
await this.setConversationStatus(convoEntity, 'Available', userPayload);
|
|
2166
2184
|
|
|
2167
2185
|
// At this point it is likely that we are stuck in a loop, so we stop here
|
|
2168
2186
|
pubSub.publish(PUSH_STATUS_UPDATES_TOPIC, {
|
|
@@ -2222,7 +2240,7 @@ cycle.`);
|
|
|
2222
2240
|
);
|
|
2223
2241
|
} catch (error) {
|
|
2224
2242
|
// Set conversation status to Available on error so user can try again
|
|
2225
|
-
await this.setConversationStatus(convoEntity, 'Available');
|
|
2243
|
+
await this.setConversationStatus(convoEntity, 'Available', userPayload);
|
|
2226
2244
|
|
|
2227
2245
|
// Log the error for debugging
|
|
2228
2246
|
LogError(`Error in HandleSkipChatRequest sendPostRequest: ${error}`);
|
|
@@ -2305,7 +2323,7 @@ cycle.`);
|
|
|
2305
2323
|
}
|
|
2306
2324
|
} else {
|
|
2307
2325
|
// Set status of conversation to Available since we still want to allow the user to ask questions
|
|
2308
|
-
await this.setConversationStatus(convoEntity, 'Available');
|
|
2326
|
+
await this.setConversationStatus(convoEntity, 'Available', userPayload);
|
|
2309
2327
|
|
|
2310
2328
|
pubSub.publish(PUSH_STATUS_UPDATES_TOPIC, {
|
|
2311
2329
|
message: JSON.stringify({
|
|
@@ -2477,7 +2495,7 @@ cycle.`);
|
|
|
2477
2495
|
convoDetailEntityAI.CompletionTime = endTime.getTime() - startTime.getTime();
|
|
2478
2496
|
|
|
2479
2497
|
// Set conversation status back to Available since we need user input for the clarifying question
|
|
2480
|
-
await this.setConversationStatus(convoEntity, 'Available');
|
|
2498
|
+
await this.setConversationStatus(convoEntity, 'Available', userPayload);
|
|
2481
2499
|
|
|
2482
2500
|
if (await convoDetailEntityAI.Save()) {
|
|
2483
2501
|
return {
|
|
@@ -2765,6 +2783,7 @@ cycle.`);
|
|
|
2765
2783
|
artifactVersionEntity.ConversationArtifactID = artifactId;
|
|
2766
2784
|
artifactVersionEntity.Version = newVersion;
|
|
2767
2785
|
artifactVersionEntity.Configuration = sResult; // store the full response here
|
|
2786
|
+
|
|
2768
2787
|
if (await artifactVersionEntity.Save()) {
|
|
2769
2788
|
// success saving the new version, set the artifactVersionId
|
|
2770
2789
|
artifactVersionId = artifactVersionEntity.ID;
|
|
@@ -2792,6 +2811,7 @@ cycle.`);
|
|
|
2792
2811
|
convoDetailEntityAI.ArtifactVersionID = artifactVersionId;
|
|
2793
2812
|
}
|
|
2794
2813
|
}
|
|
2814
|
+
|
|
2795
2815
|
const convoDetailSaveResult: boolean = await convoDetailEntityAI.Save();
|
|
2796
2816
|
if (!convoDetailSaveResult) {
|
|
2797
2817
|
LogError(`Error saving conversation detail entity for AI message: ${sResult}`, undefined, convoDetailEntityAI.LatestResult);
|
|
@@ -2872,9 +2892,10 @@ cycle.`);
|
|
|
2872
2892
|
};
|
|
2873
2893
|
}
|
|
2874
2894
|
|
|
2875
|
-
private async setConversationStatus(convoEntity: ConversationEntity, status: 'Processing' | 'Available'): Promise<boolean> {
|
|
2895
|
+
private async setConversationStatus(convoEntity: ConversationEntity, status: 'Processing' | 'Available', userPayload: UserPayload): Promise<boolean> {
|
|
2876
2896
|
if (convoEntity.Status !== status) {
|
|
2877
2897
|
convoEntity.Status = status;
|
|
2898
|
+
|
|
2878
2899
|
const convoSaveResult = await convoEntity.Save();
|
|
2879
2900
|
if (!convoSaveResult) {
|
|
2880
2901
|
LogError(`Error updating conversation status to '${status}'`, undefined, convoEntity.LatestResult);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Arg, Ctx, Field, InputType, Mutation, ObjectType, registerEnumType, Resolver, PubSub, PubSubEngine } from 'type-graphql';
|
|
2
|
-
import { AppContext } from '../types.js';
|
|
3
|
-
import { LogError, Metadata, RunView, UserInfo, CompositeKey } from '@memberjunction/core';
|
|
2
|
+
import { AppContext, UserPayload } from '../types.js';
|
|
3
|
+
import { LogError, Metadata, RunView, UserInfo, CompositeKey, EntitySaveOptions } from '@memberjunction/core';
|
|
4
4
|
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
5
5
|
import { QueryCategoryEntity } from '@memberjunction/core-entities';
|
|
6
6
|
import { QueryResolver } from '../generated/generated.js';
|
|
7
|
-
import {
|
|
7
|
+
import { GetReadWriteProvider } from '../util.js';
|
|
8
8
|
import { DeleteOptionsInput } from '../generic/DeleteOptionsInput.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -108,7 +108,7 @@ export class QueryResolverExtended extends QueryResolver {
|
|
|
108
108
|
let finalCategoryID = input.CategoryID;
|
|
109
109
|
if (input.CategoryPath) {
|
|
110
110
|
const md = new Metadata();
|
|
111
|
-
finalCategoryID = await this.findOrCreateCategoryPath(input.CategoryPath, md, context.userPayload.userRecord);
|
|
111
|
+
finalCategoryID = await this.findOrCreateCategoryPath(input.CategoryPath, md, context.userPayload.userRecord, context.userPayload);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
// Create input for the inherited CreateRecord method
|
|
@@ -128,8 +128,8 @@ export class QueryResolverExtended extends QueryResolver {
|
|
|
128
128
|
};
|
|
129
129
|
|
|
130
130
|
// Use inherited CreateRecord method which bypasses AI processing
|
|
131
|
-
const
|
|
132
|
-
const createdQuery = await this.CreateRecord('Queries', createInput,
|
|
131
|
+
const provider = GetReadWriteProvider(context.providers);
|
|
132
|
+
const createdQuery = await this.CreateRecord('Queries', createInput, provider, context.userPayload, pubSub);
|
|
133
133
|
|
|
134
134
|
if (createdQuery) {
|
|
135
135
|
return {
|
|
@@ -162,14 +162,22 @@ export class QueryResolverExtended extends QueryResolver {
|
|
|
162
162
|
@RequireSystemUser()
|
|
163
163
|
@Mutation(() => DeleteQueryResultType)
|
|
164
164
|
async DeleteQuerySystemResolver(
|
|
165
|
-
@Arg('ID', () => String)
|
|
165
|
+
@Arg('ID', () => String) ID: string,
|
|
166
166
|
@Arg('options', () => DeleteOptionsInput, { nullable: true }) options: DeleteOptionsInput | null,
|
|
167
167
|
@Ctx() context: AppContext,
|
|
168
168
|
@PubSub() pubSub: PubSubEngine
|
|
169
169
|
): Promise<DeleteQueryResultType> {
|
|
170
170
|
try {
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
// Validate ID is not null/undefined/empty
|
|
172
|
+
if (!ID || ID.trim() === '') {
|
|
173
|
+
return {
|
|
174
|
+
Success: false,
|
|
175
|
+
ErrorMessage: 'QueryResolverExtended::DeleteQuerySystemResolver --- Invalid query ID: ID cannot be null or empty'
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const provider = GetReadWriteProvider(context.providers);
|
|
180
|
+
const key = new CompositeKey([{FieldName: 'ID', Value: ID}]);
|
|
173
181
|
|
|
174
182
|
// Provide default options if none provided
|
|
175
183
|
const deleteOptions = options || {
|
|
@@ -178,7 +186,7 @@ export class QueryResolverExtended extends QueryResolver {
|
|
|
178
186
|
};
|
|
179
187
|
|
|
180
188
|
// Use inherited DeleteRecord method from ResolverBase
|
|
181
|
-
const deletedQuery = await this.DeleteRecord('Queries', key, deleteOptions,
|
|
189
|
+
const deletedQuery = await this.DeleteRecord('Queries', key, deleteOptions, provider, context.userPayload, pubSub);
|
|
182
190
|
|
|
183
191
|
if (deletedQuery) {
|
|
184
192
|
return {
|
|
@@ -209,7 +217,7 @@ export class QueryResolverExtended extends QueryResolver {
|
|
|
209
217
|
* @param contextUser - User context for operations
|
|
210
218
|
* @returns The ID of the final category in the path
|
|
211
219
|
*/
|
|
212
|
-
private async findOrCreateCategoryPath(categoryPath: string, md: Metadata, contextUser: UserInfo): Promise<string> {
|
|
220
|
+
private async findOrCreateCategoryPath(categoryPath: string, md: Metadata, contextUser: UserInfo, userPayload: UserPayload): Promise<string> {
|
|
213
221
|
if (!categoryPath || categoryPath.trim() === '') {
|
|
214
222
|
throw new Error('CategoryPath cannot be empty');
|
|
215
223
|
}
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import { EntityPermissionType } from '@memberjunction/core';
|
|
1
|
+
import { EntityPermissionType, IRunViewProvider } from '@memberjunction/core';
|
|
2
2
|
import { AppContext } from '../types.js';
|
|
3
3
|
import { Arg, Ctx, Query, Resolver, InputType, Field } from 'type-graphql';
|
|
4
4
|
import { Entity_, EntityResolverBase } from '../generated/generated.js';
|
|
5
5
|
import sql from 'mssql';
|
|
6
|
+
import { GetReadOnlyProvider } from '../util.js';
|
|
6
7
|
|
|
7
8
|
@Resolver(Entity_)
|
|
8
9
|
export class EntityResolver extends EntityResolverBase {
|
|
9
10
|
@Query(() => [Entity_])
|
|
10
11
|
async EntitiesBySchemas(
|
|
11
|
-
@Ctx() {
|
|
12
|
+
@Ctx() { providers, userPayload }: AppContext,
|
|
12
13
|
@Arg('IncludeSchemas', () => [String], { nullable: true }) IncludeSchemas?: string[],
|
|
13
14
|
@Arg('ExcludeSchemas', () => [String], { nullable: true }) ExcludeSchemas?: string[]
|
|
14
15
|
) {
|
|
15
16
|
this.CheckUserReadPermissions('Entities', userPayload);
|
|
16
|
-
const
|
|
17
|
+
const provider = GetReadOnlyProvider(providers, { allowFallbackToReadWrite: true });
|
|
18
|
+
const rlsWhere = this.getRowLevelSecurityWhereClause(provider, 'Entities', userPayload, EntityPermissionType.Read, ' WHERE');
|
|
17
19
|
const includeSchemaSQL =
|
|
18
20
|
IncludeSchemas && IncludeSchemas.length > 0 ? `SchemaName IN (${IncludeSchemas.map((s) => `'${s}'`).join(',')})` : '';
|
|
19
21
|
const excludeSchemaSQL =
|
|
@@ -25,14 +27,21 @@ export class EntityResolver extends EntityResolverBase {
|
|
|
25
27
|
else schemaSQL = excludeSchemaSQL;
|
|
26
28
|
}
|
|
27
29
|
let totalWhere = '';
|
|
28
|
-
if (schemaSQL) totalWhere =
|
|
30
|
+
if (schemaSQL) totalWhere = `${schemaSQL}`;
|
|
29
31
|
if (rlsWhere) {
|
|
30
32
|
if (totalWhere) totalWhere = `${totalWhere} AND ${rlsWhere}`;
|
|
31
|
-
else totalWhere = `
|
|
33
|
+
else totalWhere = ` ${rlsWhere}`;
|
|
34
|
+
}
|
|
35
|
+
const rv = provider as any as IRunViewProvider;
|
|
36
|
+
const result = await rv.RunView({
|
|
37
|
+
EntityName: 'Entities',
|
|
38
|
+
ExtraFilter: totalWhere,
|
|
39
|
+
}, userPayload.userRecord);
|
|
40
|
+
if (result && result.Success) {
|
|
41
|
+
return result.Results;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
throw new Error(`Failed to fetch entities: ${result?.ErrorMessage || 'Unknown error'}`);
|
|
32
45
|
}
|
|
33
|
-
const sSQL = `SELECT * FROM [${this.MJCoreSchema}].vwEntities${totalWhere}`;
|
|
34
|
-
const request = new sql.Request(dataSource);
|
|
35
|
-
const result = await request.query(sSQL);
|
|
36
|
-
return result.recordset;
|
|
37
46
|
}
|
|
38
47
|
}
|
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
import { CompositeKey, EntityPermissionType, Metadata, RunView } from '@memberjunction/core';
|
|
1
|
+
import { CompositeKey, EntityDeleteOptions, EntityPermissionType, EntitySaveOptions, Metadata, RunView } from '@memberjunction/core';
|
|
2
2
|
import { FileCategoryEntity, FileEntity } from '@memberjunction/core-entities';
|
|
3
3
|
import { AppContext, Arg, Ctx, DeleteOptionsInput, Int, Mutation } from '@memberjunction/server';
|
|
4
4
|
import { mj_core_schema } from '../config.js';
|
|
5
5
|
import { FileCategoryResolver as FileCategoryResolverBase, FileCategory_ } from '../generated/generated.js';
|
|
6
6
|
import sql from 'mssql';
|
|
7
|
+
import { SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';
|
|
8
|
+
import { GetReadWriteProvider } from '../util.js';
|
|
7
9
|
|
|
8
10
|
export class FileResolver extends FileCategoryResolverBase {
|
|
9
11
|
@Mutation(() => FileCategory_)
|
|
10
12
|
async DeleteFileCategory(
|
|
11
13
|
@Arg('ID', () => String) ID: string,
|
|
12
14
|
@Arg('options___', () => DeleteOptionsInput) options: DeleteOptionsInput,
|
|
13
|
-
@Ctx() {
|
|
15
|
+
@Ctx() { providers, userPayload }: AppContext
|
|
14
16
|
) {
|
|
15
17
|
const key = new CompositeKey();
|
|
16
18
|
key.LoadFromSingleKeyValuePair('ID', ID);
|
|
17
|
-
|
|
19
|
+
const provider = GetReadWriteProvider(providers);
|
|
20
|
+
|
|
21
|
+
if (!(await this.BeforeDelete(provider, key))) {
|
|
18
22
|
return null;
|
|
19
23
|
}
|
|
20
24
|
|
|
@@ -30,8 +34,7 @@ export class FileResolver extends FileCategoryResolverBase {
|
|
|
30
34
|
const returnValue = fileCategoryEntity.GetAll();
|
|
31
35
|
|
|
32
36
|
// Any files using the deleted category fall back to its parent
|
|
33
|
-
|
|
34
|
-
await transaction.begin();
|
|
37
|
+
await provider.BeginTransaction();
|
|
35
38
|
try {
|
|
36
39
|
// SHOULD USE BaseEntity for each of these records to ensure object model
|
|
37
40
|
// is used everywhere - new code below. The below is SLOWER than a single
|
|
@@ -63,14 +66,14 @@ export class FileResolver extends FileCategoryResolverBase {
|
|
|
63
66
|
await fileEntity.Save();
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
|
-
await fileCategoryEntity.Delete();
|
|
67
|
-
await
|
|
69
|
+
await fileCategoryEntity.Delete(options);
|
|
70
|
+
await provider.CommitTransaction();
|
|
68
71
|
} catch (error) {
|
|
69
|
-
await
|
|
72
|
+
await provider.RollbackTransaction();
|
|
70
73
|
throw error;
|
|
71
74
|
}
|
|
72
75
|
|
|
73
|
-
await this.AfterDelete(
|
|
76
|
+
await this.AfterDelete(provider, key); // fire event
|
|
74
77
|
return returnValue;
|
|
75
78
|
}
|
|
76
79
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EntityPermissionType, Metadata, FieldValueCollection } from '@memberjunction/core';
|
|
1
|
+
import { EntityPermissionType, Metadata, FieldValueCollection, EntitySaveOptions } from '@memberjunction/core';
|
|
2
2
|
import { FileEntity, FileStorageProviderEntity } from '@memberjunction/core-entities';
|
|
3
3
|
import {
|
|
4
4
|
AppContext,
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
import { createDownloadUrl, createUploadUrl, deleteObject, moveObject } from '@memberjunction/storage';
|
|
20
20
|
import { CreateFileInput, FileResolver as FileResolverBase, File_, UpdateFileInput } from '../generated/generated.js';
|
|
21
21
|
import { FieldMapper } from '@memberjunction/graphql-dataprovider';
|
|
22
|
+
import { GetReadOnlyProvider } from '../util.js';
|
|
22
23
|
|
|
23
24
|
@InputType()
|
|
24
25
|
export class CreateUploadURLInput {
|
|
@@ -57,8 +58,9 @@ export class FileResolver extends FileResolverBase {
|
|
|
57
58
|
fileEntity.CheckPermissions(EntityPermissionType.Create, true);
|
|
58
59
|
|
|
59
60
|
// Check to see if there's already an object with that name
|
|
61
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true})
|
|
60
62
|
const [sameName] = await this.findBy(
|
|
61
|
-
|
|
63
|
+
provider,
|
|
62
64
|
'Files',
|
|
63
65
|
{ Name: input.Name, ProviderID: input.ProviderID },
|
|
64
66
|
context.userPayload.userRecord
|
|
@@ -163,7 +163,8 @@ export class RecordMergeResolver {
|
|
|
163
163
|
) {
|
|
164
164
|
try {
|
|
165
165
|
const md = new Metadata();
|
|
166
|
-
const
|
|
166
|
+
const options = {};
|
|
167
|
+
const result = await md.MergeRecords(request, userPayload.userRecord, options);
|
|
167
168
|
return result;
|
|
168
169
|
} catch (e) {
|
|
169
170
|
LogError(e);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Metadata, RunReport } from '@memberjunction/core';
|
|
1
|
+
import { EntitySaveOptions, Metadata, RunReport } from '@memberjunction/core';
|
|
2
2
|
import { Arg, Ctx, Field, Int, Mutation, ObjectType, Query, Resolver } from 'type-graphql';
|
|
3
3
|
import { AppContext } from '../types.js';
|
|
4
4
|
import { ConversationDetailEntity, ReportEntity } from '@memberjunction/core-entities';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Arg, Ctx, Field, InputType, Mutation, ObjectType, registerEnumType } from 'type-graphql';
|
|
2
|
-
import { AppContext } from '../types.js';
|
|
3
|
-
import { BaseEntity, CompositeKey, LogError, Metadata, RunView, UserInfo } from '@memberjunction/core';
|
|
2
|
+
import { AppContext, UserPayload } from '../types.js';
|
|
3
|
+
import { BaseEntity, CompositeKey, EntityDeleteOptions, EntitySaveOptions, LogError, Metadata, RunView, UserInfo } from '@memberjunction/core';
|
|
4
4
|
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
5
5
|
import { CompositeKeyInputType, CompositeKeyOutputType } from '../generic/KeyInputOutputTypes.js';
|
|
6
6
|
import { DatasetItemEntity } from '@memberjunction/core-entities';
|
|
@@ -115,7 +115,7 @@ export class SyncDataResolver {
|
|
|
115
115
|
const md = new Metadata();
|
|
116
116
|
const results: ActionItemOutputType[] = [];
|
|
117
117
|
for (const item of items) {
|
|
118
|
-
results.push(await this.SyncSingleItem(item, context, md));
|
|
118
|
+
results.push(await this.SyncSingleItem(item, context, md, context.userPayload));
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
if (await this.DoSyncItemsAffectMetadata(context.userPayload.userRecord, items)) {
|
|
@@ -160,7 +160,7 @@ export class SyncDataResolver {
|
|
|
160
160
|
return false; // didn't find any
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
protected async SyncSingleItem(item: ActionItemInputType, context: AppContext, md: Metadata): Promise<ActionItemOutputType> {
|
|
163
|
+
protected async SyncSingleItem(item: ActionItemInputType, context: AppContext, md: Metadata, userPayload: UserPayload): Promise<ActionItemOutputType> {
|
|
164
164
|
const result = new ActionItemOutputType();
|
|
165
165
|
result.AlternateKey = item.AlternateKey;
|
|
166
166
|
result.PrimaryKey = item.PrimaryKey;
|
|
@@ -179,20 +179,20 @@ export class SyncDataResolver {
|
|
|
179
179
|
const fieldValues = item.RecordJSON ? JSON.parse(item.RecordJSON) : {};
|
|
180
180
|
switch (item.Type) {
|
|
181
181
|
case SyncDataActionType.Create:
|
|
182
|
-
await this.SyncSingleItemCreate(entityObject, fieldValues, result);
|
|
182
|
+
await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
|
|
183
183
|
break;
|
|
184
184
|
case SyncDataActionType.Update:
|
|
185
|
-
await this.SyncSingleItemUpdate(entityObject, pk, ak, fieldValues, result);
|
|
185
|
+
await this.SyncSingleItemUpdate(entityObject, pk, ak, fieldValues, result, userPayload);
|
|
186
186
|
break;
|
|
187
187
|
case SyncDataActionType.CreateOrUpdate:
|
|
188
188
|
// in this case we attempt to load the item first, if it is not possible to load the item, then we create it
|
|
189
|
-
await this.SyncSingleItemCreateOrUpdate(entityObject, pk, ak, fieldValues, result);
|
|
189
|
+
await this.SyncSingleItemCreateOrUpdate(entityObject, pk, ak, fieldValues, result, userPayload);
|
|
190
190
|
break;
|
|
191
191
|
case SyncDataActionType.Delete:
|
|
192
|
-
await this.SyncSingleItemDelete(entityObject, pk, ak, result);
|
|
192
|
+
await this.SyncSingleItemDelete(entityObject, pk, ak, result, userPayload);
|
|
193
193
|
break;
|
|
194
194
|
case SyncDataActionType.DeleteWithFilter:
|
|
195
|
-
await this.SyncSingleItemDeleteWithFilter(item.EntityName, item.DeleteFilter, result, context.userPayload.userRecord);
|
|
195
|
+
await this.SyncSingleItemDeleteWithFilter(item.EntityName, item.DeleteFilter, result, context.userPayload.userRecord, userPayload);
|
|
196
196
|
break;
|
|
197
197
|
default:
|
|
198
198
|
throw new Error('Invalid SyncDataActionType');
|
|
@@ -211,7 +211,7 @@ export class SyncDataResolver {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
|
|
214
|
-
protected async SyncSingleItemDeleteWithFilter(entityName: string, filter: string, result: ActionItemOutputType, user: UserInfo) {
|
|
214
|
+
protected async SyncSingleItemDeleteWithFilter(entityName: string, filter: string, result: ActionItemOutputType, user: UserInfo, userPayload: UserPayload) {
|
|
215
215
|
try {
|
|
216
216
|
// here we will iterate through the result of a RunView on the entityname/filter and delete each matching record
|
|
217
217
|
let overallSuccess: boolean = true;
|
|
@@ -273,30 +273,30 @@ export class SyncDataResolver {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
-
protected async SyncSingleItemCreateOrUpdate(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, fieldValues: any, result: ActionItemOutputType) {
|
|
276
|
+
protected async SyncSingleItemCreateOrUpdate(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
|
|
277
277
|
if (!pk || pk.KeyValuePairs.length === 0) {
|
|
278
278
|
// no primary key try to load from alt key
|
|
279
279
|
const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
|
|
280
280
|
if (!altKeyResult) {
|
|
281
281
|
// no record found, create a new one
|
|
282
|
-
await this.SyncSingleItemCreate(entityObject, fieldValues, result);
|
|
282
|
+
await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
|
|
283
283
|
}
|
|
284
284
|
else {
|
|
285
|
-
await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result);
|
|
285
|
+
await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result, userPayload);
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
288
|
else {
|
|
289
289
|
// have a primary key do the usual load
|
|
290
290
|
if (await entityObject.InnerLoad(pk)) {
|
|
291
|
-
await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result);
|
|
291
|
+
await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result, userPayload);
|
|
292
292
|
}
|
|
293
293
|
else {
|
|
294
|
-
await this.SyncSingleItemCreate(entityObject, fieldValues, result);
|
|
294
|
+
await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
-
protected async SyncSingleItemDelete(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, result: ActionItemOutputType) {
|
|
299
|
+
protected async SyncSingleItemDelete(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, result: ActionItemOutputType, userPayload: UserPayload) {
|
|
300
300
|
if (!pk || pk.KeyValuePairs.length === 0) {
|
|
301
301
|
const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
|
|
302
302
|
if (!altKeyResult) {
|
|
@@ -342,7 +342,7 @@ export class SyncDataResolver {
|
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
-
protected async SyncSingleItemCreate(entityObject: BaseEntity, fieldValues: any, result: ActionItemOutputType) {
|
|
345
|
+
protected async SyncSingleItemCreate(entityObject: BaseEntity, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
|
|
346
346
|
// make sure we strip out the primary key from fieldValues before we pass it in because otherwise it will appear to be an existing record to the BaseEntity
|
|
347
347
|
const noPKValues = {...fieldValues};
|
|
348
348
|
entityObject.EntityInfo.PrimaryKeys.forEach((pk) => {
|
|
@@ -367,7 +367,7 @@ export class SyncDataResolver {
|
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
369
|
|
|
370
|
-
protected async SyncSingleItemUpdate(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, fieldValues: any, result: ActionItemOutputType) {
|
|
370
|
+
protected async SyncSingleItemUpdate(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
|
|
371
371
|
if (!pk || pk.KeyValuePairs.length === 0) {
|
|
372
372
|
// no pk, attempt to load by alt key
|
|
373
373
|
const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
|
|
@@ -376,11 +376,11 @@ export class SyncDataResolver {
|
|
|
376
376
|
result.ErrorMessage = 'Failed to load the item, it is possible the record with the specified alternate key does not exist';
|
|
377
377
|
}
|
|
378
378
|
else {
|
|
379
|
-
await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result);
|
|
379
|
+
await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result, userPayload);
|
|
380
380
|
}
|
|
381
381
|
}
|
|
382
382
|
else if (await entityObject.InnerLoad(pk)) {
|
|
383
|
-
await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result);
|
|
383
|
+
await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result, userPayload);
|
|
384
384
|
}
|
|
385
385
|
else {
|
|
386
386
|
// failed to load the item
|
|
@@ -388,7 +388,7 @@ export class SyncDataResolver {
|
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
-
protected async InnerSyncSingleItemUpdate(entityObject: BaseEntity, fieldValues: any, result: ActionItemOutputType) {
|
|
391
|
+
protected async InnerSyncSingleItemUpdate(entityObject: BaseEntity, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
|
|
392
392
|
entityObject.SetMany(fieldValues);
|
|
393
393
|
if (await entityObject.Save()) {
|
|
394
394
|
result.Success = true;
|