tychat-contracts 1.5.0 → 1.5.1

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.
@@ -1,4 +1,4 @@
1
- export { NotificationUserCreatedEventPayload, NotificationPasswordResetRequestedEventPayload, NotificationConversationChangeToHumanEventPayload, NotificationTenantAiTokensThresholdEventPayload, } from './notifications-kafka.payloads';
1
+ export { NotificationUserCreatedEventPayload, NotificationPasswordResetRequestedEventPayload, NotificationNewDeviceLoginEventPayload, NotificationConversationChangeToHumanEventPayload, NotificationTenantAiTokensThresholdEventPayload, } from './notifications-kafka.payloads';
2
2
  export { TOPIC_NOTIFICATIONS_FIND_ALL, TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN, TOPIC_NOTIFICATIONS_UNREGISTER_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, NotificationsUnregisterPushTokenKafkaDto, } from './register-push-token.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,EACjD,+CAA+C,GAChD,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,4BAA4B,EAC5B,uCAAuC,EACvC,yCAAyC,EACzC,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,EACtC,wCAAwC,GACzC,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
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mCAAmC,EACnC,8CAA8C,EAC9C,sCAAsC,EACtC,iDAAiD,EACjD,+CAA+C,GAChD,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,4BAA4B,EAC5B,uCAAuC,EACvC,yCAAyC,EACzC,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,EACtC,wCAAwC,GACzC,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,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NotificationsSendPushToUserKafkaDto = exports.NotificationsUpdateViewedKafkaDto = exports.UpdateNotificationViewedDto = exports.NotificationListItemDto = exports.NotificationsFindAllKafkaDto = exports.NOTIFICATION_STATUS_FILTERS = exports.NOTIFICATION_PROVIDER_FILTERS = exports.ListNotificationsQueryDto = exports.NotificationsUnregisterPushTokenKafkaDto = 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_UNREGISTER_PUSH_TOKEN = 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.NotificationsUnregisterPushTokenKafkaDto = 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_UNREGISTER_PUSH_TOKEN = exports.TOPIC_NOTIFICATIONS_REGISTER_PUSH_TOKEN = exports.TOPIC_NOTIFICATIONS_FIND_ALL = exports.NotificationTenantAiTokensThresholdEventPayload = exports.NotificationConversationChangeToHumanEventPayload = exports.NotificationNewDeviceLoginEventPayload = 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
+ Object.defineProperty(exports, "NotificationNewDeviceLoginEventPayload", { enumerable: true, get: function () { return notifications_kafka_payloads_1.NotificationNewDeviceLoginEventPayload; } });
7
8
  Object.defineProperty(exports, "NotificationConversationChangeToHumanEventPayload", { enumerable: true, get: function () { return notifications_kafka_payloads_1.NotificationConversationChangeToHumanEventPayload; } });
8
9
  Object.defineProperty(exports, "NotificationTenantAiTokensThresholdEventPayload", { enumerable: true, get: function () { return notifications_kafka_payloads_1.NotificationTenantAiTokensThresholdEventPayload; } });
9
10
  var notifications_kafka_topics_1 = require("./notifications-kafka-topics");
@@ -13,6 +13,22 @@ export declare class NotificationPasswordResetRequestedEventPayload {
13
13
  verifyToken: string;
14
14
  occurredAt: string;
15
15
  }
16
+ /**
17
+ * Evento RabbitMQ `notifications.new_device_login` — alerta de login a partir de um perfil de
18
+ * dispositivo ainda não registado para o utilizador (par deviceName + deviceType após normalização no auth).
19
+ */
20
+ export declare class NotificationNewDeviceLoginEventPayload {
21
+ eventId: string;
22
+ tenant: string;
23
+ userId: string;
24
+ email: string;
25
+ name: string;
26
+ deviceName: string;
27
+ deviceType: string;
28
+ ipAddress?: string;
29
+ location?: string;
30
+ occurredAt: string;
31
+ }
16
32
  /** Evento Kafka `notifications.conversation-change-to-human` (IA ou clínica → fila humana). */
17
33
  export declare class NotificationConversationChangeToHumanEventPayload {
18
34
  eventId: string;
@@ -1 +1 @@
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"}
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;;;GAGG;AACH,qBAAa,sCAAsC;IAMjD,OAAO,EAAE,MAAM,CAAC;IAMhB,MAAM,EAAE,MAAM,CAAC;IAIf,MAAM,EAAE,MAAM,CAAC;IAKf,KAAK,EAAE,MAAM,CAAC;IAMd,IAAI,EAAE,MAAM,CAAC;IAMb,UAAU,EAAE,MAAM,CAAC;IAMnB,UAAU,EAAE,MAAM,CAAC;IAMnB,SAAS,CAAC,EAAE,MAAM,CAAC;IAMnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAIlB,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.NotificationTenantAiTokensThresholdEventPayload = exports.NotificationConversationChangeToHumanEventPayload = exports.NotificationPasswordResetRequestedEventPayload = exports.NotificationUserCreatedEventPayload = void 0;
12
+ exports.NotificationTenantAiTokensThresholdEventPayload = exports.NotificationConversationChangeToHumanEventPayload = exports.NotificationNewDeviceLoginEventPayload = 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 {
@@ -129,6 +129,89 @@ __decorate([
129
129
  (0, class_validator_1.IsISO8601)(),
130
130
  __metadata("design:type", String)
131
131
  ], NotificationPasswordResetRequestedEventPayload.prototype, "occurredAt", void 0);
132
+ /**
133
+ * Evento RabbitMQ `notifications.new_device_login` — alerta de login a partir de um perfil de
134
+ * dispositivo ainda não registado para o utilizador (par deviceName + deviceType após normalização no auth).
135
+ */
136
+ class NotificationNewDeviceLoginEventPayload {
137
+ eventId;
138
+ tenant;
139
+ userId;
140
+ email;
141
+ name;
142
+ deviceName;
143
+ deviceType;
144
+ ipAddress;
145
+ location;
146
+ occurredAt;
147
+ }
148
+ exports.NotificationNewDeviceLoginEventPayload = NotificationNewDeviceLoginEventPayload;
149
+ __decorate([
150
+ (0, swagger_1.ApiProperty)({
151
+ description: 'Idempotência',
152
+ example: '2d3ecf0d-8d38-4b95-95c8-d3e903e6f1fe',
153
+ }),
154
+ (0, class_validator_1.IsUUID)(),
155
+ __metadata("design:type", String)
156
+ ], NotificationNewDeviceLoginEventPayload.prototype, "eventId", void 0);
157
+ __decorate([
158
+ (0, swagger_1.ApiProperty)({ example: 'default' }),
159
+ (0, class_validator_1.IsString)(),
160
+ (0, class_validator_1.MinLength)(1),
161
+ (0, class_validator_1.MaxLength)(255),
162
+ __metadata("design:type", String)
163
+ ], NotificationNewDeviceLoginEventPayload.prototype, "tenant", void 0);
164
+ __decorate([
165
+ (0, swagger_1.ApiProperty)(),
166
+ (0, class_validator_1.IsUUID)(),
167
+ __metadata("design:type", String)
168
+ ], NotificationNewDeviceLoginEventPayload.prototype, "userId", void 0);
169
+ __decorate([
170
+ (0, swagger_1.ApiProperty)({ example: 'maria.silva@example.com' }),
171
+ (0, class_validator_1.IsEmail)(),
172
+ (0, class_validator_1.MaxLength)(255),
173
+ __metadata("design:type", String)
174
+ ], NotificationNewDeviceLoginEventPayload.prototype, "email", void 0);
175
+ __decorate([
176
+ (0, swagger_1.ApiProperty)({ example: 'Maria Silva' }),
177
+ (0, class_validator_1.IsString)(),
178
+ (0, class_validator_1.MinLength)(1),
179
+ (0, class_validator_1.MaxLength)(255),
180
+ __metadata("design:type", String)
181
+ ], NotificationNewDeviceLoginEventPayload.prototype, "name", void 0);
182
+ __decorate([
183
+ (0, swagger_1.ApiProperty)({ example: 'Chrome on Windows' }),
184
+ (0, class_validator_1.IsString)(),
185
+ (0, class_validator_1.MinLength)(1),
186
+ (0, class_validator_1.MaxLength)(255),
187
+ __metadata("design:type", String)
188
+ ], NotificationNewDeviceLoginEventPayload.prototype, "deviceName", void 0);
189
+ __decorate([
190
+ (0, swagger_1.ApiProperty)({ example: 'web' }),
191
+ (0, class_validator_1.IsString)(),
192
+ (0, class_validator_1.MinLength)(1),
193
+ (0, class_validator_1.MaxLength)(32),
194
+ __metadata("design:type", String)
195
+ ], NotificationNewDeviceLoginEventPayload.prototype, "deviceType", void 0);
196
+ __decorate([
197
+ (0, swagger_1.ApiPropertyOptional)({ example: '203.0.113.10' }),
198
+ (0, class_validator_1.IsOptional)(),
199
+ (0, class_validator_1.IsString)(),
200
+ (0, class_validator_1.MaxLength)(64),
201
+ __metadata("design:type", String)
202
+ ], NotificationNewDeviceLoginEventPayload.prototype, "ipAddress", void 0);
203
+ __decorate([
204
+ (0, swagger_1.ApiPropertyOptional)({ example: 'Lisboa, PT' }),
205
+ (0, class_validator_1.IsOptional)(),
206
+ (0, class_validator_1.IsString)(),
207
+ (0, class_validator_1.MaxLength)(255),
208
+ __metadata("design:type", String)
209
+ ], NotificationNewDeviceLoginEventPayload.prototype, "location", void 0);
210
+ __decorate([
211
+ (0, swagger_1.ApiProperty)({ example: '2026-03-22T12:30:00.000Z' }),
212
+ (0, class_validator_1.IsISO8601)(),
213
+ __metadata("design:type", String)
214
+ ], NotificationNewDeviceLoginEventPayload.prototype, "occurredAt", void 0);
132
215
  /** Evento Kafka `notifications.conversation-change-to-human` (IA ou clínica → fila humana). */
133
216
  class NotificationConversationChangeToHumanEventPayload {
134
217
  eventId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tychat-contracts",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "DTOs compartilhados com class-validator (API e microserviços)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,6 +1,7 @@
1
1
  export {
2
2
  NotificationUserCreatedEventPayload,
3
3
  NotificationPasswordResetRequestedEventPayload,
4
+ NotificationNewDeviceLoginEventPayload,
4
5
  NotificationConversationChangeToHumanEventPayload,
5
6
  NotificationTenantAiTokensThresholdEventPayload,
6
7
  } from './notifications-kafka.payloads';
@@ -108,6 +108,68 @@ export class NotificationPasswordResetRequestedEventPayload {
108
108
  occurredAt: string;
109
109
  }
110
110
 
111
+ /**
112
+ * Evento RabbitMQ `notifications.new_device_login` — alerta de login a partir de um perfil de
113
+ * dispositivo ainda não registado para o utilizador (par deviceName + deviceType após normalização no auth).
114
+ */
115
+ export class NotificationNewDeviceLoginEventPayload {
116
+ @ApiProperty({
117
+ description: 'Idempotência',
118
+ example: '2d3ecf0d-8d38-4b95-95c8-d3e903e6f1fe',
119
+ })
120
+ @IsUUID()
121
+ eventId: string;
122
+
123
+ @ApiProperty({ example: 'default' })
124
+ @IsString()
125
+ @MinLength(1)
126
+ @MaxLength(255)
127
+ tenant: string;
128
+
129
+ @ApiProperty()
130
+ @IsUUID()
131
+ userId: string;
132
+
133
+ @ApiProperty({ example: 'maria.silva@example.com' })
134
+ @IsEmail()
135
+ @MaxLength(255)
136
+ email: string;
137
+
138
+ @ApiProperty({ example: 'Maria Silva' })
139
+ @IsString()
140
+ @MinLength(1)
141
+ @MaxLength(255)
142
+ name: string;
143
+
144
+ @ApiProperty({ example: 'Chrome on Windows' })
145
+ @IsString()
146
+ @MinLength(1)
147
+ @MaxLength(255)
148
+ deviceName: string;
149
+
150
+ @ApiProperty({ example: 'web' })
151
+ @IsString()
152
+ @MinLength(1)
153
+ @MaxLength(32)
154
+ deviceType: string;
155
+
156
+ @ApiPropertyOptional({ example: '203.0.113.10' })
157
+ @IsOptional()
158
+ @IsString()
159
+ @MaxLength(64)
160
+ ipAddress?: string;
161
+
162
+ @ApiPropertyOptional({ example: 'Lisboa, PT' })
163
+ @IsOptional()
164
+ @IsString()
165
+ @MaxLength(255)
166
+ location?: string;
167
+
168
+ @ApiProperty({ example: '2026-03-22T12:30:00.000Z' })
169
+ @IsISO8601()
170
+ occurredAt: string;
171
+ }
172
+
111
173
  /** Evento Kafka `notifications.conversation-change-to-human` (IA ou clínica → fila humana). */
112
174
  export class NotificationConversationChangeToHumanEventPayload {
113
175
  @ApiProperty({ description: 'Idempotência' })