From b93102d075cbdd57e98fe9366015f8a7d82a23bc Mon Sep 17 00:00:00 2001 From: Charles Pizzato <311327716+modernitconsultants@users.noreply.github.com> Date: Thu, 13 Aug 2026 10:49:37 +1000 Subject: [PATCH] fix(rate-plans): the update DTO never allowed deactivation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UpdateRatePlanDto is a partial of the create DTO, and the create DTO never carried isActive (a schema default) — so the API has no way to retire a rate plan. PATCH {"isActive": false} answers 400 "property isActive should not exist", and the only lever left is validTo, which expires a plan but leaves it active in every isActive-filtered list. isActive joins the UPDATE DTO only: plans are created active, and retiring one is an explicit later act. --- .../rate-plan/dto/update-rate-plan.dto.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/apps/api/src/modules/rate-plan/dto/update-rate-plan.dto.ts b/apps/api/src/modules/rate-plan/dto/update-rate-plan.dto.ts index 17193c75..0e8d48b5 100644 --- a/apps/api/src/modules/rate-plan/dto/update-rate-plan.dto.ts +++ b/apps/api/src/modules/rate-plan/dto/update-rate-plan.dto.ts @@ -1,6 +1,19 @@ -import { PartialType, OmitType } from '@nestjs/swagger'; +import { PartialType, OmitType, ApiPropertyOptional } from '@nestjs/swagger'; +import { IsBoolean, IsOptional } from 'class-validator'; import { CreateRatePlanDto } from './create-rate-plan.dto'; export class UpdateRatePlanDto extends PartialType( OmitType(CreateRatePlanDto, ['propertyId', 'roomTypeId'] as const), -) {} +) { + /** + * Deactivation. The create DTO never carried isActive (it is a schema + * default), which left the API with NO way to retire a rate plan — the only + * lever was validTo, which expires a plan but keeps it active in every + * isActive-filtered list. Deliberately update-only: plans are created + * active, and retiring one is an explicit later act. + */ + @ApiPropertyOptional({ description: 'Set false to deactivate the plan' }) + @IsOptional() + @IsBoolean() + isActive?: boolean; +}