Files
trackgo-be/src/modules/configuration/employees/dto/employee.dto.ts
T
shancheas 8a61c94078 Add user and employee management enhancements with database schema updates
- Introduced new columns `status`, `created_by`, and `updated_by` in the `users` table to track user status and ownership.
- Updated the `employees` table to include a foreign key reference to the `users` table via `user_id`.
- Created migration script `0012_users_primary.sql` to apply these changes to the database schema.
- Enhanced the `EmployeesService` and `EmployeesRepository` to support user assignments and related data retrieval.
- Updated DTOs and service methods to reflect the new user and employee relationships.
- Added unit tests to validate the new functionality and ensure data integrity.
- Modified existing controllers to accommodate the new fields and relationships in user and employee management.
2026-08-26 15:29:18 +07:00

206 lines
4.4 KiB
TypeScript

import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
ArrayNotEmpty,
IsArray,
IsIn,
IsNotEmpty,
IsOptional,
IsString,
IsUUID,
Matches,
MaxLength,
ValidateIf,
} from 'class-validator';
import {
PaginationQueryDto,
UserRelationDto,
} from '../../../../common/http/response';
import { CORE_STATUSES } from '../../../../common/value-objects/status/status';
import {
EMPLOYEE_CODE_MAX_LENGTH,
EMPLOYEE_CODE_PATTERN,
EMPLOYEE_NAME_MAX_LENGTH,
EMPLOYEE_NAME_PATTERN,
EMPLOYEE_POSITIONS,
} from '../employee-fields';
export class CreateEmployeeDto {
@ApiProperty({ example: 'EMP_01', maxLength: EMPLOYEE_CODE_MAX_LENGTH })
@IsString()
@IsNotEmpty()
@MaxLength(EMPLOYEE_CODE_MAX_LENGTH)
@Matches(EMPLOYEE_CODE_PATTERN, {
message: 'code must contain only letters, numbers, and underscores',
})
code!: string;
@ApiProperty({
example: 'Ada Lovelace',
maxLength: EMPLOYEE_NAME_MAX_LENGTH,
})
@IsString()
@IsNotEmpty()
@MaxLength(EMPLOYEE_NAME_MAX_LENGTH)
@Matches(EMPLOYEE_NAME_PATTERN, {
message: 'name must contain only letters and spaces',
})
name!: string;
@ApiProperty({ example: '+6281234567890' })
@IsString()
@IsNotEmpty()
phone!: string;
@ApiProperty({ enum: EMPLOYEE_POSITIONS, example: 'sales' })
@IsIn([...EMPLOYEE_POSITIONS])
position!: string;
@ApiPropertyOptional({ enum: CORE_STATUSES })
@IsOptional()
@IsIn([...CORE_STATUSES])
status?: string;
@ApiPropertyOptional({ format: 'uuid' })
@IsOptional()
@IsUUID('4')
userId?: string;
}
export class UpdateEmployeeDto {
@ApiPropertyOptional({ example: 'EMP_01' })
@IsOptional()
@IsString()
@IsNotEmpty()
@MaxLength(EMPLOYEE_CODE_MAX_LENGTH)
@Matches(EMPLOYEE_CODE_PATTERN, {
message: 'code must contain only letters, numbers, and underscores',
})
code?: string;
@ApiPropertyOptional({ example: 'Ada Lovelace' })
@IsOptional()
@IsString()
@IsNotEmpty()
@MaxLength(EMPLOYEE_NAME_MAX_LENGTH)
@Matches(EMPLOYEE_NAME_PATTERN, {
message: 'name must contain only letters and spaces',
})
name?: string;
@ApiPropertyOptional({ example: '+6281234567890' })
@IsOptional()
@IsString()
@IsNotEmpty()
phone?: string;
@ApiPropertyOptional({ enum: EMPLOYEE_POSITIONS })
@IsOptional()
@IsIn([...EMPLOYEE_POSITIONS])
position?: string;
@ApiPropertyOptional({ format: 'uuid', nullable: true })
@ValidateIf((_, value) => value !== undefined)
@IsUUID('4')
userId?: string | null;
}
export class UpdateEmployeeStatusDto {
@ApiProperty({ enum: CORE_STATUSES })
@IsIn([...CORE_STATUSES])
status!: string;
}
export class BulkIdsDto {
@ApiProperty({ type: [String], format: 'uuid' })
@IsArray()
@ArrayNotEmpty()
@IsUUID('4', { each: true })
ids!: string[];
}
export class BulkStatusDto {
@ApiProperty({ type: [String], format: 'uuid' })
@IsArray()
@ArrayNotEmpty()
@IsUUID('4', { each: true })
ids!: string[];
@ApiProperty({ enum: CORE_STATUSES })
@IsIn([...CORE_STATUSES])
status!: string;
}
export class ListEmployeesQueryDto extends PaginationQueryDto {
@ApiPropertyOptional()
@IsOptional()
@IsString()
code?: string;
@ApiPropertyOptional()
@IsOptional()
@IsString()
name?: string;
@ApiPropertyOptional()
@IsOptional()
@IsString()
phone?: string;
@ApiPropertyOptional({ enum: EMPLOYEE_POSITIONS })
@IsOptional()
@IsIn([...EMPLOYEE_POSITIONS])
position?: string;
@ApiPropertyOptional({ enum: CORE_STATUSES })
@IsOptional()
@IsIn([...CORE_STATUSES])
status?: string;
@ApiPropertyOptional({ format: 'uuid' })
@IsOptional()
@IsUUID('4')
userId?: string;
@ApiPropertyOptional({
description: 'Case-insensitive match on code or name',
})
@IsOptional()
@IsString()
search?: string;
}
export class EmployeeDto {
@ApiProperty({ format: 'uuid' })
id!: string;
@ApiProperty()
code!: string;
@ApiProperty()
name!: string;
@ApiProperty({ example: '+6281234567890' })
phone!: string;
@ApiProperty({ enum: EMPLOYEE_POSITIONS })
position!: string;
@ApiProperty({ enum: CORE_STATUSES })
status!: string;
@ApiProperty({ description: 'Unix ms' })
createdAt!: number;
@ApiProperty({ description: 'Unix ms' })
updatedAt!: number;
@ApiProperty({ format: 'uuid' })
createdBy!: string;
@ApiProperty({ format: 'uuid' })
updatedBy!: string;
@ApiPropertyOptional({ type: UserRelationDto, nullable: true })
user!: UserRelationDto | null;
}