tychat-contracts 1.0.47 → 1.0.48

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/README.md CHANGED
@@ -4,7 +4,8 @@ DTOs compartilhados com **class-validator** usados pela **tychat-api** e pelos m
4
4
 
5
5
  ## Estrutura
6
6
 
7
- - **auth**: `LoginDto`
7
+ - **auth**: `LoginDto`, `RefreshTokenDto`, payloads Kafka (`LoginPayload`, etc.)
8
+ - **users**: `CreateUserDto`, `UserListItemDto`, `UpdateSelfUserDto`, `UpdateUserByAdminDto`, `UpdatedUserDto` (atualização de perfil e por administrador)
8
9
 
9
10
  ## Uso
10
11
 
@@ -0,0 +1,7 @@
1
+ import { ValidationOptions } from 'class-validator';
2
+ /**
3
+ * Ensures at least one of the listed properties is present and non-empty on the object.
4
+ * Apply to a dummy property (e.g. `_atLeastOne`) that is not sent by clients.
5
+ */
6
+ export declare function AtLeastOneOf(propertyNames: string[], validationOptions?: ValidationOptions): (object: object, propertyName: string) => void;
7
+ //# sourceMappingURL=at-least-one-of.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"at-least-one-of.decorator.d.ts","sourceRoot":"","sources":["../../src/users/at-least-one-of.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAEzB;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,aAAa,EAAE,MAAM,EAAE,EACvB,iBAAiB,CAAC,EAAE,iBAAiB,IAEpB,QAAQ,MAAM,EAAE,cAAc,MAAM,UAyBtD"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AtLeastOneOf = AtLeastOneOf;
4
+ const class_validator_1 = require("class-validator");
5
+ /**
6
+ * Ensures at least one of the listed properties is present and non-empty on the object.
7
+ * Apply to a dummy property (e.g. `_atLeastOne`) that is not sent by clients.
8
+ */
9
+ function AtLeastOneOf(propertyNames, validationOptions) {
10
+ return function (object, propertyName) {
11
+ (0, class_validator_1.registerDecorator)({
12
+ name: 'atLeastOneOf',
13
+ target: object.constructor,
14
+ propertyName,
15
+ constraints: [propertyNames],
16
+ options: validationOptions,
17
+ validator: {
18
+ validate(_value, args) {
19
+ const obj = args.object;
20
+ const props = args.constraints[0];
21
+ return props.some((prop) => {
22
+ const v = obj[prop];
23
+ if (v == null)
24
+ return false;
25
+ if (typeof v === 'string')
26
+ return v.trim().length > 0;
27
+ return true;
28
+ });
29
+ },
30
+ defaultMessage(args) {
31
+ const props = args.constraints[0];
32
+ return `Provide at least one of: ${props.join(', ')}`;
33
+ },
34
+ },
35
+ });
36
+ };
37
+ }
@@ -1,3 +1,7 @@
1
1
  export { CreateUserDto, CREATABLE_USER_ROLES, type CreatableUserRole, } from './create-user.dto';
2
2
  export { UserListItemDto } from './user-list-item.dto';
3
+ export { UpdateSelfUserDto } from './update-self-user.dto';
4
+ export { UpdateUserByAdminDto, ALL_USER_ROLES, type AllUserRole, } from './update-user-by-admin.dto';
5
+ export { UpdatedUserDto } from './updated-user.dto';
6
+ export type { AuthUpdateSelfPayload, AuthUpdateUserAdminPayload, } from './user-update-kafka-payloads';
3
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/users/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,KAAK,iBAAiB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/users/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,KAAK,iBAAiB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,KAAK,WAAW,GACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,YAAY,EACV,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC"}
@@ -1,8 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UserListItemDto = exports.CREATABLE_USER_ROLES = exports.CreateUserDto = void 0;
3
+ exports.UpdatedUserDto = exports.ALL_USER_ROLES = exports.UpdateUserByAdminDto = exports.UpdateSelfUserDto = exports.UserListItemDto = exports.CREATABLE_USER_ROLES = exports.CreateUserDto = void 0;
4
4
  var create_user_dto_1 = require("./create-user.dto");
5
5
  Object.defineProperty(exports, "CreateUserDto", { enumerable: true, get: function () { return create_user_dto_1.CreateUserDto; } });
6
6
  Object.defineProperty(exports, "CREATABLE_USER_ROLES", { enumerable: true, get: function () { return create_user_dto_1.CREATABLE_USER_ROLES; } });
7
7
  var user_list_item_dto_1 = require("./user-list-item.dto");
8
8
  Object.defineProperty(exports, "UserListItemDto", { enumerable: true, get: function () { return user_list_item_dto_1.UserListItemDto; } });
9
+ var update_self_user_dto_1 = require("./update-self-user.dto");
10
+ Object.defineProperty(exports, "UpdateSelfUserDto", { enumerable: true, get: function () { return update_self_user_dto_1.UpdateSelfUserDto; } });
11
+ var update_user_by_admin_dto_1 = require("./update-user-by-admin.dto");
12
+ Object.defineProperty(exports, "UpdateUserByAdminDto", { enumerable: true, get: function () { return update_user_by_admin_dto_1.UpdateUserByAdminDto; } });
13
+ Object.defineProperty(exports, "ALL_USER_ROLES", { enumerable: true, get: function () { return update_user_by_admin_dto_1.ALL_USER_ROLES; } });
14
+ var updated_user_dto_1 = require("./updated-user.dto");
15
+ Object.defineProperty(exports, "UpdatedUserDto", { enumerable: true, get: function () { return updated_user_dto_1.UpdatedUserDto; } });
@@ -0,0 +1,8 @@
1
+ /** Fields the authenticated user may change on their own profile (no role change). */
2
+ export declare class UpdateSelfUserDto {
3
+ _atLeastOne?: string;
4
+ name?: string;
5
+ email?: string;
6
+ password?: string;
7
+ }
8
+ //# sourceMappingURL=update-self-user.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-self-user.dto.d.ts","sourceRoot":"","sources":["../../src/users/update-self-user.dto.ts"],"names":[],"mappings":"AAIA,sFAAsF;AACtF,qBAAa,iBAAiB;IAG5B,WAAW,CAAC,EAAE,MAAM,CAAC;IAWrB,IAAI,CAAC,EAAE,MAAM,CAAC;IAUd,KAAK,CAAC,EAAE,MAAM,CAAC;IAWf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,63 @@
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.UpdateSelfUserDto = void 0;
13
+ const swagger_1 = require("@nestjs/swagger");
14
+ const class_validator_1 = require("class-validator");
15
+ const at_least_one_of_decorator_1 = require("./at-least-one-of.decorator");
16
+ /** Fields the authenticated user may change on their own profile (no role change). */
17
+ class UpdateSelfUserDto {
18
+ _atLeastOne;
19
+ name;
20
+ email;
21
+ password;
22
+ }
23
+ exports.UpdateSelfUserDto = UpdateSelfUserDto;
24
+ __decorate([
25
+ (0, swagger_1.ApiHideProperty)(),
26
+ (0, at_least_one_of_decorator_1.AtLeastOneOf)(['name', 'email', 'password']),
27
+ __metadata("design:type", String)
28
+ ], UpdateSelfUserDto.prototype, "_atLeastOne", void 0);
29
+ __decorate([
30
+ (0, swagger_1.ApiPropertyOptional)({
31
+ description: 'Full name',
32
+ example: 'Maria da Silva',
33
+ maxLength: 255,
34
+ }),
35
+ (0, class_validator_1.IsOptional)(),
36
+ (0, class_validator_1.IsString)(),
37
+ (0, class_validator_1.MinLength)(1, { message: 'name cannot be empty when provided' }),
38
+ (0, class_validator_1.MaxLength)(255),
39
+ __metadata("design:type", String)
40
+ ], UpdateSelfUserDto.prototype, "name", void 0);
41
+ __decorate([
42
+ (0, swagger_1.ApiPropertyOptional)({
43
+ description: 'E-mail (unique per tenant)',
44
+ example: 'maria@empresa.com',
45
+ maxLength: 255,
46
+ }),
47
+ (0, class_validator_1.IsOptional)(),
48
+ (0, class_validator_1.IsEmail)({}, { message: 'email must be a valid e-mail' }),
49
+ (0, class_validator_1.MaxLength)(255),
50
+ __metadata("design:type", String)
51
+ ], UpdateSelfUserDto.prototype, "email", void 0);
52
+ __decorate([
53
+ (0, swagger_1.ApiPropertyOptional)({
54
+ description: 'New password (bcrypt-hashed on the auth service)',
55
+ example: 'senha123',
56
+ minLength: 6,
57
+ }),
58
+ (0, class_validator_1.IsOptional)(),
59
+ (0, class_validator_1.IsString)(),
60
+ (0, class_validator_1.MinLength)(6, { message: 'password must be at least 6 characters' }),
61
+ (0, class_validator_1.MaxLength)(255),
62
+ __metadata("design:type", String)
63
+ ], UpdateSelfUserDto.prototype, "password", void 0);
@@ -0,0 +1,11 @@
1
+ export declare const ALL_USER_ROLES: readonly ["administrator", "attendant", "health_professional"];
2
+ export type AllUserRole = (typeof ALL_USER_ROLES)[number];
3
+ /** Fields an administrator may change for any user (including role). */
4
+ export declare class UpdateUserByAdminDto {
5
+ _atLeastOne?: string;
6
+ name?: string;
7
+ email?: string;
8
+ password?: string;
9
+ role?: AllUserRole;
10
+ }
11
+ //# sourceMappingURL=update-user-by-admin.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-user-by-admin.dto.d.ts","sourceRoot":"","sources":["../../src/users/update-user-by-admin.dto.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc,gEAIjB,CAAC;AACX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,wEAAwE;AACxE,qBAAa,oBAAoB;IAG/B,WAAW,CAAC,EAAE,MAAM,CAAC;IAWrB,IAAI,CAAC,EAAE,MAAM,CAAC;IAUd,KAAK,CAAC,EAAE,MAAM,CAAC;IAWf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAYlB,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB"}
@@ -0,0 +1,82 @@
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.UpdateUserByAdminDto = exports.ALL_USER_ROLES = void 0;
13
+ const swagger_1 = require("@nestjs/swagger");
14
+ const class_validator_1 = require("class-validator");
15
+ const at_least_one_of_decorator_1 = require("./at-least-one-of.decorator");
16
+ exports.ALL_USER_ROLES = [
17
+ 'administrator',
18
+ 'attendant',
19
+ 'health_professional',
20
+ ];
21
+ /** Fields an administrator may change for any user (including role). */
22
+ class UpdateUserByAdminDto {
23
+ _atLeastOne;
24
+ name;
25
+ email;
26
+ password;
27
+ role;
28
+ }
29
+ exports.UpdateUserByAdminDto = UpdateUserByAdminDto;
30
+ __decorate([
31
+ (0, swagger_1.ApiHideProperty)(),
32
+ (0, at_least_one_of_decorator_1.AtLeastOneOf)(['name', 'email', 'password', 'role']),
33
+ __metadata("design:type", String)
34
+ ], UpdateUserByAdminDto.prototype, "_atLeastOne", void 0);
35
+ __decorate([
36
+ (0, swagger_1.ApiPropertyOptional)({
37
+ description: 'Full name',
38
+ example: 'Maria da Silva',
39
+ maxLength: 255,
40
+ }),
41
+ (0, class_validator_1.IsOptional)(),
42
+ (0, class_validator_1.IsString)(),
43
+ (0, class_validator_1.MinLength)(1, { message: 'name cannot be empty when provided' }),
44
+ (0, class_validator_1.MaxLength)(255),
45
+ __metadata("design:type", String)
46
+ ], UpdateUserByAdminDto.prototype, "name", void 0);
47
+ __decorate([
48
+ (0, swagger_1.ApiPropertyOptional)({
49
+ description: 'E-mail (unique per tenant)',
50
+ example: 'maria@empresa.com',
51
+ maxLength: 255,
52
+ }),
53
+ (0, class_validator_1.IsOptional)(),
54
+ (0, class_validator_1.IsEmail)({}, { message: 'email must be a valid e-mail' }),
55
+ (0, class_validator_1.MaxLength)(255),
56
+ __metadata("design:type", String)
57
+ ], UpdateUserByAdminDto.prototype, "email", void 0);
58
+ __decorate([
59
+ (0, swagger_1.ApiPropertyOptional)({
60
+ description: 'New password (bcrypt-hashed on the auth service)',
61
+ example: 'senha123',
62
+ minLength: 6,
63
+ }),
64
+ (0, class_validator_1.IsOptional)(),
65
+ (0, class_validator_1.IsString)(),
66
+ (0, class_validator_1.MinLength)(6, { message: 'password must be at least 6 characters' }),
67
+ (0, class_validator_1.MaxLength)(255),
68
+ __metadata("design:type", String)
69
+ ], UpdateUserByAdminDto.prototype, "password", void 0);
70
+ __decorate([
71
+ (0, swagger_1.ApiPropertyOptional)({
72
+ description: 'User role',
73
+ enum: exports.ALL_USER_ROLES,
74
+ example: 'attendant',
75
+ }),
76
+ (0, class_validator_1.IsOptional)(),
77
+ (0, class_validator_1.IsString)(),
78
+ (0, class_validator_1.IsIn)(exports.ALL_USER_ROLES, {
79
+ message: 'role must be administrator, attendant, or health_professional',
80
+ }),
81
+ __metadata("design:type", String)
82
+ ], UpdateUserByAdminDto.prototype, "role", void 0);
@@ -0,0 +1,10 @@
1
+ /** User payload returned after create or update (no password). */
2
+ export declare class UpdatedUserDto {
3
+ userId: string;
4
+ name: string;
5
+ email: string;
6
+ role: 'administrator' | 'attendant' | 'health_professional';
7
+ createdAt: Date;
8
+ updatedAt: Date;
9
+ }
10
+ //# sourceMappingURL=updated-user.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updated-user.dto.d.ts","sourceRoot":"","sources":["../../src/users/updated-user.dto.ts"],"names":[],"mappings":"AAEA,kEAAkE;AAClE,qBAAa,cAAc;IAMzB,MAAM,EAAE,MAAM,CAAC;IAGf,IAAI,EAAE,MAAM,CAAC;IAGb,KAAK,EAAE,MAAM,CAAC;IAOd,IAAI,EAAE,eAAe,GAAG,WAAW,GAAG,qBAAqB,CAAC;IAG5D,SAAS,EAAE,IAAI,CAAC;IAGhB,SAAS,EAAE,IAAI,CAAC;CACjB"}
@@ -0,0 +1,55 @@
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.UpdatedUserDto = void 0;
13
+ const swagger_1 = require("@nestjs/swagger");
14
+ /** User payload returned after create or update (no password). */
15
+ class UpdatedUserDto {
16
+ userId;
17
+ name;
18
+ email;
19
+ role;
20
+ createdAt;
21
+ updatedAt;
22
+ }
23
+ exports.UpdatedUserDto = UpdatedUserDto;
24
+ __decorate([
25
+ (0, swagger_1.ApiProperty)({
26
+ format: 'uuid',
27
+ description: 'User identifier',
28
+ example: '550e8400-e29b-41d4-a716-446655440000',
29
+ }),
30
+ __metadata("design:type", String)
31
+ ], UpdatedUserDto.prototype, "userId", void 0);
32
+ __decorate([
33
+ (0, swagger_1.ApiProperty)({ description: 'Full name', example: 'Maria da Silva' }),
34
+ __metadata("design:type", String)
35
+ ], UpdatedUserDto.prototype, "name", void 0);
36
+ __decorate([
37
+ (0, swagger_1.ApiProperty)({ description: 'E-mail (unique per tenant)', example: 'maria@empresa.com' }),
38
+ __metadata("design:type", String)
39
+ ], UpdatedUserDto.prototype, "email", void 0);
40
+ __decorate([
41
+ (0, swagger_1.ApiProperty)({
42
+ description: 'User role',
43
+ enum: ['administrator', 'attendant', 'health_professional'],
44
+ example: 'attendant',
45
+ }),
46
+ __metadata("design:type", String)
47
+ ], UpdatedUserDto.prototype, "role", void 0);
48
+ __decorate([
49
+ (0, swagger_1.ApiProperty)({ description: 'Creation timestamp' }),
50
+ __metadata("design:type", Date)
51
+ ], UpdatedUserDto.prototype, "createdAt", void 0);
52
+ __decorate([
53
+ (0, swagger_1.ApiProperty)({ description: 'Last update timestamp' }),
54
+ __metadata("design:type", Date)
55
+ ], UpdatedUserDto.prototype, "updatedAt", void 0);
@@ -0,0 +1,12 @@
1
+ import { ValidationArguments, ValidatorConstraintInterface } from 'class-validator';
2
+ /** Ensures at least one of name, email, or password is provided for PATCH-style updates. */
3
+ export declare class AtLeastOneUserUpdateFieldConstraint implements ValidatorConstraintInterface {
4
+ validate(_: unknown, args: ValidationArguments): boolean;
5
+ defaultMessage(): string;
6
+ }
7
+ /** Same as self-update, plus optional role (for admin PATCH). */
8
+ export declare class AtLeastOneAdminUpdateFieldConstraint implements ValidatorConstraintInterface {
9
+ validate(_: unknown, args: ValidationArguments): boolean;
10
+ defaultMessage(): string;
11
+ }
12
+ //# sourceMappingURL=user-update-constraints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-update-constraints.d.ts","sourceRoot":"","sources":["../../src/users/user-update-constraints.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAEnB,4BAA4B,EAC7B,MAAM,iBAAiB,CAAC;AAEzB,4FAA4F;AAC5F,qBACa,mCAAoC,YAAW,4BAA4B;IACtF,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,mBAAmB;IAQ9C,cAAc;CAGf;AAED,iEAAiE;AACjE,qBACa,oCAAqC,YAAW,4BAA4B;IACvF,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,mBAAmB;IAc9C,cAAc;CAGf"}
@@ -0,0 +1,45 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AtLeastOneAdminUpdateFieldConstraint = exports.AtLeastOneUserUpdateFieldConstraint = void 0;
10
+ const class_validator_1 = require("class-validator");
11
+ /** Ensures at least one of name, email, or password is provided for PATCH-style updates. */
12
+ let AtLeastOneUserUpdateFieldConstraint = class AtLeastOneUserUpdateFieldConstraint {
13
+ validate(_, args) {
14
+ const o = args.object;
15
+ const hasName = o.name != null && String(o.name).trim() !== '';
16
+ const hasEmail = o.email != null && String(o.email).trim() !== '';
17
+ const hasPassword = o.password != null && String(o.password).length > 0;
18
+ return hasName || hasEmail || hasPassword;
19
+ }
20
+ defaultMessage() {
21
+ return 'Provide at least one of name, email, or password';
22
+ }
23
+ };
24
+ exports.AtLeastOneUserUpdateFieldConstraint = AtLeastOneUserUpdateFieldConstraint;
25
+ exports.AtLeastOneUserUpdateFieldConstraint = AtLeastOneUserUpdateFieldConstraint = __decorate([
26
+ (0, class_validator_1.ValidatorConstraint)({ name: 'atLeastOneUserUpdateField', async: false })
27
+ ], AtLeastOneUserUpdateFieldConstraint);
28
+ /** Same as self-update, plus optional role (for admin PATCH). */
29
+ let AtLeastOneAdminUpdateFieldConstraint = class AtLeastOneAdminUpdateFieldConstraint {
30
+ validate(_, args) {
31
+ const o = args.object;
32
+ const hasName = o.name != null && String(o.name).trim() !== '';
33
+ const hasEmail = o.email != null && String(o.email).trim() !== '';
34
+ const hasPassword = o.password != null && String(o.password).length > 0;
35
+ const hasRole = o.role != null && String(o.role).trim() !== '';
36
+ return hasName || hasEmail || hasPassword || hasRole;
37
+ }
38
+ defaultMessage() {
39
+ return 'Provide at least one of name, email, password, or role';
40
+ }
41
+ };
42
+ exports.AtLeastOneAdminUpdateFieldConstraint = AtLeastOneAdminUpdateFieldConstraint;
43
+ exports.AtLeastOneAdminUpdateFieldConstraint = AtLeastOneAdminUpdateFieldConstraint = __decorate([
44
+ (0, class_validator_1.ValidatorConstraint)({ name: 'atLeastOneAdminUpdateField', async: false })
45
+ ], AtLeastOneAdminUpdateFieldConstraint);
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Kafka payload for auth.update_self (tychat-api → tychat-auth-service).
3
+ */
4
+ export interface AuthUpdateSelfPayload {
5
+ tenant?: string;
6
+ userId: string;
7
+ name?: string;
8
+ email?: string;
9
+ password?: string;
10
+ }
11
+ /**
12
+ * Kafka payload for auth.update_user_admin (tychat-api → tychat-auth-service).
13
+ * actorRole must be "administrator" or the handler rejects the request.
14
+ */
15
+ export interface AuthUpdateUserAdminPayload {
16
+ tenant?: string;
17
+ actorRole: string;
18
+ targetUserId: string;
19
+ name?: string;
20
+ email?: string;
21
+ password?: string;
22
+ role?: 'administrator' | 'attendant' | 'health_professional';
23
+ }
24
+ //# sourceMappingURL=user-update-kafka-payloads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-update-kafka-payloads.d.ts","sourceRoot":"","sources":["../../src/users/user-update-kafka-payloads.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,eAAe,GAAG,WAAW,GAAG,qBAAqB,CAAC;CAC9D"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tychat-contracts",
3
- "version": "1.0.47",
3
+ "version": "1.0.48",
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",
@@ -0,0 +1,40 @@
1
+ import {
2
+ registerDecorator,
3
+ ValidationArguments,
4
+ ValidationOptions,
5
+ } from 'class-validator';
6
+
7
+ /**
8
+ * Ensures at least one of the listed properties is present and non-empty on the object.
9
+ * Apply to a dummy property (e.g. `_atLeastOne`) that is not sent by clients.
10
+ */
11
+ export function AtLeastOneOf(
12
+ propertyNames: string[],
13
+ validationOptions?: ValidationOptions,
14
+ ) {
15
+ return function (object: object, propertyName: string) {
16
+ registerDecorator({
17
+ name: 'atLeastOneOf',
18
+ target: object.constructor,
19
+ propertyName,
20
+ constraints: [propertyNames],
21
+ options: validationOptions,
22
+ validator: {
23
+ validate(_value: unknown, args: ValidationArguments) {
24
+ const obj = args.object as Record<string, unknown>;
25
+ const props = args.constraints[0] as string[];
26
+ return props.some((prop) => {
27
+ const v = obj[prop];
28
+ if (v == null) return false;
29
+ if (typeof v === 'string') return v.trim().length > 0;
30
+ return true;
31
+ });
32
+ },
33
+ defaultMessage(args: ValidationArguments) {
34
+ const props = args.constraints[0] as string[];
35
+ return `Provide at least one of: ${props.join(', ')}`;
36
+ },
37
+ },
38
+ });
39
+ };
40
+ }
@@ -4,3 +4,14 @@ export {
4
4
  type CreatableUserRole,
5
5
  } from './create-user.dto';
6
6
  export { UserListItemDto } from './user-list-item.dto';
7
+ export { UpdateSelfUserDto } from './update-self-user.dto';
8
+ export {
9
+ UpdateUserByAdminDto,
10
+ ALL_USER_ROLES,
11
+ type AllUserRole,
12
+ } from './update-user-by-admin.dto';
13
+ export { UpdatedUserDto } from './updated-user.dto';
14
+ export type {
15
+ AuthUpdateSelfPayload,
16
+ AuthUpdateUserAdminPayload,
17
+ } from './user-update-kafka-payloads';
@@ -0,0 +1,42 @@
1
+ import { ApiHideProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+ import { IsEmail, IsOptional, IsString, MaxLength, MinLength } from 'class-validator';
3
+ import { AtLeastOneOf } from './at-least-one-of.decorator';
4
+
5
+ /** Fields the authenticated user may change on their own profile (no role change). */
6
+ export class UpdateSelfUserDto {
7
+ @ApiHideProperty()
8
+ @AtLeastOneOf(['name', 'email', 'password'])
9
+ _atLeastOne?: string;
10
+
11
+ @ApiPropertyOptional({
12
+ description: 'Full name',
13
+ example: 'Maria da Silva',
14
+ maxLength: 255,
15
+ })
16
+ @IsOptional()
17
+ @IsString()
18
+ @MinLength(1, { message: 'name cannot be empty when provided' })
19
+ @MaxLength(255)
20
+ name?: string;
21
+
22
+ @ApiPropertyOptional({
23
+ description: 'E-mail (unique per tenant)',
24
+ example: 'maria@empresa.com',
25
+ maxLength: 255,
26
+ })
27
+ @IsOptional()
28
+ @IsEmail({}, { message: 'email must be a valid e-mail' })
29
+ @MaxLength(255)
30
+ email?: string;
31
+
32
+ @ApiPropertyOptional({
33
+ description: 'New password (bcrypt-hashed on the auth service)',
34
+ example: 'senha123',
35
+ minLength: 6,
36
+ })
37
+ @IsOptional()
38
+ @IsString()
39
+ @MinLength(6, { message: 'password must be at least 6 characters' })
40
+ @MaxLength(255)
41
+ password?: string;
42
+ }
@@ -0,0 +1,61 @@
1
+ import { ApiHideProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+ import { IsEmail, IsIn, IsOptional, IsString, MaxLength, MinLength } from 'class-validator';
3
+ import { AtLeastOneOf } from './at-least-one-of.decorator';
4
+
5
+ export const ALL_USER_ROLES = [
6
+ 'administrator',
7
+ 'attendant',
8
+ 'health_professional',
9
+ ] as const;
10
+ export type AllUserRole = (typeof ALL_USER_ROLES)[number];
11
+
12
+ /** Fields an administrator may change for any user (including role). */
13
+ export class UpdateUserByAdminDto {
14
+ @ApiHideProperty()
15
+ @AtLeastOneOf(['name', 'email', 'password', 'role'])
16
+ _atLeastOne?: string;
17
+
18
+ @ApiPropertyOptional({
19
+ description: 'Full name',
20
+ example: 'Maria da Silva',
21
+ maxLength: 255,
22
+ })
23
+ @IsOptional()
24
+ @IsString()
25
+ @MinLength(1, { message: 'name cannot be empty when provided' })
26
+ @MaxLength(255)
27
+ name?: string;
28
+
29
+ @ApiPropertyOptional({
30
+ description: 'E-mail (unique per tenant)',
31
+ example: 'maria@empresa.com',
32
+ maxLength: 255,
33
+ })
34
+ @IsOptional()
35
+ @IsEmail({}, { message: 'email must be a valid e-mail' })
36
+ @MaxLength(255)
37
+ email?: string;
38
+
39
+ @ApiPropertyOptional({
40
+ description: 'New password (bcrypt-hashed on the auth service)',
41
+ example: 'senha123',
42
+ minLength: 6,
43
+ })
44
+ @IsOptional()
45
+ @IsString()
46
+ @MinLength(6, { message: 'password must be at least 6 characters' })
47
+ @MaxLength(255)
48
+ password?: string;
49
+
50
+ @ApiPropertyOptional({
51
+ description: 'User role',
52
+ enum: ALL_USER_ROLES,
53
+ example: 'attendant',
54
+ })
55
+ @IsOptional()
56
+ @IsString()
57
+ @IsIn(ALL_USER_ROLES, {
58
+ message: 'role must be administrator, attendant, or health_professional',
59
+ })
60
+ role?: AllUserRole;
61
+ }
@@ -0,0 +1,30 @@
1
+ import { ApiProperty } from '@nestjs/swagger';
2
+
3
+ /** User payload returned after create or update (no password). */
4
+ export class UpdatedUserDto {
5
+ @ApiProperty({
6
+ format: 'uuid',
7
+ description: 'User identifier',
8
+ example: '550e8400-e29b-41d4-a716-446655440000',
9
+ })
10
+ userId: string;
11
+
12
+ @ApiProperty({ description: 'Full name', example: 'Maria da Silva' })
13
+ name: string;
14
+
15
+ @ApiProperty({ description: 'E-mail (unique per tenant)', example: 'maria@empresa.com' })
16
+ email: string;
17
+
18
+ @ApiProperty({
19
+ description: 'User role',
20
+ enum: ['administrator', 'attendant', 'health_professional'],
21
+ example: 'attendant',
22
+ })
23
+ role: 'administrator' | 'attendant' | 'health_professional';
24
+
25
+ @ApiProperty({ description: 'Creation timestamp' })
26
+ createdAt: Date;
27
+
28
+ @ApiProperty({ description: 'Last update timestamp' })
29
+ updatedAt: Date;
30
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Kafka payload for auth.update_self (tychat-api → tychat-auth-service).
3
+ */
4
+ export interface AuthUpdateSelfPayload {
5
+ tenant?: string;
6
+ userId: string;
7
+ name?: string;
8
+ email?: string;
9
+ password?: string;
10
+ }
11
+
12
+ /**
13
+ * Kafka payload for auth.update_user_admin (tychat-api → tychat-auth-service).
14
+ * actorRole must be "administrator" or the handler rejects the request.
15
+ */
16
+ export interface AuthUpdateUserAdminPayload {
17
+ tenant?: string;
18
+ actorRole: string;
19
+ targetUserId: string;
20
+ name?: string;
21
+ email?: string;
22
+ password?: string;
23
+ role?: 'administrator' | 'attendant' | 'health_professional';
24
+ }