tychat-contracts 1.3.5 → 1.3.7
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/anamneses/anamnesis-token-session.dto.d.ts +2 -0
- package/dist/anamneses/anamnesis-token-session.dto.d.ts.map +1 -1
- package/dist/anamneses/anamnesis-token-session.dto.js +9 -0
- package/dist/configurations/anamnesis-custom-field.dto.d.ts +8 -0
- package/dist/configurations/anamnesis-custom-field.dto.d.ts.map +1 -0
- package/dist/configurations/anamnesis-custom-field.dto.js +47 -0
- package/dist/configurations/clinic-configuration.dto.d.ts +2 -0
- package/dist/configurations/clinic-configuration.dto.d.ts.map +1 -1
- package/dist/configurations/clinic-configuration.dto.js +10 -0
- package/dist/configurations/index.d.ts +1 -0
- package/dist/configurations/index.d.ts.map +1 -1
- package/dist/configurations/index.js +1 -0
- package/dist/configurations/update-clinic-configuration.dto.d.ts +2 -0
- package/dist/configurations/update-clinic-configuration.dto.d.ts.map +1 -1
- package/dist/configurations/update-clinic-configuration.dto.js +18 -0
- package/dist/notifications/index.d.ts +2 -2
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +3 -1
- package/dist/notifications/notifications-kafka-topics.d.ts +2 -0
- package/dist/notifications/notifications-kafka-topics.d.ts.map +1 -1
- package/dist/notifications/notifications-kafka-topics.js +3 -1
- package/dist/notifications/notifications-kafka.payloads.d.ts +13 -0
- package/dist/notifications/notifications-kafka.payloads.d.ts.map +1 -1
- package/dist/notifications/notifications-kafka.payloads.js +78 -1
- package/package.json +1 -1
- package/src/anamneses/anamnesis-token-session.dto.ts +7 -0
- package/src/configurations/anamnesis-custom-field.dto.ts +30 -0
- package/src/configurations/clinic-configuration.dto.ts +8 -0
- package/src/configurations/index.ts +1 -0
- package/src/configurations/update-clinic-configuration.dto.ts +17 -0
- package/src/notifications/index.ts +2 -0
- package/src/notifications/notifications-kafka-topics.ts +4 -0
- package/src/notifications/notifications-kafka.payloads.ts +59 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AnamnesisCustomFieldDto } from '../configurations';
|
|
1
2
|
export declare class AnamnesisTokenSessionPatientDto {
|
|
2
3
|
id: string;
|
|
3
4
|
name: string;
|
|
@@ -11,5 +12,6 @@ export declare class AnamnesisTokenSessionDto {
|
|
|
11
12
|
expiresAt?: string;
|
|
12
13
|
appointmentId?: string;
|
|
13
14
|
patient?: AnamnesisTokenSessionPatientDto;
|
|
15
|
+
anamnesisCustomFields?: AnamnesisCustomFieldDto[];
|
|
14
16
|
}
|
|
15
17
|
//# sourceMappingURL=anamnesis-token-session.dto.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anamnesis-token-session.dto.d.ts","sourceRoot":"","sources":["../../src/anamneses/anamnesis-token-session.dto.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"anamnesis-token-session.dto.d.ts","sourceRoot":"","sources":["../../src/anamneses/anamnesis-token-session.dto.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,qBAAa,+BAA+B;IAE1C,EAAE,EAAE,MAAM,CAAC;IAGX,IAAI,EAAE,MAAM,CAAC;IAGb,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAGnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,qBAAa,wBAAwB;IAEnC,KAAK,EAAE,OAAO,CAAC;IAMf,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,eAAe,CAAC;IAGhE,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,OAAO,CAAC,EAAE,+BAA+B,CAAC;IAM1C,qBAAqB,CAAC,EAAE,uBAAuB,EAAE,CAAC;CACnD"}
|
|
@@ -11,6 +11,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.AnamnesisTokenSessionDto = exports.AnamnesisTokenSessionPatientDto = void 0;
|
|
13
13
|
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const configurations_1 = require("../configurations");
|
|
14
15
|
class AnamnesisTokenSessionPatientDto {
|
|
15
16
|
id;
|
|
16
17
|
name;
|
|
@@ -41,6 +42,7 @@ class AnamnesisTokenSessionDto {
|
|
|
41
42
|
expiresAt;
|
|
42
43
|
appointmentId;
|
|
43
44
|
patient;
|
|
45
|
+
anamnesisCustomFields;
|
|
44
46
|
}
|
|
45
47
|
exports.AnamnesisTokenSessionDto = AnamnesisTokenSessionDto;
|
|
46
48
|
__decorate([
|
|
@@ -70,3 +72,10 @@ __decorate([
|
|
|
70
72
|
(0, swagger_1.ApiPropertyOptional)({ type: AnamnesisTokenSessionPatientDto }),
|
|
71
73
|
__metadata("design:type", AnamnesisTokenSessionPatientDto)
|
|
72
74
|
], AnamnesisTokenSessionDto.prototype, "patient", void 0);
|
|
75
|
+
__decorate([
|
|
76
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
77
|
+
type: [configurations_1.AnamnesisCustomFieldDto],
|
|
78
|
+
description: 'Campos adicionais da anamnese configurados pela clínica',
|
|
79
|
+
}),
|
|
80
|
+
__metadata("design:type", Array)
|
|
81
|
+
], AnamnesisTokenSessionDto.prototype, "anamnesisCustomFields", void 0);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const ANAMNESIS_CUSTOM_FIELD_TYPES: readonly ["number", "date", "boolean", "text"];
|
|
2
|
+
export type AnamnesisCustomFieldType = (typeof ANAMNESIS_CUSTOM_FIELD_TYPES)[number];
|
|
3
|
+
export declare class AnamnesisCustomFieldDto {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
question: string;
|
|
6
|
+
type: AnamnesisCustomFieldType;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=anamnesis-custom-field.dto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anamnesis-custom-field.dto.d.ts","sourceRoot":"","sources":["../../src/configurations/anamnesis-custom-field.dto.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,4BAA4B,gDAAiD,CAAC;AAC3F,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,4BAA4B,CAAC,CAAC,MAAM,CAAC,CAAC;AAErF,qBAAa,uBAAuB;IAMlC,OAAO,EAAE,OAAO,CAAC;IAQjB,QAAQ,EAAE,MAAM,CAAC;IAQjB,IAAI,EAAE,wBAAwB,CAAC;CAChC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
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.AnamnesisCustomFieldDto = exports.ANAMNESIS_CUSTOM_FIELD_TYPES = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
exports.ANAMNESIS_CUSTOM_FIELD_TYPES = ['number', 'date', 'boolean', 'text'];
|
|
16
|
+
class AnamnesisCustomFieldDto {
|
|
17
|
+
enabled;
|
|
18
|
+
question;
|
|
19
|
+
type;
|
|
20
|
+
}
|
|
21
|
+
exports.AnamnesisCustomFieldDto = AnamnesisCustomFieldDto;
|
|
22
|
+
__decorate([
|
|
23
|
+
(0, swagger_1.ApiProperty)({
|
|
24
|
+
description: 'Campo está ativo para aparecer no formulário público',
|
|
25
|
+
example: true,
|
|
26
|
+
}),
|
|
27
|
+
(0, class_validator_1.IsBoolean)(),
|
|
28
|
+
__metadata("design:type", Boolean)
|
|
29
|
+
], AnamnesisCustomFieldDto.prototype, "enabled", void 0);
|
|
30
|
+
__decorate([
|
|
31
|
+
(0, swagger_1.ApiProperty)({
|
|
32
|
+
description: 'Pergunta exibida ao paciente',
|
|
33
|
+
example: 'Qual sua pressão arterial média?',
|
|
34
|
+
}),
|
|
35
|
+
(0, class_validator_1.IsString)(),
|
|
36
|
+
(0, class_validator_1.MinLength)(3),
|
|
37
|
+
__metadata("design:type", String)
|
|
38
|
+
], AnamnesisCustomFieldDto.prototype, "question", void 0);
|
|
39
|
+
__decorate([
|
|
40
|
+
(0, swagger_1.ApiProperty)({
|
|
41
|
+
description: 'Tipo de resposta esperada para o campo',
|
|
42
|
+
enum: exports.ANAMNESIS_CUSTOM_FIELD_TYPES,
|
|
43
|
+
example: 'number',
|
|
44
|
+
}),
|
|
45
|
+
(0, class_validator_1.IsIn)(exports.ANAMNESIS_CUSTOM_FIELD_TYPES),
|
|
46
|
+
__metadata("design:type", String)
|
|
47
|
+
], AnamnesisCustomFieldDto.prototype, "type", void 0);
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { OpeningHoursSlotDto } from './opening-hours-slot.dto';
|
|
2
|
+
import { AnamnesisCustomFieldDto } from './anamnesis-custom-field.dto';
|
|
2
3
|
/**
|
|
3
4
|
* Response DTO for clinic configuration (opening hours, etc.).
|
|
4
5
|
*/
|
|
5
6
|
export declare class ClinicConfigurationDto {
|
|
6
7
|
id: string;
|
|
7
8
|
opening_hours: OpeningHoursSlotDto[];
|
|
9
|
+
anamnesis_custom_fields?: AnamnesisCustomFieldDto[];
|
|
8
10
|
createdAt: Date;
|
|
9
11
|
updatedAt: Date;
|
|
10
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clinic-configuration.dto.d.ts","sourceRoot":"","sources":["../../src/configurations/clinic-configuration.dto.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"clinic-configuration.dto.d.ts","sourceRoot":"","sources":["../../src/configurations/clinic-configuration.dto.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE;;GAEG;AACH,qBAAa,sBAAsB;IAKjC,EAAE,EAAE,MAAM,CAAC;IAMX,aAAa,EAAE,mBAAmB,EAAE,CAAC;IAOrC,uBAAuB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAMpD,SAAS,EAAE,IAAI,CAAC;IAMhB,SAAS,EAAE,IAAI,CAAC;CACjB"}
|
|
@@ -12,12 +12,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.ClinicConfigurationDto = void 0;
|
|
13
13
|
const swagger_1 = require("@nestjs/swagger");
|
|
14
14
|
const opening_hours_slot_dto_1 = require("./opening-hours-slot.dto");
|
|
15
|
+
const anamnesis_custom_field_dto_1 = require("./anamnesis-custom-field.dto");
|
|
15
16
|
/**
|
|
16
17
|
* Response DTO for clinic configuration (opening hours, etc.).
|
|
17
18
|
*/
|
|
18
19
|
class ClinicConfigurationDto {
|
|
19
20
|
id;
|
|
20
21
|
opening_hours;
|
|
22
|
+
anamnesis_custom_fields;
|
|
21
23
|
createdAt;
|
|
22
24
|
updatedAt;
|
|
23
25
|
}
|
|
@@ -36,6 +38,14 @@ __decorate([
|
|
|
36
38
|
}),
|
|
37
39
|
__metadata("design:type", Array)
|
|
38
40
|
], ClinicConfigurationDto.prototype, "opening_hours", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, swagger_1.ApiProperty)({
|
|
43
|
+
description: 'Campos adicionais de anamnese configurados pela clínica',
|
|
44
|
+
type: [anamnesis_custom_field_dto_1.AnamnesisCustomFieldDto],
|
|
45
|
+
required: false,
|
|
46
|
+
}),
|
|
47
|
+
__metadata("design:type", Array)
|
|
48
|
+
], ClinicConfigurationDto.prototype, "anamnesis_custom_fields", void 0);
|
|
39
49
|
__decorate([
|
|
40
50
|
(0, swagger_1.ApiProperty)({
|
|
41
51
|
description: 'Creation timestamp',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/configurations/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,oCAAoC,CAAC;AACnD,cAAc,wCAAwC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/configurations/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,oCAAoC,CAAC;AACnD,cAAc,wCAAwC,CAAC"}
|
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./opening-hours-slot.dto"), exports);
|
|
18
|
+
__exportStar(require("./anamnesis-custom-field.dto"), exports);
|
|
18
19
|
__exportStar(require("./update-clinic-configuration.dto"), exports);
|
|
19
20
|
__exportStar(require("./clinic-configuration.dto"), exports);
|
|
20
21
|
__exportStar(require("./ai-tool-policy.enums"), exports);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { OpeningHoursSlotDto } from './opening-hours-slot.dto';
|
|
2
|
+
import { AnamnesisCustomFieldDto } from './anamnesis-custom-field.dto';
|
|
2
3
|
export declare class UpdateClinicConfigurationDto {
|
|
3
4
|
opening_hours: OpeningHoursSlotDto[];
|
|
5
|
+
anamnesis_custom_fields?: AnamnesisCustomFieldDto[];
|
|
4
6
|
}
|
|
5
7
|
//# sourceMappingURL=update-clinic-configuration.dto.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-clinic-configuration.dto.d.ts","sourceRoot":"","sources":["../../src/configurations/update-clinic-configuration.dto.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update-clinic-configuration.dto.d.ts","sourceRoot":"","sources":["../../src/configurations/update-clinic-configuration.dto.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,qBAAa,4BAA4B;IAYvC,aAAa,EAAE,mBAAmB,EAAE,CAAC;IAerC,uBAAuB,CAAC,EAAE,uBAAuB,EAAE,CAAC;CACrD"}
|
|
@@ -14,8 +14,10 @@ const swagger_1 = require("@nestjs/swagger");
|
|
|
14
14
|
const class_transformer_1 = require("class-transformer");
|
|
15
15
|
const class_validator_1 = require("class-validator");
|
|
16
16
|
const opening_hours_slot_dto_1 = require("./opening-hours-slot.dto");
|
|
17
|
+
const anamnesis_custom_field_dto_1 = require("./anamnesis-custom-field.dto");
|
|
17
18
|
class UpdateClinicConfigurationDto {
|
|
18
19
|
opening_hours;
|
|
20
|
+
anamnesis_custom_fields;
|
|
19
21
|
}
|
|
20
22
|
exports.UpdateClinicConfigurationDto = UpdateClinicConfigurationDto;
|
|
21
23
|
__decorate([
|
|
@@ -32,3 +34,19 @@ __decorate([
|
|
|
32
34
|
(0, class_transformer_1.Type)(() => opening_hours_slot_dto_1.OpeningHoursSlotDto),
|
|
33
35
|
__metadata("design:type", Array)
|
|
34
36
|
], UpdateClinicConfigurationDto.prototype, "opening_hours", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
(0, swagger_1.ApiProperty)({
|
|
39
|
+
description: 'Campos adicionais de anamnese configurados pela clínica',
|
|
40
|
+
type: [anamnesis_custom_field_dto_1.AnamnesisCustomFieldDto],
|
|
41
|
+
required: false,
|
|
42
|
+
example: [
|
|
43
|
+
{ enabled: true, question: 'Qual foi sua última glicemia?', type: 'number' },
|
|
44
|
+
{ enabled: true, question: 'Data do último exame?', type: 'date' },
|
|
45
|
+
],
|
|
46
|
+
}),
|
|
47
|
+
(0, class_validator_1.IsOptional)(),
|
|
48
|
+
(0, class_validator_1.IsArray)(),
|
|
49
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
50
|
+
(0, class_transformer_1.Type)(() => anamnesis_custom_field_dto_1.AnamnesisCustomFieldDto),
|
|
51
|
+
__metadata("design:type", Array)
|
|
52
|
+
], UpdateClinicConfigurationDto.prototype, "anamnesis_custom_fields", void 0);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { NotificationUserCreatedEventPayload, NotificationPasswordResetRequestedEventPayload, NotificationConversationChangeToHumanEventPayload, } 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, } from './notifications-kafka-topics';
|
|
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';
|
|
3
3
|
export { AdminBroadcastPushDto } 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';
|
|
@@ -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,
|
|
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,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,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,16 +1,18 @@
|
|
|
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.AdminBroadcastPushDto = 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.NotificationConversationChangeToHumanEventPayload = exports.NotificationPasswordResetRequestedEventPayload = exports.NotificationUserCreatedEventPayload = void 0;
|
|
3
|
+
exports.NotificationsUpdateViewedKafkaDto = exports.UpdateNotificationViewedDto = exports.NotificationListItemDto = exports.NotificationsFindAllKafkaDto = exports.NOTIFICATION_STATUS_FILTERS = exports.NOTIFICATION_PROVIDER_FILTERS = exports.ListNotificationsQueryDto = exports.NotificationsRegisterPushTokenKafkaDto = exports.RegisterPushTokenDto = 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;
|
|
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; } });
|
|
7
7
|
Object.defineProperty(exports, "NotificationConversationChangeToHumanEventPayload", { enumerable: true, get: function () { return notifications_kafka_payloads_1.NotificationConversationChangeToHumanEventPayload; } });
|
|
8
|
+
Object.defineProperty(exports, "NotificationTenantAiTokensThresholdEventPayload", { enumerable: true, get: function () { return notifications_kafka_payloads_1.NotificationTenantAiTokensThresholdEventPayload; } });
|
|
8
9
|
var notifications_kafka_topics_1 = require("./notifications-kafka-topics");
|
|
9
10
|
Object.defineProperty(exports, "TOPIC_NOTIFICATIONS_FIND_ALL", { enumerable: true, get: function () { return notifications_kafka_topics_1.TOPIC_NOTIFICATIONS_FIND_ALL; } });
|
|
10
11
|
Object.defineProperty(exports, "TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN", { enumerable: true, get: function () { return notifications_kafka_topics_1.TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN; } });
|
|
11
12
|
Object.defineProperty(exports, "TOPIC_NOTIFICATIONS_UPDATE_VIEWED", { enumerable: true, get: function () { return notifications_kafka_topics_1.TOPIC_NOTIFICATIONS_UPDATE_VIEWED; } });
|
|
12
13
|
Object.defineProperty(exports, "EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH", { enumerable: true, get: function () { return notifications_kafka_topics_1.EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH; } });
|
|
13
14
|
Object.defineProperty(exports, "EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH", { enumerable: true, get: function () { return notifications_kafka_topics_1.EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH; } });
|
|
15
|
+
Object.defineProperty(exports, "EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD", { enumerable: true, get: function () { return notifications_kafka_topics_1.EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD; } });
|
|
14
16
|
var admin_broadcast_push_dto_1 = require("./admin-broadcast-push.dto");
|
|
15
17
|
Object.defineProperty(exports, "AdminBroadcastPushDto", { enumerable: true, get: function () { return admin_broadcast_push_dto_1.AdminBroadcastPushDto; } });
|
|
16
18
|
var register_push_token_dto_1 = require("./register-push-token.dto");
|
|
@@ -7,4 +7,6 @@ export declare const TOPIC_NOTIFICATIONS_UPDATE_VIEWED = "notifications.updateVi
|
|
|
7
7
|
export declare const EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH = "notifications.admin_broadcast_push";
|
|
8
8
|
/** Registo `notifications` / FCM quando a clínica recebe alerta de conversa para humano. */
|
|
9
9
|
export declare const EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH = "notifications.conversation_change_to_human_push";
|
|
10
|
+
/** Evento Kafka: alerta de cota mensal de tokens de IA para administradores do tenant. */
|
|
11
|
+
export declare const EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD = "notifications.tenant_ai_tokens_threshold";
|
|
10
12
|
//# 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"}
|
|
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,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
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_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;
|
|
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';
|
|
@@ -10,3 +10,5 @@ exports.TOPIC_NOTIFICATIONS_UPDATE_VIEWED = 'notifications.updateViewed';
|
|
|
10
10
|
exports.EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH = 'notifications.admin_broadcast_push';
|
|
11
11
|
/** Registo `notifications` / FCM quando a clínica recebe alerta de conversa para humano. */
|
|
12
12
|
exports.EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH = 'notifications.conversation_change_to_human_push';
|
|
13
|
+
/** Evento Kafka: alerta de cota mensal de tokens de IA para administradores do tenant. */
|
|
14
|
+
exports.EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD = 'notifications.tenant_ai_tokens_threshold';
|
|
@@ -26,4 +26,17 @@ export declare class NotificationConversationChangeToHumanEventPayload {
|
|
|
26
26
|
isUrgent?: boolean;
|
|
27
27
|
handoffSource?: 'ai' | 'manual';
|
|
28
28
|
}
|
|
29
|
+
/** Evento Kafka `notifications.tenant_ai_tokens_threshold` para alertas de cota de IA. */
|
|
30
|
+
export declare class NotificationTenantAiTokensThresholdEventPayload {
|
|
31
|
+
eventId: string;
|
|
32
|
+
tenant: string;
|
|
33
|
+
thresholdPercent: 70 | 80 | 90 | 100;
|
|
34
|
+
consumedPercent: number;
|
|
35
|
+
remainingPercent: number;
|
|
36
|
+
currentBalance: number;
|
|
37
|
+
monthlyAllowance: number;
|
|
38
|
+
cycleStartedAt: string;
|
|
39
|
+
nextRenewalAt: string;
|
|
40
|
+
occurredAt: string;
|
|
41
|
+
}
|
|
29
42
|
//# sourceMappingURL=notifications-kafka.payloads.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications-kafka.payloads.d.ts","sourceRoot":"","sources":["../../src/notifications/notifications-kafka.payloads.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"notifications-kafka.payloads.d.ts","sourceRoot":"","sources":["../../src/notifications/notifications-kafka.payloads.ts"],"names":[],"mappings":"AAiBA,qBAAa,mCAAmC;IAM9C,OAAO,EAAE,MAAM,CAAC;IAShB,MAAM,EAAE,MAAM,CAAC;IAQf,KAAK,EAAE,MAAM,CAAC;IASd,IAAI,EAAE,MAAM,CAAC;IASb,QAAQ,EAAE,MAAM,CAAC;IAOjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,8CAA8C;IAMzD,OAAO,EAAE,MAAM,CAAC;IAShB,MAAM,EAAE,MAAM,CAAC;IAQf,KAAK,EAAE,MAAM,CAAC;IASd,WAAW,EAAE,MAAM,CAAC;IAOpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,+FAA+F;AAC/F,qBAAa,iDAAiD;IAG5D,OAAO,EAAE,MAAM,CAAC;IAMhB,MAAM,EAAE,MAAM,CAAC;IAIf,SAAS,EAAE,MAAM,CAAC;IAKlB,WAAW,EAAE,MAAM,CAAC;IAMpB,MAAM,EAAE,MAAM,CAAC;IAIf,UAAU,EAAE,MAAM,CAAC;IAMnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAKrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAOhB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAKnB,aAAa,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC;CACjC;AAED,0FAA0F;AAC1F,qBAAa,+CAA+C;IAG1D,OAAO,EAAE,MAAM,CAAC;IAMhB,MAAM,EAAE,MAAM,CAAC;IASf,gBAAgB,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAMrC,eAAe,EAAE,MAAM,CAAC;IAMxB,gBAAgB,EAAE,MAAM,CAAC;IAKzB,cAAc,EAAE,MAAM,CAAC;IAKvB,gBAAgB,EAAE,MAAM,CAAC;IAIzB,cAAc,EAAE,MAAM,CAAC;IAIvB,aAAa,EAAE,MAAM,CAAC;IAItB,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -9,7 +9,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.NotificationConversationChangeToHumanEventPayload = exports.NotificationPasswordResetRequestedEventPayload = exports.NotificationUserCreatedEventPayload = void 0;
|
|
12
|
+
exports.NotificationTenantAiTokensThresholdEventPayload = exports.NotificationConversationChangeToHumanEventPayload = exports.NotificationPasswordResetRequestedEventPayload = exports.NotificationUserCreatedEventPayload = void 0;
|
|
13
13
|
const swagger_1 = require("@nestjs/swagger");
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
15
|
class NotificationUserCreatedEventPayload {
|
|
@@ -205,3 +205,80 @@ __decorate([
|
|
|
205
205
|
(0, class_validator_1.IsIn)(['ai', 'manual']),
|
|
206
206
|
__metadata("design:type", String)
|
|
207
207
|
], NotificationConversationChangeToHumanEventPayload.prototype, "handoffSource", void 0);
|
|
208
|
+
/** Evento Kafka `notifications.tenant_ai_tokens_threshold` para alertas de cota de IA. */
|
|
209
|
+
class NotificationTenantAiTokensThresholdEventPayload {
|
|
210
|
+
eventId;
|
|
211
|
+
tenant;
|
|
212
|
+
thresholdPercent;
|
|
213
|
+
consumedPercent;
|
|
214
|
+
remainingPercent;
|
|
215
|
+
currentBalance;
|
|
216
|
+
monthlyAllowance;
|
|
217
|
+
cycleStartedAt;
|
|
218
|
+
nextRenewalAt;
|
|
219
|
+
occurredAt;
|
|
220
|
+
}
|
|
221
|
+
exports.NotificationTenantAiTokensThresholdEventPayload = NotificationTenantAiTokensThresholdEventPayload;
|
|
222
|
+
__decorate([
|
|
223
|
+
(0, swagger_1.ApiProperty)({ description: 'Idempotência do evento' }),
|
|
224
|
+
(0, class_validator_1.IsUUID)(),
|
|
225
|
+
__metadata("design:type", String)
|
|
226
|
+
], NotificationTenantAiTokensThresholdEventPayload.prototype, "eventId", void 0);
|
|
227
|
+
__decorate([
|
|
228
|
+
(0, swagger_1.ApiProperty)({ description: 'Slug do tenant', example: 'default' }),
|
|
229
|
+
(0, class_validator_1.IsString)(),
|
|
230
|
+
(0, class_validator_1.MinLength)(1),
|
|
231
|
+
(0, class_validator_1.MaxLength)(255),
|
|
232
|
+
__metadata("design:type", String)
|
|
233
|
+
], NotificationTenantAiTokensThresholdEventPayload.prototype, "tenant", void 0);
|
|
234
|
+
__decorate([
|
|
235
|
+
(0, swagger_1.ApiProperty)({
|
|
236
|
+
description: 'Limiar de consumo atingido em percentual',
|
|
237
|
+
example: 70,
|
|
238
|
+
enum: [70, 80, 90, 100],
|
|
239
|
+
}),
|
|
240
|
+
(0, class_validator_1.IsInt)(),
|
|
241
|
+
(0, class_validator_1.IsIn)([70, 80, 90, 100]),
|
|
242
|
+
__metadata("design:type", Number)
|
|
243
|
+
], NotificationTenantAiTokensThresholdEventPayload.prototype, "thresholdPercent", void 0);
|
|
244
|
+
__decorate([
|
|
245
|
+
(0, swagger_1.ApiProperty)({ description: 'Percentual consumido após o débito', example: 72 }),
|
|
246
|
+
(0, class_validator_1.IsInt)(),
|
|
247
|
+
(0, class_validator_1.Min)(0),
|
|
248
|
+
(0, class_validator_1.Max)(100),
|
|
249
|
+
__metadata("design:type", Number)
|
|
250
|
+
], NotificationTenantAiTokensThresholdEventPayload.prototype, "consumedPercent", void 0);
|
|
251
|
+
__decorate([
|
|
252
|
+
(0, swagger_1.ApiProperty)({ description: 'Percentual restante após o débito', example: 28 }),
|
|
253
|
+
(0, class_validator_1.IsInt)(),
|
|
254
|
+
(0, class_validator_1.Min)(0),
|
|
255
|
+
(0, class_validator_1.Max)(100),
|
|
256
|
+
__metadata("design:type", Number)
|
|
257
|
+
], NotificationTenantAiTokensThresholdEventPayload.prototype, "remainingPercent", void 0);
|
|
258
|
+
__decorate([
|
|
259
|
+
(0, swagger_1.ApiProperty)({ description: 'Saldo atual de tokens após o débito', example: 2800 }),
|
|
260
|
+
(0, class_validator_1.IsInt)(),
|
|
261
|
+
(0, class_validator_1.Min)(0),
|
|
262
|
+
__metadata("design:type", Number)
|
|
263
|
+
], NotificationTenantAiTokensThresholdEventPayload.prototype, "currentBalance", void 0);
|
|
264
|
+
__decorate([
|
|
265
|
+
(0, swagger_1.ApiProperty)({ description: 'Cota mensal total do ciclo', example: 10000 }),
|
|
266
|
+
(0, class_validator_1.IsInt)(),
|
|
267
|
+
(0, class_validator_1.Min)(0),
|
|
268
|
+
__metadata("design:type", Number)
|
|
269
|
+
], NotificationTenantAiTokensThresholdEventPayload.prototype, "monthlyAllowance", void 0);
|
|
270
|
+
__decorate([
|
|
271
|
+
(0, swagger_1.ApiProperty)({ description: 'Data de início do ciclo atual (UTC ISO-8601)' }),
|
|
272
|
+
(0, class_validator_1.IsISO8601)(),
|
|
273
|
+
__metadata("design:type", String)
|
|
274
|
+
], NotificationTenantAiTokensThresholdEventPayload.prototype, "cycleStartedAt", void 0);
|
|
275
|
+
__decorate([
|
|
276
|
+
(0, swagger_1.ApiProperty)({ description: 'Data prevista para renovação do ciclo (UTC ISO-8601)' }),
|
|
277
|
+
(0, class_validator_1.IsISO8601)(),
|
|
278
|
+
__metadata("design:type", String)
|
|
279
|
+
], NotificationTenantAiTokensThresholdEventPayload.prototype, "nextRenewalAt", void 0);
|
|
280
|
+
__decorate([
|
|
281
|
+
(0, swagger_1.ApiProperty)({ description: 'Timestamp do disparo (UTC ISO-8601)' }),
|
|
282
|
+
(0, class_validator_1.IsISO8601)(),
|
|
283
|
+
__metadata("design:type", String)
|
|
284
|
+
], NotificationTenantAiTokensThresholdEventPayload.prototype, "occurredAt", void 0);
|
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
2
|
+
import { AnamnesisCustomFieldDto } from '../configurations';
|
|
2
3
|
|
|
3
4
|
export class AnamnesisTokenSessionPatientDto {
|
|
4
5
|
@ApiProperty({ example: '550e8400-e29b-41d4-a716-446655440000' })
|
|
@@ -35,4 +36,10 @@ export class AnamnesisTokenSessionDto {
|
|
|
35
36
|
|
|
36
37
|
@ApiPropertyOptional({ type: AnamnesisTokenSessionPatientDto })
|
|
37
38
|
patient?: AnamnesisTokenSessionPatientDto;
|
|
39
|
+
|
|
40
|
+
@ApiPropertyOptional({
|
|
41
|
+
type: [AnamnesisCustomFieldDto],
|
|
42
|
+
description: 'Campos adicionais da anamnese configurados pela clínica',
|
|
43
|
+
})
|
|
44
|
+
anamnesisCustomFields?: AnamnesisCustomFieldDto[];
|
|
38
45
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ApiProperty } from '@nestjs/swagger';
|
|
2
|
+
import { IsBoolean, IsIn, IsString, MinLength } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
export const ANAMNESIS_CUSTOM_FIELD_TYPES = ['number', 'date', 'boolean', 'text'] as const;
|
|
5
|
+
export type AnamnesisCustomFieldType = (typeof ANAMNESIS_CUSTOM_FIELD_TYPES)[number];
|
|
6
|
+
|
|
7
|
+
export class AnamnesisCustomFieldDto {
|
|
8
|
+
@ApiProperty({
|
|
9
|
+
description: 'Campo está ativo para aparecer no formulário público',
|
|
10
|
+
example: true,
|
|
11
|
+
})
|
|
12
|
+
@IsBoolean()
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
|
|
15
|
+
@ApiProperty({
|
|
16
|
+
description: 'Pergunta exibida ao paciente',
|
|
17
|
+
example: 'Qual sua pressão arterial média?',
|
|
18
|
+
})
|
|
19
|
+
@IsString()
|
|
20
|
+
@MinLength(3)
|
|
21
|
+
question: string;
|
|
22
|
+
|
|
23
|
+
@ApiProperty({
|
|
24
|
+
description: 'Tipo de resposta esperada para o campo',
|
|
25
|
+
enum: ANAMNESIS_CUSTOM_FIELD_TYPES,
|
|
26
|
+
example: 'number',
|
|
27
|
+
})
|
|
28
|
+
@IsIn(ANAMNESIS_CUSTOM_FIELD_TYPES)
|
|
29
|
+
type: AnamnesisCustomFieldType;
|
|
30
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ApiProperty } from '@nestjs/swagger';
|
|
2
2
|
import { OpeningHoursSlotDto } from './opening-hours-slot.dto';
|
|
3
|
+
import { AnamnesisCustomFieldDto } from './anamnesis-custom-field.dto';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Response DTO for clinic configuration (opening hours, etc.).
|
|
@@ -17,6 +18,13 @@ export class ClinicConfigurationDto {
|
|
|
17
18
|
})
|
|
18
19
|
opening_hours: OpeningHoursSlotDto[];
|
|
19
20
|
|
|
21
|
+
@ApiProperty({
|
|
22
|
+
description: 'Campos adicionais de anamnese configurados pela clínica',
|
|
23
|
+
type: [AnamnesisCustomFieldDto],
|
|
24
|
+
required: false,
|
|
25
|
+
})
|
|
26
|
+
anamnesis_custom_fields?: AnamnesisCustomFieldDto[];
|
|
27
|
+
|
|
20
28
|
@ApiProperty({
|
|
21
29
|
description: 'Creation timestamp',
|
|
22
30
|
example: '2026-03-10T12:00:00.000Z',
|
|
@@ -2,9 +2,11 @@ import { ApiProperty } from '@nestjs/swagger';
|
|
|
2
2
|
import { Type } from 'class-transformer';
|
|
3
3
|
import {
|
|
4
4
|
IsArray,
|
|
5
|
+
IsOptional,
|
|
5
6
|
ValidateNested,
|
|
6
7
|
} from 'class-validator';
|
|
7
8
|
import { OpeningHoursSlotDto } from './opening-hours-slot.dto';
|
|
9
|
+
import { AnamnesisCustomFieldDto } from './anamnesis-custom-field.dto';
|
|
8
10
|
|
|
9
11
|
export class UpdateClinicConfigurationDto {
|
|
10
12
|
@ApiProperty({
|
|
@@ -19,4 +21,19 @@ export class UpdateClinicConfigurationDto {
|
|
|
19
21
|
@ValidateNested({ each: true })
|
|
20
22
|
@Type(() => OpeningHoursSlotDto)
|
|
21
23
|
opening_hours: OpeningHoursSlotDto[];
|
|
24
|
+
|
|
25
|
+
@ApiProperty({
|
|
26
|
+
description: 'Campos adicionais de anamnese configurados pela clínica',
|
|
27
|
+
type: [AnamnesisCustomFieldDto],
|
|
28
|
+
required: false,
|
|
29
|
+
example: [
|
|
30
|
+
{ enabled: true, question: 'Qual foi sua última glicemia?', type: 'number' },
|
|
31
|
+
{ enabled: true, question: 'Data do último exame?', type: 'date' },
|
|
32
|
+
],
|
|
33
|
+
})
|
|
34
|
+
@IsOptional()
|
|
35
|
+
@IsArray()
|
|
36
|
+
@ValidateNested({ each: true })
|
|
37
|
+
@Type(() => AnamnesisCustomFieldDto)
|
|
38
|
+
anamnesis_custom_fields?: AnamnesisCustomFieldDto[];
|
|
22
39
|
}
|
|
@@ -2,6 +2,7 @@ export {
|
|
|
2
2
|
NotificationUserCreatedEventPayload,
|
|
3
3
|
NotificationPasswordResetRequestedEventPayload,
|
|
4
4
|
NotificationConversationChangeToHumanEventPayload,
|
|
5
|
+
NotificationTenantAiTokensThresholdEventPayload,
|
|
5
6
|
} from './notifications-kafka.payloads';
|
|
6
7
|
export {
|
|
7
8
|
TOPIC_NOTIFICATIONS_FIND_ALL,
|
|
@@ -9,6 +10,7 @@ export {
|
|
|
9
10
|
TOPIC_NOTIFICATIONS_UPDATE_VIEWED,
|
|
10
11
|
EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH,
|
|
11
12
|
EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH,
|
|
13
|
+
EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD,
|
|
12
14
|
} from './notifications-kafka-topics';
|
|
13
15
|
export { AdminBroadcastPushDto } from './admin-broadcast-push.dto';
|
|
14
16
|
export {
|
|
@@ -14,3 +14,7 @@ export const EVENT_NOTIFICATIONS_ADMIN_BROADCAST_PUSH =
|
|
|
14
14
|
/** Registo `notifications` / FCM quando a clínica recebe alerta de conversa para humano. */
|
|
15
15
|
export const EVENT_NOTIFICATIONS_CONVERSATION_HANDOFF_PUSH =
|
|
16
16
|
'notifications.conversation_change_to_human_push';
|
|
17
|
+
|
|
18
|
+
/** Evento Kafka: alerta de cota mensal de tokens de IA para administradores do tenant. */
|
|
19
|
+
export const EVENT_NOTIFICATIONS_TENANT_AI_TOKENS_THRESHOLD =
|
|
20
|
+
'notifications.tenant_ai_tokens_threshold';
|
|
@@ -4,11 +4,14 @@ import {
|
|
|
4
4
|
IsEmail,
|
|
5
5
|
IsIn,
|
|
6
6
|
IsISO8601,
|
|
7
|
+
IsInt,
|
|
7
8
|
IsNumber,
|
|
8
9
|
IsOptional,
|
|
9
10
|
IsString,
|
|
10
11
|
IsUUID,
|
|
12
|
+
Max,
|
|
11
13
|
MaxLength,
|
|
14
|
+
Min,
|
|
12
15
|
MinLength,
|
|
13
16
|
} from 'class-validator';
|
|
14
17
|
|
|
@@ -159,3 +162,59 @@ export class NotificationConversationChangeToHumanEventPayload {
|
|
|
159
162
|
@IsIn(['ai', 'manual'])
|
|
160
163
|
handoffSource?: 'ai' | 'manual';
|
|
161
164
|
}
|
|
165
|
+
|
|
166
|
+
/** Evento Kafka `notifications.tenant_ai_tokens_threshold` para alertas de cota de IA. */
|
|
167
|
+
export class NotificationTenantAiTokensThresholdEventPayload {
|
|
168
|
+
@ApiProperty({ description: 'Idempotência do evento' })
|
|
169
|
+
@IsUUID()
|
|
170
|
+
eventId: string;
|
|
171
|
+
|
|
172
|
+
@ApiProperty({ description: 'Slug do tenant', example: 'default' })
|
|
173
|
+
@IsString()
|
|
174
|
+
@MinLength(1)
|
|
175
|
+
@MaxLength(255)
|
|
176
|
+
tenant: string;
|
|
177
|
+
|
|
178
|
+
@ApiProperty({
|
|
179
|
+
description: 'Limiar de consumo atingido em percentual',
|
|
180
|
+
example: 70,
|
|
181
|
+
enum: [70, 80, 90, 100],
|
|
182
|
+
})
|
|
183
|
+
@IsInt()
|
|
184
|
+
@IsIn([70, 80, 90, 100])
|
|
185
|
+
thresholdPercent: 70 | 80 | 90 | 100;
|
|
186
|
+
|
|
187
|
+
@ApiProperty({ description: 'Percentual consumido após o débito', example: 72 })
|
|
188
|
+
@IsInt()
|
|
189
|
+
@Min(0)
|
|
190
|
+
@Max(100)
|
|
191
|
+
consumedPercent: number;
|
|
192
|
+
|
|
193
|
+
@ApiProperty({ description: 'Percentual restante após o débito', example: 28 })
|
|
194
|
+
@IsInt()
|
|
195
|
+
@Min(0)
|
|
196
|
+
@Max(100)
|
|
197
|
+
remainingPercent: number;
|
|
198
|
+
|
|
199
|
+
@ApiProperty({ description: 'Saldo atual de tokens após o débito', example: 2800 })
|
|
200
|
+
@IsInt()
|
|
201
|
+
@Min(0)
|
|
202
|
+
currentBalance: number;
|
|
203
|
+
|
|
204
|
+
@ApiProperty({ description: 'Cota mensal total do ciclo', example: 10000 })
|
|
205
|
+
@IsInt()
|
|
206
|
+
@Min(0)
|
|
207
|
+
monthlyAllowance: number;
|
|
208
|
+
|
|
209
|
+
@ApiProperty({ description: 'Data de início do ciclo atual (UTC ISO-8601)' })
|
|
210
|
+
@IsISO8601()
|
|
211
|
+
cycleStartedAt: string;
|
|
212
|
+
|
|
213
|
+
@ApiProperty({ description: 'Data prevista para renovação do ciclo (UTC ISO-8601)' })
|
|
214
|
+
@IsISO8601()
|
|
215
|
+
nextRenewalAt: string;
|
|
216
|
+
|
|
217
|
+
@ApiProperty({ description: 'Timestamp do disparo (UTC ISO-8601)' })
|
|
218
|
+
@IsISO8601()
|
|
219
|
+
occurredAt: string;
|
|
220
|
+
}
|