tychat-contracts 1.0.39 → 1.0.41

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.
Files changed (33) hide show
  1. package/dist/ai/ai-action.dto.d.ts +27 -0
  2. package/dist/ai/ai-action.dto.d.ts.map +1 -0
  3. package/dist/ai/ai-action.dto.js +212 -0
  4. package/dist/ai/ai-integration-request.dto.d.ts +1 -0
  5. package/dist/ai/ai-integration-request.dto.d.ts.map +1 -1
  6. package/dist/ai/ai-integration-request.dto.js +10 -0
  7. package/dist/ai/ai-integration-response.dto.d.ts +3 -1
  8. package/dist/ai/ai-integration-response.dto.d.ts.map +1 -1
  9. package/dist/ai/ai-integration-response.dto.js +15 -1
  10. package/dist/ai/index.d.ts +1 -0
  11. package/dist/ai/index.d.ts.map +1 -1
  12. package/dist/ai/index.js +1 -0
  13. package/dist/auth/login.dto.d.ts +1 -1
  14. package/dist/auth/login.dto.d.ts.map +1 -1
  15. package/dist/auth/login.dto.js +5 -4
  16. package/dist/patients/create-patient.dto.d.ts +4 -0
  17. package/dist/patients/create-patient.dto.d.ts.map +1 -1
  18. package/dist/patients/create-patient.dto.js +48 -0
  19. package/dist/procedures/create-procedure.dto.d.ts +5 -0
  20. package/dist/procedures/create-procedure.dto.d.ts.map +1 -1
  21. package/dist/procedures/create-procedure.dto.js +57 -0
  22. package/dist/users/create-user.dto.d.ts +1 -1
  23. package/dist/users/create-user.dto.d.ts.map +1 -1
  24. package/dist/users/create-user.dto.js +6 -5
  25. package/package.json +2 -1
  26. package/src/ai/ai-action.dto.ts +176 -0
  27. package/src/ai/ai-integration-request.dto.ts +8 -0
  28. package/src/ai/ai-integration-response.dto.ts +15 -3
  29. package/src/ai/index.ts +1 -0
  30. package/src/auth/login.dto.ts +5 -4
  31. package/src/patients/create-patient.dto.ts +41 -0
  32. package/src/procedures/create-procedure.dto.ts +48 -0
  33. package/src/users/create-user.dto.ts +6 -4
@@ -0,0 +1,27 @@
1
+ export declare const AI_RESPONSE_TYPES: readonly ["message", "action"];
2
+ export type AiResponseTypeDto = (typeof AI_RESPONSE_TYPES)[number];
3
+ export declare const AI_ACTION_TYPES: readonly ["create_patient", "create_appointment", "cancel_appointment"];
4
+ export type AiActionTypeDto = (typeof AI_ACTION_TYPES)[number];
5
+ export declare class AiActionDataDto {
6
+ patientId?: string;
7
+ name?: string;
8
+ cpf?: string;
9
+ birthDate?: string;
10
+ hasDisability?: boolean;
11
+ disabilityDescription?: string;
12
+ initialObservation?: string;
13
+ observation?: string;
14
+ procedureIds?: string[];
15
+ userId?: string;
16
+ date?: string;
17
+ appointmentId?: string;
18
+ reason?: string;
19
+ missingFields?: string[];
20
+ }
21
+ export declare class AiStructuredResponseDto {
22
+ type: AiResponseTypeDto;
23
+ actionType?: AiActionTypeDto;
24
+ message?: string;
25
+ data?: AiActionDataDto;
26
+ }
27
+ //# sourceMappingURL=ai-action.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-action.dto.d.ts","sourceRoot":"","sources":["../../src/ai/ai-action.dto.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,iBAAiB,gCAAiC,CAAC;AAChE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE,eAAO,MAAM,eAAe,yEAIlB,CAAC;AACX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,qBAAa,eAAe;IAO1B,SAAS,CAAC,EAAE,MAAM,CAAC;IASnB,IAAI,CAAC,EAAE,MAAM,CAAC;IASd,GAAG,CAAC,EAAE,MAAM,CAAC;IAQb,SAAS,CAAC,EAAE,MAAM,CAAC;IAQnB,aAAa,CAAC,EAAE,OAAO,CAAC;IAQxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAQ/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAQ5B,WAAW,CAAC,EAAE,MAAM,CAAC;IAUrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAQxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAQhB,IAAI,CAAC,EAAE,MAAM,CAAC;IAQd,aAAa,CAAC,EAAE,MAAM,CAAC;IAQvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAUhB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,qBAAa,uBAAuB;IAOlC,IAAI,EAAE,iBAAiB,CAAC;IASxB,UAAU,CAAC,EAAE,eAAe,CAAC;IAQ7B,OAAO,CAAC,EAAE,MAAM,CAAC;IAOjB,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB"}
@@ -0,0 +1,212 @@
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.AiStructuredResponseDto = exports.AiActionDataDto = exports.AI_ACTION_TYPES = exports.AI_RESPONSE_TYPES = void 0;
13
+ const swagger_1 = require("@nestjs/swagger");
14
+ const class_validator_1 = require("class-validator");
15
+ exports.AI_RESPONSE_TYPES = ['message', 'action'];
16
+ exports.AI_ACTION_TYPES = [
17
+ 'create_patient',
18
+ 'create_appointment',
19
+ 'cancel_appointment',
20
+ ];
21
+ class AiActionDataDto {
22
+ patientId;
23
+ name;
24
+ cpf;
25
+ birthDate;
26
+ hasDisability;
27
+ disabilityDescription;
28
+ initialObservation;
29
+ observation;
30
+ procedureIds;
31
+ userId;
32
+ date;
33
+ appointmentId;
34
+ reason;
35
+ missingFields;
36
+ }
37
+ exports.AiActionDataDto = AiActionDataDto;
38
+ __decorate([
39
+ (0, swagger_1.ApiPropertyOptional)({
40
+ description: 'Suggested patient id when the patient already exists',
41
+ example: '550e8400-e29b-41d4-a716-446655440000',
42
+ }),
43
+ (0, class_validator_1.IsOptional)(),
44
+ (0, class_validator_1.IsUUID)('4'),
45
+ __metadata("design:type", String)
46
+ ], AiActionDataDto.prototype, "patientId", void 0);
47
+ __decorate([
48
+ (0, swagger_1.ApiPropertyOptional)({
49
+ description: 'Patient full name',
50
+ example: 'Joao da Silva',
51
+ }),
52
+ (0, class_validator_1.IsOptional)(),
53
+ (0, class_validator_1.IsString)(),
54
+ (0, class_validator_1.IsNotEmpty)(),
55
+ __metadata("design:type", String)
56
+ ], AiActionDataDto.prototype, "name", void 0);
57
+ __decorate([
58
+ (0, swagger_1.ApiPropertyOptional)({
59
+ description: 'Patient CPF with 11 digits',
60
+ example: '12345678909',
61
+ }),
62
+ (0, class_validator_1.IsOptional)(),
63
+ (0, class_validator_1.IsString)(),
64
+ (0, class_validator_1.Length)(11, 11),
65
+ __metadata("design:type", String)
66
+ ], AiActionDataDto.prototype, "cpf", void 0);
67
+ __decorate([
68
+ (0, swagger_1.ApiPropertyOptional)({
69
+ description: 'Patient birth date in ISO format (YYYY-MM-DD)',
70
+ example: '1990-01-01',
71
+ }),
72
+ (0, class_validator_1.IsOptional)(),
73
+ (0, class_validator_1.IsDateString)(),
74
+ __metadata("design:type", String)
75
+ ], AiActionDataDto.prototype, "birthDate", void 0);
76
+ __decorate([
77
+ (0, swagger_1.ApiPropertyOptional)({
78
+ description: 'Indicates whether the patient has a disability',
79
+ example: false,
80
+ }),
81
+ (0, class_validator_1.IsOptional)(),
82
+ (0, class_validator_1.IsBoolean)(),
83
+ __metadata("design:type", Boolean)
84
+ ], AiActionDataDto.prototype, "hasDisability", void 0);
85
+ __decorate([
86
+ (0, swagger_1.ApiPropertyOptional)({
87
+ description: 'Disability description when applicable',
88
+ example: 'Visual impairment',
89
+ }),
90
+ (0, class_validator_1.IsOptional)(),
91
+ (0, class_validator_1.IsString)(),
92
+ __metadata("design:type", String)
93
+ ], AiActionDataDto.prototype, "disabilityDescription", void 0);
94
+ __decorate([
95
+ (0, swagger_1.ApiPropertyOptional)({
96
+ description: 'Initial patient observation',
97
+ example: 'Patient has back pain for two weeks',
98
+ }),
99
+ (0, class_validator_1.IsOptional)(),
100
+ (0, class_validator_1.IsString)(),
101
+ __metadata("design:type", String)
102
+ ], AiActionDataDto.prototype, "initialObservation", void 0);
103
+ __decorate([
104
+ (0, swagger_1.ApiPropertyOptional)({
105
+ description: 'Optional observation for history',
106
+ example: 'Patient is allergic to penicillin',
107
+ }),
108
+ (0, class_validator_1.IsOptional)(),
109
+ (0, class_validator_1.IsString)(),
110
+ __metadata("design:type", String)
111
+ ], AiActionDataDto.prototype, "observation", void 0);
112
+ __decorate([
113
+ (0, swagger_1.ApiPropertyOptional)({
114
+ description: 'Procedure ids selected by the user',
115
+ type: [String],
116
+ example: ['550e8400-e29b-41d4-a716-446655440010'],
117
+ }),
118
+ (0, class_validator_1.IsOptional)(),
119
+ (0, class_validator_1.IsArray)(),
120
+ (0, class_validator_1.IsUUID)('4', { each: true }),
121
+ __metadata("design:type", Array)
122
+ ], AiActionDataDto.prototype, "procedureIds", void 0);
123
+ __decorate([
124
+ (0, swagger_1.ApiPropertyOptional)({
125
+ description: 'Professional user id selected by the user',
126
+ example: '550e8400-e29b-41d4-a716-446655440001',
127
+ }),
128
+ (0, class_validator_1.IsOptional)(),
129
+ (0, class_validator_1.IsUUID)('4'),
130
+ __metadata("design:type", String)
131
+ ], AiActionDataDto.prototype, "userId", void 0);
132
+ __decorate([
133
+ (0, swagger_1.ApiPropertyOptional)({
134
+ description: 'Requested appointment date/time in ISO format',
135
+ example: '2026-03-15T14:00:00.000Z',
136
+ }),
137
+ (0, class_validator_1.IsOptional)(),
138
+ (0, class_validator_1.IsDateString)(),
139
+ __metadata("design:type", String)
140
+ ], AiActionDataDto.prototype, "date", void 0);
141
+ __decorate([
142
+ (0, swagger_1.ApiPropertyOptional)({
143
+ description: 'Existing appointment id for cancellation',
144
+ example: '550e8400-e29b-41d4-a716-446655440002',
145
+ }),
146
+ (0, class_validator_1.IsOptional)(),
147
+ (0, class_validator_1.IsUUID)('4'),
148
+ __metadata("design:type", String)
149
+ ], AiActionDataDto.prototype, "appointmentId", void 0);
150
+ __decorate([
151
+ (0, swagger_1.ApiPropertyOptional)({
152
+ description: 'Optional human-readable reason or assistant notes',
153
+ example: 'User asked to cancel due to travel',
154
+ }),
155
+ (0, class_validator_1.IsOptional)(),
156
+ (0, class_validator_1.IsString)(),
157
+ __metadata("design:type", String)
158
+ ], AiActionDataDto.prototype, "reason", void 0);
159
+ __decorate([
160
+ (0, swagger_1.ApiPropertyOptional)({
161
+ description: 'Fields still required to complete the action',
162
+ type: [String],
163
+ example: ['cpf', 'birthDate'],
164
+ }),
165
+ (0, class_validator_1.IsOptional)(),
166
+ (0, class_validator_1.IsArray)(),
167
+ (0, class_validator_1.IsString)({ each: true }),
168
+ __metadata("design:type", Array)
169
+ ], AiActionDataDto.prototype, "missingFields", void 0);
170
+ class AiStructuredResponseDto {
171
+ type;
172
+ actionType;
173
+ message;
174
+ data;
175
+ }
176
+ exports.AiStructuredResponseDto = AiStructuredResponseDto;
177
+ __decorate([
178
+ (0, swagger_1.ApiProperty)({
179
+ description: 'Response type returned by AI',
180
+ enum: exports.AI_RESPONSE_TYPES,
181
+ example: 'action',
182
+ }),
183
+ (0, class_validator_1.IsEnum)(exports.AI_RESPONSE_TYPES),
184
+ __metadata("design:type", String)
185
+ ], AiStructuredResponseDto.prototype, "type", void 0);
186
+ __decorate([
187
+ (0, swagger_1.ApiPropertyOptional)({
188
+ description: 'Action type when the response type is action',
189
+ enum: exports.AI_ACTION_TYPES,
190
+ example: 'create_patient',
191
+ }),
192
+ (0, class_validator_1.IsOptional)(),
193
+ (0, class_validator_1.IsEnum)(exports.AI_ACTION_TYPES),
194
+ __metadata("design:type", String)
195
+ ], AiStructuredResponseDto.prototype, "actionType", void 0);
196
+ __decorate([
197
+ (0, swagger_1.ApiPropertyOptional)({
198
+ description: 'Message returned to the user',
199
+ example: 'I need your CPF and birth date to create the patient.',
200
+ }),
201
+ (0, class_validator_1.IsOptional)(),
202
+ (0, class_validator_1.IsString)(),
203
+ __metadata("design:type", String)
204
+ ], AiStructuredResponseDto.prototype, "message", void 0);
205
+ __decorate([
206
+ (0, swagger_1.ApiPropertyOptional)({
207
+ description: 'Structured payload extracted from the conversation',
208
+ type: AiActionDataDto,
209
+ }),
210
+ (0, class_validator_1.IsOptional)(),
211
+ __metadata("design:type", AiActionDataDto)
212
+ ], AiStructuredResponseDto.prototype, "data", void 0);
@@ -2,6 +2,7 @@ export declare class AiIntegrationRequestDto {
2
2
  tenant: string;
3
3
  unitId?: number;
4
4
  message: string;
5
+ id: string;
5
6
  is_document: boolean;
6
7
  documents_url?: string[];
7
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ai-integration-request.dto.d.ts","sourceRoot":"","sources":["../../src/ai/ai-integration-request.dto.ts"],"names":[],"mappings":"AAGA,qBAAa,uBAAuB;IAOlC,MAAM,EAAE,MAAM,CAAC;IASf,MAAM,CAAC,EAAE,MAAM,CAAC;IAQhB,OAAO,EAAE,MAAM,CAAC;IAOhB,WAAW,EAAE,OAAO,CAAC;IAUrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B"}
1
+ {"version":3,"file":"ai-integration-request.dto.d.ts","sourceRoot":"","sources":["../../src/ai/ai-integration-request.dto.ts"],"names":[],"mappings":"AAGA,qBAAa,uBAAuB;IAOlC,MAAM,EAAE,MAAM,CAAC;IASf,MAAM,CAAC,EAAE,MAAM,CAAC;IAQhB,OAAO,EAAE,MAAM,CAAC;IAQhB,EAAE,EAAE,MAAM,CAAC;IAOX,WAAW,EAAE,OAAO,CAAC;IAUrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B"}
@@ -16,6 +16,7 @@ class AiIntegrationRequestDto {
16
16
  tenant;
17
17
  unitId;
18
18
  message;
19
+ id;
19
20
  is_document;
20
21
  documents_url;
21
22
  }
@@ -48,6 +49,15 @@ __decorate([
48
49
  (0, class_validator_1.IsNotEmpty)(),
49
50
  __metadata("design:type", String)
50
51
  ], AiIntegrationRequestDto.prototype, "message", void 0);
52
+ __decorate([
53
+ (0, swagger_1.ApiProperty)({
54
+ description: 'Conversation identifier used for context isolation',
55
+ example: '5511999999999',
56
+ }),
57
+ (0, class_validator_1.IsString)(),
58
+ (0, class_validator_1.IsNotEmpty)(),
59
+ __metadata("design:type", String)
60
+ ], AiIntegrationRequestDto.prototype, "id", void 0);
51
61
  __decorate([
52
62
  (0, swagger_1.ApiProperty)({
53
63
  description: 'Indicates whether the input is document-based',
@@ -1,5 +1,7 @@
1
+ import { AiStructuredResponseDto } from './ai-action.dto';
1
2
  export declare class AiIntegrationResponseDto {
2
3
  tenant: string;
3
- output: string;
4
+ response: AiStructuredResponseDto;
5
+ output?: string;
4
6
  }
5
7
  //# sourceMappingURL=ai-integration-response.dto.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-integration-response.dto.d.ts","sourceRoot":"","sources":["../../src/ai/ai-integration-response.dto.ts"],"names":[],"mappings":"AAGA,qBAAa,wBAAwB;IAOnC,MAAM,EAAE,MAAM,CAAC;IAQf,MAAM,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"ai-integration-response.dto.d.ts","sourceRoot":"","sources":["../../src/ai/ai-integration-response.dto.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,qBAAa,wBAAwB;IAOnC,MAAM,EAAE,MAAM,CAAC;IAQf,QAAQ,EAAE,uBAAuB,CAAC;IAUlC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
@@ -11,9 +11,12 @@ var __metadata = (this && this.__metadata) || function (k, v) {
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.AiIntegrationResponseDto = void 0;
13
13
  const swagger_1 = require("@nestjs/swagger");
14
+ const class_transformer_1 = require("class-transformer");
14
15
  const class_validator_1 = require("class-validator");
16
+ const ai_action_dto_1 = require("./ai-action.dto");
15
17
  class AiIntegrationResponseDto {
16
18
  tenant;
19
+ response;
17
20
  output;
18
21
  }
19
22
  exports.AiIntegrationResponseDto = AiIntegrationResponseDto;
@@ -28,9 +31,20 @@ __decorate([
28
31
  ], AiIntegrationResponseDto.prototype, "tenant", void 0);
29
32
  __decorate([
30
33
  (0, swagger_1.ApiProperty)({
31
- description: 'Model output content',
34
+ description: 'Structured AI response',
35
+ type: ai_action_dto_1.AiStructuredResponseDto,
36
+ }),
37
+ (0, class_validator_1.ValidateNested)(),
38
+ (0, class_transformer_1.Type)(() => ai_action_dto_1.AiStructuredResponseDto),
39
+ __metadata("design:type", ai_action_dto_1.AiStructuredResponseDto)
40
+ ], AiIntegrationResponseDto.prototype, "response", void 0);
41
+ __decorate([
42
+ (0, swagger_1.ApiProperty)({
43
+ description: 'Model output content (legacy field, use response.message)',
32
44
  example: 'Sure, I can help you reschedule your appointment.',
45
+ required: false,
33
46
  }),
47
+ (0, class_validator_1.IsOptional)(),
34
48
  (0, class_validator_1.IsString)(),
35
49
  (0, class_validator_1.IsNotEmpty)(),
36
50
  __metadata("design:type", String)
@@ -5,4 +5,5 @@ export * from './agent-response.dto';
5
5
  export * from './ai-integration-request.dto';
6
6
  export * from './ai-integration-response.dto';
7
7
  export * from './list-models.dto';
8
+ export * from './ai-action.dto';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC"}
package/dist/ai/index.js CHANGED
@@ -21,3 +21,4 @@ __exportStar(require("./agent-response.dto"), exports);
21
21
  __exportStar(require("./ai-integration-request.dto"), exports);
22
22
  __exportStar(require("./ai-integration-response.dto"), exports);
23
23
  __exportStar(require("./list-models.dto"), exports);
24
+ __exportStar(require("./ai-action.dto"), exports);
@@ -1,5 +1,5 @@
1
1
  export declare class LoginDto {
2
- username: string;
2
+ email: string;
3
3
  password: string;
4
4
  }
5
5
  //# sourceMappingURL=login.dto.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"login.dto.d.ts","sourceRoot":"","sources":["../../src/auth/login.dto.ts"],"names":[],"mappings":"AAGA,qBAAa,QAAQ;IAInB,QAAQ,EAAE,MAAM,CAAC;IAKjB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"login.dto.d.ts","sourceRoot":"","sources":["../../src/auth/login.dto.ts"],"names":[],"mappings":"AAGA,qBAAa,QAAQ;IAKnB,KAAK,EAAE,MAAM,CAAC;IAKd,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -13,16 +13,17 @@ exports.LoginDto = void 0;
13
13
  const swagger_1 = require("@nestjs/swagger");
14
14
  const class_validator_1 = require("class-validator");
15
15
  class LoginDto {
16
- username;
16
+ email;
17
17
  password;
18
18
  }
19
19
  exports.LoginDto = LoginDto;
20
20
  __decorate([
21
- (0, swagger_1.ApiProperty)({ description: 'Nome de usuário', example: 'usuario' }),
21
+ (0, swagger_1.ApiProperty)({ description: 'E-mail do usuário', example: 'usuario@empresa.com' }),
22
+ (0, class_validator_1.IsEmail)({}, { message: 'email deve ser um e-mail válido' }),
22
23
  (0, class_validator_1.IsString)(),
23
- (0, class_validator_1.MinLength)(1, { message: 'username não pode ser vazio' }),
24
+ (0, class_validator_1.MinLength)(1, { message: 'email não pode ser vazio' }),
24
25
  __metadata("design:type", String)
25
- ], LoginDto.prototype, "username", void 0);
26
+ ], LoginDto.prototype, "email", void 0);
26
27
  __decorate([
27
28
  (0, swagger_1.ApiProperty)({ description: 'Senha do usuário', example: 'senha123' }),
28
29
  (0, class_validator_1.IsString)(),
@@ -2,6 +2,10 @@ export declare class CreatePatientDto {
2
2
  name: string;
3
3
  cpf: string;
4
4
  birthDate: string;
5
+ email?: string | null;
6
+ phone?: string | null;
7
+ gender?: string | null;
8
+ address?: string | null;
5
9
  hasDisability: boolean;
6
10
  disabilityDescription?: string | null;
7
11
  initialObservation?: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"create-patient.dto.d.ts","sourceRoot":"","sources":["../../src/patients/create-patient.dto.ts"],"names":[],"mappings":"AAYA,qBAAa,gBAAgB;IAS3B,IAAI,EAAE,MAAM,CAAC;IAUb,GAAG,EAAE,MAAM,CAAC;IAOZ,SAAS,EAAE,MAAM,CAAC;IAOlB,aAAa,EAAE,OAAO,CAAC;IAWvB,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAUtC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAYnC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B"}
1
+ {"version":3,"file":"create-patient.dto.d.ts","sourceRoot":"","sources":["../../src/patients/create-patient.dto.ts"],"names":[],"mappings":"AAaA,qBAAa,gBAAgB;IAS3B,IAAI,EAAE,MAAM,CAAC;IAUb,GAAG,EAAE,MAAM,CAAC;IAOZ,SAAS,EAAE,MAAM,CAAC;IAUlB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAUtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAUtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAUvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAOxB,aAAa,EAAE,OAAO,CAAC;IAWvB,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAUtC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAYnC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B"}
@@ -17,6 +17,10 @@ class CreatePatientDto {
17
17
  name;
18
18
  cpf;
19
19
  birthDate;
20
+ email;
21
+ phone;
22
+ gender;
23
+ address;
20
24
  hasDisability;
21
25
  disabilityDescription;
22
26
  initialObservation;
@@ -53,6 +57,50 @@ __decorate([
53
57
  (0, class_validator_1.IsDateString)(),
54
58
  __metadata("design:type", String)
55
59
  ], CreatePatientDto.prototype, "birthDate", void 0);
60
+ __decorate([
61
+ (0, swagger_1.ApiPropertyOptional)({
62
+ description: 'E-mail do paciente',
63
+ example: 'joao.silva@email.com',
64
+ maxLength: 255,
65
+ }),
66
+ (0, class_validator_1.IsOptional)(),
67
+ (0, class_validator_1.IsEmail)({}, { message: 'email deve ser um e-mail válido' }),
68
+ (0, class_validator_1.MaxLength)(255),
69
+ __metadata("design:type", Object)
70
+ ], CreatePatientDto.prototype, "email", void 0);
71
+ __decorate([
72
+ (0, swagger_1.ApiPropertyOptional)({
73
+ description: 'Telefone de contato do paciente',
74
+ example: '+55 11 99999-9999',
75
+ maxLength: 30,
76
+ }),
77
+ (0, class_validator_1.IsString)(),
78
+ (0, class_validator_1.IsOptional)(),
79
+ (0, class_validator_1.MaxLength)(30),
80
+ __metadata("design:type", Object)
81
+ ], CreatePatientDto.prototype, "phone", void 0);
82
+ __decorate([
83
+ (0, swagger_1.ApiPropertyOptional)({
84
+ description: 'Gênero do paciente',
85
+ example: 'masculino',
86
+ maxLength: 50,
87
+ }),
88
+ (0, class_validator_1.IsString)(),
89
+ (0, class_validator_1.IsOptional)(),
90
+ (0, class_validator_1.MaxLength)(50),
91
+ __metadata("design:type", Object)
92
+ ], CreatePatientDto.prototype, "gender", void 0);
93
+ __decorate([
94
+ (0, swagger_1.ApiPropertyOptional)({
95
+ description: 'Endereço completo do paciente',
96
+ example: 'Rua Exemplo, 123 - São Paulo/SP',
97
+ maxLength: 500,
98
+ }),
99
+ (0, class_validator_1.IsString)(),
100
+ (0, class_validator_1.IsOptional)(),
101
+ (0, class_validator_1.MaxLength)(500),
102
+ __metadata("design:type", Object)
103
+ ], CreatePatientDto.prototype, "address", void 0);
56
104
  __decorate([
57
105
  (0, swagger_1.ApiProperty)({
58
106
  description: 'Indica se o paciente possui alguma deficiência',
@@ -1,5 +1,10 @@
1
1
  export declare class CreateProcedureDto {
2
2
  name: string;
3
+ category?: string | null;
4
+ description?: string | null;
5
+ blockTime?: number | null;
6
+ defaultValue?: number | null;
7
+ returnDays?: number | null;
3
8
  value: number;
4
9
  duration: number;
5
10
  side_effects?: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"create-procedure.dto.d.ts","sourceRoot":"","sources":["../../src/procedures/create-procedure.dto.ts"],"names":[],"mappings":"AAWA,qBAAa,kBAAkB;IAS7B,IAAI,EAAE,MAAM,CAAC;IAQb,KAAK,EAAE,MAAM,CAAC;IAQd,QAAQ,EAAE,MAAM,CAAC;IAUjB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAQ7B,WAAW,EAAE,MAAM,CAAC;CACrB"}
1
+ {"version":3,"file":"create-procedure.dto.d.ts","sourceRoot":"","sources":["../../src/procedures/create-procedure.dto.ts"],"names":[],"mappings":"AAYA,qBAAa,kBAAkB;IAS7B,IAAI,EAAE,MAAM,CAAC;IAUb,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAUzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAS5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAS1B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAS7B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAQ3B,KAAK,EAAE,MAAM,CAAC;IAQd,QAAQ,EAAE,MAAM,CAAC;IAUjB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAQ7B,WAAW,EAAE,MAAM,CAAC;CACrB"}
@@ -14,6 +14,11 @@ const swagger_1 = require("@nestjs/swagger");
14
14
  const class_validator_1 = require("class-validator");
15
15
  class CreateProcedureDto {
16
16
  name;
17
+ category;
18
+ description;
19
+ blockTime;
20
+ defaultValue;
21
+ returnDays;
17
22
  value;
18
23
  duration;
19
24
  side_effects;
@@ -31,6 +36,58 @@ __decorate([
31
36
  (0, class_validator_1.MaxLength)(255),
32
37
  __metadata("design:type", String)
33
38
  ], CreateProcedureDto.prototype, "name", void 0);
39
+ __decorate([
40
+ (0, swagger_1.ApiPropertyOptional)({
41
+ description: 'Categoria do procedimento',
42
+ example: 'Consulta',
43
+ maxLength: 100,
44
+ }),
45
+ (0, class_validator_1.IsString)(),
46
+ (0, class_validator_1.IsOptional)(),
47
+ (0, class_validator_1.MaxLength)(100),
48
+ __metadata("design:type", Object)
49
+ ], CreateProcedureDto.prototype, "category", void 0);
50
+ __decorate([
51
+ (0, swagger_1.ApiPropertyOptional)({
52
+ description: 'Descrição detalhada do procedimento',
53
+ example: 'Consulta clínica com anamnese e avaliação geral',
54
+ maxLength: 5000,
55
+ }),
56
+ (0, class_validator_1.IsString)(),
57
+ (0, class_validator_1.IsOptional)(),
58
+ (0, class_validator_1.MaxLength)(5000),
59
+ __metadata("design:type", Object)
60
+ ], CreateProcedureDto.prototype, "description", void 0);
61
+ __decorate([
62
+ (0, swagger_1.ApiPropertyOptional)({
63
+ description: 'Tempo de bloqueio da agenda em minutos',
64
+ example: 30,
65
+ }),
66
+ (0, class_validator_1.IsInt)(),
67
+ (0, class_validator_1.IsOptional)(),
68
+ (0, class_validator_1.Min)(1),
69
+ __metadata("design:type", Object)
70
+ ], CreateProcedureDto.prototype, "blockTime", void 0);
71
+ __decorate([
72
+ (0, swagger_1.ApiPropertyOptional)({
73
+ description: 'Valor padrão sugerido para o procedimento',
74
+ example: 150.5,
75
+ }),
76
+ (0, class_validator_1.IsNumber)({ maxDecimalPlaces: 2 }),
77
+ (0, class_validator_1.IsOptional)(),
78
+ (0, class_validator_1.Min)(0),
79
+ __metadata("design:type", Object)
80
+ ], CreateProcedureDto.prototype, "defaultValue", void 0);
81
+ __decorate([
82
+ (0, swagger_1.ApiPropertyOptional)({
83
+ description: 'Quantidade de dias sugerida para retorno',
84
+ example: 30,
85
+ }),
86
+ (0, class_validator_1.IsInt)(),
87
+ (0, class_validator_1.IsOptional)(),
88
+ (0, class_validator_1.Min)(0),
89
+ __metadata("design:type", Object)
90
+ ], CreateProcedureDto.prototype, "returnDays", void 0);
34
91
  __decorate([
35
92
  (0, swagger_1.ApiProperty)({
36
93
  description: 'Valor monetário do procedimento',
@@ -6,7 +6,7 @@ export declare const CREATABLE_USER_ROLES: readonly ["attendant", "health_profes
6
6
  export type CreatableUserRole = (typeof CREATABLE_USER_ROLES)[number];
7
7
  export declare class CreateUserDto {
8
8
  name: string;
9
- username: string;
9
+ email: string;
10
10
  password: string;
11
11
  role: CreatableUserRole;
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create-user.dto.d.ts","sourceRoot":"","sources":["../../src/users/create-user.dto.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,+CAAgD,CAAC;AAClF,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,qBAAa,aAAa;IASxB,IAAI,EAAE,MAAM,CAAC;IAUb,QAAQ,EAAE,MAAM,CAAC;IAUjB,QAAQ,EAAE,MAAM,CAAC;IAWjB,IAAI,EAAE,iBAAiB,CAAC;CACzB"}
1
+ {"version":3,"file":"create-user.dto.d.ts","sourceRoot":"","sources":["../../src/users/create-user.dto.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,+CAAgD,CAAC;AAClF,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,qBAAa,aAAa;IASxB,IAAI,EAAE,MAAM,CAAC;IAWb,KAAK,EAAE,MAAM,CAAC;IAUd,QAAQ,EAAE,MAAM,CAAC;IAWjB,IAAI,EAAE,iBAAiB,CAAC;CACzB"}
@@ -19,7 +19,7 @@ const class_validator_1 = require("class-validator");
19
19
  exports.CREATABLE_USER_ROLES = ['attendant', 'health_professional'];
20
20
  class CreateUserDto {
21
21
  name;
22
- username;
22
+ email;
23
23
  password;
24
24
  role;
25
25
  }
@@ -37,15 +37,16 @@ __decorate([
37
37
  ], CreateUserDto.prototype, "name", void 0);
38
38
  __decorate([
39
39
  (0, swagger_1.ApiProperty)({
40
- description: 'Login do usuário (único no tenant)',
41
- example: 'maria.silva',
40
+ description: 'E-mail do usuário (único no tenant)',
41
+ example: 'maria.silva@empresa.com',
42
42
  maxLength: 255,
43
43
  }),
44
+ (0, class_validator_1.IsEmail)({}, { message: 'email deve ser um e-mail válido' }),
44
45
  (0, class_validator_1.IsString)(),
45
- (0, class_validator_1.MinLength)(1, { message: 'username não pode ser vazio' }),
46
+ (0, class_validator_1.MinLength)(1, { message: 'email não pode ser vazio' }),
46
47
  (0, class_validator_1.MaxLength)(255),
47
48
  __metadata("design:type", String)
48
- ], CreateUserDto.prototype, "username", void 0);
49
+ ], CreateUserDto.prototype, "email", void 0);
49
50
  __decorate([
50
51
  (0, swagger_1.ApiProperty)({
51
52
  description: 'Senha (será hasheada com bcrypt)',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tychat-contracts",
3
- "version": "1.0.39",
3
+ "version": "1.0.41",
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",
@@ -12,6 +12,7 @@
12
12
  "dependencies": {
13
13
  "class-transformer": "^0.5.1",
14
14
  "class-validator": "^0.14.1",
15
+ "ioredis": "^5.10.0",
15
16
  "reflect-metadata": "*"
16
17
  },
17
18
  "devDependencies": {
@@ -0,0 +1,176 @@
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+ import {
3
+ IsArray,
4
+ IsBoolean,
5
+ IsDateString,
6
+ IsEnum,
7
+ IsNotEmpty,
8
+ IsOptional,
9
+ IsString,
10
+ IsUUID,
11
+ Length,
12
+ } from 'class-validator';
13
+
14
+ export const AI_RESPONSE_TYPES = ['message', 'action'] as const;
15
+ export type AiResponseTypeDto = (typeof AI_RESPONSE_TYPES)[number];
16
+
17
+ export const AI_ACTION_TYPES = [
18
+ 'create_patient',
19
+ 'create_appointment',
20
+ 'cancel_appointment',
21
+ ] as const;
22
+ export type AiActionTypeDto = (typeof AI_ACTION_TYPES)[number];
23
+
24
+ export class AiActionDataDto {
25
+ @ApiPropertyOptional({
26
+ description: 'Suggested patient id when the patient already exists',
27
+ example: '550e8400-e29b-41d4-a716-446655440000',
28
+ })
29
+ @IsOptional()
30
+ @IsUUID('4')
31
+ patientId?: string;
32
+
33
+ @ApiPropertyOptional({
34
+ description: 'Patient full name',
35
+ example: 'Joao da Silva',
36
+ })
37
+ @IsOptional()
38
+ @IsString()
39
+ @IsNotEmpty()
40
+ name?: string;
41
+
42
+ @ApiPropertyOptional({
43
+ description: 'Patient CPF with 11 digits',
44
+ example: '12345678909',
45
+ })
46
+ @IsOptional()
47
+ @IsString()
48
+ @Length(11, 11)
49
+ cpf?: string;
50
+
51
+ @ApiPropertyOptional({
52
+ description: 'Patient birth date in ISO format (YYYY-MM-DD)',
53
+ example: '1990-01-01',
54
+ })
55
+ @IsOptional()
56
+ @IsDateString()
57
+ birthDate?: string;
58
+
59
+ @ApiPropertyOptional({
60
+ description: 'Indicates whether the patient has a disability',
61
+ example: false,
62
+ })
63
+ @IsOptional()
64
+ @IsBoolean()
65
+ hasDisability?: boolean;
66
+
67
+ @ApiPropertyOptional({
68
+ description: 'Disability description when applicable',
69
+ example: 'Visual impairment',
70
+ })
71
+ @IsOptional()
72
+ @IsString()
73
+ disabilityDescription?: string;
74
+
75
+ @ApiPropertyOptional({
76
+ description: 'Initial patient observation',
77
+ example: 'Patient has back pain for two weeks',
78
+ })
79
+ @IsOptional()
80
+ @IsString()
81
+ initialObservation?: string;
82
+
83
+ @ApiPropertyOptional({
84
+ description: 'Optional observation for history',
85
+ example: 'Patient is allergic to penicillin',
86
+ })
87
+ @IsOptional()
88
+ @IsString()
89
+ observation?: string;
90
+
91
+ @ApiPropertyOptional({
92
+ description: 'Procedure ids selected by the user',
93
+ type: [String],
94
+ example: ['550e8400-e29b-41d4-a716-446655440010'],
95
+ })
96
+ @IsOptional()
97
+ @IsArray()
98
+ @IsUUID('4', { each: true })
99
+ procedureIds?: string[];
100
+
101
+ @ApiPropertyOptional({
102
+ description: 'Professional user id selected by the user',
103
+ example: '550e8400-e29b-41d4-a716-446655440001',
104
+ })
105
+ @IsOptional()
106
+ @IsUUID('4')
107
+ userId?: string;
108
+
109
+ @ApiPropertyOptional({
110
+ description: 'Requested appointment date/time in ISO format',
111
+ example: '2026-03-15T14:00:00.000Z',
112
+ })
113
+ @IsOptional()
114
+ @IsDateString()
115
+ date?: string;
116
+
117
+ @ApiPropertyOptional({
118
+ description: 'Existing appointment id for cancellation',
119
+ example: '550e8400-e29b-41d4-a716-446655440002',
120
+ })
121
+ @IsOptional()
122
+ @IsUUID('4')
123
+ appointmentId?: string;
124
+
125
+ @ApiPropertyOptional({
126
+ description: 'Optional human-readable reason or assistant notes',
127
+ example: 'User asked to cancel due to travel',
128
+ })
129
+ @IsOptional()
130
+ @IsString()
131
+ reason?: string;
132
+
133
+ @ApiPropertyOptional({
134
+ description: 'Fields still required to complete the action',
135
+ type: [String],
136
+ example: ['cpf', 'birthDate'],
137
+ })
138
+ @IsOptional()
139
+ @IsArray()
140
+ @IsString({ each: true })
141
+ missingFields?: string[];
142
+ }
143
+
144
+ export class AiStructuredResponseDto {
145
+ @ApiProperty({
146
+ description: 'Response type returned by AI',
147
+ enum: AI_RESPONSE_TYPES,
148
+ example: 'action',
149
+ })
150
+ @IsEnum(AI_RESPONSE_TYPES)
151
+ type: AiResponseTypeDto;
152
+
153
+ @ApiPropertyOptional({
154
+ description: 'Action type when the response type is action',
155
+ enum: AI_ACTION_TYPES,
156
+ example: 'create_patient',
157
+ })
158
+ @IsOptional()
159
+ @IsEnum(AI_ACTION_TYPES)
160
+ actionType?: AiActionTypeDto;
161
+
162
+ @ApiPropertyOptional({
163
+ description: 'Message returned to the user',
164
+ example: 'I need your CPF and birth date to create the patient.',
165
+ })
166
+ @IsOptional()
167
+ @IsString()
168
+ message?: string;
169
+
170
+ @ApiPropertyOptional({
171
+ description: 'Structured payload extracted from the conversation',
172
+ type: AiActionDataDto,
173
+ })
174
+ @IsOptional()
175
+ data?: AiActionDataDto;
176
+ }
@@ -27,6 +27,14 @@ export class AiIntegrationRequestDto {
27
27
  @IsNotEmpty()
28
28
  message: string;
29
29
 
30
+ @ApiProperty({
31
+ description: 'Conversation identifier used for context isolation',
32
+ example: '5511999999999',
33
+ })
34
+ @IsString()
35
+ @IsNotEmpty()
36
+ id: string;
37
+
30
38
  @ApiProperty({
31
39
  description: 'Indicates whether the input is document-based',
32
40
  example: false,
@@ -1,5 +1,7 @@
1
1
  import { ApiProperty } from '@nestjs/swagger';
2
- import { IsNotEmpty, IsString } from 'class-validator';
2
+ import { Type } from 'class-transformer';
3
+ import { IsNotEmpty, IsOptional, IsString, ValidateNested } from 'class-validator';
4
+ import { AiStructuredResponseDto } from './ai-action.dto';
3
5
 
4
6
  export class AiIntegrationResponseDto {
5
7
  @ApiProperty({
@@ -11,10 +13,20 @@ export class AiIntegrationResponseDto {
11
13
  tenant: string;
12
14
 
13
15
  @ApiProperty({
14
- description: 'Model output content',
16
+ description: 'Structured AI response',
17
+ type: AiStructuredResponseDto,
18
+ })
19
+ @ValidateNested()
20
+ @Type(() => AiStructuredResponseDto)
21
+ response: AiStructuredResponseDto;
22
+
23
+ @ApiProperty({
24
+ description: 'Model output content (legacy field, use response.message)',
15
25
  example: 'Sure, I can help you reschedule your appointment.',
26
+ required: false,
16
27
  })
28
+ @IsOptional()
17
29
  @IsString()
18
30
  @IsNotEmpty()
19
- output: string;
31
+ output?: string;
20
32
  }
package/src/ai/index.ts CHANGED
@@ -5,3 +5,4 @@ export * from './agent-response.dto';
5
5
  export * from './ai-integration-request.dto';
6
6
  export * from './ai-integration-response.dto';
7
7
  export * from './list-models.dto';
8
+ export * from './ai-action.dto';
@@ -1,11 +1,12 @@
1
1
  import { ApiProperty } from '@nestjs/swagger';
2
- import { IsString, MinLength } from 'class-validator';
2
+ import { IsEmail, IsString, MinLength } from 'class-validator';
3
3
 
4
4
  export class LoginDto {
5
- @ApiProperty({ description: 'Nome de usuário', example: 'usuario' })
5
+ @ApiProperty({ description: 'E-mail do usuário', example: 'usuario@empresa.com' })
6
+ @IsEmail({}, { message: 'email deve ser um e-mail válido' })
6
7
  @IsString()
7
- @MinLength(1, { message: 'username não pode ser vazio' })
8
- username: string;
8
+ @MinLength(1, { message: 'email não pode ser vazio' })
9
+ email: string;
9
10
 
10
11
  @ApiProperty({ description: 'Senha do usuário', example: 'senha123' })
11
12
  @IsString()
@@ -2,6 +2,7 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
2
  import {
3
3
  IsBoolean,
4
4
  IsDateString,
5
+ IsEmail,
5
6
  IsNotEmpty,
6
7
  IsOptional,
7
8
  IsString,
@@ -38,6 +39,46 @@ export class CreatePatientDto {
38
39
  @IsDateString()
39
40
  birthDate: string;
40
41
 
42
+ @ApiPropertyOptional({
43
+ description: 'E-mail do paciente',
44
+ example: 'joao.silva@email.com',
45
+ maxLength: 255,
46
+ })
47
+ @IsOptional()
48
+ @IsEmail({}, { message: 'email deve ser um e-mail válido' })
49
+ @MaxLength(255)
50
+ email?: string | null;
51
+
52
+ @ApiPropertyOptional({
53
+ description: 'Telefone de contato do paciente',
54
+ example: '+55 11 99999-9999',
55
+ maxLength: 30,
56
+ })
57
+ @IsString()
58
+ @IsOptional()
59
+ @MaxLength(30)
60
+ phone?: string | null;
61
+
62
+ @ApiPropertyOptional({
63
+ description: 'Gênero do paciente',
64
+ example: 'masculino',
65
+ maxLength: 50,
66
+ })
67
+ @IsString()
68
+ @IsOptional()
69
+ @MaxLength(50)
70
+ gender?: string | null;
71
+
72
+ @ApiPropertyOptional({
73
+ description: 'Endereço completo do paciente',
74
+ example: 'Rua Exemplo, 123 - São Paulo/SP',
75
+ maxLength: 500,
76
+ })
77
+ @IsString()
78
+ @IsOptional()
79
+ @MaxLength(500)
80
+ address?: string | null;
81
+
41
82
  @ApiProperty({
42
83
  description: 'Indica se o paciente possui alguma deficiência',
43
84
  example: true,
@@ -1,5 +1,6 @@
1
1
  import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
2
  import {
3
+ IsInt,
3
4
  IsNotEmpty,
4
5
  IsNumber,
5
6
  IsOptional,
@@ -20,6 +21,53 @@ export class CreateProcedureDto {
20
21
  @MaxLength(255)
21
22
  name: string;
22
23
 
24
+ @ApiPropertyOptional({
25
+ description: 'Categoria do procedimento',
26
+ example: 'Consulta',
27
+ maxLength: 100,
28
+ })
29
+ @IsString()
30
+ @IsOptional()
31
+ @MaxLength(100)
32
+ category?: string | null;
33
+
34
+ @ApiPropertyOptional({
35
+ description: 'Descrição detalhada do procedimento',
36
+ example: 'Consulta clínica com anamnese e avaliação geral',
37
+ maxLength: 5000,
38
+ })
39
+ @IsString()
40
+ @IsOptional()
41
+ @MaxLength(5000)
42
+ description?: string | null;
43
+
44
+ @ApiPropertyOptional({
45
+ description: 'Tempo de bloqueio da agenda em minutos',
46
+ example: 30,
47
+ })
48
+ @IsInt()
49
+ @IsOptional()
50
+ @Min(1)
51
+ blockTime?: number | null;
52
+
53
+ @ApiPropertyOptional({
54
+ description: 'Valor padrão sugerido para o procedimento',
55
+ example: 150.5,
56
+ })
57
+ @IsNumber({ maxDecimalPlaces: 2 })
58
+ @IsOptional()
59
+ @Min(0)
60
+ defaultValue?: number | null;
61
+
62
+ @ApiPropertyOptional({
63
+ description: 'Quantidade de dias sugerida para retorno',
64
+ example: 30,
65
+ })
66
+ @IsInt()
67
+ @IsOptional()
68
+ @Min(0)
69
+ returnDays?: number | null;
70
+
23
71
  @ApiProperty({
24
72
  description: 'Valor monetário do procedimento',
25
73
  example: 150.5,
@@ -1,5 +1,6 @@
1
1
  import { ApiProperty } from '@nestjs/swagger';
2
2
  import {
3
+ IsEmail,
3
4
  IsString,
4
5
  IsIn,
5
6
  MinLength,
@@ -25,14 +26,15 @@ export class CreateUserDto {
25
26
  name: string;
26
27
 
27
28
  @ApiProperty({
28
- description: 'Login do usuário (único no tenant)',
29
- example: 'maria.silva',
29
+ description: 'E-mail do usuário (único no tenant)',
30
+ example: 'maria.silva@empresa.com',
30
31
  maxLength: 255,
31
32
  })
33
+ @IsEmail({}, { message: 'email deve ser um e-mail válido' })
32
34
  @IsString()
33
- @MinLength(1, { message: 'username não pode ser vazio' })
35
+ @MinLength(1, { message: 'email não pode ser vazio' })
34
36
  @MaxLength(255)
35
- username: string;
37
+ email: string;
36
38
 
37
39
  @ApiProperty({
38
40
  description: 'Senha (será hasheada com bcrypt)',