@memberjunction/server 1.2.1 → 1.3.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.json +213 -1
- package/CHANGELOG.md +51 -2
- package/dist/entitySubclasses/DuplicateRunEntity.server.d.ts +6 -0
- package/dist/entitySubclasses/DuplicateRunEntity.server.d.ts.map +1 -0
- package/dist/entitySubclasses/DuplicateRunEntity.server.js +37 -0
- package/dist/entitySubclasses/DuplicateRunEntity.server.js.map +1 -0
- package/dist/generated/generated.d.ts +12 -0
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +89 -1
- package/dist/generated/generated.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 +17 -4
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +3 -0
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +21 -0
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.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 +7 -7
- package/dist/resolvers/AskSkipResolver.js.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts +5 -5
- package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +19 -19
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts +4 -1
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +35 -3
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts +9 -8
- package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.js +28 -27
- package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.d.ts +20 -7
- package/dist/resolvers/PotentialDuplicateRecordResolver.d.ts.map +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.js +66 -16
- package/dist/resolvers/PotentialDuplicateRecordResolver.js.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.d.ts +6 -6
- package/dist/resolvers/UserFavoriteResolver.d.ts.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.js +14 -13
- package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
- package/package.json +16 -14
- package/src/entitySubclasses/DuplicateRunEntity.server.ts +29 -0
- package/src/generated/generated.ts +74 -2
- package/src/generic/ResolverBase.ts +20 -0
- package/src/generic/RunViewResolver.ts +21 -0
- package/src/index.ts +1 -0
- package/src/resolvers/AskSkipResolver.ts +7 -6
- package/src/resolvers/EntityRecordNameResolver.ts +16 -16
- package/src/resolvers/FileResolver.ts +39 -5
- package/src/resolvers/MergeRecordsResolver.ts +14 -13
- package/src/resolvers/PotentialDuplicateRecordResolver.ts +49 -14
- package/src/resolvers/UserFavoriteResolver.ts +13 -12
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Arg, Ctx, Field, Int, ObjectType, PubSub, PubSubEngine, Query, Resolver } from 'type-graphql';
|
|
2
|
-
import { LogError, LogStatus, Metadata,
|
|
2
|
+
import { LogError, LogStatus, Metadata, KeyValuePair, RunView, UserInfo, CompositeKey } from '@memberjunction/core';
|
|
3
3
|
import { AppContext, UserPayload } from '../types';
|
|
4
4
|
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
5
5
|
import { DataContext } from '@memberjunction/data-context'
|
|
@@ -18,7 +18,8 @@ import { registerEnumType } from "type-graphql";
|
|
|
18
18
|
import { MJGlobal, CopyScalarsAndArrays } from '@memberjunction/global';
|
|
19
19
|
import { sendPostRequest } from '../util';
|
|
20
20
|
import { GetAIAPIKey } from '@memberjunction/ai';
|
|
21
|
-
import {
|
|
21
|
+
import { KeyValuePairInputType } from './MergeRecordsResolver';
|
|
22
|
+
import { CompositeKeyInputType } from './PotentialDuplicateRecordResolver';
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
enum SkipResponsePhase {
|
|
@@ -73,7 +74,7 @@ export class AskSkipResolver {
|
|
|
73
74
|
async ExecuteAskSkipRecordChat(@Arg('UserQuestion', () => String) UserQuestion: string,
|
|
74
75
|
@Arg('ConversationId', () => Int) ConversationId: number,
|
|
75
76
|
@Arg('EntityName', () => String) EntityName: string,
|
|
76
|
-
@Arg('
|
|
77
|
+
@Arg('CompositeKey', () => CompositeKeyInputType) CompositeKey: CompositeKeyInputType,
|
|
77
78
|
@Ctx() { dataSource, userPayload }: AppContext,
|
|
78
79
|
@PubSub() pubSub: PubSubEngine) {
|
|
79
80
|
// In this function we're simply going to call the Skip API and pass along the message from the user
|
|
@@ -96,15 +97,15 @@ export class AskSkipResolver {
|
|
|
96
97
|
dci.DataContextID = dataContext.ID;
|
|
97
98
|
dci.Type = 'single_record';
|
|
98
99
|
dci.EntityID = md.Entities.find((e) => e.Name === EntityName)?.ID;
|
|
99
|
-
dci.RecordID =
|
|
100
|
+
dci.RecordID = CompositeKey.Values();
|
|
100
101
|
await dci.Save();
|
|
101
102
|
|
|
102
103
|
await dataContext.Load(dataContext.ID, dataSource, false, true, 10, user); // load again because we added a new data context item
|
|
103
|
-
await dataContext.SaveItems(); // persist
|
|
104
|
+
await dataContext.SaveItems(user, true); // persist the data becuase the deep loading above with related data is expensive
|
|
104
105
|
|
|
105
106
|
// also, in the situation for a new convo, we need to update the Conversation ID to have a LinkedEntity and LinkedRecord
|
|
106
107
|
convoEntity.LinkedEntityID = dci.EntityID;
|
|
107
|
-
convoEntity.LinkedRecordID =
|
|
108
|
+
convoEntity.LinkedRecordID = CompositeKey.Values();
|
|
108
109
|
convoEntity.DataContextID = dataContext.ID;
|
|
109
110
|
await convoEntity.Save();
|
|
110
111
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { Metadata,
|
|
1
|
+
import { Metadata, CompositeKey } from '@memberjunction/core';
|
|
2
2
|
import { Arg, Ctx, Field, InputType, ObjectType, Query, Resolver } from 'type-graphql';
|
|
3
3
|
import { AppContext } from '../types';
|
|
4
|
-
import {
|
|
4
|
+
import { CompositeKeyInputType, CompositeKeyOutputType } from './PotentialDuplicateRecordResolver';
|
|
5
5
|
|
|
6
6
|
@InputType()
|
|
7
7
|
export class EntityRecordNameInput {
|
|
8
8
|
@Field(() => String)
|
|
9
9
|
EntityName: string;
|
|
10
10
|
|
|
11
|
-
@Field(() =>
|
|
12
|
-
|
|
11
|
+
@Field(() => CompositeKeyInputType)
|
|
12
|
+
CompositeKey: CompositeKey;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
@ObjectType()
|
|
@@ -20,8 +20,8 @@ export class EntityRecordNameResult {
|
|
|
20
20
|
@Field(() => String)
|
|
21
21
|
Status: string;
|
|
22
22
|
|
|
23
|
-
@Field(() =>
|
|
24
|
-
|
|
23
|
+
@Field(() => CompositeKeyOutputType)
|
|
24
|
+
CompositeKey: CompositeKey;
|
|
25
25
|
|
|
26
26
|
@Field(() => String)
|
|
27
27
|
EntityName: string;
|
|
@@ -35,11 +35,11 @@ export class EntityRecordNameResolver {
|
|
|
35
35
|
@Query(() => EntityRecordNameResult)
|
|
36
36
|
async GetEntityRecordName(
|
|
37
37
|
@Arg('EntityName', () => String) EntityName: string,
|
|
38
|
-
@Arg('
|
|
38
|
+
@Arg('CompositeKey', () => CompositeKeyInputType) CompositeKey: CompositeKey,
|
|
39
39
|
@Ctx() {}: AppContext
|
|
40
40
|
): Promise<EntityRecordNameResult> {
|
|
41
41
|
const md = new Metadata();
|
|
42
|
-
return await this.InnerGetEntityRecordName(md, EntityName,
|
|
42
|
+
return await this.InnerGetEntityRecordName(md, EntityName, CompositeKey);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
@Query(() => [EntityRecordNameResult])
|
|
@@ -50,27 +50,27 @@ export class EntityRecordNameResolver {
|
|
|
50
50
|
const result: EntityRecordNameResult[] = [];
|
|
51
51
|
const md = new Metadata();
|
|
52
52
|
for (const i of info) {
|
|
53
|
-
result.push(await this.InnerGetEntityRecordName(md, i.EntityName, i.
|
|
53
|
+
result.push(await this.InnerGetEntityRecordName(md, i.EntityName, i.CompositeKey));
|
|
54
54
|
}
|
|
55
55
|
return result;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
async InnerGetEntityRecordName(md: Metadata, EntityName: string,
|
|
58
|
+
async InnerGetEntityRecordName(md: Metadata, EntityName: string, CompositeKey: CompositeKey): Promise<EntityRecordNameResult> {
|
|
59
59
|
const e = md.Entities.find((e) => e.Name === EntityName);
|
|
60
60
|
if (e) {
|
|
61
|
-
const recordName = await md.GetEntityRecordName(e.Name,
|
|
61
|
+
const recordName = await md.GetEntityRecordName(e.Name, CompositeKey);
|
|
62
62
|
if (recordName)
|
|
63
|
-
return { Success: true, Status: 'OK',
|
|
63
|
+
return { Success: true, Status: 'OK', CompositeKey, RecordName: recordName, EntityName };
|
|
64
64
|
else
|
|
65
65
|
return {
|
|
66
66
|
Success: false,
|
|
67
|
-
Status: `Name for record, or record ${
|
|
68
|
-
|
|
69
|
-
EntityName
|
|
67
|
+
Status: `Name for record, or record ${CompositeKey.ToString()} itself not found, could be an access issue if user doesn't have Row Level Access (RLS) if RLS is enabled for this entity`,
|
|
68
|
+
CompositeKey,
|
|
69
|
+
EntityName
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
else
|
|
73
|
-
return { Success: false, Status: `Entity ${EntityName} not found`,
|
|
73
|
+
return { Success: false, Status: `Entity ${EntityName} not found`, CompositeKey, EntityName };
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
Resolver,
|
|
16
16
|
Root,
|
|
17
17
|
} from '@memberjunction/server';
|
|
18
|
-
import { createDownloadUrl, createUploadUrl, deleteObject } from '@memberjunction/storage';
|
|
19
|
-
import { CreateFileInput, FileResolver as FileResolverBase, File_ } from '../generated/generated';
|
|
18
|
+
import { createDownloadUrl, createUploadUrl, deleteObject, moveObject } from '@memberjunction/storage';
|
|
19
|
+
import { CreateFileInput, FileResolver as FileResolverBase, File_, UpdateFileInput } from '../generated/generated';
|
|
20
20
|
|
|
21
21
|
@InputType()
|
|
22
22
|
export class CreateUploadURLInput {
|
|
@@ -30,6 +30,8 @@ export class CreateFilePayload {
|
|
|
30
30
|
File: File_;
|
|
31
31
|
@Field(() => String)
|
|
32
32
|
UploadUrl: string;
|
|
33
|
+
@Field(() => Boolean)
|
|
34
|
+
NameExists: boolean;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
@ObjectType()
|
|
@@ -52,6 +54,10 @@ export class FileResolver extends FileResolverBase {
|
|
|
52
54
|
const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', user);
|
|
53
55
|
fileEntity.CheckPermissions(EntityPermissionType.Create, true);
|
|
54
56
|
|
|
57
|
+
// Check to see if there's already an object with that name
|
|
58
|
+
const [sameName] = await this.findBy(dataSource, 'Files', { Name: input.Name, ProviderID: input.ProviderID });
|
|
59
|
+
const NameExists = Boolean(sameName);
|
|
60
|
+
|
|
55
61
|
const fileRecord = (await super.CreateFile({ ...input, Status: 'Pending' }, { dataSource, userPayload }, pubSub)) as File_;
|
|
56
62
|
|
|
57
63
|
// If there's a problem creating the file record, the base resolver will return null
|
|
@@ -68,7 +74,7 @@ export class FileResolver extends FileResolverBase {
|
|
|
68
74
|
await fileEntity.Save();
|
|
69
75
|
const File = fileEntity.GetAll();
|
|
70
76
|
|
|
71
|
-
return { File, UploadUrl };
|
|
77
|
+
return { File, UploadUrl, NameExists };
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
@FieldResolver(() => String)
|
|
@@ -81,11 +87,39 @@ export class FileResolver extends FileResolverBase {
|
|
|
81
87
|
const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', user);
|
|
82
88
|
await providerEntity.Load(file.ProviderID);
|
|
83
89
|
|
|
84
|
-
const url = await createDownloadUrl(providerEntity, file.ProviderKey ?? file.
|
|
90
|
+
const url = await createDownloadUrl(providerEntity, file.ProviderKey ?? file.Name);
|
|
85
91
|
|
|
86
92
|
return url;
|
|
87
93
|
}
|
|
88
94
|
|
|
95
|
+
@Mutation(() => File_)
|
|
96
|
+
async UpdateFile(
|
|
97
|
+
@Arg('input', () => UpdateFileInput) input: UpdateFileInput,
|
|
98
|
+
@Ctx() { dataSource, userPayload }: AppContext,
|
|
99
|
+
@PubSub() pubSub: PubSubEngine
|
|
100
|
+
) {
|
|
101
|
+
// if the name is changing, rename the target object as well
|
|
102
|
+
const md = new Metadata();
|
|
103
|
+
const user = this.GetUserFromPayload(userPayload);
|
|
104
|
+
const fileEntity = await md.GetEntityObject<FileEntity>('Files', user);
|
|
105
|
+
fileEntity.CheckPermissions(EntityPermissionType.Update, true);
|
|
106
|
+
|
|
107
|
+
await fileEntity.Load(input.ID);
|
|
108
|
+
|
|
109
|
+
if (fileEntity.Name !== input.Name) {
|
|
110
|
+
const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', user);
|
|
111
|
+
await providerEntity.Load(fileEntity.ProviderID);
|
|
112
|
+
|
|
113
|
+
const success = await moveObject(providerEntity, fileEntity.Name, input.Name);
|
|
114
|
+
if (!success) {
|
|
115
|
+
throw new Error('Error updating object name');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const updatedFile = await super.UpdateFile(input, { dataSource, userPayload }, pubSub);
|
|
120
|
+
return updatedFile;
|
|
121
|
+
}
|
|
122
|
+
|
|
89
123
|
@Mutation(() => File_)
|
|
90
124
|
async DeleteFile(@Arg('ID', () => Int) ID: number, @Ctx() { dataSource, userPayload }: AppContext, @PubSub() pubSub: PubSubEngine) {
|
|
91
125
|
const md = new Metadata();
|
|
@@ -102,7 +136,7 @@ export class FileResolver extends FileResolverBase {
|
|
|
102
136
|
if (fileEntity.Status === 'Uploaded') {
|
|
103
137
|
const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', userInfo);
|
|
104
138
|
await providerEntity.Load(fileEntity.ProviderID);
|
|
105
|
-
await deleteObject(providerEntity, fileEntity.ProviderKey ?? fileEntity.
|
|
139
|
+
await deleteObject(providerEntity, fileEntity.ProviderKey ?? fileEntity.Name);
|
|
106
140
|
}
|
|
107
141
|
|
|
108
142
|
return super.DeleteFile(ID, { dataSource, userPayload }, pubSub);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { LogError, Metadata,
|
|
1
|
+
import { LogError, Metadata, CompositeKey } from '@memberjunction/core';
|
|
2
2
|
import { Arg, Ctx, Field, InputType, Int, Mutation, ObjectType, PubSub, PubSubEngine, Query, Resolver } from 'type-graphql';
|
|
3
3
|
import { AppContext } from '../types';
|
|
4
|
+
import { CompositeKeyInputType, CompositeKeyOutputType } from './PotentialDuplicateRecordResolver';
|
|
4
5
|
|
|
5
6
|
@ObjectType()
|
|
6
7
|
export class EntityDependencyResult {
|
|
@@ -36,7 +37,7 @@ export class EntityDependencyResolver {
|
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
@InputType()
|
|
39
|
-
export class
|
|
40
|
+
export class KeyValuePairInputType {
|
|
40
41
|
@Field(() => String)
|
|
41
42
|
FieldName: string;
|
|
42
43
|
|
|
@@ -45,7 +46,7 @@ export class PrimaryKeyValueInputType {
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
@ObjectType()
|
|
48
|
-
export class
|
|
49
|
+
export class KeyValuePairOutputType {
|
|
49
50
|
@Field(() => String)
|
|
50
51
|
FieldName: string;
|
|
51
52
|
|
|
@@ -65,8 +66,8 @@ export class RecordDependencyResult {
|
|
|
65
66
|
@Field(() => String)
|
|
66
67
|
FieldName: string; // required
|
|
67
68
|
|
|
68
|
-
@Field(() =>
|
|
69
|
-
|
|
69
|
+
@Field(() => CompositeKeyOutputType)
|
|
70
|
+
CompositeKey: CompositeKey;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
|
|
@@ -77,13 +78,13 @@ export class RecordDependencyResolver {
|
|
|
77
78
|
@Query(() => [RecordDependencyResult])
|
|
78
79
|
async GetRecordDependencies(
|
|
79
80
|
@Arg('entityName', () => String) entityName: string,
|
|
80
|
-
@Arg('
|
|
81
|
+
@Arg('CompositeKey', () => CompositeKeyInputType) CompositeKey: CompositeKey,
|
|
81
82
|
@Ctx() { dataSource, userPayload }: AppContext,
|
|
82
83
|
@PubSub() pubSub: PubSubEngine
|
|
83
84
|
) {
|
|
84
85
|
try {
|
|
85
86
|
const md = new Metadata();
|
|
86
|
-
const result = await md.GetRecordDependencies(entityName,
|
|
87
|
+
const result = await md.GetRecordDependencies(entityName, CompositeKey);
|
|
87
88
|
return result;
|
|
88
89
|
}
|
|
89
90
|
catch (e) {
|
|
@@ -116,11 +117,11 @@ export class RecordMergeRequest {
|
|
|
116
117
|
@Field(() => String)
|
|
117
118
|
EntityName: string;
|
|
118
119
|
|
|
119
|
-
@Field(() =>
|
|
120
|
-
|
|
120
|
+
@Field(() => CompositeKeyInputType)
|
|
121
|
+
SurvivingRecordCompositeKey: CompositeKey;
|
|
121
122
|
|
|
122
|
-
@Field(() => [
|
|
123
|
-
RecordsToMerge:
|
|
123
|
+
@Field(() => [CompositeKeyInputType])
|
|
124
|
+
RecordsToMerge: CompositeKey[];
|
|
124
125
|
|
|
125
126
|
@Field(() => [FieldMapping], { nullable: true })
|
|
126
127
|
FieldMap?: FieldMapping[];
|
|
@@ -144,8 +145,8 @@ export class RecordMergeRequestOutput {
|
|
|
144
145
|
|
|
145
146
|
@ObjectType()
|
|
146
147
|
export class RecordMergeDetailResult {
|
|
147
|
-
@Field(() =>
|
|
148
|
-
|
|
148
|
+
@Field(() => CompositeKeyOutputType)
|
|
149
|
+
CompositeKey: CompositeKeyOutputType;
|
|
149
150
|
|
|
150
151
|
@Field(() => Boolean)
|
|
151
152
|
Success: boolean;
|
|
@@ -1,26 +1,43 @@
|
|
|
1
1
|
import { Arg, Ctx, Field, Float, InputType, Int, ObjectType, Query, Resolver } from "type-graphql";
|
|
2
|
-
import { PotentialDuplicateRequest, PotentialDuplicateResponse, PotentialDuplicate, Metadata,
|
|
3
|
-
import {
|
|
2
|
+
import { PotentialDuplicateRequest, PotentialDuplicateResponse, PotentialDuplicate, Metadata, KeyValuePair, LogError, CompositeKey, PotentialDuplicateResult } from '@memberjunction/core';
|
|
3
|
+
import {KeyValuePairInputType, KeyValuePairOutputType} from './MergeRecordsResolver'
|
|
4
4
|
import { AppContext } from "../types";
|
|
5
5
|
import { UserCache } from "@memberjunction/sqlserver-dataprovider";
|
|
6
6
|
|
|
7
|
+
//load the default vectorDB and embedding model
|
|
8
|
+
import {LoadMistralEmbedding} from '@memberjunction/ai-mistral';
|
|
9
|
+
import {LoadPineconeVectorDB} from '@memberjunction/ai-vectors-pinecone';
|
|
10
|
+
LoadMistralEmbedding();
|
|
11
|
+
LoadPineconeVectorDB();
|
|
12
|
+
|
|
7
13
|
@InputType()
|
|
8
14
|
export class PotentialDuplicateRequestType extends PotentialDuplicateRequest {
|
|
9
15
|
@Field(() => Int)
|
|
10
|
-
|
|
16
|
+
EntityID: number;
|
|
11
17
|
|
|
12
|
-
@Field(() => [
|
|
13
|
-
|
|
18
|
+
@Field(() => [CompositeKeyInputType])
|
|
19
|
+
RecordIDs: CompositeKey[];
|
|
14
20
|
|
|
15
21
|
@Field(() => Int, { nullable: true })
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@Field(() => String, { nullable: true })
|
|
19
|
-
EntityName: string;
|
|
22
|
+
EntityDocumentID: number;
|
|
20
23
|
|
|
21
24
|
@Field(() => Int, { nullable: true })
|
|
22
25
|
ProbabilityScore: number;
|
|
26
|
+
|
|
27
|
+
@Field(() => Int)
|
|
28
|
+
ListID: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@InputType()
|
|
32
|
+
export class CompositeKeyInputType extends CompositeKey {
|
|
33
|
+
@Field(() => [KeyValuePairInputType])
|
|
34
|
+
KeyValuePairs: KeyValuePair[];
|
|
35
|
+
}
|
|
23
36
|
|
|
37
|
+
@ObjectType()
|
|
38
|
+
export class CompositeKeyOutputType extends CompositeKey {
|
|
39
|
+
@Field(() => [KeyValuePairOutputType])
|
|
40
|
+
KeyValuePairs: KeyValuePair[];
|
|
24
41
|
}
|
|
25
42
|
|
|
26
43
|
@ObjectType()
|
|
@@ -28,18 +45,36 @@ export class PotentialDuplicateType extends PotentialDuplicate {
|
|
|
28
45
|
@Field(() => Float)
|
|
29
46
|
ProbabilityScore: number;
|
|
30
47
|
|
|
31
|
-
@Field(() => [
|
|
32
|
-
|
|
48
|
+
@Field(() => [KeyValuePairOutputType])
|
|
49
|
+
KeyValuePairs: KeyValuePairOutputType[];
|
|
33
50
|
}
|
|
34
51
|
|
|
35
52
|
@ObjectType()
|
|
36
|
-
export class
|
|
37
|
-
|
|
38
|
-
@Field(() => Int)
|
|
53
|
+
export class PotentialDuplicateResultType extends PotentialDuplicateResult {
|
|
54
|
+
@Field(() => Int, { nullable: true })
|
|
39
55
|
EntityID: number;
|
|
40
56
|
|
|
41
57
|
@Field(() => [PotentialDuplicateType])
|
|
42
58
|
Duplicates: PotentialDuplicateType[];
|
|
59
|
+
|
|
60
|
+
@Field(() => CompositeKeyOutputType)
|
|
61
|
+
RecordPrimaryKeys: CompositeKey;
|
|
62
|
+
|
|
63
|
+
@Field(() => [Int])
|
|
64
|
+
DuplicateRunDetailMatchRecordIDs: number[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@ObjectType()
|
|
68
|
+
export class PotentialDuplicateResponseType extends PotentialDuplicateResponse{
|
|
69
|
+
|
|
70
|
+
@Field(() => String)
|
|
71
|
+
Status: 'Inprogress' | 'Success' | 'Error';
|
|
72
|
+
|
|
73
|
+
@Field(() => String, { nullable: true })
|
|
74
|
+
ErrorMessage?: string;
|
|
75
|
+
|
|
76
|
+
@Field(() => [PotentialDuplicateResultType])
|
|
77
|
+
PotentialDuplicateResult: PotentialDuplicateResult[]
|
|
43
78
|
}
|
|
44
79
|
|
|
45
80
|
@Resolver(PotentialDuplicateResponseType)
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Metadata,
|
|
2
|
-
import { AppContext, Arg, Ctx, Field, InputType, Int, Mutation, ObjectType,
|
|
1
|
+
import { Metadata, KeyValuePair, CompositeKey } from '@memberjunction/core';
|
|
2
|
+
import { AppContext, Arg, Ctx, Field, InputType, Int, Mutation, ObjectType, KeyValuePairInputType, KeyValuePairOutputType, Query, Resolver } from '@memberjunction/server';
|
|
3
3
|
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
4
4
|
import { UserFavoriteEntity } from '@memberjunction/core-entities';
|
|
5
5
|
|
|
6
6
|
import { UserFavorite_, UserFavoriteResolverBase } from '../generated/generated';
|
|
7
|
+
import { CompositeKeyInputType, CompositeKeyOutputType } from './PotentialDuplicateRecordResolver';
|
|
7
8
|
|
|
8
9
|
//****************************************************************************
|
|
9
10
|
// INPUT TYPE for User Favorite Queries
|
|
@@ -13,8 +14,8 @@ export class UserFavoriteSearchParams {
|
|
|
13
14
|
@Field(() => Int)
|
|
14
15
|
EntityID: number;
|
|
15
16
|
|
|
16
|
-
@Field(() =>
|
|
17
|
-
|
|
17
|
+
@Field(() => CompositeKeyInputType)
|
|
18
|
+
CompositeKey: CompositeKey;
|
|
18
19
|
|
|
19
20
|
@Field(() => Int)
|
|
20
21
|
UserID: number;
|
|
@@ -25,8 +26,8 @@ export class UserFavoriteSetParams {
|
|
|
25
26
|
@Field(() => Int)
|
|
26
27
|
EntityID: number;
|
|
27
28
|
|
|
28
|
-
@Field(() =>
|
|
29
|
-
|
|
29
|
+
@Field(() => CompositeKeyInputType)
|
|
30
|
+
CompositeKey: CompositeKey;
|
|
30
31
|
|
|
31
32
|
@Field(() => Int)
|
|
32
33
|
UserID: number;
|
|
@@ -40,8 +41,8 @@ export class UserFavoriteResult {
|
|
|
40
41
|
@Field(() => Int)
|
|
41
42
|
EntityID: number;
|
|
42
43
|
|
|
43
|
-
@Field(() =>
|
|
44
|
-
|
|
44
|
+
@Field(() => CompositeKeyOutputType)
|
|
45
|
+
CompositeKey: CompositeKey;
|
|
45
46
|
|
|
46
47
|
@Field(() => Int)
|
|
47
48
|
UserID: number;
|
|
@@ -73,8 +74,8 @@ export class UserFavoriteResolver extends UserFavoriteResolverBase {
|
|
|
73
74
|
return {
|
|
74
75
|
EntityID: params.EntityID,
|
|
75
76
|
UserID: params.UserID,
|
|
76
|
-
|
|
77
|
-
IsFavorite: await md.GetRecordFavoriteStatus(params.UserID, e.Name, params.
|
|
77
|
+
CompositeKey: params.CompositeKey,
|
|
78
|
+
IsFavorite: await md.GetRecordFavoriteStatus(params.UserID, e.Name, params.CompositeKey),
|
|
78
79
|
Success: true,
|
|
79
80
|
};
|
|
80
81
|
else throw new Error(`Entity ID:${params.EntityID} not found`);
|
|
@@ -86,12 +87,12 @@ export class UserFavoriteResolver extends UserFavoriteResolverBase {
|
|
|
86
87
|
const e = md.Entities.find((e) => e.ID === params.EntityID);
|
|
87
88
|
const u = UserCache.Users.find((u) => u.ID === userPayload.userRecord.ID);
|
|
88
89
|
if (e) {
|
|
89
|
-
md.SetRecordFavoriteStatus(params.UserID, e.Name, params.
|
|
90
|
+
md.SetRecordFavoriteStatus(params.UserID, e.Name, params.CompositeKey, params.IsFavorite, u);
|
|
90
91
|
return {
|
|
91
92
|
Success: true,
|
|
92
93
|
EntityID: params.EntityID,
|
|
93
94
|
UserID: params.UserID,
|
|
94
|
-
|
|
95
|
+
CompositeKey: params.CompositeKey,
|
|
95
96
|
IsFavorite: params.IsFavorite,
|
|
96
97
|
};
|
|
97
98
|
} else throw new Error(`Entity ID:${params.EntityID} not found`);
|