Files
dyolink/backend/src/modules/tasks/dto/tasks.dto.ts

221 lines
4.3 KiB
TypeScript

import {
IsBoolean,
IsDateString,
IsEnum,
IsIn,
IsInt,
IsOptional,
IsString,
IsUUID,
Max,
Min,
} from 'class-validator';
import { Transform } from 'class-transformer';
import { LabTaskStatus, LabCaseOrigin } from '@prisma/client';
const toBoolean = ({ value }: { value: unknown }) => {
if (typeof value === 'boolean') return value;
if (value === 'true' || value === '1') return true;
if (value === 'false' || value === '0') return false;
return value;
};
export class UpdateLabTaskDto {
@IsEnum(LabTaskStatus)
status: LabTaskStatus;
}
export type TaskSortField =
| 'date'
| 'status'
| 'clinic'
| 'patient'
| 'important'
| 'prosthesis'
| 'taskType'
| 'dueDate';
export class ListLabTasksDto {
@IsOptional()
@IsString()
q?: string;
@IsOptional()
@IsUUID()
clinicOrganizationId?: string;
@IsOptional()
@IsEnum(LabTaskStatus)
status?: LabTaskStatus;
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
completed?: boolean;
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
important?: boolean;
/** When true, important lab cases are listed before others (does not hide non-important). */
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
pinImportant?: boolean;
@IsOptional()
@IsDateString()
sentFrom?: string;
@IsOptional()
@IsDateString()
sentTo?: string;
/** Workflow step code (e.g. design) completed within the prosthesis group. */
@IsOptional()
@IsString()
stepCompleted?: string;
/** Narrow list to a single lab case (e.g. show-in-case navigation). */
@IsOptional()
@IsUUID()
labCaseId?: string;
/** When true, only tasks assigned to the current user. */
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
assignedToMe?: boolean;
/** Past due date with at least one in-progress task on the case. */
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
overdue?: boolean;
/** When true, only tasks with no assignee. */
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
unassignedOnly?: boolean;
/** Narrow list to a single prosthesis type code. */
@IsOptional()
@IsString()
prosthesisTypeCode?: string;
/** CLINIC_DISPATCH = received from clinic; LAB_INTERNAL = generated in the lab. */
@IsOptional()
@IsEnum(LabCaseOrigin)
origin?: LabCaseOrigin;
@IsOptional()
@IsIn(['date', 'status', 'clinic', 'patient', 'important', 'prosthesis', 'taskType', 'dueDate'])
sortBy?: TaskSortField;
@IsOptional()
@IsIn(['asc', 'desc'])
sortDir?: 'asc' | 'desc';
@IsOptional()
@Transform(({ value }) => Number(value))
@IsInt()
@Min(1)
page = 1;
@IsOptional()
@Transform(({ value }) => Number(value))
@IsInt()
@Min(1)
@Max(100)
limit = 50;
}
/** Same filters as list (no page) — used to find which page contains a task. */
export class LocateTaskPageDto {
@IsUUID()
taskId: string;
@IsOptional()
@IsString()
q?: string;
@IsOptional()
@IsUUID()
clinicOrganizationId?: string;
@IsOptional()
@IsEnum(LabTaskStatus)
status?: LabTaskStatus;
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
completed?: boolean;
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
important?: boolean;
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
pinImportant?: boolean;
@IsOptional()
@IsDateString()
sentFrom?: string;
@IsOptional()
@IsDateString()
sentTo?: string;
@IsOptional()
@IsString()
stepCompleted?: string;
/** When true, only tasks assigned to the current user. */
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
assignedToMe?: boolean;
/** Past due date with at least one in-progress task on the case. */
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
overdue?: boolean;
/** When true, only tasks with no assignee. */
@IsOptional()
@Transform(toBoolean)
@IsBoolean()
unassignedOnly?: boolean;
/** Narrow list to a single prosthesis type code. */
@IsOptional()
@IsString()
prosthesisTypeCode?: string;
@IsOptional()
@IsEnum(LabCaseOrigin)
origin?: LabCaseOrigin;
@IsOptional()
@IsIn(['date', 'status', 'clinic', 'patient', 'important', 'prosthesis', 'taskType', 'dueDate'])
sortBy?: TaskSortField;
@IsOptional()
@IsIn(['asc', 'desc'])
sortDir?: 'asc' | 'desc';
@IsOptional()
@Transform(({ value }) => Number(value))
@IsInt()
@Min(1)
@Max(100)
limit = 50;
}