tychat-contracts 1.3.8 → 1.3.10
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/conversations/conversation-type.dto.d.ts +2 -2
- package/dist/conversations/conversation-type.dto.d.ts.map +1 -1
- package/dist/conversations/conversation-type.dto.js +2 -1
- package/dist/conversations/followup-config-response.dto.d.ts +9 -0
- package/dist/conversations/followup-config-response.dto.d.ts.map +1 -1
- package/dist/conversations/followup-config-response.dto.js +90 -0
- package/dist/notifications/index.d.ts +2 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +5 -1
- package/dist/notifications/notifications-kafka-topics.d.ts +4 -0
- package/dist/notifications/notifications-kafka-topics.d.ts.map +1 -1
- package/dist/notifications/notifications-kafka-topics.js +5 -1
- package/dist/notifications/notifications-send-push-to-user.dto.d.ts +13 -0
- package/dist/notifications/notifications-send-push-to-user.dto.d.ts.map +1 -0
- package/dist/notifications/notifications-send-push-to-user.dto.js +76 -0
- package/package.json +1 -1
- package/src/conversations/conversation-type.dto.ts +2 -1
- package/src/conversations/followup-config-response.dto.ts +91 -1
- package/src/notifications/index.ts +3 -0
- package/src/notifications/notifications-kafka-topics.ts +7 -0
- package/src/notifications/notifications-send-push-to-user.dto.ts +58 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const CONVERSATION_SESSION_TYPES: readonly ["ia", "human"];
|
|
2
|
-
export declare const CONVERSATION_TYPES: readonly ["ia", "human"];
|
|
1
|
+
export declare const CONVERSATION_SESSION_TYPES: readonly ["ia", "human", "waiting"];
|
|
2
|
+
export declare const CONVERSATION_TYPES: readonly ["ia", "human", "waiting"];
|
|
3
3
|
export type ConversationTypeDto = (typeof CONVERSATION_SESSION_TYPES)[number];
|
|
4
4
|
export declare const CONVERSATION_MESSAGE_TYPES: readonly ["ia", "human", "patient"];
|
|
5
5
|
export type ConversationMessageTypeDto = (typeof CONVERSATION_MESSAGE_TYPES)[number];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-type.dto.d.ts","sourceRoot":"","sources":["../../src/conversations/conversation-type.dto.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"conversation-type.dto.d.ts","sourceRoot":"","sources":["../../src/conversations/conversation-type.dto.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,0BAA0B,qCAAsC,CAAC;AAG9E,eAAO,MAAM,kBAAkB,qCAA6B,CAAC;AAE7D,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAI9E,eAAO,MAAM,0BAA0B,qCAAsC,CAAC;AAC9E,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -4,7 +4,8 @@ exports.CONVERSATION_MESSAGE_TYPES = exports.CONVERSATION_TYPES = exports.CONVER
|
|
|
4
4
|
// Allowed conversation session types.
|
|
5
5
|
// "ia" → patient interacting with the AI.
|
|
6
6
|
// "human" → human staff member responding to the patient.
|
|
7
|
-
|
|
7
|
+
// "waiting" → waiting queue for human handoff.
|
|
8
|
+
exports.CONVERSATION_SESSION_TYPES = ['ia', 'human', 'waiting'];
|
|
8
9
|
// Backwards-compatible alias for session types.
|
|
9
10
|
exports.CONVERSATION_TYPES = exports.CONVERSATION_SESSION_TYPES;
|
|
10
11
|
// Allowed conversation message types for the `conversations` table.
|
|
@@ -33,5 +33,14 @@ export declare class FollowupConfigResponseDto {
|
|
|
33
33
|
templateReturnSuggestion?: string;
|
|
34
34
|
templateAbandonment?: string;
|
|
35
35
|
enabled: boolean;
|
|
36
|
+
humanPatientIdleWarningDelayMinutes: number;
|
|
37
|
+
humanPatientIdleFinalizeDelayMinutes: number;
|
|
38
|
+
humanAttendantIdleRequeueDelayMinutes: number;
|
|
39
|
+
humanAttendantIdlePushWarningLeadMinutes: number;
|
|
40
|
+
humanPatientIdleWarningMessage: string;
|
|
41
|
+
humanPatientIdleFinalizeMessage: string;
|
|
42
|
+
humanAttendantIdleRequeueMessage: string;
|
|
43
|
+
humanAfterHoursWaitingMessage: string;
|
|
44
|
+
humanRequestOutsideHoursMessage: string;
|
|
36
45
|
}
|
|
37
46
|
//# sourceMappingURL=followup-config-response.dto.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"followup-config-response.dto.d.ts","sourceRoot":"","sources":["../../src/conversations/followup-config-response.dto.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"followup-config-response.dto.d.ts","sourceRoot":"","sources":["../../src/conversations/followup-config-response.dto.ts"],"names":[],"mappings":"AAWA;;;;;GAKG;AACH,qBAAa,yBAAyB;IAIpC,EAAE,EAAE,MAAM,CAAC;IAMX,MAAM,CAAC,EAAE,MAAM,CAAC;IAYhB,2BAA2B,EAAE,MAAM,CAAC;IAKpC,qBAAqB,EAAE,MAAM,CAAC;IAK9B,qBAAqB,EAAE,MAAM,CAAC;IAK9B,qBAAqB,EAAE,MAAM,CAAC;IAK9B,qBAAqB,EAAE,MAAM,CAAC;IAK9B,qBAAqB,EAAE,MAAM,CAAC;IAS9B,yBAAyB,EAAE,MAAM,CAAC;IAIlC,mBAAmB,EAAE,OAAO,CAAC;IAS7B,+BAA+B,EAAE,MAAM,CAAC;IAIxC,0BAA0B,EAAE,OAAO,CAAC;IAKpC,gCAAgC,EAAE,MAAM,CAAC;IAIzC,2BAA2B,EAAE,OAAO,CAAC;IASrC,kBAAkB,EAAE,MAAM,CAAC;IAI3B,aAAa,EAAE,OAAO,CAAC;IASvB,yBAAyB,EAAE,MAAM,CAAC;IAIlC,oBAAoB,EAAE,OAAO,CAAC;IAS9B,4BAA4B,EAAE,MAAM,CAAC;IAIrC,uBAAuB,EAAE,OAAO,CAAC;IAYjC,+BAA+B,CAAC,EAAE,MAAM,CAAC;IAQzC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IAQrC,4BAA4B,CAAC,EAAE,MAAM,CAAC;IAQtC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAQlC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAQ/B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAQlC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAQ7B,OAAO,EAAE,OAAO,CAAC;IASjB,mCAAmC,EAAE,MAAM,CAAC;IAS5C,oCAAoC,EAAE,MAAM,CAAC;IAS7C,qCAAqC,EAAE,MAAM,CAAC;IAS9C,wCAAwC,EAAE,MAAM,CAAC;IASjD,8BAA8B,EAAE,MAAM,CAAC;IASvC,+BAA+B,EAAE,MAAM,CAAC;IASxC,gCAAgC,EAAE,MAAM,CAAC;IASzC,6BAA6B,EAAE,MAAM,CAAC;IAUtC,+BAA+B,EAAE,MAAM,CAAC;CACzC"}
|
|
@@ -71,6 +71,15 @@ class FollowupConfigResponseDto {
|
|
|
71
71
|
// Global setting
|
|
72
72
|
// ---------------------------------------------------------------------------
|
|
73
73
|
enabled;
|
|
74
|
+
humanPatientIdleWarningDelayMinutes;
|
|
75
|
+
humanPatientIdleFinalizeDelayMinutes;
|
|
76
|
+
humanAttendantIdleRequeueDelayMinutes;
|
|
77
|
+
humanAttendantIdlePushWarningLeadMinutes;
|
|
78
|
+
humanPatientIdleWarningMessage;
|
|
79
|
+
humanPatientIdleFinalizeMessage;
|
|
80
|
+
humanAttendantIdleRequeueMessage;
|
|
81
|
+
humanAfterHoursWaitingMessage;
|
|
82
|
+
humanRequestOutsideHoursMessage;
|
|
74
83
|
}
|
|
75
84
|
exports.FollowupConfigResponseDto = FollowupConfigResponseDto;
|
|
76
85
|
__decorate([
|
|
@@ -259,3 +268,84 @@ __decorate([
|
|
|
259
268
|
(0, class_validator_1.IsBoolean)(),
|
|
260
269
|
__metadata("design:type", Boolean)
|
|
261
270
|
], FollowupConfigResponseDto.prototype, "enabled", void 0);
|
|
271
|
+
__decorate([
|
|
272
|
+
(0, swagger_1.ApiProperty)({
|
|
273
|
+
description: 'Minutes to send warning when attendant sent the last message and patient did not reply',
|
|
274
|
+
example: 5,
|
|
275
|
+
}),
|
|
276
|
+
(0, class_validator_1.IsInt)(),
|
|
277
|
+
(0, class_validator_1.Min)(1),
|
|
278
|
+
__metadata("design:type", Number)
|
|
279
|
+
], FollowupConfigResponseDto.prototype, "humanPatientIdleWarningDelayMinutes", void 0);
|
|
280
|
+
__decorate([
|
|
281
|
+
(0, swagger_1.ApiProperty)({
|
|
282
|
+
description: 'Minutes after warning to finalize human attendance and return session to IA',
|
|
283
|
+
example: 10,
|
|
284
|
+
}),
|
|
285
|
+
(0, class_validator_1.IsInt)(),
|
|
286
|
+
(0, class_validator_1.Min)(1),
|
|
287
|
+
__metadata("design:type", Number)
|
|
288
|
+
], FollowupConfigResponseDto.prototype, "humanPatientIdleFinalizeDelayMinutes", void 0);
|
|
289
|
+
__decorate([
|
|
290
|
+
(0, swagger_1.ApiProperty)({
|
|
291
|
+
description: 'Minutes to requeue when patient sent the last message and attendant did not reply',
|
|
292
|
+
example: 15,
|
|
293
|
+
}),
|
|
294
|
+
(0, class_validator_1.IsInt)(),
|
|
295
|
+
(0, class_validator_1.Min)(1),
|
|
296
|
+
__metadata("design:type", Number)
|
|
297
|
+
], FollowupConfigResponseDto.prototype, "humanAttendantIdleRequeueDelayMinutes", void 0);
|
|
298
|
+
__decorate([
|
|
299
|
+
(0, swagger_1.ApiProperty)({
|
|
300
|
+
description: 'Minutes before requeue to send a push to the responsible attendant (0 = disabled). Must be less than humanAttendantIdleRequeueDelayMinutes when > 0.',
|
|
301
|
+
example: 3,
|
|
302
|
+
}),
|
|
303
|
+
(0, class_validator_1.IsInt)(),
|
|
304
|
+
(0, class_validator_1.Min)(0),
|
|
305
|
+
__metadata("design:type", Number)
|
|
306
|
+
], FollowupConfigResponseDto.prototype, "humanAttendantIdlePushWarningLeadMinutes", void 0);
|
|
307
|
+
__decorate([
|
|
308
|
+
(0, swagger_1.ApiProperty)({
|
|
309
|
+
description: 'Message sent as warning when patient is idle during human attendance',
|
|
310
|
+
example: 'Ainda estamos aguardando sua resposta. Em alguns minutos, o atendimento humano sera finalizado caso nao haja retorno.',
|
|
311
|
+
}),
|
|
312
|
+
(0, class_validator_1.IsString)(),
|
|
313
|
+
(0, class_validator_1.MaxLength)(5000),
|
|
314
|
+
__metadata("design:type", String)
|
|
315
|
+
], FollowupConfigResponseDto.prototype, "humanPatientIdleWarningMessage", void 0);
|
|
316
|
+
__decorate([
|
|
317
|
+
(0, swagger_1.ApiProperty)({
|
|
318
|
+
description: 'Message sent when human attendance is finalized due to patient inactivity',
|
|
319
|
+
example: 'Como nao recebemos seu retorno, encerramos o atendimento humano por agora. Se precisar, posso continuar seu atendimento por IA.',
|
|
320
|
+
}),
|
|
321
|
+
(0, class_validator_1.IsString)(),
|
|
322
|
+
(0, class_validator_1.MaxLength)(5000),
|
|
323
|
+
__metadata("design:type", String)
|
|
324
|
+
], FollowupConfigResponseDto.prototype, "humanPatientIdleFinalizeMessage", void 0);
|
|
325
|
+
__decorate([
|
|
326
|
+
(0, swagger_1.ApiProperty)({
|
|
327
|
+
description: 'Message sent when session is requeued due to attendant inactivity',
|
|
328
|
+
example: 'Devido a alta demanda, outro atendente continuara seu atendimento em breve.',
|
|
329
|
+
}),
|
|
330
|
+
(0, class_validator_1.IsString)(),
|
|
331
|
+
(0, class_validator_1.MaxLength)(5000),
|
|
332
|
+
__metadata("design:type", String)
|
|
333
|
+
], FollowupConfigResponseDto.prototype, "humanAttendantIdleRequeueMessage", void 0);
|
|
334
|
+
__decorate([
|
|
335
|
+
(0, swagger_1.ApiProperty)({
|
|
336
|
+
description: 'Message sent when clinic is closed and session remains in waiting queue',
|
|
337
|
+
example: 'Nosso horario de atendimento foi encerrado. Retornaremos o contato no proximo dia util.',
|
|
338
|
+
}),
|
|
339
|
+
(0, class_validator_1.IsString)(),
|
|
340
|
+
(0, class_validator_1.MaxLength)(5000),
|
|
341
|
+
__metadata("design:type", String)
|
|
342
|
+
], FollowupConfigResponseDto.prototype, "humanAfterHoursWaitingMessage", void 0);
|
|
343
|
+
__decorate([
|
|
344
|
+
(0, swagger_1.ApiProperty)({
|
|
345
|
+
description: 'Message sent when patient requests human support outside clinic hours',
|
|
346
|
+
example: 'No momento estamos fora do horario de atendimento humano. Sua conversa foi para a fila e retornaremos no proximo dia util.',
|
|
347
|
+
}),
|
|
348
|
+
(0, class_validator_1.IsString)(),
|
|
349
|
+
(0, class_validator_1.MaxLength)(5000),
|
|
350
|
+
__metadata("design:type", String)
|
|
351
|
+
], FollowupConfigResponseDto.prototype, "humanRequestOutsideHoursMessage", void 0);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export { NotificationUserCreatedEventPayload, NotificationPasswordResetRequestedEventPayload, NotificationConversationChangeToHumanEventPayload, NotificationTenantAiTokensThresholdEventPayload, } from './notifications-kafka.payloads';
|
|
2
|
-
export { TOPIC_NOTIFICATIONS_FIND_ALL, TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN, TOPIC_NOTIFICATIONS_UPDATE_VIEWED, EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH, EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH, EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD, } from './notifications-kafka-topics';
|
|
2
|
+
export { TOPIC_NOTIFICATIONS_FIND_ALL, TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN, TOPIC_NOTIFICATIONS_UPDATE_VIEWED, TOPIC_NOTIFICATIONS_SEND_PUSH_TO_USER, EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH, EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH, EVENT_NOTIFICATIONS_HUMAN_ATTENDANT_IDLE_WARNING_PUSH, EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD, } from './notifications-kafka-topics';
|
|
3
3
|
export { AdminBroadcastPushDto, ADMIN_NOTIFICATION_KINDS, type AdminNotificationKind, } from './admin-broadcast-push.dto';
|
|
4
4
|
export { RegisterPushTokenDto, NotificationsRegisterPushTokenKafkaDto, } from './register-push-token.dto';
|
|
5
5
|
export { ListNotificationsQueryDto, NOTIFICATION_PROVIDER_FILTERS, NOTIFICATION_STATUS_FILTERS, type NotificationProviderFilterDto, type NotificationStatusFilterDto, } from './list-notifications-query.dto';
|
|
6
6
|
export { NotificationsFindAllKafkaDto } from './notifications-find-all-kafka.dto';
|
|
7
7
|
export { NotificationListItemDto } from './notification-list-item.dto';
|
|
8
8
|
export { UpdateNotificationViewedDto, NotificationsUpdateViewedKafkaDto, } from './update-notification-viewed.dto';
|
|
9
|
+
export { NotificationsSendPushToUserKafkaDto } from './notifications-send-push-to-user.dto';
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mCAAmC,EACnC,8CAA8C,EAC9C,iDAAiD,EACjD,+CAA+C,GAChD,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,4BAA4B,EAC5B,uCAAuC,EACvC,iCAAiC,EACjC,wCAAwC,EACxC,6CAA6C,EAC7C,8CAA8C,GAC/C,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,oBAAoB,EACpB,sCAAsC,GACvC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,EAC3B,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,GACjC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EACL,2BAA2B,EAC3B,iCAAiC,GAClC,MAAM,kCAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mCAAmC,EACnC,8CAA8C,EAC9C,iDAAiD,EACjD,+CAA+C,GAChD,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,4BAA4B,EAC5B,uCAAuC,EACvC,iCAAiC,EACjC,qCAAqC,EACrC,wCAAwC,EACxC,6CAA6C,EAC7C,qDAAqD,EACrD,8CAA8C,GAC/C,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,oBAAoB,EACpB,sCAAsC,GACvC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,EAC3B,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,GACjC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EACL,2BAA2B,EAC3B,iCAAiC,GAClC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,mCAAmC,EAAE,MAAM,uCAAuC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NotificationsUpdateViewedKafkaDto = exports.UpdateNotificationViewedDto = exports.NotificationListItemDto = exports.NotificationsFindAllKafkaDto = exports.NOTIFICATION_STATUS_FILTERS = exports.NOTIFICATION_PROVIDER_FILTERS = exports.ListNotificationsQueryDto = exports.NotificationsRegisterPushTokenKafkaDto = exports.RegisterPushTokenDto = exports.ADMIN_NOTIFICATION_KINDS = exports.AdminBroadcastPushDto = exports.EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD = exports.EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH = exports.EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH = exports.TOPIC_NOTIFICATIONS_UPDATE_VIEWED = exports.TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN = exports.TOPIC_NOTIFICATIONS_FIND_ALL = exports.NotificationTenantAiTokensThresholdEventPayload = exports.NotificationConversationChangeToHumanEventPayload = exports.NotificationPasswordResetRequestedEventPayload = exports.NotificationUserCreatedEventPayload = void 0;
|
|
3
|
+
exports.NotificationsSendPushToUserKafkaDto = exports.NotificationsUpdateViewedKafkaDto = exports.UpdateNotificationViewedDto = exports.NotificationListItemDto = exports.NotificationsFindAllKafkaDto = exports.NOTIFICATION_STATUS_FILTERS = exports.NOTIFICATION_PROVIDER_FILTERS = exports.ListNotificationsQueryDto = exports.NotificationsRegisterPushTokenKafkaDto = exports.RegisterPushTokenDto = exports.ADMIN_NOTIFICATION_KINDS = exports.AdminBroadcastPushDto = exports.EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD = exports.EVENT_NOTIFICATIONS_HUMAN_ATTENDANT_IDLE_WARNING_PUSH = exports.EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH = exports.EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH = exports.TOPIC_NOTIFICATIONS_SEND_PUSH_TO_USER = exports.TOPIC_NOTIFICATIONS_UPDATE_VIEWED = exports.TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN = exports.TOPIC_NOTIFICATIONS_FIND_ALL = exports.NotificationTenantAiTokensThresholdEventPayload = exports.NotificationConversationChangeToHumanEventPayload = exports.NotificationPasswordResetRequestedEventPayload = exports.NotificationUserCreatedEventPayload = void 0;
|
|
4
4
|
var notifications_kafka_payloads_1 = require("./notifications-kafka.payloads");
|
|
5
5
|
Object.defineProperty(exports, "NotificationUserCreatedEventPayload", { enumerable: true, get: function () { return notifications_kafka_payloads_1.NotificationUserCreatedEventPayload; } });
|
|
6
6
|
Object.defineProperty(exports, "NotificationPasswordResetRequestedEventPayload", { enumerable: true, get: function () { return notifications_kafka_payloads_1.NotificationPasswordResetRequestedEventPayload; } });
|
|
@@ -10,8 +10,10 @@ var notifications_kafka_topics_1 = require("./notifications-kafka-topics");
|
|
|
10
10
|
Object.defineProperty(exports, "TOPIC_NOTIFICATIONS_FIND_ALL", { enumerable: true, get: function () { return notifications_kafka_topics_1.TOPIC_NOTIFICATIONS_FIND_ALL; } });
|
|
11
11
|
Object.defineProperty(exports, "TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN", { enumerable: true, get: function () { return notifications_kafka_topics_1.TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN; } });
|
|
12
12
|
Object.defineProperty(exports, "TOPIC_NOTIFICATIONS_UPDATE_VIEWED", { enumerable: true, get: function () { return notifications_kafka_topics_1.TOPIC_NOTIFICATIONS_UPDATE_VIEWED; } });
|
|
13
|
+
Object.defineProperty(exports, "TOPIC_NOTIFICATIONS_SEND_PUSH_TO_USER", { enumerable: true, get: function () { return notifications_kafka_topics_1.TOPIC_NOTIFICATIONS_SEND_PUSH_TO_USER; } });
|
|
13
14
|
Object.defineProperty(exports, "EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH", { enumerable: true, get: function () { return notifications_kafka_topics_1.EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH; } });
|
|
14
15
|
Object.defineProperty(exports, "EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH", { enumerable: true, get: function () { return notifications_kafka_topics_1.EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH; } });
|
|
16
|
+
Object.defineProperty(exports, "EVENT_NOTIFICATIONS_HUMAN_ATTENDANT_IDLE_WARNING_PUSH", { enumerable: true, get: function () { return notifications_kafka_topics_1.EVENT_NOTIFICATIONS_HUMAN_ATTENDANT_IDLE_WARNING_PUSH; } });
|
|
15
17
|
Object.defineProperty(exports, "EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD", { enumerable: true, get: function () { return notifications_kafka_topics_1.EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD; } });
|
|
16
18
|
var admin_broadcast_push_dto_1 = require("./admin-broadcast-push.dto");
|
|
17
19
|
Object.defineProperty(exports, "AdminBroadcastPushDto", { enumerable: true, get: function () { return admin_broadcast_push_dto_1.AdminBroadcastPushDto; } });
|
|
@@ -30,3 +32,5 @@ Object.defineProperty(exports, "NotificationListItemDto", { enumerable: true, ge
|
|
|
30
32
|
var update_notification_viewed_dto_1 = require("./update-notification-viewed.dto");
|
|
31
33
|
Object.defineProperty(exports, "UpdateNotificationViewedDto", { enumerable: true, get: function () { return update_notification_viewed_dto_1.UpdateNotificationViewedDto; } });
|
|
32
34
|
Object.defineProperty(exports, "NotificationsUpdateViewedKafkaDto", { enumerable: true, get: function () { return update_notification_viewed_dto_1.NotificationsUpdateViewedKafkaDto; } });
|
|
35
|
+
var notifications_send_push_to_user_dto_1 = require("./notifications-send-push-to-user.dto");
|
|
36
|
+
Object.defineProperty(exports, "NotificationsSendPushToUserKafkaDto", { enumerable: true, get: function () { return notifications_send_push_to_user_dto_1.NotificationsSendPushToUserKafkaDto; } });
|
|
@@ -3,10 +3,14 @@ export declare const TOPIC_NOTIFICATIONS_FIND_ALL = "notifications.findAll";
|
|
|
3
3
|
export declare const TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN = "notifications.registerPushToken";
|
|
4
4
|
/** Kafka request–reply: atualizar visualização de uma notificação persistida. */
|
|
5
5
|
export declare const TOPIC_NOTIFICATIONS_UPDATE_VIEWED = "notifications.updateViewed";
|
|
6
|
+
/** RabbitMQ request–reply: enviar push FCM a um utilizador (serviços internos). */
|
|
7
|
+
export declare const TOPIC_NOTIFICATIONS_SEND_PUSH_TO_USER = "notifications.sendPushToUser";
|
|
6
8
|
/** Kafka event: push FCM em massa (painel administrativo). */
|
|
7
9
|
export declare const EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH = "notifications.admin_broadcast_push";
|
|
8
10
|
/** Registo `notifications` / FCM quando a clínica recebe alerta de conversa para humano. */
|
|
9
11
|
export declare const EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH = "notifications.conversation_change_to_human_push";
|
|
12
|
+
/** Push ao atendente responsável: perto do timeout de inatividade (antes de ir à fila). */
|
|
13
|
+
export declare const EVENT_NOTIFICATIONS_HUMAN_ATTENDANT_IDLE_WARNING_PUSH = "notifications.human_attendant_idle_warning_push";
|
|
10
14
|
/** Evento Kafka: alerta de cota mensal de tokens de IA para administradores do tenant. */
|
|
11
15
|
export declare const EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD = "notifications.tenant_ai_tokens_threshold";
|
|
12
16
|
//# sourceMappingURL=notifications-kafka-topics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications-kafka-topics.d.ts","sourceRoot":"","sources":["../../src/notifications/notifications-kafka-topics.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,eAAO,MAAM,4BAA4B,0BAA0B,CAAC;AAEpE,eAAO,MAAM,uCAAuC,oCACjB,CAAC;AAEpC,iFAAiF;AACjF,eAAO,MAAM,iCAAiC,+BAA+B,CAAC;AAE9E,8DAA8D;AAC9D,eAAO,MAAM,wCAAwC,uCACf,CAAC;AAEvC,4FAA4F;AAC5F,eAAO,MAAM,6CAA6C,oDACP,CAAC;AAEpD,0FAA0F;AAC1F,eAAO,MAAM,8CAA8C,6CACf,CAAC"}
|
|
1
|
+
{"version":3,"file":"notifications-kafka-topics.d.ts","sourceRoot":"","sources":["../../src/notifications/notifications-kafka-topics.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,eAAO,MAAM,4BAA4B,0BAA0B,CAAC;AAEpE,eAAO,MAAM,uCAAuC,oCACjB,CAAC;AAEpC,iFAAiF;AACjF,eAAO,MAAM,iCAAiC,+BAA+B,CAAC;AAE9E,mFAAmF;AACnF,eAAO,MAAM,qCAAqC,iCAAiC,CAAC;AAEpF,8DAA8D;AAC9D,eAAO,MAAM,wCAAwC,uCACf,CAAC;AAEvC,4FAA4F;AAC5F,eAAO,MAAM,6CAA6C,oDACP,CAAC;AAEpD,2FAA2F;AAC3F,eAAO,MAAM,qDAAqD,oDACf,CAAC;AAEpD,0FAA0F;AAC1F,eAAO,MAAM,8CAA8C,6CACf,CAAC"}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD = exports.EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH = exports.EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH = exports.TOPIC_NOTIFICATIONS_UPDATE_VIEWED = exports.TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN = exports.TOPIC_NOTIFICATIONS_FIND_ALL = void 0;
|
|
3
|
+
exports.EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD = exports.EVENT_NOTIFICATIONS_HUMAN_ATTENDANT_IDLE_WARNING_PUSH = exports.EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH = exports.EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH = exports.TOPIC_NOTIFICATIONS_SEND_PUSH_TO_USER = exports.TOPIC_NOTIFICATIONS_UPDATE_VIEWED = exports.TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN = exports.TOPIC_NOTIFICATIONS_FIND_ALL = void 0;
|
|
4
4
|
/** Kafka request–reply: lista notificações persistidas no banco do tenant. */
|
|
5
5
|
exports.TOPIC_NOTIFICATIONS_FIND_ALL = 'notifications.findAll';
|
|
6
6
|
exports.TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN = 'notifications.registerPushToken';
|
|
7
7
|
/** Kafka request–reply: atualizar visualização de uma notificação persistida. */
|
|
8
8
|
exports.TOPIC_NOTIFICATIONS_UPDATE_VIEWED = 'notifications.updateViewed';
|
|
9
|
+
/** RabbitMQ request–reply: enviar push FCM a um utilizador (serviços internos). */
|
|
10
|
+
exports.TOPIC_NOTIFICATIONS_SEND_PUSH_TO_USER = 'notifications.sendPushToUser';
|
|
9
11
|
/** Kafka event: push FCM em massa (painel administrativo). */
|
|
10
12
|
exports.EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH = 'notifications.admin_broadcast_push';
|
|
11
13
|
/** Registo `notifications` / FCM quando a clínica recebe alerta de conversa para humano. */
|
|
12
14
|
exports.EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH = 'notifications.conversation_change_to_human_push';
|
|
15
|
+
/** Push ao atendente responsável: perto do timeout de inatividade (antes de ir à fila). */
|
|
16
|
+
exports.EVENT_NOTIFICATIONS_HUMAN_ATTENDANT_IDLE_WARNING_PUSH = 'notifications.human_attendant_idle_warning_push';
|
|
13
17
|
/** Evento Kafka: alerta de cota mensal de tokens de IA para administradores do tenant. */
|
|
14
18
|
exports.EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD = 'notifications.tenant_ai_tokens_threshold';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC RabbitMQ `notifications.sendPushToUser` — envio FCM a um utilizador (microserviços internos).
|
|
3
|
+
*/
|
|
4
|
+
export declare class NotificationsSendPushToUserKafkaDto {
|
|
5
|
+
tenant: string;
|
|
6
|
+
userId: string;
|
|
7
|
+
title: string;
|
|
8
|
+
body: string;
|
|
9
|
+
data?: Record<string, string>;
|
|
10
|
+
notificationEvent?: string;
|
|
11
|
+
notificationKind?: 'notification' | 'alert';
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=notifications-send-push-to-user.dto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifications-send-push-to-user.dto.d.ts","sourceRoot":"","sources":["../../src/notifications/notifications-send-push-to-user.dto.ts"],"names":[],"mappings":"AAYA;;GAEG;AACH,qBAAa,mCAAmC;IAK9C,MAAM,EAAE,MAAM,CAAC;IAIf,MAAM,EAAE,MAAM,CAAC;IAMf,KAAK,EAAE,MAAM,CAAC;IAMd,IAAI,EAAE,MAAM,CAAC;IAOb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAQ9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAK3B,gBAAgB,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC;CAC7C"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.NotificationsSendPushToUserKafkaDto = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/**
|
|
16
|
+
* RPC RabbitMQ `notifications.sendPushToUser` — envio FCM a um utilizador (microserviços internos).
|
|
17
|
+
*/
|
|
18
|
+
class NotificationsSendPushToUserKafkaDto {
|
|
19
|
+
tenant;
|
|
20
|
+
userId;
|
|
21
|
+
title;
|
|
22
|
+
body;
|
|
23
|
+
data;
|
|
24
|
+
notificationEvent;
|
|
25
|
+
notificationKind;
|
|
26
|
+
}
|
|
27
|
+
exports.NotificationsSendPushToUserKafkaDto = NotificationsSendPushToUserKafkaDto;
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, swagger_1.ApiProperty)({ example: 'default' }),
|
|
30
|
+
(0, class_validator_1.IsString)(),
|
|
31
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
32
|
+
(0, class_validator_1.MaxLength)(255),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], NotificationsSendPushToUserKafkaDto.prototype, "tenant", void 0);
|
|
35
|
+
__decorate([
|
|
36
|
+
(0, swagger_1.ApiProperty)({ format: 'uuid', description: 'Destinatário (ex.: JWT sub do atendente)' }),
|
|
37
|
+
(0, class_validator_1.IsUUID)('4'),
|
|
38
|
+
__metadata("design:type", String)
|
|
39
|
+
], NotificationsSendPushToUserKafkaDto.prototype, "userId", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
(0, swagger_1.ApiProperty)({ example: 'Título curto' }),
|
|
42
|
+
(0, class_validator_1.IsString)(),
|
|
43
|
+
(0, class_validator_1.MinLength)(1),
|
|
44
|
+
(0, class_validator_1.MaxLength)(200),
|
|
45
|
+
__metadata("design:type", String)
|
|
46
|
+
], NotificationsSendPushToUserKafkaDto.prototype, "title", void 0);
|
|
47
|
+
__decorate([
|
|
48
|
+
(0, swagger_1.ApiProperty)({ example: 'Corpo da notificação' }),
|
|
49
|
+
(0, class_validator_1.IsString)(),
|
|
50
|
+
(0, class_validator_1.MinLength)(1),
|
|
51
|
+
(0, class_validator_1.MaxLength)(2000),
|
|
52
|
+
__metadata("design:type", String)
|
|
53
|
+
], NotificationsSendPushToUserKafkaDto.prototype, "body", void 0);
|
|
54
|
+
__decorate([
|
|
55
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
56
|
+
description: 'Dados extras FCM (strings); ex.: sessionUuid, patientId',
|
|
57
|
+
}),
|
|
58
|
+
(0, class_validator_1.IsOptional)(),
|
|
59
|
+
(0, class_validator_1.IsObject)(),
|
|
60
|
+
__metadata("design:type", Object)
|
|
61
|
+
], NotificationsSendPushToUserKafkaDto.prototype, "data", void 0);
|
|
62
|
+
__decorate([
|
|
63
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
64
|
+
description: 'Valor gravado em notifications.notification_event (auditoria)',
|
|
65
|
+
}),
|
|
66
|
+
(0, class_validator_1.IsOptional)(),
|
|
67
|
+
(0, class_validator_1.IsString)(),
|
|
68
|
+
(0, class_validator_1.MaxLength)(120),
|
|
69
|
+
__metadata("design:type", String)
|
|
70
|
+
], NotificationsSendPushToUserKafkaDto.prototype, "notificationEvent", void 0);
|
|
71
|
+
__decorate([
|
|
72
|
+
(0, swagger_1.ApiPropertyOptional)({ enum: ['notification', 'alert'] }),
|
|
73
|
+
(0, class_validator_1.IsOptional)(),
|
|
74
|
+
(0, class_validator_1.IsIn)(['notification', 'alert']),
|
|
75
|
+
__metadata("design:type", String)
|
|
76
|
+
], NotificationsSendPushToUserKafkaDto.prototype, "notificationKind", void 0);
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Allowed conversation session types.
|
|
2
2
|
// "ia" → patient interacting with the AI.
|
|
3
3
|
// "human" → human staff member responding to the patient.
|
|
4
|
-
|
|
4
|
+
// "waiting" → waiting queue for human handoff.
|
|
5
|
+
export const CONVERSATION_SESSION_TYPES = ['ia', 'human', 'waiting'] as const;
|
|
5
6
|
|
|
6
7
|
// Backwards-compatible alias for session types.
|
|
7
8
|
export const CONVERSATION_TYPES = CONVERSATION_SESSION_TYPES;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
IsBoolean,
|
|
4
|
+
IsInt,
|
|
5
|
+
IsNotEmpty,
|
|
6
|
+
IsOptional,
|
|
7
|
+
IsString,
|
|
8
|
+
MaxLength,
|
|
9
|
+
Min,
|
|
10
|
+
} from 'class-validator';
|
|
3
11
|
|
|
4
12
|
/**
|
|
5
13
|
* Represents a follow-up timing configuration for a tenant.
|
|
@@ -197,4 +205,86 @@ export class FollowupConfigResponseDto {
|
|
|
197
205
|
@ApiProperty({ description: 'Whether abandonment follow-up is enabled for this tenant' })
|
|
198
206
|
@IsBoolean()
|
|
199
207
|
enabled: boolean;
|
|
208
|
+
|
|
209
|
+
@ApiProperty({
|
|
210
|
+
description:
|
|
211
|
+
'Minutes to send warning when attendant sent the last message and patient did not reply',
|
|
212
|
+
example: 5,
|
|
213
|
+
})
|
|
214
|
+
@IsInt()
|
|
215
|
+
@Min(1)
|
|
216
|
+
humanPatientIdleWarningDelayMinutes: number;
|
|
217
|
+
|
|
218
|
+
@ApiProperty({
|
|
219
|
+
description:
|
|
220
|
+
'Minutes after warning to finalize human attendance and return session to IA',
|
|
221
|
+
example: 10,
|
|
222
|
+
})
|
|
223
|
+
@IsInt()
|
|
224
|
+
@Min(1)
|
|
225
|
+
humanPatientIdleFinalizeDelayMinutes: number;
|
|
226
|
+
|
|
227
|
+
@ApiProperty({
|
|
228
|
+
description:
|
|
229
|
+
'Minutes to requeue when patient sent the last message and attendant did not reply',
|
|
230
|
+
example: 15,
|
|
231
|
+
})
|
|
232
|
+
@IsInt()
|
|
233
|
+
@Min(1)
|
|
234
|
+
humanAttendantIdleRequeueDelayMinutes: number;
|
|
235
|
+
|
|
236
|
+
@ApiProperty({
|
|
237
|
+
description:
|
|
238
|
+
'Minutes before requeue to send a push to the responsible attendant (0 = disabled). Must be less than humanAttendantIdleRequeueDelayMinutes when > 0.',
|
|
239
|
+
example: 3,
|
|
240
|
+
})
|
|
241
|
+
@IsInt()
|
|
242
|
+
@Min(0)
|
|
243
|
+
humanAttendantIdlePushWarningLeadMinutes: number;
|
|
244
|
+
|
|
245
|
+
@ApiProperty({
|
|
246
|
+
description: 'Message sent as warning when patient is idle during human attendance',
|
|
247
|
+
example:
|
|
248
|
+
'Ainda estamos aguardando sua resposta. Em alguns minutos, o atendimento humano sera finalizado caso nao haja retorno.',
|
|
249
|
+
})
|
|
250
|
+
@IsString()
|
|
251
|
+
@MaxLength(5000)
|
|
252
|
+
humanPatientIdleWarningMessage: string;
|
|
253
|
+
|
|
254
|
+
@ApiProperty({
|
|
255
|
+
description: 'Message sent when human attendance is finalized due to patient inactivity',
|
|
256
|
+
example:
|
|
257
|
+
'Como nao recebemos seu retorno, encerramos o atendimento humano por agora. Se precisar, posso continuar seu atendimento por IA.',
|
|
258
|
+
})
|
|
259
|
+
@IsString()
|
|
260
|
+
@MaxLength(5000)
|
|
261
|
+
humanPatientIdleFinalizeMessage: string;
|
|
262
|
+
|
|
263
|
+
@ApiProperty({
|
|
264
|
+
description: 'Message sent when session is requeued due to attendant inactivity',
|
|
265
|
+
example:
|
|
266
|
+
'Devido a alta demanda, outro atendente continuara seu atendimento em breve.',
|
|
267
|
+
})
|
|
268
|
+
@IsString()
|
|
269
|
+
@MaxLength(5000)
|
|
270
|
+
humanAttendantIdleRequeueMessage: string;
|
|
271
|
+
|
|
272
|
+
@ApiProperty({
|
|
273
|
+
description: 'Message sent when clinic is closed and session remains in waiting queue',
|
|
274
|
+
example:
|
|
275
|
+
'Nosso horario de atendimento foi encerrado. Retornaremos o contato no proximo dia util.',
|
|
276
|
+
})
|
|
277
|
+
@IsString()
|
|
278
|
+
@MaxLength(5000)
|
|
279
|
+
humanAfterHoursWaitingMessage: string;
|
|
280
|
+
|
|
281
|
+
@ApiProperty({
|
|
282
|
+
description:
|
|
283
|
+
'Message sent when patient requests human support outside clinic hours',
|
|
284
|
+
example:
|
|
285
|
+
'No momento estamos fora do horario de atendimento humano. Sua conversa foi para a fila e retornaremos no proximo dia util.',
|
|
286
|
+
})
|
|
287
|
+
@IsString()
|
|
288
|
+
@MaxLength(5000)
|
|
289
|
+
humanRequestOutsideHoursMessage: string;
|
|
200
290
|
}
|
|
@@ -8,8 +8,10 @@ export {
|
|
|
8
8
|
TOPIC_NOTIFICATIONS_FIND_ALL,
|
|
9
9
|
TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN,
|
|
10
10
|
TOPIC_NOTIFICATIONS_UPDATE_VIEWED,
|
|
11
|
+
TOPIC_NOTIFICATIONS_SEND_PUSH_TO_USER,
|
|
11
12
|
EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH,
|
|
12
13
|
EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH,
|
|
14
|
+
EVENT_NOTIFICATIONS_HUMAN_ATTENDANT_IDLE_WARNING_PUSH,
|
|
13
15
|
EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD,
|
|
14
16
|
} from './notifications-kafka-topics';
|
|
15
17
|
export {
|
|
@@ -34,3 +36,4 @@ export {
|
|
|
34
36
|
UpdateNotificationViewedDto,
|
|
35
37
|
NotificationsUpdateViewedKafkaDto,
|
|
36
38
|
} from './update-notification-viewed.dto';
|
|
39
|
+
export { NotificationsSendPushToUserKafkaDto } from './notifications-send-push-to-user.dto';
|
|
@@ -7,6 +7,9 @@ export const TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN =
|
|
|
7
7
|
/** Kafka request–reply: atualizar visualização de uma notificação persistida. */
|
|
8
8
|
export const TOPIC_NOTIFICATIONS_UPDATE_VIEWED = 'notifications.updateViewed';
|
|
9
9
|
|
|
10
|
+
/** RabbitMQ request–reply: enviar push FCM a um utilizador (serviços internos). */
|
|
11
|
+
export const TOPIC_NOTIFICATIONS_SEND_PUSH_TO_USER = 'notifications.sendPushToUser';
|
|
12
|
+
|
|
10
13
|
/** Kafka event: push FCM em massa (painel administrativo). */
|
|
11
14
|
export const EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH =
|
|
12
15
|
'notifications.admin_broadcast_push';
|
|
@@ -15,6 +18,10 @@ export const EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH =
|
|
|
15
18
|
export const EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH =
|
|
16
19
|
'notifications.conversation_change_to_human_push';
|
|
17
20
|
|
|
21
|
+
/** Push ao atendente responsável: perto do timeout de inatividade (antes de ir à fila). */
|
|
22
|
+
export const EVENT_NOTIFICATIONS_HUMAN_ATTENDANT_IDLE_WARNING_PUSH =
|
|
23
|
+
'notifications.human_attendant_idle_warning_push';
|
|
24
|
+
|
|
18
25
|
/** Evento Kafka: alerta de cota mensal de tokens de IA para administradores do tenant. */
|
|
19
26
|
export const EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD =
|
|
20
27
|
'notifications.tenant_ai_tokens_threshold';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
2
|
+
import {
|
|
3
|
+
IsIn,
|
|
4
|
+
IsNotEmpty,
|
|
5
|
+
IsObject,
|
|
6
|
+
IsOptional,
|
|
7
|
+
IsString,
|
|
8
|
+
IsUUID,
|
|
9
|
+
MaxLength,
|
|
10
|
+
MinLength,
|
|
11
|
+
} from 'class-validator';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* RPC RabbitMQ `notifications.sendPushToUser` — envio FCM a um utilizador (microserviços internos).
|
|
15
|
+
*/
|
|
16
|
+
export class NotificationsSendPushToUserKafkaDto {
|
|
17
|
+
@ApiProperty({ example: 'default' })
|
|
18
|
+
@IsString()
|
|
19
|
+
@IsNotEmpty()
|
|
20
|
+
@MaxLength(255)
|
|
21
|
+
tenant: string;
|
|
22
|
+
|
|
23
|
+
@ApiProperty({ format: 'uuid', description: 'Destinatário (ex.: JWT sub do atendente)' })
|
|
24
|
+
@IsUUID('4')
|
|
25
|
+
userId: string;
|
|
26
|
+
|
|
27
|
+
@ApiProperty({ example: 'Título curto' })
|
|
28
|
+
@IsString()
|
|
29
|
+
@MinLength(1)
|
|
30
|
+
@MaxLength(200)
|
|
31
|
+
title: string;
|
|
32
|
+
|
|
33
|
+
@ApiProperty({ example: 'Corpo da notificação' })
|
|
34
|
+
@IsString()
|
|
35
|
+
@MinLength(1)
|
|
36
|
+
@MaxLength(2000)
|
|
37
|
+
body: string;
|
|
38
|
+
|
|
39
|
+
@ApiPropertyOptional({
|
|
40
|
+
description: 'Dados extras FCM (strings); ex.: sessionUuid, patientId',
|
|
41
|
+
})
|
|
42
|
+
@IsOptional()
|
|
43
|
+
@IsObject()
|
|
44
|
+
data?: Record<string, string>;
|
|
45
|
+
|
|
46
|
+
@ApiPropertyOptional({
|
|
47
|
+
description: 'Valor gravado em notifications.notification_event (auditoria)',
|
|
48
|
+
})
|
|
49
|
+
@IsOptional()
|
|
50
|
+
@IsString()
|
|
51
|
+
@MaxLength(120)
|
|
52
|
+
notificationEvent?: string;
|
|
53
|
+
|
|
54
|
+
@ApiPropertyOptional({ enum: ['notification', 'alert'] })
|
|
55
|
+
@IsOptional()
|
|
56
|
+
@IsIn(['notification', 'alert'])
|
|
57
|
+
notificationKind?: 'notification' | 'alert';
|
|
58
|
+
}
|