import { IsOptional, IsString, IsInt, Min, Max, IsArray, IsEnum } from "class-validator"; import { Type, Transform } from "class-transformer"; import { EntryStatus } from "@prisma/client"; /** * DTO for full-text search query parameters */ export class SearchQueryDto { @IsString({ message: "q (query) must be a string" }) q!: string; @IsOptional() @IsEnum(EntryStatus, { message: "status must be a valid EntryStatus" }) status?: EntryStatus; @IsOptional() @Type(() => Number) @IsInt({ message: "page must be an integer" }) @Min(1, { message: "page must be at least 1" }) page?: number; @IsOptional() @Type(() => Number) @IsInt({ message: "limit must be an integer" }) @Min(1, { message: "limit must be at least 1" }) @Max(100, { message: "limit must not exceed 100" }) limit?: number; } /** * DTO for searching by tags */ export class TagSearchDto { @Transform(({ value }) => (typeof value === "string" ? value.split(",") : (value as string[]))) @IsArray({ message: "tags must be an array" }) @IsString({ each: true, message: "each tag must be a string" }) tags!: string[]; @IsOptional() @IsEnum(EntryStatus, { message: "status must be a valid EntryStatus" }) status?: EntryStatus; @IsOptional() @Type(() => Number) @IsInt({ message: "page must be an integer" }) @Min(1, { message: "page must be at least 1" }) page?: number; @IsOptional() @Type(() => Number) @IsInt({ message: "limit must be an integer" }) @Min(1, { message: "limit must be at least 1" }) @Max(100, { message: "limit must not exceed 100" }) limit?: number; } /** * DTO for recent entries query */ export class RecentEntriesDto { @IsOptional() @Type(() => Number) @IsInt({ message: "limit must be an integer" }) @Min(1, { message: "limit must be at least 1" }) @Max(50, { message: "limit must not exceed 50" }) limit?: number; @IsOptional() @IsEnum(EntryStatus, { message: "status must be a valid EntryStatus" }) status?: EntryStatus; }