@solidstarters/solid-core 1.2.140 → 1.2.142
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/dtos/create-ai-interaction.dto.d.ts +1 -0
- package/dist/dtos/create-ai-interaction.dto.d.ts.map +1 -1
- package/dist/dtos/create-ai-interaction.dto.js +10 -1
- package/dist/dtos/create-ai-interaction.dto.js.map +1 -1
- package/dist/dtos/update-ai-interaction.dto.d.ts +1 -0
- package/dist/dtos/update-ai-interaction.dto.d.ts.map +1 -1
- package/dist/dtos/update-ai-interaction.dto.js +7 -1
- package/dist/dtos/update-ai-interaction.dto.js.map +1 -1
- package/dist/entities/ai-interaction.entity.d.ts +1 -0
- package/dist/entities/ai-interaction.entity.d.ts.map +1 -1
- package/dist/entities/ai-interaction.entity.js +9 -1
- package/dist/entities/ai-interaction.entity.js.map +1 -1
- package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts +1 -0
- package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts.map +1 -1
- package/dist/entities/dashboard-question-sql-dataset-config.entity.js +6 -1
- package/dist/entities/dashboard-question-sql-dataset-config.entity.js.map +1 -1
- package/dist/entities/dashboard-question.entity.d.ts +1 -0
- package/dist/entities/dashboard-question.entity.d.ts.map +1 -1
- package/dist/entities/dashboard-question.entity.js +6 -1
- package/dist/entities/dashboard-question.entity.js.map +1 -1
- package/dist/interfaces.d.ts +2 -2
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts.map +1 -1
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js +4 -2
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -1
- package/dist/mappers/dashboard-mapper.d.ts.map +1 -1
- package/dist/mappers/dashboard-mapper.js +2 -0
- package/dist/mappers/dashboard-mapper.js.map +1 -1
- package/dist/repository/view-metadata.repository.d.ts +9 -0
- package/dist/repository/view-metadata.repository.d.ts.map +1 -0
- package/dist/repository/view-metadata.repository.js +42 -0
- package/dist/repository/view-metadata.repository.js.map +1 -0
- package/dist/seeders/module-metadata-seeder.service.d.ts +1 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +22 -8
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +61 -0
- package/dist/services/ai-interaction.service.d.ts.map +1 -1
- package/dist/services/ai-interaction.service.js +1 -0
- package/dist/services/ai-interaction.service.js.map +1 -1
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.d.ts +19 -0
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.d.ts.map +1 -0
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js +69 -0
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js.map +1 -0
- package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.d.ts +2 -2
- package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.d.ts.map +1 -1
- package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.js +3 -3
- package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.js.map +1 -1
- package/dist/services/computed-fields/entity/noops-entity-computed-field-provider.service.d.ts +10 -0
- package/dist/services/computed-fields/entity/noops-entity-computed-field-provider.service.d.ts.map +1 -0
- package/dist/services/computed-fields/entity/noops-entity-computed-field-provider.service.js +18 -0
- package/dist/services/computed-fields/entity/noops-entity-computed-field-provider.service.js.map +1 -0
- package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.d.ts +14 -1
- package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.d.ts.map +1 -1
- package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.js +81 -5
- package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.js.map +1 -1
- package/dist/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.d.ts +12 -0
- package/dist/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.d.ts.map +1 -0
- package/dist/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.js +36 -0
- package/dist/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.js.map +1 -0
- package/dist/services/setting.service.d.ts.map +1 -1
- package/dist/services/setting.service.js +14 -2
- package/dist/services/setting.service.js.map +1 -1
- package/dist/services/user.service.d.ts +2 -0
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/user.service.js +15 -0
- package/dist/services/user.service.js.map +1 -1
- package/dist/services/view-metadata.service.d.ts +3 -2
- package/dist/services/view-metadata.service.d.ts.map +1 -1
- package/dist/services/view-metadata.service.js +2 -3
- package/dist/services/view-metadata.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +8 -0
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.d.ts +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.d.ts.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.js +5 -3
- package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/dtos/create-ai-interaction.dto.ts +51 -55
- package/src/dtos/update-ai-interaction.dto.ts +51 -56
- package/src/entities/ai-interaction.entity.ts +29 -34
- package/src/entities/dashboard-question-sql-dataset-config.entity.ts +3 -0
- package/src/entities/dashboard-question.entity.ts +3 -0
- package/src/interfaces.ts +2 -2
- package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +4 -2
- package/src/mappers/dashboard-mapper.ts +2 -1
- package/src/repository/view-metadata.repository.ts +31 -0
- package/src/seeders/module-metadata-seeder.service.ts +23 -17
- package/src/seeders/seed-data/solid-core-metadata.json +61 -0
- package/src/services/ai-interaction.service.ts +3 -0
- package/src/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.ts +68 -0
- package/src/services/computed-fields/entity/concat-entity-computed-field-provider.service.ts +4 -5
- package/src/services/computed-fields/entity/noops-entity-computed-field-provider.service.ts +22 -0
- package/src/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.ts +83 -9
- package/src/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.ts +34 -0
- package/src/services/setting.service.ts +14 -2
- package/src/services/user.service.ts +22 -0
- package/src/services/view-metadata.service.ts +3 -2
- package/src/solid-core.module.ts +8 -0
- package/src/subscribers/computed-entity-field.subscriber.ts +6 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidstarters/solid-core",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.142",
|
|
4
4
|
"description": "This module is a NestJS module containing all the required core providers required by a Solid application",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -1,60 +1,56 @@
|
|
|
1
1
|
import { ApiProperty } from '@nestjs/swagger';
|
|
2
2
|
import { IsInt } from 'class-validator';
|
|
3
3
|
import { IsOptional } from 'class-validator';
|
|
4
|
-
import { IsString, IsNotEmpty, IsJSON } from 'class-validator';
|
|
5
|
-
export class CreateAiInteractionDto {
|
|
6
|
-
@IsOptional()
|
|
7
|
-
@IsInt()
|
|
8
|
-
@ApiProperty()
|
|
9
|
-
userId: number;
|
|
10
|
-
|
|
11
|
-
@IsString()
|
|
12
|
-
@IsOptional()
|
|
13
|
-
@ApiProperty()
|
|
14
|
-
userUserKey: string;
|
|
15
|
-
|
|
16
|
-
@IsNotEmpty()
|
|
17
|
-
@IsString()
|
|
18
|
-
@ApiProperty()
|
|
19
|
-
threadId: string;
|
|
20
|
-
|
|
21
|
-
@IsNotEmpty()
|
|
22
|
-
@IsString()
|
|
23
|
-
@ApiProperty()
|
|
24
|
-
role: string;
|
|
25
|
-
|
|
26
|
-
@IsNotEmpty()
|
|
27
|
-
@IsString()
|
|
28
|
-
@ApiProperty()
|
|
29
|
-
message: string;
|
|
30
|
-
|
|
31
|
-
@IsOptional()
|
|
32
|
-
@IsString()
|
|
33
|
-
@ApiProperty()
|
|
34
|
-
contentType: string;
|
|
4
|
+
import { IsString, IsNotEmpty, IsJSON, IsBoolean } from 'class-validator';
|
|
35
5
|
|
|
36
|
-
|
|
37
|
-
@
|
|
38
|
-
@
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@
|
|
42
|
-
@
|
|
43
|
-
@ApiProperty()
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@
|
|
47
|
-
@
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@
|
|
52
|
-
|
|
53
|
-
@
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
@
|
|
58
|
-
@
|
|
59
|
-
|
|
6
|
+
export class CreateAiInteractionDto {
|
|
7
|
+
@IsOptional()
|
|
8
|
+
@IsInt()
|
|
9
|
+
@ApiProperty()
|
|
10
|
+
userId: number;
|
|
11
|
+
@IsString()
|
|
12
|
+
@IsOptional()
|
|
13
|
+
@ApiProperty()
|
|
14
|
+
userUserKey: string;
|
|
15
|
+
@IsNotEmpty()
|
|
16
|
+
@IsString()
|
|
17
|
+
@ApiProperty()
|
|
18
|
+
threadId: string;
|
|
19
|
+
@IsNotEmpty()
|
|
20
|
+
@IsString()
|
|
21
|
+
@ApiProperty()
|
|
22
|
+
role: string;
|
|
23
|
+
@IsNotEmpty()
|
|
24
|
+
@IsString()
|
|
25
|
+
@ApiProperty()
|
|
26
|
+
message: string;
|
|
27
|
+
@IsOptional()
|
|
28
|
+
@IsString()
|
|
29
|
+
@ApiProperty()
|
|
30
|
+
contentType: string;
|
|
31
|
+
@IsOptional()
|
|
32
|
+
@IsString()
|
|
33
|
+
@ApiProperty()
|
|
34
|
+
status: string;
|
|
35
|
+
@IsOptional()
|
|
36
|
+
@IsString()
|
|
37
|
+
@ApiProperty()
|
|
38
|
+
errorMessage: string;
|
|
39
|
+
@IsOptional()
|
|
40
|
+
@IsString()
|
|
41
|
+
@ApiProperty()
|
|
42
|
+
modelUsed: string;
|
|
43
|
+
@IsOptional()
|
|
44
|
+
@IsInt()
|
|
45
|
+
@ApiProperty()
|
|
46
|
+
responseTimeMs: number;
|
|
47
|
+
@IsOptional()
|
|
48
|
+
@IsJSON()
|
|
49
|
+
@ApiProperty()
|
|
50
|
+
metadata: any;
|
|
51
|
+
|
|
52
|
+
@IsOptional()
|
|
53
|
+
@IsBoolean()
|
|
54
|
+
@ApiProperty()
|
|
55
|
+
isApplied: boolean = false;
|
|
60
56
|
}
|
|
@@ -1,65 +1,60 @@
|
|
|
1
|
-
import { IsInt,IsOptional, IsString, IsNotEmpty, IsJSON } from 'class-validator';
|
|
1
|
+
import { IsInt,IsOptional, IsString, IsNotEmpty, IsJSON, IsBoolean } from 'class-validator';
|
|
2
2
|
import { ApiProperty } from '@nestjs/swagger';
|
|
3
|
+
|
|
3
4
|
export class UpdateAiInteractionDto {
|
|
4
5
|
@IsOptional()
|
|
5
6
|
@IsInt()
|
|
6
7
|
id: number;
|
|
8
|
+
@IsOptional()
|
|
9
|
+
@IsInt()
|
|
10
|
+
@ApiProperty()
|
|
11
|
+
userId: number;
|
|
12
|
+
@IsString()
|
|
13
|
+
@IsOptional()
|
|
14
|
+
@ApiProperty()
|
|
15
|
+
userUserKey: string;
|
|
16
|
+
@IsNotEmpty()
|
|
17
|
+
@IsOptional()
|
|
18
|
+
@IsString()
|
|
19
|
+
@ApiProperty()
|
|
20
|
+
threadId: string;
|
|
21
|
+
@IsNotEmpty()
|
|
22
|
+
@IsOptional()
|
|
23
|
+
@IsString()
|
|
24
|
+
@ApiProperty()
|
|
25
|
+
role: string;
|
|
26
|
+
@IsNotEmpty()
|
|
27
|
+
@IsOptional()
|
|
28
|
+
@IsString()
|
|
29
|
+
@ApiProperty()
|
|
30
|
+
message: string;
|
|
31
|
+
@IsOptional()
|
|
32
|
+
@IsString()
|
|
33
|
+
@ApiProperty()
|
|
34
|
+
contentType: string;
|
|
35
|
+
@IsOptional()
|
|
36
|
+
@IsString()
|
|
37
|
+
@ApiProperty()
|
|
38
|
+
status: string;
|
|
39
|
+
@IsOptional()
|
|
40
|
+
@IsString()
|
|
41
|
+
@ApiProperty()
|
|
42
|
+
errorMessage: string;
|
|
43
|
+
@IsOptional()
|
|
44
|
+
@IsString()
|
|
45
|
+
@ApiProperty()
|
|
46
|
+
modelUsed: string;
|
|
47
|
+
@IsOptional()
|
|
48
|
+
@IsInt()
|
|
49
|
+
@ApiProperty()
|
|
50
|
+
responseTimeMs: number;
|
|
51
|
+
@IsOptional()
|
|
52
|
+
@IsJSON()
|
|
53
|
+
@ApiProperty()
|
|
54
|
+
metadata: any;
|
|
7
55
|
|
|
8
56
|
@IsOptional()
|
|
9
|
-
@
|
|
10
|
-
@ApiProperty()
|
|
11
|
-
userId: number;
|
|
12
|
-
|
|
13
|
-
@IsString()
|
|
14
|
-
@IsOptional()
|
|
15
|
-
@ApiProperty()
|
|
16
|
-
userUserKey: string;
|
|
17
|
-
|
|
18
|
-
@IsNotEmpty()
|
|
19
|
-
@IsOptional()
|
|
20
|
-
@IsString()
|
|
21
|
-
@ApiProperty()
|
|
22
|
-
threadId: string;
|
|
23
|
-
|
|
24
|
-
@IsNotEmpty()
|
|
25
|
-
@IsOptional()
|
|
26
|
-
@IsString()
|
|
27
|
-
@ApiProperty()
|
|
28
|
-
role: string;
|
|
29
|
-
|
|
30
|
-
@IsNotEmpty()
|
|
31
|
-
@IsOptional()
|
|
32
|
-
@IsString()
|
|
33
|
-
@ApiProperty()
|
|
34
|
-
message: string;
|
|
35
|
-
|
|
36
|
-
@IsOptional()
|
|
37
|
-
@IsString()
|
|
38
|
-
@ApiProperty()
|
|
39
|
-
contentType: string;
|
|
40
|
-
|
|
41
|
-
@IsOptional()
|
|
42
|
-
@IsString()
|
|
43
|
-
@ApiProperty()
|
|
44
|
-
status: string;
|
|
45
|
-
|
|
46
|
-
@IsOptional()
|
|
47
|
-
@IsString()
|
|
48
|
-
@ApiProperty()
|
|
49
|
-
errorMessage: string;
|
|
50
|
-
|
|
51
|
-
@IsOptional()
|
|
52
|
-
@IsString()
|
|
53
|
-
@ApiProperty()
|
|
54
|
-
modelUsed: string;
|
|
55
|
-
|
|
56
|
-
@IsOptional()
|
|
57
|
-
@IsInt()
|
|
58
|
-
@ApiProperty()
|
|
59
|
-
responseTimeMs: number;
|
|
60
|
-
|
|
61
|
-
@IsOptional()
|
|
62
|
-
@IsJSON()
|
|
57
|
+
@IsBoolean()
|
|
63
58
|
@ApiProperty()
|
|
64
|
-
|
|
59
|
+
isApplied: boolean;
|
|
65
60
|
}
|
|
@@ -1,39 +1,34 @@
|
|
|
1
1
|
import { CommonEntity } from 'src/entities/common.entity'
|
|
2
2
|
import {Entity, JoinColumn, ManyToOne, Index, Column} from 'typeorm';
|
|
3
3
|
import { User } from 'src/entities/user.entity'
|
|
4
|
-
@Entity("ss_ai_interactions")
|
|
5
|
-
export class AiInteraction extends CommonEntity{
|
|
6
|
-
@Index()
|
|
7
|
-
@ManyToOne(() => User, { onDelete: "CASCADE", nullable: false })
|
|
8
|
-
@JoinColumn()
|
|
9
|
-
user: User;
|
|
10
|
-
|
|
11
|
-
@Index()
|
|
12
|
-
@Column({ type: "varchar" })
|
|
13
|
-
threadId: string;
|
|
14
|
-
|
|
15
|
-
@Column({ type: "varchar" })
|
|
16
|
-
role: string;
|
|
17
|
-
|
|
18
|
-
@Column({ type: "text" })
|
|
19
|
-
message: string;
|
|
20
|
-
|
|
21
|
-
@Column({ type: "varchar", nullable: true })
|
|
22
|
-
contentType: string;
|
|
23
4
|
|
|
24
|
-
@
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@Column({ type: "varchar"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
@Column({ type: "
|
|
38
|
-
|
|
5
|
+
@Entity("ss_ai_interactions")
|
|
6
|
+
export class AiInteraction extends CommonEntity {
|
|
7
|
+
@Index()
|
|
8
|
+
@ManyToOne(() => User, { onDelete: "CASCADE", nullable: false })
|
|
9
|
+
@JoinColumn()
|
|
10
|
+
user: User;
|
|
11
|
+
@Index()
|
|
12
|
+
@Column({ type: "varchar" })
|
|
13
|
+
threadId: string;
|
|
14
|
+
@Column({ type: "varchar" })
|
|
15
|
+
role: string;
|
|
16
|
+
@Column({ type: "text" })
|
|
17
|
+
message: string;
|
|
18
|
+
@Column({ type: "varchar", nullable: true })
|
|
19
|
+
contentType: string;
|
|
20
|
+
@Index()
|
|
21
|
+
@Column({ type: "varchar", nullable: true })
|
|
22
|
+
status: string;
|
|
23
|
+
@Column({ type: "text", nullable: true })
|
|
24
|
+
errorMessage: string;
|
|
25
|
+
@Column({ type: "varchar", nullable: true })
|
|
26
|
+
modelUsed: string;
|
|
27
|
+
@Column({ type: "integer", nullable: true })
|
|
28
|
+
responseTimeMs: number;
|
|
29
|
+
@Column({ type: "jsonb", nullable: true })
|
|
30
|
+
metadata: any;
|
|
31
|
+
|
|
32
|
+
@Column({ type: "boolean", nullable: true, default: false })
|
|
33
|
+
isApplied: boolean = false;
|
|
39
34
|
}
|
|
@@ -22,4 +22,7 @@ export class DashboardQuestionSqlDatasetConfig extends CommonEntity {
|
|
|
22
22
|
question: DashboardQuestion;
|
|
23
23
|
@Column({ type: "text", nullable: true })
|
|
24
24
|
options: any;
|
|
25
|
+
@Index({ unique: true })
|
|
26
|
+
@Column({ type: "varchar", nullable: true })
|
|
27
|
+
externalId: string;
|
|
25
28
|
}
|
package/src/interfaces.ts
CHANGED
|
@@ -134,8 +134,8 @@ export interface IEntityComputedFieldProvider {
|
|
|
134
134
|
name(): string;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
export interface IEntityPreComputeFieldProvider<TTriggerEntity, TContext, TValue> extends IEntityComputedFieldProvider {
|
|
138
|
-
preComputeValue(
|
|
137
|
+
export interface IEntityPreComputeFieldProvider<TTriggerEntity, TContext, TValue=void> extends IEntityComputedFieldProvider {
|
|
138
|
+
preComputeValue(triggerEntity: TTriggerEntity, computedFieldMetadata: ComputedFieldMetadata<TContext>): Promise<TValue>;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
export interface IEntityPostComputeFieldProvider<TTriggerEntity, TContext> extends IEntityComputedFieldProvider {
|
|
@@ -62,7 +62,8 @@ export class TriggerMcpClientSubscriberDatabase extends DatabaseSubscriber<Trigg
|
|
|
62
62
|
errorMessage: errorsStr,
|
|
63
63
|
modelUsed: aiResponse.model,
|
|
64
64
|
responseTimeMs: aiResponse.duration_ms,
|
|
65
|
-
metadata: JSON.stringify(aiResponse)
|
|
65
|
+
metadata: JSON.stringify(aiResponse),
|
|
66
|
+
isApplied: aiInteraction.isApplied
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
// update the job entry with failure... raising an error will lead the job to be marked as failed...
|
|
@@ -80,7 +81,8 @@ export class TriggerMcpClientSubscriberDatabase extends DatabaseSubscriber<Trigg
|
|
|
80
81
|
errorMessage: '',
|
|
81
82
|
modelUsed: aiResponse.model,
|
|
82
83
|
responseTimeMs: aiResponse.duration_ms,
|
|
83
|
-
metadata: JSON.stringify(aiResponse)
|
|
84
|
+
metadata: JSON.stringify(aiResponse),
|
|
85
|
+
isApplied: aiInteraction.isApplied
|
|
84
86
|
});
|
|
85
87
|
}
|
|
86
88
|
|
|
@@ -28,7 +28,7 @@ export class DashboardMapper {
|
|
|
28
28
|
chartOptions: question.chartOptions ?? null,
|
|
29
29
|
labelSql: question.labelSql ?? null,
|
|
30
30
|
kpiSql: question.kpiSql ?? null,
|
|
31
|
-
|
|
31
|
+
externalId: question.externalId,
|
|
32
32
|
questionSqlDatasetConfigs: (question.questionSqlDatasetConfigs || []).map(config => ({
|
|
33
33
|
sql: config.sql,
|
|
34
34
|
datasetName: config.datasetName,
|
|
@@ -37,6 +37,7 @@ export class DashboardMapper {
|
|
|
37
37
|
labelColumnName: config.labelColumnName,
|
|
38
38
|
valueColumnName: config.valueColumnName,
|
|
39
39
|
options: this.safeParseJSON(config.options, {}),
|
|
40
|
+
externalId: config.externalId
|
|
40
41
|
}))
|
|
41
42
|
}))
|
|
42
43
|
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Injectable, Logger } from "@nestjs/common";
|
|
2
|
+
import { Dashboard } from "src/entities/dashboard.entity";
|
|
3
|
+
import { ViewMetadata } from "src/entities/view-metadata.entity";
|
|
4
|
+
import { DataSource, Repository, View } from "typeorm";
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class ViewMetadataRepository extends Repository<ViewMetadata> {
|
|
8
|
+
private readonly logger = new Logger(this.constructor.name);
|
|
9
|
+
|
|
10
|
+
constructor(
|
|
11
|
+
private dataSource: DataSource,
|
|
12
|
+
) {
|
|
13
|
+
super(ViewMetadata, dataSource.createEntityManager());
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Custom repository methods can be added here if needed
|
|
17
|
+
async findByNameAndModelNameAndModuleName(name: string, modelUserKey: string, moduleUserKey: string): Promise<ViewMetadata | null> {
|
|
18
|
+
const viewMetadata = await this.findOne({
|
|
19
|
+
where: {
|
|
20
|
+
name,
|
|
21
|
+
model: {
|
|
22
|
+
singularName: modelUserKey,
|
|
23
|
+
module: {
|
|
24
|
+
name: moduleUserKey
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return viewMetadata;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -189,7 +189,7 @@ export class ModuleMetadataSeederService {
|
|
|
189
189
|
// Email templates
|
|
190
190
|
this.logger.debug(`[Start] Processing email templates for ${moduleMetadata.name}`);
|
|
191
191
|
const emailTemplates: CreateEmailTemplateDto[] = overallMetadata.emailTemplates;
|
|
192
|
-
await this.seedEmailTemplates(emailTemplates);
|
|
192
|
+
await this.seedEmailTemplates(emailTemplates, moduleMetadata);
|
|
193
193
|
this.logger.debug(`[End] Processing email templates for ${moduleMetadata.name}`);
|
|
194
194
|
|
|
195
195
|
// Sms templates
|
|
@@ -255,10 +255,11 @@ export class ModuleMetadataSeederService {
|
|
|
255
255
|
'SavedFiltersController.partialUpdate',
|
|
256
256
|
'SavedFiltersController.update',
|
|
257
257
|
'SavedFiltersController.insertMany',
|
|
258
|
-
'SavedFiltersController.create'
|
|
258
|
+
'SavedFiltersController.create',
|
|
259
|
+
'AuthenticationController.logout'
|
|
259
260
|
]
|
|
260
261
|
await this.roleService.addPermissionToRole('Internal User', internalRolePermission);
|
|
261
|
-
await this.roleService.addPermissionToRole('Public', ['SettingController.wrapSettings']);
|
|
262
|
+
await this.roleService.addPermissionToRole('Public', ['SettingController.wrapSettings','AuthenticationController.logout']);
|
|
262
263
|
this.logger.log(`All Seeders finished`);
|
|
263
264
|
this.logger.log(`Newly created username is: ${usersDetail?.length > 0 ? usersDetail[0]?.username : ''} and password is ${usersDetail?.length > 0 ? usersDetail[0]?.password : ''}`);
|
|
264
265
|
}
|
|
@@ -313,7 +314,7 @@ export class ModuleMetadataSeederService {
|
|
|
313
314
|
}
|
|
314
315
|
}
|
|
315
316
|
|
|
316
|
-
async seedEmailTemplates(emailTemplates: CreateEmailTemplateDto[]) {
|
|
317
|
+
async seedEmailTemplates(emailTemplates: CreateEmailTemplateDto[], moduleMetadata: CreateModuleMetadataDto) {
|
|
317
318
|
if (!emailTemplates) {
|
|
318
319
|
return;
|
|
319
320
|
}
|
|
@@ -323,19 +324,24 @@ export class ModuleMetadataSeederService {
|
|
|
323
324
|
this.logger.log(`Found ${emailTemplate.name} email template`);
|
|
324
325
|
|
|
325
326
|
// We need to load the actual template contents.
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
327
|
+
if (moduleMetadata.name === 'solid-core') {
|
|
328
|
+
const modulePath = path.dirname(require.resolve('@solidstarters/solid-core'));
|
|
329
|
+
const seedDataPath = path.join(modulePath, '../src/seeders/seed-data/email-templates');
|
|
330
|
+
const filePath = path.join(seedDataPath, emailTemplate.body);
|
|
331
|
+
this.logger.log(`Seeding email template from solid-core at path: ${filePath}`);
|
|
332
|
+
if (fs.existsSync(filePath)) {
|
|
333
|
+
emailTemplate.body = fs.readFileSync(filePath, 'utf-8').toString();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
// Check if file exists
|
|
338
|
+
const emailTemplateHandlebar = `module-metadata/${moduleMetadata.name}/email-templates/${emailTemplate.body}`
|
|
339
|
+
const fullPath = path.join(process.cwd(), emailTemplateHandlebar);
|
|
340
|
+
this.logger.log(`Seeding custom email template from consuming model at path: ${fullPath}`);
|
|
341
|
+
if (fs.existsSync(fullPath)) {
|
|
342
|
+
emailTemplate.body = fs.readFileSync(fullPath, 'utf-8').toString();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
339
345
|
|
|
340
346
|
// Save to DB.
|
|
341
347
|
await this.emailTemplateService.removeByName(emailTemplate.name);
|
|
@@ -4736,6 +4736,31 @@
|
|
|
4736
4736
|
"index": false,
|
|
4737
4737
|
"private": false,
|
|
4738
4738
|
"encrypt": false
|
|
4739
|
+
},
|
|
4740
|
+
{
|
|
4741
|
+
"name": "externalId",
|
|
4742
|
+
"displayName": "External ID",
|
|
4743
|
+
"type": "computed",
|
|
4744
|
+
"ormType": "varchar",
|
|
4745
|
+
"length": 128,
|
|
4746
|
+
"required": false,
|
|
4747
|
+
"unique": true,
|
|
4748
|
+
"index": true,
|
|
4749
|
+
"private": false,
|
|
4750
|
+
"encrypt": false,
|
|
4751
|
+
"isSystem": true,
|
|
4752
|
+
"computedFieldValueType": "string",
|
|
4753
|
+
"computedFieldValueProvider": "AlphaNumExternalIdComputationProvider",
|
|
4754
|
+
"computedFieldValueProviderCtxt": "{\"prefix\": \"DQ\"}",
|
|
4755
|
+
"computedFieldTriggerConfig": [
|
|
4756
|
+
{
|
|
4757
|
+
"modelName": "dashboardQuestion",
|
|
4758
|
+
"moduleName": "fees-portal",
|
|
4759
|
+
"operations": [
|
|
4760
|
+
"before-insert"
|
|
4761
|
+
]
|
|
4762
|
+
}
|
|
4763
|
+
]
|
|
4739
4764
|
}
|
|
4740
4765
|
]
|
|
4741
4766
|
},
|
|
@@ -4858,6 +4883,31 @@
|
|
|
4858
4883
|
"index": false,
|
|
4859
4884
|
"private": false,
|
|
4860
4885
|
"encrypt": false
|
|
4886
|
+
},
|
|
4887
|
+
{
|
|
4888
|
+
"name": "externalId",
|
|
4889
|
+
"displayName": "External ID",
|
|
4890
|
+
"type": "computed",
|
|
4891
|
+
"ormType": "varchar",
|
|
4892
|
+
"length": 128,
|
|
4893
|
+
"required": false,
|
|
4894
|
+
"unique": true,
|
|
4895
|
+
"index": true,
|
|
4896
|
+
"private": false,
|
|
4897
|
+
"encrypt": false,
|
|
4898
|
+
"isSystem": true,
|
|
4899
|
+
"computedFieldValueType": "string",
|
|
4900
|
+
"computedFieldValueProvider": "AlphaNumExternalIdComputationProvider",
|
|
4901
|
+
"computedFieldValueProviderCtxt": "{\"prefix\": \"DQSDC\"}",
|
|
4902
|
+
"computedFieldTriggerConfig": [
|
|
4903
|
+
{
|
|
4904
|
+
"modelName": "dashboardQuestionSqlDatasetConfig",
|
|
4905
|
+
"moduleName": "fees-portal",
|
|
4906
|
+
"operations": [
|
|
4907
|
+
"before-insert"
|
|
4908
|
+
]
|
|
4909
|
+
}
|
|
4910
|
+
]
|
|
4861
4911
|
}
|
|
4862
4912
|
]
|
|
4863
4913
|
},
|
|
@@ -4996,6 +5046,17 @@
|
|
|
4996
5046
|
"index": false,
|
|
4997
5047
|
"private": false,
|
|
4998
5048
|
"encrypt": false
|
|
5049
|
+
},
|
|
5050
|
+
{
|
|
5051
|
+
"name": "isApplied",
|
|
5052
|
+
"displayName": "Is Applied",
|
|
5053
|
+
"type": "boolean",
|
|
5054
|
+
"ormType": "boolean",
|
|
5055
|
+
"required": false,
|
|
5056
|
+
"unique": false,
|
|
5057
|
+
"index": false,
|
|
5058
|
+
"private": false,
|
|
5059
|
+
"encrypt": false
|
|
4999
5060
|
}
|
|
5000
5061
|
]
|
|
5001
5062
|
}
|
|
@@ -205,6 +205,9 @@ export class AiInteractionService extends CRUDService<AiInteraction> {
|
|
|
205
205
|
|
|
206
206
|
// TODO: This provider to implement an interface - IMcpToolResponseHandler ... apply(aiInteraction: AiInteraction)
|
|
207
207
|
// throw new Error('Method not implemented.');
|
|
208
|
+
|
|
209
|
+
// Mark the interaction as applied
|
|
210
|
+
await this.update(aiInteraction.id, { isApplied: true }, [], true);
|
|
208
211
|
|
|
209
212
|
return handlerApplicationResponse;
|
|
210
213
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { InjectEntityManager } from '@nestjs/typeorm';
|
|
3
|
+
import { ComputedFieldProvider } from 'src/decorators/computed-field-provider.decorator';
|
|
4
|
+
import { CommonEntity } from 'src/entities/common.entity';
|
|
5
|
+
import { ComputedFieldMetadata } from 'src/helpers/solid-registry';
|
|
6
|
+
import { IEntityPreComputeFieldProvider } from 'src/interfaces';
|
|
7
|
+
import { EntityManager } from 'typeorm';
|
|
8
|
+
|
|
9
|
+
export interface AlphaNumExternalIdContext {
|
|
10
|
+
prefix: string; // The prefix to use for the external ID
|
|
11
|
+
length?: number; // Optional: length of the unique code to generate, default is 5
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@ComputedFieldProvider()
|
|
15
|
+
@Injectable()
|
|
16
|
+
export class AlphaNumExternalIdComputationProvider<T extends CommonEntity> implements IEntityPreComputeFieldProvider<T, AlphaNumExternalIdContext> {
|
|
17
|
+
constructor(
|
|
18
|
+
@InjectEntityManager()
|
|
19
|
+
private readonly entityManager: EntityManager
|
|
20
|
+
) { }
|
|
21
|
+
|
|
22
|
+
name(): string {
|
|
23
|
+
return this.constructor.name;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
help(): string {
|
|
27
|
+
return 'Provider used to compute external ID for a CommonEntity.';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async preComputeValue(triggerEntity: T, computedFieldMetadata: ComputedFieldMetadata<AlphaNumExternalIdContext>) {
|
|
31
|
+
const prefix = computedFieldMetadata.computedFieldValueProviderCtxt.prefix;
|
|
32
|
+
const codeLength = computedFieldMetadata.computedFieldValueProviderCtxt.length || 5;
|
|
33
|
+
const uniqueCode = await this.generateUniqueExternalId(codeLength, triggerEntity, computedFieldMetadata.fieldName);
|
|
34
|
+
triggerEntity[computedFieldMetadata.fieldName] = `${prefix}-${uniqueCode}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private generateRandomCode(length = 5): string {
|
|
38
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
39
|
+
let result = '';
|
|
40
|
+
for (let i = 0; i < length; i++) {
|
|
41
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private async isExternalIdUnique(externalId: string, triggerEntity: T, fieldName: string): Promise<boolean> {
|
|
47
|
+
const count = await this.entityManager.count(triggerEntity.constructor.name, {
|
|
48
|
+
where: { [fieldName]: externalId },
|
|
49
|
+
});
|
|
50
|
+
return count === 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private async generateUniqueExternalId(codeLength: number, triggerEntity: T, fieldName: string): Promise<string> {
|
|
54
|
+
const maxAttempts = 10;
|
|
55
|
+
|
|
56
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
57
|
+
const newId = this.generateRandomCode(codeLength);
|
|
58
|
+
|
|
59
|
+
const isUnique = await this.isExternalIdUnique(newId, triggerEntity, fieldName);
|
|
60
|
+
|
|
61
|
+
if (isUnique) {
|
|
62
|
+
return newId;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
throw new Error('Failed to generate a unique external ID after multiple attempts');
|
|
67
|
+
}
|
|
68
|
+
}
|
package/src/services/computed-fields/entity/concat-entity-computed-field-provider.service.ts
CHANGED
|
@@ -14,7 +14,7 @@ export interface ConcatComputedFieldContext {
|
|
|
14
14
|
|
|
15
15
|
@ComputedFieldProvider()
|
|
16
16
|
@Injectable()
|
|
17
|
-
export class ConcatEntityComputedFieldProvider<T extends CommonEntity> implements IEntityPreComputeFieldProvider<T, ConcatComputedFieldContext
|
|
17
|
+
export class ConcatEntityComputedFieldProvider<T extends CommonEntity> implements IEntityPreComputeFieldProvider<T, ConcatComputedFieldContext> {
|
|
18
18
|
|
|
19
19
|
name(): string {
|
|
20
20
|
return "ConcatEntityComputedFieldProvider";
|
|
@@ -24,7 +24,7 @@ export class ConcatEntityComputedFieldProvider<T extends CommonEntity> implement
|
|
|
24
24
|
return "Computed field provider used to create fields whose value is a concatenation of other fields in the same model.";
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
async preComputeValue(
|
|
27
|
+
async preComputeValue(triggerEntity: T, computedFieldMetadata: ComputedFieldMetadata<ConcatComputedFieldContext>){
|
|
28
28
|
const { computedFieldValueProviderCtxt } = computedFieldMetadata;
|
|
29
29
|
const separator = computedFieldValueProviderCtxt.separator || ' '; // Default to space if no separator is provided
|
|
30
30
|
const fields = computedFieldValueProviderCtxt.fields || [];
|
|
@@ -35,7 +35,7 @@ export class ConcatEntityComputedFieldProvider<T extends CommonEntity> implement
|
|
|
35
35
|
const field = fields[i];
|
|
36
36
|
|
|
37
37
|
// if slugify then each field val to be converted to a slug before concatenation
|
|
38
|
-
let fieldVal =
|
|
38
|
+
let fieldVal = triggerEntity[field];
|
|
39
39
|
if (slugify && typeof fieldVal === 'string') {
|
|
40
40
|
fieldVal = kebabCase(fieldVal);
|
|
41
41
|
}
|
|
@@ -45,8 +45,7 @@ export class ConcatEntityComputedFieldProvider<T extends CommonEntity> implement
|
|
|
45
45
|
}
|
|
46
46
|
concatenatedString += fieldVal;
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
return concatenatedString;
|
|
48
|
+
triggerEntity[computedFieldMetadata.fieldName] = concatenatedString; //This set the computed value on the entity, since for pre-compute, entity and triggerEntity are the same
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
}
|