From c4aeaa2c4508a6fe17e18b1b908a133e65eedfe3 Mon Sep 17 00:00:00 2001 From: Suman991 Date: Fri, 10 Apr 2026 11:20:41 +0530 Subject: [PATCH] added filter by isDeleted --- src/form/dto/query-form.dto.ts | 9 ++++++++- src/form/helpers/form-query.builder.ts | 18 ++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/form/dto/query-form.dto.ts b/src/form/dto/query-form.dto.ts index 12fec3f..05145fa 100644 --- a/src/form/dto/query-form.dto.ts +++ b/src/form/dto/query-form.dto.ts @@ -1,6 +1,6 @@ import { ApiPropertyOptional } from '@nestjs/swagger'; import { Type } from 'class-transformer'; -import { IsEnum, IsInt, IsOptional, IsString, Max, Min } from 'class-validator'; +import { IsBoolean, IsEnum, IsInt, IsOptional, IsString, Max, MaxLength, Min } from 'class-validator'; export enum SortOrder { ASC = 'asc', @@ -33,8 +33,15 @@ export class QueryFormDto { @ApiPropertyOptional({ example: '' }) @IsString() @IsOptional() + @MaxLength(100) search?: string; + @ApiPropertyOptional({ example: false, description: 'true = deleted only, false = active only, omit = all' }) + @Type(() => Boolean) + @IsBoolean() + @IsOptional() + isDeleted?: boolean; + @ApiPropertyOptional({ enum: SortBy, example: SortBy.CREATED_AT }) @IsEnum(SortBy) @IsOptional() diff --git a/src/form/helpers/form-query.builder.ts b/src/form/helpers/form-query.builder.ts index ab8eeec..ff395de 100644 --- a/src/form/helpers/form-query.builder.ts +++ b/src/form/helpers/form-query.builder.ts @@ -1,12 +1,26 @@ import { QueryFormDto, SortOrder } from '../dto/query-form.dto'; export class FormQueryBuilder { - // Build filter + private static escapeRegex(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // escapes: . * + ? ^ $ { } ( ) | [ ] \ + } + static buildFilter(query: QueryFormDto): Record { const filter: Record = {}; + + // text serach if (query.search) { - filter.name = { $regex: query.search, $options: 'i' }; + const sanitized = this.escapeRegex(query.search.trim()); // trim + escape + filter.name = { $regex: sanitized, $options: 'i' }; } + + // soft delete search + if (query.isDeleted === true) { + filter.deletedAt = { $ne: null }; + } else if (query.isDeleted === false) { + filter.deletedAt = null; + } + return filter; }