@solidstarters/solid-core 1.2.161 → 1.2.165
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/commands/ingest.command.d.ts +16 -0
- package/dist/commands/ingest.command.d.ts.map +1 -0
- package/dist/commands/ingest.command.js +50 -0
- package/dist/commands/ingest.command.js.map +1 -0
- package/dist/commands/refresh-module.command.d.ts.map +1 -1
- package/dist/commands/refresh-module.command.js.map +1 -1
- package/dist/controllers/service.controller.d.ts +16 -1
- package/dist/controllers/service.controller.d.ts.map +1 -1
- package/dist/controllers/service.controller.js +55 -2
- package/dist/controllers/service.controller.js.map +1 -1
- package/dist/controllers/test-queue.controller.d.ts +1 -1
- package/dist/controllers/test-queue.controller.d.ts.map +1 -1
- package/dist/controllers/test-queue.controller.js +6 -4
- package/dist/controllers/test-queue.controller.js.map +1 -1
- package/dist/controllers/test.controller.d.ts +6 -1
- package/dist/controllers/test.controller.d.ts.map +1 -1
- package/dist/controllers/test.controller.js +21 -3
- package/dist/controllers/test.controller.js.map +1 -1
- package/dist/entities/common.entity.d.ts.map +1 -1
- package/dist/entities/common.entity.js +14 -2
- package/dist/entities/common.entity.js.map +1 -1
- package/dist/entities/user.entity.d.ts.map +1 -1
- package/dist/entities/user.entity.js +11 -1
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/helpers/error-mapper.service.d.ts +8 -0
- package/dist/helpers/error-mapper.service.d.ts.map +1 -0
- package/dist/helpers/error-mapper.service.js +108 -0
- package/dist/helpers/error-mapper.service.js.map +1 -0
- package/dist/jobs/chatter-queue-options.d.ts +8 -0
- package/dist/jobs/chatter-queue-options.d.ts.map +1 -0
- package/dist/jobs/chatter-queue-options.js +10 -0
- package/dist/jobs/chatter-queue-options.js.map +1 -0
- package/dist/jobs/chatter-queue-publisher.service.d.ts +22 -0
- package/dist/jobs/chatter-queue-publisher.service.d.ts.map +1 -0
- package/dist/jobs/chatter-queue-publisher.service.js +39 -0
- package/dist/jobs/chatter-queue-publisher.service.js.map +1 -0
- package/dist/jobs/chatter-queue-subscriber.service.d.ts +17 -0
- package/dist/jobs/chatter-queue-subscriber.service.d.ts.map +1 -0
- package/dist/jobs/chatter-queue-subscriber.service.js +59 -0
- package/dist/jobs/chatter-queue-subscriber.service.js.map +1 -0
- package/dist/jobs/{database/computed-field-evaluation-publisher.service.d.ts → computed-field-evaluation-publisher.service.d.ts} +2 -2
- package/dist/jobs/computed-field-evaluation-publisher.service.d.ts.map +1 -0
- package/dist/jobs/{database/computed-field-evaluation-publisher.service.js → computed-field-evaluation-publisher.service.js} +8 -8
- package/dist/jobs/computed-field-evaluation-publisher.service.js.map +1 -0
- package/dist/jobs/{database/computed-field-evaluation-queue-options.d.ts → computed-field-evaluation-queue-options.d.ts} +1 -1
- package/dist/jobs/computed-field-evaluation-queue-options.d.ts.map +1 -0
- package/dist/jobs/{database/computed-field-evaluation-queue-options.js → computed-field-evaluation-queue-options.js} +2 -2
- package/dist/jobs/computed-field-evaluation-queue-options.js.map +1 -0
- package/dist/jobs/{database/computed-field-evaluation-subscriber.service.d.ts → computed-field-evaluation-subscriber.service.d.ts} +3 -3
- package/dist/jobs/computed-field-evaluation-subscriber.service.d.ts.map +1 -0
- package/dist/jobs/computed-field-evaluation-subscriber.service.js +51 -0
- package/dist/jobs/computed-field-evaluation-subscriber.service.js.map +1 -0
- package/dist/jobs/database/computed-field-evaluation-publisher-database.service.d.ts +12 -0
- package/dist/jobs/database/computed-field-evaluation-publisher-database.service.d.ts.map +1 -0
- package/dist/jobs/database/computed-field-evaluation-publisher-database.service.js +39 -0
- package/dist/jobs/database/computed-field-evaluation-publisher-database.service.js.map +1 -0
- package/dist/jobs/database/computed-field-evaluation-queue-options-database.d.ts +8 -0
- package/dist/jobs/database/computed-field-evaluation-queue-options-database.d.ts.map +1 -0
- package/dist/jobs/database/computed-field-evaluation-queue-options-database.js +10 -0
- package/dist/jobs/database/computed-field-evaluation-queue-options-database.js.map +1 -0
- package/dist/jobs/database/computed-field-evaluation-subscriber-database.service.d.ts +18 -0
- package/dist/jobs/database/computed-field-evaluation-subscriber-database.service.d.ts.map +1 -0
- package/dist/jobs/database/{computed-field-evaluation-subscriber.service.js → computed-field-evaluation-subscriber-database.service.js} +8 -8
- package/dist/jobs/database/computed-field-evaluation-subscriber-database.service.js.map +1 -0
- package/dist/jobs/database/generate-code-queue-options-database.js +2 -2
- package/dist/jobs/database/generate-code-queue-options-database.js.map +1 -1
- package/dist/jobs/database/test-queue-subscriber-database.service.d.ts.map +1 -1
- package/dist/jobs/database/test-queue-subscriber-database.service.js +7 -1
- package/dist/jobs/database/test-queue-subscriber-database.service.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/jobs/generate-code-publisher.service.d.ts +11 -0
- package/dist/jobs/generate-code-publisher.service.d.ts.map +1 -0
- package/dist/jobs/generate-code-publisher.service.js +39 -0
- package/dist/jobs/generate-code-publisher.service.js.map +1 -0
- package/dist/jobs/generate-code-queue-options.d.ts +8 -0
- package/dist/jobs/generate-code-queue-options.d.ts.map +1 -0
- package/dist/jobs/generate-code-queue-options.js +10 -0
- package/dist/jobs/generate-code-queue-options.js.map +1 -0
- package/dist/jobs/generate-code-subscriber.service.d.ts +18 -0
- package/dist/jobs/generate-code-subscriber.service.d.ts.map +1 -0
- package/dist/jobs/generate-code-subscriber.service.js +70 -0
- package/dist/jobs/generate-code-subscriber.service.js.map +1 -0
- package/dist/jobs/test-queue-subscriber.service.d.ts +1 -1
- package/dist/jobs/test-queue-subscriber.service.d.ts.map +1 -1
- package/dist/jobs/test-queue-subscriber.service.js +9 -6
- package/dist/jobs/test-queue-subscriber.service.js.map +1 -1
- package/dist/jobs/trigger-mcp-client-publisher.service.d.ts +11 -0
- package/dist/jobs/trigger-mcp-client-publisher.service.d.ts.map +1 -0
- package/dist/jobs/trigger-mcp-client-publisher.service.js +39 -0
- package/dist/jobs/trigger-mcp-client-publisher.service.js.map +1 -0
- package/dist/jobs/trigger-mcp-client-queue-options.d.ts +8 -0
- package/dist/jobs/trigger-mcp-client-queue-options.d.ts.map +1 -0
- package/dist/jobs/trigger-mcp-client-queue-options.js +10 -0
- package/dist/jobs/trigger-mcp-client-queue-options.js.map +1 -0
- package/dist/jobs/trigger-mcp-client-subscriber.service.d.ts +18 -0
- package/dist/jobs/trigger-mcp-client-subscriber.service.d.ts.map +1 -0
- package/dist/jobs/trigger-mcp-client-subscriber.service.js +103 -0
- package/dist/jobs/trigger-mcp-client-subscriber.service.js.map +1 -0
- package/dist/jobs/twilio-sms-publisher.service.d.ts +11 -0
- package/dist/jobs/twilio-sms-publisher.service.d.ts.map +1 -0
- package/dist/jobs/twilio-sms-publisher.service.js +39 -0
- package/dist/jobs/twilio-sms-publisher.service.js.map +1 -0
- package/dist/jobs/twilio-sms-queue-options.d.ts +8 -0
- package/dist/jobs/twilio-sms-queue-options.d.ts.map +1 -0
- package/dist/jobs/twilio-sms-queue-options.js +10 -0
- package/dist/jobs/twilio-sms-queue-options.js.map +1 -0
- package/dist/jobs/twilio-sms-subscriber.service.d.ts +17 -0
- package/dist/jobs/twilio-sms-subscriber.service.d.ts.map +1 -0
- package/dist/jobs/twilio-sms-subscriber.service.js +48 -0
- package/dist/jobs/twilio-sms-subscriber.service.js.map +1 -0
- package/dist/seeders/seed-data/solid-core-metadata.json +21 -0
- package/dist/services/genai/ingest-metadata.service.d.ts +38 -0
- package/dist/services/genai/ingest-metadata.service.d.ts.map +1 -0
- package/dist/services/genai/ingest-metadata.service.js +530 -0
- package/dist/services/genai/ingest-metadata.service.js.map +1 -0
- package/dist/services/genai/r2r-helper.service.d.ts +7 -0
- package/dist/services/genai/r2r-helper.service.d.ts.map +1 -0
- package/dist/services/genai/r2r-helper.service.js +36 -0
- package/dist/services/genai/r2r-helper.service.js.map +1 -0
- package/dist/services/queues/database-publisher.service.js +2 -2
- package/dist/services/queues/database-publisher.service.js.map +1 -1
- package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/database-subscriber.service.js +2 -1
- package/dist/services/queues/database-subscriber.service.js.map +1 -1
- package/dist/services/queues/publisher-factory.service.js +1 -1
- package/dist/services/queues/publisher-factory.service.js.map +1 -1
- package/dist/services/setting.service.d.ts.map +1 -1
- package/dist/services/setting.service.js +38 -20
- package/dist/services/setting.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +29 -4
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/audit.subscriber.d.ts +8 -0
- package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
- package/dist/subscribers/audit.subscriber.js +52 -3
- package/dist/subscribers/audit.subscriber.js.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.d.ts +3 -3
- package/dist/subscribers/computed-entity-field.subscriber.d.ts.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.js +5 -7
- package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/src/commands/ingest-rag-chunking-strategy-for.md +224 -0
- package/src/commands/ingest.command.ts +36 -0
- package/src/commands/refresh-module.command.ts +0 -1
- package/src/controllers/service.controller.ts +66 -3
- package/src/controllers/test-queue.controller.ts +4 -3
- package/src/controllers/test.controller.ts +15 -3
- package/src/entities/common.entity.ts +10 -0
- package/src/entities/user.entity.ts +33 -1
- package/src/helpers/error-mapper.service.ts +214 -0
- package/src/jobs/chatter-queue-options.ts +9 -0
- package/src/jobs/chatter-queue-publisher.service.ts +37 -0
- package/src/jobs/chatter-queue-subscriber.service.ts +46 -0
- package/src/jobs/computed-field-evaluation-publisher.service.ts +23 -0
- package/src/jobs/{database/computed-field-evaluation-queue-options.ts → computed-field-evaluation-queue-options.ts} +2 -2
- package/src/jobs/computed-field-evaluation-subscriber.service.ts +38 -0
- package/src/jobs/database/{computed-field-evaluation-publisher.service.ts → computed-field-evaluation-publisher-database.service.ts} +2 -2
- package/src/jobs/database/computed-field-evaluation-queue-options-database.ts +9 -0
- package/src/jobs/database/{computed-field-evaluation-subscriber.service.ts → computed-field-evaluation-subscriber-database.service.ts} +2 -2
- package/src/jobs/database/generate-code-queue-options-database.ts +2 -2
- package/src/jobs/database/test-queue-subscriber-database.service.ts +10 -2
- package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +4 -2
- package/src/jobs/generate-code-publisher.service.ts +23 -0
- package/src/jobs/generate-code-queue-options.ts +9 -0
- package/src/jobs/generate-code-subscriber.service.ts +59 -0
- package/src/jobs/test-queue-subscriber.service.ts +15 -7
- package/src/jobs/trigger-mcp-client-publisher.service.ts +22 -0
- package/src/jobs/trigger-mcp-client-queue-options.ts +9 -0
- package/src/jobs/trigger-mcp-client-subscriber.service.ts +104 -0
- package/src/jobs/twilio-sms-publisher.service.ts +23 -0
- package/src/jobs/twilio-sms-queue-options.ts +9 -0
- package/src/jobs/twilio-sms-subscriber.service.ts +32 -0
- package/src/seeders/seed-data/solid-core-metadata.json +21 -0
- package/src/services/genai/ingest-metadata.service.ts +695 -0
- package/src/services/genai/r2r-helper.service.ts +33 -0
- package/src/services/queues/database-publisher.service.ts +2 -2
- package/src/services/queues/database-subscriber.service.ts +2 -1
- package/src/services/queues/publisher-factory.service.ts +1 -1
- package/src/services/setting.service.ts +46 -22
- package/src/solid-core.module.ts +41 -8
- package/src/subscribers/audit.subscriber.ts +235 -5
- package/src/subscribers/computed-entity-field.subscriber.ts +7 -5
- package/dist/jobs/database/computed-field-evaluation-publisher.service.d.ts.map +0 -1
- package/dist/jobs/database/computed-field-evaluation-publisher.service.js.map +0 -1
- package/dist/jobs/database/computed-field-evaluation-queue-options.d.ts.map +0 -1
- package/dist/jobs/database/computed-field-evaluation-queue-options.js.map +0 -1
- package/dist/jobs/database/computed-field-evaluation-subscriber.service.d.ts.map +0 -1
- package/dist/jobs/database/computed-field-evaluation-subscriber.service.js.map +0 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Injectable, Logger } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import { r2rClient } from 'r2r-js';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@Injectable()
|
|
8
|
+
export class R2RHelperService {
|
|
9
|
+
private readonly logger = new Logger(R2RHelperService.name);
|
|
10
|
+
|
|
11
|
+
constructor() { }
|
|
12
|
+
|
|
13
|
+
async getClient() {
|
|
14
|
+
this.logger.debug(`Attempting to create RAG client with url: ${process.env.GENAI_RAG_SERVER_URL}`);
|
|
15
|
+
const client = new r2rClient(process.env.GENAI_RAG_SERVER_URL);
|
|
16
|
+
|
|
17
|
+
// @ts-ignore
|
|
18
|
+
this.logger.debug(`Attempting to login to our RAG server with user ${process.env.GENAI_RAG_SERVER_LOGIN}`)
|
|
19
|
+
await client.users.login({
|
|
20
|
+
email: process.env.GENAI_RAG_SERVER_LOGIN,
|
|
21
|
+
password: process.env.GENAI_RAG_SERVER_PASSWORD
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return client;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// async checkHealth() {
|
|
28
|
+
// const client = new r2rClient('http://localhost:7272');
|
|
29
|
+
|
|
30
|
+
// return await client.health();
|
|
31
|
+
// }
|
|
32
|
+
|
|
33
|
+
}
|
|
@@ -18,7 +18,7 @@ export abstract class DatabasePublisher<T> implements QueuePublisher<T> {
|
|
|
18
18
|
if (!this.serviceRole) {
|
|
19
19
|
this.logger.debug('Queue service Role is not defined in the environment variables');
|
|
20
20
|
}
|
|
21
|
-
this.logger.debug(`DatabasePublisher instance created with options: ${JSON.stringify(this.options())}
|
|
21
|
+
this.logger.debug(`DatabasePublisher instance created with options: ${JSON.stringify(this.options())}`);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
abstract options(): QueuesModuleOptions;
|
|
@@ -33,7 +33,7 @@ export abstract class DatabasePublisher<T> implements QueuePublisher<T> {
|
|
|
33
33
|
throw new Error('Queue service Role is subscriber, cannot publish messages');
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
this.logger.debug(`DatabasePublisher publishing with options: ${JSON.stringify(this.options())}
|
|
36
|
+
this.logger.debug(`DatabasePublisher publishing with options: ${JSON.stringify(this.options())}`);
|
|
37
37
|
|
|
38
38
|
const options = this.options();
|
|
39
39
|
|
|
@@ -98,8 +98,9 @@ export abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
98
98
|
// }
|
|
99
99
|
|
|
100
100
|
async onModuleInit(): Promise<void> {
|
|
101
|
+
const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'database';
|
|
101
102
|
// we will start subscriber only if the current service role is subscriber.
|
|
102
|
-
if (['both', 'subscriber'].includes(this.serviceRole)) {
|
|
103
|
+
if (['both', 'subscriber'].includes(this.serviceRole) && defaultBroker === 'database') {
|
|
103
104
|
|
|
104
105
|
const options = this.options();
|
|
105
106
|
|
|
@@ -34,7 +34,7 @@ export class PublisherFactory<T> {
|
|
|
34
34
|
|
|
35
35
|
// type safe
|
|
36
36
|
const typedActualPublisher: QueuePublisher<T> = actualPublisherToUse.instance;
|
|
37
|
-
this.logger.
|
|
37
|
+
this.logger.debug(`Resolved publisher with name ${actualPublisherToUse.name}, and with options: ${JSON.stringify(typedActualPublisher.options())}`);
|
|
38
38
|
|
|
39
39
|
return typedActualPublisher.publish(message);
|
|
40
40
|
}
|
|
@@ -73,6 +73,10 @@ export class SettingService extends CRUDService<Setting> {
|
|
|
73
73
|
authScreenRightBackgroundImage: null,
|
|
74
74
|
authScreenLeftBackgroundImage: null,
|
|
75
75
|
authScreenCenterBackgroundImage: null,
|
|
76
|
+
solidXGenAiCodeBuilderConfig: JSON.stringify({
|
|
77
|
+
defaultProvider: "",
|
|
78
|
+
availableProviders: []
|
|
79
|
+
})
|
|
76
80
|
};
|
|
77
81
|
|
|
78
82
|
const existingSettings = await this.repo.find();
|
|
@@ -106,21 +110,34 @@ export class SettingService extends CRUDService<Setting> {
|
|
|
106
110
|
for (const setting of settingsArray) {
|
|
107
111
|
if (setting.key && setting.value !== undefined && setting.value !== null) {
|
|
108
112
|
let value = setting.value;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
113
|
+
try {
|
|
114
|
+
settingsMap[setting.key] = JSON.parse(value);
|
|
115
|
+
} catch {
|
|
116
|
+
if (value === 'true' || value === 'false') {
|
|
117
|
+
settingsMap[setting.key] = value === 'true';
|
|
118
|
+
} else if (!isNaN(Number(value)) && value.trim() !== '') {
|
|
119
|
+
settingsMap[setting.key] = Number(value);
|
|
120
|
+
} else if (value.includes(',')) {
|
|
121
|
+
settingsMap[setting.key] = value.split(',').map(item => item.trim());
|
|
122
|
+
} else {
|
|
123
|
+
settingsMap[setting.key] = value;
|
|
124
|
+
}
|
|
121
125
|
}
|
|
126
|
+
|
|
127
|
+
// if (value === 'true' || value === 'false') {
|
|
128
|
+
// settingsMap[setting.key] = value === 'true';
|
|
129
|
+
// }
|
|
130
|
+
// else if (!isNaN(Number(value)) && value.trim() !== '') {
|
|
131
|
+
// settingsMap[setting.key] = Number(value);
|
|
132
|
+
// }
|
|
133
|
+
// else if (value.includes(',')) {
|
|
134
|
+
// settingsMap[setting.key] = value.split(',').map(item => item.trim());
|
|
135
|
+
// }
|
|
136
|
+
// else {
|
|
137
|
+
// settingsMap[setting.key] = value;
|
|
138
|
+
// }
|
|
122
139
|
}
|
|
123
|
-
}
|
|
140
|
+
}
|
|
124
141
|
|
|
125
142
|
const defaultSettings = this.getDefaultSettings();
|
|
126
143
|
|
|
@@ -166,6 +183,10 @@ export class SettingService extends CRUDService<Setting> {
|
|
|
166
183
|
authScreenRightBackgroundImage: null,
|
|
167
184
|
authScreenLeftBackgroundImage: null,
|
|
168
185
|
authScreenCenterBackgroundImage: null,
|
|
186
|
+
solidXGenAiCodeBuilderConfig: JSON.stringify({
|
|
187
|
+
defaultProvider: "",
|
|
188
|
+
availableProviders: []
|
|
189
|
+
})
|
|
169
190
|
};
|
|
170
191
|
}
|
|
171
192
|
|
|
@@ -303,16 +324,19 @@ export class SettingService extends CRUDService<Setting> {
|
|
|
303
324
|
const value = setting.value;
|
|
304
325
|
let parsedValue: any;
|
|
305
326
|
|
|
306
|
-
|
|
307
|
-
parsedValue = value
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
327
|
+
try {
|
|
328
|
+
parsedValue = JSON.parse(value);
|
|
329
|
+
} catch {
|
|
330
|
+
if (value === 'true' || value === 'false') {
|
|
331
|
+
parsedValue = value === 'true';
|
|
332
|
+
} else if (!isNaN(Number(value)) && value.trim() !== '') {
|
|
333
|
+
parsedValue = Number(value);
|
|
334
|
+
} else if (value.includes(',')) {
|
|
335
|
+
parsedValue = value.split(',').map(item => item.trim());
|
|
336
|
+
} else {
|
|
337
|
+
parsedValue = value;
|
|
338
|
+
}
|
|
314
339
|
}
|
|
315
|
-
|
|
316
340
|
if (setting.type === 'user') {
|
|
317
341
|
user[setting.key] = parsedValue;
|
|
318
342
|
} else {
|
package/src/solid-core.module.ts
CHANGED
|
@@ -94,6 +94,10 @@ import { SmsQueuePublisher } from './jobs/sms-publisher.service';
|
|
|
94
94
|
import { SmsQueueSubscriber } from './jobs/sms-subscriber.service';
|
|
95
95
|
import { TestQueuePublisher } from './jobs/test-queue-publisher.service';
|
|
96
96
|
import { TestQueueSubscriber } from './jobs/test-queue-subscriber.service';
|
|
97
|
+
|
|
98
|
+
// import { ChatterQueuePublisher } from './jobs/chatter-queue-publisher.service';
|
|
99
|
+
// import { ChatterQueueSubscriber } from './jobs/chatter-queue-subscriber.service';
|
|
100
|
+
|
|
97
101
|
import { Msg91WhatsappQueuePublisher } from './jobs/msg91-whatsapp-publisher.service';
|
|
98
102
|
import { Msg91WhatsappQueueSubscriber } from './jobs/msg91-whatsapp-subscriber.service';
|
|
99
103
|
import { UserRegistrationListener } from './listeners/user-registration.listener';
|
|
@@ -176,8 +180,8 @@ import { ModelMetadataHelperService } from './helpers/model-metadata-helper.serv
|
|
|
176
180
|
import { ModuleMetadataHelperService } from './helpers/module-metadata-helper.service';
|
|
177
181
|
import { ApiEmailQueuePublisherDatabase } from './jobs/database/api-email-publisher-database.service';
|
|
178
182
|
import { ApiEmailQueueSubscriberDatabase } from './jobs/database/api-email-subscriber-database.service';
|
|
179
|
-
import {
|
|
180
|
-
import {
|
|
183
|
+
import { ComputedFieldEvaluationPublisherDatabase } from './jobs/database/computed-field-evaluation-publisher-database.service';
|
|
184
|
+
import { ComputedFieldEvaluationSubscriberDatabase } from './jobs/database/computed-field-evaluation-subscriber-database.service';
|
|
181
185
|
import { SmtpEmailQueuePublisherDatabase } from './jobs/database/smtp-email-publisher-database.service';
|
|
182
186
|
import { SmtpEmailQueueSubscriberDatabase } from './jobs/database/smtp-email-subscriber-database.service';
|
|
183
187
|
import { GenerateCodePublisherDatabase } from './jobs/database/generate-code-publisher-database.service';
|
|
@@ -284,6 +288,18 @@ import { Three60WhatsappService } from './services/whatsapp/Three60WhatsappServi
|
|
|
284
288
|
import { ThrottlerStorageRedisService } from '@nest-lab/throttler-storage-redis/src/throttler-storage-redis.service';
|
|
285
289
|
import { isRedisConfigured } from './helpers/environment.helper';
|
|
286
290
|
import { UserRepository } from './repository/user.repository';
|
|
291
|
+
import { ErrorMapperService } from './helpers/error-mapper.service';
|
|
292
|
+
import { IngestCommand } from './commands/ingest.command';
|
|
293
|
+
import { R2RHelperService } from './services/genai/r2r-helper.service';
|
|
294
|
+
import { IngestMetadataService } from './services/genai/ingest-metadata.service';
|
|
295
|
+
import { ComputedFieldEvaluationPublisherRabbitmq } from './jobs/computed-field-evaluation-publisher.service';
|
|
296
|
+
import { ComputedFieldEvaluationSubscriberRabbitmq } from './jobs/computed-field-evaluation-subscriber.service';
|
|
297
|
+
import { GenerateCodePublisherRabbitmq } from './jobs/generate-code-publisher.service';
|
|
298
|
+
import { GenerateCodeSubscriberRabbitmq } from './jobs/generate-code-subscriber.service';
|
|
299
|
+
import { TriggerMcpClientPublisherRabbitmq } from './jobs/trigger-mcp-client-publisher.service';
|
|
300
|
+
import { TriggerMcpClientSubscriberRabbitmq } from './jobs/trigger-mcp-client-subscriber.service';
|
|
301
|
+
import { TwilioSmsQueuePublisherRabbitmq } from './jobs/twilio-sms-publisher.service';
|
|
302
|
+
import { TwilioSmsQueueSubscriberRabbitmq } from './jobs/twilio-sms-subscriber.service';
|
|
287
303
|
|
|
288
304
|
|
|
289
305
|
@Global()
|
|
@@ -364,10 +380,10 @@ import { UserRepository } from './repository/user.repository';
|
|
|
364
380
|
inject: [ConfigService],
|
|
365
381
|
useFactory: (configService: ConfigService) => ({
|
|
366
382
|
throttlers: [
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
383
|
+
{ name: 'short', ttl: seconds(10), limit: 10 },
|
|
384
|
+
{ name: 'login', ttl: seconds(10), limit: 5 },
|
|
385
|
+
{ name: 'burst', ttl: seconds(1), limit: 100 },
|
|
386
|
+
{ name: 'sustained', ttl: seconds(300), limit: 500 },
|
|
371
387
|
],
|
|
372
388
|
storage: isRedisConfigured(configService) ? new ThrottlerStorageRedisService(`redis://${configService.get<string>('REDIS_HOST')}:${configService.get<string>('REDIS_PORT')}`) : undefined,
|
|
373
389
|
}),
|
|
@@ -447,6 +463,7 @@ import { UserRepository } from './repository/user.repository';
|
|
|
447
463
|
RefreshModuleCommand,
|
|
448
464
|
SolidIntrospectService,
|
|
449
465
|
DiscoveryService,
|
|
466
|
+
R2RHelperService,
|
|
450
467
|
CrudHelperService,
|
|
451
468
|
CRUDService,
|
|
452
469
|
Reflector,
|
|
@@ -470,6 +487,8 @@ import { UserRepository } from './repository/user.repository';
|
|
|
470
487
|
TextractService,
|
|
471
488
|
SolidRegistry,
|
|
472
489
|
SeedCommand,
|
|
490
|
+
IngestCommand,
|
|
491
|
+
IngestMetadataService,
|
|
473
492
|
SMTPEMailService,
|
|
474
493
|
ElasticEmailService,
|
|
475
494
|
Msg91SMSService,
|
|
@@ -480,12 +499,15 @@ import { UserRepository } from './repository/user.repository';
|
|
|
480
499
|
EmailTemplateService,
|
|
481
500
|
PublisherFactory,
|
|
482
501
|
PollerService,
|
|
502
|
+
ErrorMapperService,
|
|
483
503
|
|
|
484
504
|
McpToolResponseHandlerFactory,
|
|
485
505
|
SolidCreateModuleMcpToolResponseHandler,
|
|
486
506
|
|
|
487
507
|
TriggerMcpClientPublisherDatabase,
|
|
488
508
|
TriggerMcpClientSubscriberDatabase,
|
|
509
|
+
TriggerMcpClientPublisherRabbitmq,
|
|
510
|
+
TriggerMcpClientSubscriberRabbitmq,
|
|
489
511
|
|
|
490
512
|
SmtpEmailQueuePublisherRabbitmq,
|
|
491
513
|
SmtpEmailQueueSubscriberRabbitmq,
|
|
@@ -501,6 +523,8 @@ import { UserRepository } from './repository/user.repository';
|
|
|
501
523
|
SmsQueueSubscriberDatabase,
|
|
502
524
|
TwilioSmsQueuePublisherDatabase,
|
|
503
525
|
TwilioSmsQueueSubscriberDatabase,
|
|
526
|
+
TwilioSmsQueuePublisherRabbitmq,
|
|
527
|
+
TwilioSmsQueueSubscriberRabbitmq,
|
|
504
528
|
OTPQueuePublisher,
|
|
505
529
|
OTPQueueSubscriber,
|
|
506
530
|
OTPQueuePublisherDatabase,
|
|
@@ -535,10 +559,17 @@ import { UserRepository } from './repository/user.repository';
|
|
|
535
559
|
UserRegistrationListener,
|
|
536
560
|
TestQueuePublisher,
|
|
537
561
|
TestQueueSubscriber,
|
|
562
|
+
|
|
563
|
+
// ChatterQueuePublisher,
|
|
564
|
+
// ChatterQueueSubscriber,
|
|
565
|
+
|
|
538
566
|
TestQueuePublisherDatabase,
|
|
539
567
|
TestQueueSubscriberDatabase,
|
|
540
568
|
GenerateCodePublisherDatabase,
|
|
541
569
|
GenerateCodeSubscriberDatabase,
|
|
570
|
+
GenerateCodePublisherRabbitmq,
|
|
571
|
+
GenerateCodeSubscriberRabbitmq,
|
|
572
|
+
OTPQueuePublisher,
|
|
542
573
|
MqMessageQueueService,
|
|
543
574
|
MqMessageService,
|
|
544
575
|
ScheduledJobService,
|
|
@@ -576,8 +607,10 @@ import { UserRepository } from './repository/user.repository';
|
|
|
576
607
|
SystemFieldsSeederService,
|
|
577
608
|
FieldMetadataRepository,
|
|
578
609
|
ComputedEntityFieldSubscriber,
|
|
579
|
-
|
|
580
|
-
|
|
610
|
+
ComputedFieldEvaluationPublisherDatabase,
|
|
611
|
+
ComputedFieldEvaluationSubscriberDatabase,
|
|
612
|
+
ComputedFieldEvaluationPublisherRabbitmq,
|
|
613
|
+
ComputedFieldEvaluationSubscriberRabbitmq,
|
|
581
614
|
ConcatEntityComputedFieldProvider,
|
|
582
615
|
UserActivityHistoryService,
|
|
583
616
|
DashboardService,
|
|
@@ -6,6 +6,12 @@ import { ChatterMessageService } from '../services/chatter-message.service';
|
|
|
6
6
|
import { lowerFirst } from 'src/helpers/string.helper';
|
|
7
7
|
import { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';
|
|
8
8
|
|
|
9
|
+
|
|
10
|
+
type DeferredCall =
|
|
11
|
+
| { kind: 'insert'; args: Parameters<ChatterMessageService['postAuditMessageOnInsert']> }
|
|
12
|
+
| { kind: 'update'; args: Parameters<ChatterMessageService['postAuditMessageOnUpdate']> }
|
|
13
|
+
| { kind: 'delete'; args: Parameters<ChatterMessageService['postAuditMessageOnDelete']> };
|
|
14
|
+
|
|
9
15
|
@Injectable()
|
|
10
16
|
@EventSubscriber()
|
|
11
17
|
export class AuditSubscriber implements EntitySubscriberInterface {
|
|
@@ -16,11 +22,21 @@ export class AuditSubscriber implements EntitySubscriberInterface {
|
|
|
16
22
|
private readonly chatterMessageService: ChatterMessageService,
|
|
17
23
|
@InjectRepository(ModelMetadata)
|
|
18
24
|
private readonly modelMetadataRepo: Repository<ModelMetadata>,
|
|
19
|
-
private readonly modelMetadataHelperService
|
|
25
|
+
private readonly modelMetadataHelperService: ModelMetadataHelperService,
|
|
20
26
|
) {
|
|
21
27
|
this.dataSource.subscribers.push(this);
|
|
22
28
|
}
|
|
23
29
|
|
|
30
|
+
// Per-transaction buffer (auto-GC when queryRunner is gone)
|
|
31
|
+
private perTxn = new WeakMap<any, DeferredCall[]>();
|
|
32
|
+
|
|
33
|
+
private enqueue(event: { queryRunner: any }, call: DeferredCall) {
|
|
34
|
+
const qr = event.queryRunner;
|
|
35
|
+
const arr = this.perTxn.get(qr) ?? [];
|
|
36
|
+
arr.push(call);
|
|
37
|
+
this.perTxn.set(qr, arr);
|
|
38
|
+
}
|
|
39
|
+
|
|
24
40
|
private async shouldTrackAudit(entity: any, metadata: EntityMetadata): Promise<boolean> {
|
|
25
41
|
const model = await this.modelMetadataRepo.findOne({
|
|
26
42
|
where: {
|
|
@@ -56,19 +72,233 @@ export class AuditSubscriber implements EntitySubscriberInterface {
|
|
|
56
72
|
|
|
57
73
|
async afterInsert(event: InsertEvent<any>) {
|
|
58
74
|
if (await this.shouldTrackAudit(event.entity, event.metadata)) {
|
|
59
|
-
await this.chatterMessageService.postAuditMessageOnInsert(event.entity, event.metadata);
|
|
75
|
+
// await this.chatterMessageService.postAuditMessageOnInsert(event.entity, event.metadata);
|
|
76
|
+
this.enqueue(event, {
|
|
77
|
+
kind: 'insert',
|
|
78
|
+
args: [event.entity, event.metadata] as Parameters<ChatterMessageService['postAuditMessageOnInsert']>,
|
|
79
|
+
});
|
|
60
80
|
}
|
|
61
81
|
}
|
|
62
82
|
|
|
63
83
|
async afterUpdate(event: UpdateEvent<any>) {
|
|
64
84
|
if (await this.shouldTrackAudit(event.entity, event.metadata)) {
|
|
65
|
-
await this.chatterMessageService.postAuditMessageOnUpdate(event.entity, event.metadata, event.databaseEntity, event.updatedColumns || []);
|
|
85
|
+
// await this.chatterMessageService.postAuditMessageOnUpdate(event.entity, event.metadata, event.databaseEntity, event.updatedColumns || []);
|
|
86
|
+
this.enqueue(event, {
|
|
87
|
+
kind: 'update',
|
|
88
|
+
args: [
|
|
89
|
+
event.entity, // entity (after)
|
|
90
|
+
event.metadata,
|
|
91
|
+
event.databaseEntity, // entity (before)
|
|
92
|
+
event.updatedColumns ?? [],
|
|
93
|
+
] as Parameters<ChatterMessageService['postAuditMessageOnUpdate']>,
|
|
94
|
+
});
|
|
66
95
|
}
|
|
67
96
|
}
|
|
68
97
|
|
|
69
98
|
async afterRemove(event: RemoveEvent<any>) {
|
|
70
99
|
if (await this.shouldTrackAudit(event.entity, event.metadata)) {
|
|
71
|
-
await this.chatterMessageService.postAuditMessageOnDelete(event.entity, event.metadata, event.databaseEntity);
|
|
100
|
+
// await this.chatterMessageService.postAuditMessageOnDelete(event.entity, event.metadata, event.databaseEntity);
|
|
101
|
+
this.enqueue(event, {
|
|
102
|
+
kind: 'delete',
|
|
103
|
+
args: [
|
|
104
|
+
event.entity,
|
|
105
|
+
event.metadata,
|
|
106
|
+
event.databaseEntity,
|
|
107
|
+
] as Parameters<ChatterMessageService['postAuditMessageOnDelete']>,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// --------- transaction lifecycle ----------
|
|
113
|
+
async afterTransactionCommit(event: { queryRunner: any }) {
|
|
114
|
+
const batch = this.perTxn.get(event.queryRunner) ?? [];
|
|
115
|
+
this.perTxn.delete(event.queryRunner);
|
|
116
|
+
|
|
117
|
+
// Now we’re OUTSIDE the DB transaction — safe to do I/O/DB writes inside chatter service.
|
|
118
|
+
for (const item of batch) {
|
|
119
|
+
try {
|
|
120
|
+
switch (item.kind) {
|
|
121
|
+
case 'insert': await this.chatterMessageService.postAuditMessageOnInsert(...item.args); break;
|
|
122
|
+
case 'update': await this.chatterMessageService.postAuditMessageOnUpdate(...item.args); break;
|
|
123
|
+
case 'delete': await this.chatterMessageService.postAuditMessageOnDelete(...item.args); break;
|
|
124
|
+
}
|
|
125
|
+
} catch (e) {
|
|
126
|
+
// Best effort: log and continue; your core txn was already committed
|
|
127
|
+
// Optionally: send to a generic error logger/metric here
|
|
128
|
+
}
|
|
72
129
|
}
|
|
73
130
|
}
|
|
74
|
-
|
|
131
|
+
|
|
132
|
+
afterTransactionRollback(event: { queryRunner: any }) {
|
|
133
|
+
// Drop buffered calls; the write never happened
|
|
134
|
+
this.perTxn.delete(event.queryRunner);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// import { DataSource, EntityMetadata, EntitySubscriberInterface, EventSubscriber, InsertEvent, RemoveEvent, UpdateEvent } from 'typeorm';
|
|
139
|
+
// import { Injectable } from '@nestjs/common';
|
|
140
|
+
// import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
|
141
|
+
// import { Repository } from 'typeorm';
|
|
142
|
+
// import { ModelMetadata } from '../entities/model-metadata.entity';
|
|
143
|
+
// import { lowerFirst } from 'src/helpers/string.helper';
|
|
144
|
+
// import { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';
|
|
145
|
+
// import { ChatterMessagePayload } from 'src/jobs/chatter-queue-publisher.service';
|
|
146
|
+
// import { RequestContextService } from 'src/services/request-context.service';
|
|
147
|
+
// import { PublisherFactory } from 'src/services/queues/publisher-factory.service';
|
|
148
|
+
|
|
149
|
+
// @EventSubscriber()
|
|
150
|
+
// @Injectable()
|
|
151
|
+
// export class AuditSubscriber implements EntitySubscriberInterface {
|
|
152
|
+
// private perTxn = new WeakMap<any, ChatterMessagePayload[]>();
|
|
153
|
+
|
|
154
|
+
// constructor(
|
|
155
|
+
// @InjectDataSource() private readonly dataSource: DataSource,
|
|
156
|
+
// @InjectRepository(ModelMetadata) private readonly modelMetadataRepo: Repository<ModelMetadata>,
|
|
157
|
+
// private readonly modelMetadataHelperService: ModelMetadataHelperService,
|
|
158
|
+
// private readonly requestContext: RequestContextService,
|
|
159
|
+
// private readonly publisherFactory: PublisherFactory<any>
|
|
160
|
+
// ) {
|
|
161
|
+
// this.dataSource.subscribers.push(this);
|
|
162
|
+
// }
|
|
163
|
+
|
|
164
|
+
// // --- small cache to avoid metadata queries on every row ---
|
|
165
|
+
// private modelCache = new Map<string, { enable: boolean; fields: Array<{ name: string; enableAuditTracking: boolean; type: string; relationType?: string }>; ts: number }>();
|
|
166
|
+
// private cacheTTLms = 60_000;
|
|
167
|
+
|
|
168
|
+
// private async shouldTrackAudit(entity: any, metadata: EntityMetadata): Promise<{ enable: boolean; auditFields?: string[] }> {
|
|
169
|
+
// const key = metadata.name;
|
|
170
|
+
// const now = Date.now();
|
|
171
|
+
// const cached = this.modelCache.get(key);
|
|
172
|
+
// if (cached && (now - cached.ts) < this.cacheTTLms) {
|
|
173
|
+
// if (!cached.enable) return { enable: false };
|
|
174
|
+
// const fields = cached.fields.filter(f =>
|
|
175
|
+
// f.enableAuditTracking &&
|
|
176
|
+
// !['mediaSingle', 'mediaMultiple', 'computed', 'richText', 'json'].includes(f.type) &&
|
|
177
|
+
// !(f.type === 'relation' && f.relationType === 'one-to-many')
|
|
178
|
+
// );
|
|
179
|
+
// const present = fields.map(f => f.name).filter(n => entity?.[n] !== undefined);
|
|
180
|
+
// return { enable: present.length > 0, auditFields: present };
|
|
181
|
+
// }
|
|
182
|
+
|
|
183
|
+
// const model = await this.modelMetadataRepo.findOne({
|
|
184
|
+
// where: { singularName: lowerFirst(metadata.name) },
|
|
185
|
+
// relations: { fields: true, module: true },
|
|
186
|
+
// });
|
|
187
|
+
// const enable = !!model?.enableAuditTracking;
|
|
188
|
+
// const fields = model?.fields ?? [];
|
|
189
|
+
// this.modelCache.set(key, { enable, fields, ts: now });
|
|
190
|
+
|
|
191
|
+
// if (!enable) return { enable: false };
|
|
192
|
+
// const filtered = fields.filter(f =>
|
|
193
|
+
// f.enableAuditTracking &&
|
|
194
|
+
// !['mediaSingle', 'mediaMultiple', 'computed', 'richText', 'json'].includes(f.type) &&
|
|
195
|
+
// !(f.type === 'relation' && f.relationType === 'one-to-many')
|
|
196
|
+
// );
|
|
197
|
+
// const present = filtered.map(f => f.name).filter(n => entity?.[n] !== undefined);
|
|
198
|
+
// return { enable: present.length > 0, auditFields: present };
|
|
199
|
+
// }
|
|
200
|
+
|
|
201
|
+
// private push(event: { queryRunner: any }, msg: ChatterMessagePayload) {
|
|
202
|
+
// const arr = this.perTxn.get(event.queryRunner) ?? [];
|
|
203
|
+
// arr.push(msg);
|
|
204
|
+
// this.perTxn.set(event.queryRunner, arr);
|
|
205
|
+
// }
|
|
206
|
+
|
|
207
|
+
// async afterInsert(event: InsertEvent<any>) {
|
|
208
|
+
// if (!event.entity) return;
|
|
209
|
+
// const enable = await this.shouldTrackAudit(event.entity, event.metadata);
|
|
210
|
+
// if (!enable) return;
|
|
211
|
+
|
|
212
|
+
// const payload: ChatterMessagePayload = {
|
|
213
|
+
// eventType: 'insert',
|
|
214
|
+
// model: event.metadata.name,
|
|
215
|
+
// entityId: String(event.entity.id ?? event.entity.uuid ?? ''),
|
|
216
|
+
// occurredAt: new Date().toISOString(),
|
|
217
|
+
// after: this.safeCopy(event.entity),
|
|
218
|
+
// userId: this.getUserId(),
|
|
219
|
+
// };
|
|
220
|
+
// this.push(event, payload);
|
|
221
|
+
// }
|
|
222
|
+
|
|
223
|
+
// async afterUpdate(event: UpdateEvent<any>) {
|
|
224
|
+
// // Updated entity may be null if you used raw query; fall back to databaseEntity
|
|
225
|
+
// const current = event.entity ?? {};
|
|
226
|
+
// const before = event.databaseEntity ?? {};
|
|
227
|
+
// const { enable, auditFields } = await this.shouldTrackAudit(current, event.metadata);
|
|
228
|
+
// if (!enable) return;
|
|
229
|
+
|
|
230
|
+
// const changedCols = (event.updatedColumns || []).map(c => c.propertyName);
|
|
231
|
+
// const payload: ChatterMessagePayload = {
|
|
232
|
+
// eventType: 'update',
|
|
233
|
+
// model: event.metadata.name,
|
|
234
|
+
// entityId: String((current as any).id ?? (before as any).id ?? ''),
|
|
235
|
+
// occurredAt: new Date().toISOString(),
|
|
236
|
+
// before: this.pick(before, auditFields || changedCols),
|
|
237
|
+
// after: this.pick(current, auditFields || changedCols),
|
|
238
|
+
// diff: changedCols,
|
|
239
|
+
// userId: this.getUserId(),
|
|
240
|
+
// };
|
|
241
|
+
// this.push(event, payload);
|
|
242
|
+
// }
|
|
243
|
+
|
|
244
|
+
// async afterRemove(event: RemoveEvent<any>) {
|
|
245
|
+
// const base = event.entity ?? event.databaseEntity;
|
|
246
|
+
// if (!base) return;
|
|
247
|
+
|
|
248
|
+
// const { enable } = await this.shouldTrackAudit(base, event.metadata);
|
|
249
|
+
// if (!enable) return;
|
|
250
|
+
|
|
251
|
+
// const payload: ChatterMessagePayload = {
|
|
252
|
+
// eventType: 'delete',
|
|
253
|
+
// model: event.metadata.name,
|
|
254
|
+
// entityId: String((base as any).id ?? ''),
|
|
255
|
+
// occurredAt: new Date().toISOString(),
|
|
256
|
+
// before: this.safeCopy(base),
|
|
257
|
+
// userId: this.getUserId(),
|
|
258
|
+
// };
|
|
259
|
+
// this.push(event, payload);
|
|
260
|
+
// }
|
|
261
|
+
|
|
262
|
+
// // Publish AFTER the transaction commits -> no idle-in-transaction
|
|
263
|
+
// async afterTransactionCommit(event: { queryRunner: any }) {
|
|
264
|
+
// const batch = this.perTxn.get(event.queryRunner) ?? [];
|
|
265
|
+
// this.perTxn.delete(event.queryRunner);
|
|
266
|
+
// for (const msg of batch) {
|
|
267
|
+
// try {
|
|
268
|
+
// await this.publisherFactory.publish({ payload: msg, parentEntity: msg.model, parentEntityId: msg.entityId }, 'ChatterQueuePublisher');
|
|
269
|
+
// } catch (err) {
|
|
270
|
+
// // log + optionally send to a DLQ or retry queue
|
|
271
|
+
// // do NOT throw; commit already happened
|
|
272
|
+
// // your RabbitMqPublisher likely tracks failures in MqMessage tables anyway
|
|
273
|
+
// }
|
|
274
|
+
// }
|
|
275
|
+
// }
|
|
276
|
+
|
|
277
|
+
// afterTransactionRollback(event: { queryRunner: any }) {
|
|
278
|
+
// this.perTxn.delete(event.queryRunner);
|
|
279
|
+
// }
|
|
280
|
+
|
|
281
|
+
// // --- small helpers to keep payloads JSON-safe and small ---
|
|
282
|
+
// private safeCopy(obj: any) {
|
|
283
|
+
// try {
|
|
284
|
+
// return JSON.parse(JSON.stringify(obj));
|
|
285
|
+
// } catch {
|
|
286
|
+
// return {}; // strip circular refs
|
|
287
|
+
// }
|
|
288
|
+
// }
|
|
289
|
+
|
|
290
|
+
// private pick(obj: any, keys: string[]) {
|
|
291
|
+
// const out: any = {};
|
|
292
|
+
// for (const k of keys) out[k] = obj?.[k];
|
|
293
|
+
// return this.safeCopy(out);
|
|
294
|
+
// }
|
|
295
|
+
|
|
296
|
+
// private getUserId(): string | null {
|
|
297
|
+
|
|
298
|
+
// const activeUser = this.requestContext.getActiveUser();
|
|
299
|
+
// if (activeUser?.sub)
|
|
300
|
+
// return String(activeUser.sub);
|
|
301
|
+
// }
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
// }
|
|
@@ -4,7 +4,7 @@ import { InjectDataSource } from "@nestjs/typeorm";
|
|
|
4
4
|
import { ComputedFieldTriggerOperation } from "src/dtos/create-field-metadata.dto";
|
|
5
5
|
import { ComputedFieldMetadata, SolidRegistry } from "src/helpers/solid-registry";
|
|
6
6
|
import { IEntityPreComputeFieldProvider } from "src/interfaces";
|
|
7
|
-
import {
|
|
7
|
+
import { PublisherFactory } from "src/services/queues/publisher-factory.service";
|
|
8
8
|
import { DataSource, EntitySubscriberInterface, EventSubscriber, InsertEvent, UpdateEvent } from "typeorm";
|
|
9
9
|
|
|
10
10
|
// Create an interface i.e ComputedFieldEvaluationPayload which has same fields as the ComputedFieldMetadata and an additional field for the database entity
|
|
@@ -20,7 +20,8 @@ export class ComputedEntityFieldSubscriber implements EntitySubscriberInterface
|
|
|
20
20
|
@InjectDataSource()
|
|
21
21
|
private readonly dataSource: DataSource,
|
|
22
22
|
private readonly solidRegistry: SolidRegistry,
|
|
23
|
-
private readonly
|
|
23
|
+
private readonly publisherFactory: PublisherFactory<ComputedFieldEvaluationPayload>
|
|
24
|
+
// private readonly computedFieldPublisher: ComputedFieldEvaluationPublisherDatabase,
|
|
24
25
|
) {
|
|
25
26
|
this.dataSource.subscribers.push(this);
|
|
26
27
|
}
|
|
@@ -112,9 +113,10 @@ export class ComputedEntityFieldSubscriber implements EntitySubscriberInterface
|
|
|
112
113
|
...computedField,
|
|
113
114
|
databaseEntity,
|
|
114
115
|
};
|
|
115
|
-
this.
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
this.publisherFactory.publish({payload}, 'ComputedFieldEvaluationPublisher')
|
|
117
|
+
// this.computedFieldPublisher.publish({
|
|
118
|
+
// payload
|
|
119
|
+
// });
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"computed-field-evaluation-publisher.service.d.ts","sourceRoot":"","sources":["../../../src/jobs/database/computed-field-evaluation-publisher.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AACnF,OAAO,EAAE,8BAA8B,EAAE,MAAM,kDAAkD,CAAC;AAGlG,qBACa,gCAAiC,SAAQ,iBAAiB,CAAC,8BAA8B,CAAC;IAE/F,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;gBAD5C,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB;IAKnE,OAAO,IAAI,mBAAmB;CAKjC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"computed-field-evaluation-publisher.service.js","sourceRoot":"","sources":["../../../src/jobs/database/computed-field-evaluation-publisher.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4C;AAE5C,sFAA8E;AAC9E,0EAAmE;AACnE,iGAAmF;AAEnF,wHAA4F;AAGrF,IAAM,gCAAgC,GAAtC,MAAM,gCAAiC,SAAQ,8CAAiD;IACnG,YACuB,gBAAkC,EAClC,qBAA4C;QAE/D,KAAK,CAAC,gBAAgB,EAAE,qBAAqB,CAAC,CAAC;QAH5B,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,0BAAqB,GAArB,qBAAqB,CAAuB;IAGnE,CAAC;IAED,OAAO;QACH,OAAO;YACH,GAAG,iDAAmC;SACzC,CAAC;IACN,CAAC;CACJ,CAAA;AAbY,4EAAgC;2CAAhC,gCAAgC;IAD5C,IAAA,mBAAU,GAAE;qCAGgC,qCAAgB;QACX,gDAAqB;GAH1D,gCAAgC,CAa5C","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { QueuesModuleOptions } from \"src/interfaces\";\nimport { MqMessageQueueService } from \"src/services/mq-message-queue.service\";\nimport { MqMessageService } from \"src/services/mq-message.service\";\nimport { DatabasePublisher } from \"src/services/queues/database-publisher.service\";\nimport { ComputedFieldEvaluationPayload } from \"src/subscribers/computed-entity-field.subscriber\";\nimport computedFieldEvaluationQueueOptions from \"./computed-field-evaluation-queue-options\";\n\n@Injectable()\nexport class ComputedFieldEvaluationPublisher extends DatabasePublisher<ComputedFieldEvaluationPayload> {\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n ) {\n super(mqMessageService, mqMessageQueueService);\n }\n\n options(): QueuesModuleOptions {\n return {\n ...computedFieldEvaluationQueueOptions\n };\n }\n}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"computed-field-evaluation-queue-options.d.ts","sourceRoot":"","sources":["../../../src/jobs/database/computed-field-evaluation-queue-options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;;;;;;AAI9C,wBAIE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"computed-field-evaluation-queue-options.js","sourceRoot":"","sources":["../../../src/jobs/database/computed-field-evaluation-queue-options.ts"],"names":[],"mappings":";;AAAA,iDAA8C;AAE9C,MAAM,UAAU,GAAG,iCAAiC,CAAC;AAErD,kBAAe;IACX,IAAI,EAAE,8BAA8B;IACpC,IAAI,EAAE,uBAAU,CAAC,QAAQ;IACzB,SAAS,EAAE,UAAU;CACxB,CAAC","sourcesContent":["import { BrokerType } from \"../../interfaces\";\n\nconst QUEUE_NAME = 'computed_field_evaluation_queue';\n\nexport default {\n name: 'computedFieldEvaluationQueue',\n type: BrokerType.Database,\n queueName: QUEUE_NAME,\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"computed-field-evaluation-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/jobs/database/computed-field-evaluation-subscriber.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAiE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACpH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AACrF,OAAO,EAAE,8BAA8B,EAAE,MAAM,kDAAkD,CAAC;AAElG,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,qBACa,iCAAkC,SAAQ,kBAAkB,CAAC,8BAA8B,CAAC;IAEjG,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IAC3C,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IACrD,QAAQ,CAAC,aAAa,EAAE,aAAa;IACrC,QAAQ,CAAC,MAAM,EAAE,aAAa;gBAHrB,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB,EAC5C,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,aAAa;IAKlC,OAAO,IAAI,mBAAmB;IAQxB,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,8BAA8B,CAAC;CAOxE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"computed-field-evaluation-subscriber.service.js","sourceRoot":"","sources":["../../../src/jobs/database/computed-field-evaluation-subscriber.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4C;AAC5C,iEAA2D;AAG3D,sFAA8E;AAC9E,0EAAmE;AACnE,mGAAqF;AAErF,wHAA4F;AAC5F,kEAA4D;AAGrD,IAAM,iCAAiC,GAAvC,MAAM,iCAAkC,SAAQ,gDAAkD;IACrG,YACa,gBAAkC,EAClC,qBAA4C,EAC5C,aAA4B,EAC5B,MAAqB;QAE9B,KAAK,CAAC,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,CAAC,CAAC;QAL9C,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,0BAAqB,GAArB,qBAAqB,CAAuB;QAC5C,kBAAa,GAAb,aAAa,CAAe;QAC5B,WAAM,GAAN,MAAM,CAAe;IAGlC,CAAC;IAED,OAAO;QACH,OAAO;YACH,GAAG,iDAAmC;SACzC,CAAA;IACL,CAAC;IAID,KAAK,CAAC,SAAS,CAAC,OAAqD;QACjE,MAAM,EAAE,cAAc,EAAE,GAAG,qBAAqB,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,qBAAqB,CAAC,8BAA8B,CAAC,CAAC;QAEnH,MAAM,gBAAgB,GAAG,QAAQ,CAAC,QAAqD,CAAC;QACxF,MAAM,gBAAgB,CAAC,uBAAuB,CAAC,cAAc,EAAE,qBAAqB,CAAC,CAAC;IAC1F,CAAC;CACJ,CAAA;AAzBY,8EAAiC;4CAAjC,iCAAiC;IAD7C,IAAA,mBAAU,GAAE;qCAGsB,qCAAgB;QACX,gDAAqB;QAC7B,8BAAa;QACpB,8BAAa;GALzB,iCAAiC,CAyB7C","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { SolidRegistry } from \"src/helpers/solid-registry\";\nimport { IEntityPostComputeFieldProvider, IEntityComputedFieldProvider, QueuesModuleOptions } from \"src/interfaces\";\nimport { QueueMessage } from \"src/interfaces/mq\";\nimport { MqMessageQueueService } from \"src/services/mq-message-queue.service\";\nimport { MqMessageService } from \"src/services/mq-message.service\";\nimport { DatabaseSubscriber } from \"src/services/queues/database-subscriber.service\";\nimport { ComputedFieldEvaluationPayload } from \"src/subscribers/computed-entity-field.subscriber\";\nimport computedFieldEvaluationQueueOptions from \"./computed-field-evaluation-queue-options\";\nimport { PollerService } from \"src/services/poller.service\";\n\n@Injectable()\nexport class ComputedFieldEvaluationSubscriber extends DatabaseSubscriber<ComputedFieldEvaluationPayload> {\n constructor(\n readonly mqMessageService: MqMessageService,\n readonly mqMessageQueueService: MqMessageQueueService,\n readonly solidRegistry: SolidRegistry,\n readonly poller: PollerService,\n ) {\n super(mqMessageService, mqMessageQueueService, poller);\n }\n\n options(): QueuesModuleOptions {\n return {\n ...computedFieldEvaluationQueueOptions\n }\n }\n\n // This method will use the ComputedFieldEvaluationPayload to evaluate the computed fields\n // It will then call the corresponding provider computeAndSave method to perform the evaluation\n async subscribe(message: QueueMessage<ComputedFieldEvaluationPayload>) {\n const { databaseEntity, ...computedFieldMetadata } = message.payload;\n const provider = this.solidRegistry.getComputedFieldProvider(computedFieldMetadata.computedFieldValueProviderName);\n // Get the instance of the provider and assert it is of type IEntityComputedFieldProvider\n const providerInstance = provider.instance as IEntityPostComputeFieldProvider<any, any>; // IEntityComputedFieldProvider\n await providerInstance.postComputeAndSaveValue(databaseEntity, computedFieldMetadata); //FIXME There should some way to check/assert if the provider actually has a postComputeAndSaveValue\n }\n}"]}
|