feat(shifts): ajusted validations for create/update/delete shifts

This commit is contained in:
Matthieu Haineault 2025-09-16 09:17:59 -04:00
parent f9931f99c8
commit cc48584b99
3 changed files with 20 additions and 10 deletions

View File

@ -28,9 +28,7 @@ export class ShiftsController {
@Param('date') date_param: string,
@Body() payload: UpsertShiftDto,
) {
const email = decodeURIComponent(email_param);
const date = date_param;
return this.shiftsCommandService.upsertShfitsByDate(email, date, payload);
return this.shiftsCommandService.upsertShfitsByDate(email_param, date_param, payload);
}
@Post()

View File

@ -1,13 +1,14 @@
import { IsBoolean, IsOptional, IsString, Matches, MaxLength } from "class-validator";
import { Type } from "class-transformer";
import { IsBoolean, IsOptional, IsString, Matches, MaxLength, ValidateNested } from "class-validator";
export const COMMENT_MAX_LENGTH = 512;
export class ShiftPayloadDto {
@Matches(/^\d{2}:\d{2}$/, {message: 'start_time must be HH:mm' })
@Matches(/^([01]\d|2[0-3]):([0-5]\d)$/)
start_time!: string;
@Matches(/^\d{2}:\d{2}$/, {message: 'start_time must be HH:mm' })
@Matches(/^([01]\d|2[0-3]):([0-5]\d)$/)
end_time!: string;
@IsString()
@ -24,6 +25,13 @@ export class ShiftPayloadDto {
export class UpsertShiftDto {
@IsOptional()
@ValidateNested()
@Type(()=> ShiftPayloadDto)
old_shift?: ShiftPayloadDto;
@IsOptional()
@ValidateNested()
@Type(()=> ShiftPayloadDto)
new_shift?: ShiftPayloadDto;
};

View File

@ -1,4 +1,4 @@
import { BadRequestException, ConflictException, Injectable, NotFoundException, ParseUUIDPipe, UnprocessableEntityException } from "@nestjs/common";
import { BadRequestException, ConflictException, Injectable, NotFoundException, UnprocessableEntityException } from "@nestjs/common";
import { Prisma, Shifts } from "@prisma/client";
import { BaseApprovalService } from "src/common/shared/base-approval.service";
import { PrismaService } from "src/prisma/prisma.service";
@ -22,6 +22,8 @@ export class ShiftsCommandService extends BaseApprovalService<Shifts> {
//create/update/delete master method
async upsertShfitsByDate(email:string, date_string: string, dto: UpsertShiftDto):
Promise<{ action: UpsertAction; day: DayShiftResponse[] }> {
const { old_shift, new_shift } = dto;
if(!dto.old_shift && !dto.new_shift) {
throw new BadRequestException('At least one of old or new shift must be provided');
}
@ -145,7 +147,7 @@ async upsertShfitsByDate(email:string, date_string: string, dto: UpsertShiftDto)
};
// DELETE
if ( dto.old_shift && !dto.new_shift ) {
if ( old_shift && !new_shift ) {
const existing = await find_exact_old_shift();
if(!existing) {
throw new NotFoundException({
@ -157,7 +159,7 @@ async upsertShfitsByDate(email:string, date_string: string, dto: UpsertShiftDto)
action = 'deleted';
}
// CREATE
else if (!dto.old_shift && dto.new_shift) {
else if (!old_shift && new_shift) {
assert_no_overlap();
await transaction.shifts.create({
data: {
@ -173,7 +175,7 @@ async upsertShfitsByDate(email:string, date_string: string, dto: UpsertShiftDto)
action = 'created';
}
//UPDATE
else {
else if (old_shift && new_shift){
const existing = await find_exact_old_shift();
if(!existing) {
throw new NotFoundException({
@ -195,6 +197,8 @@ async upsertShfitsByDate(email:string, date_string: string, dto: UpsertShiftDto)
},
});
action = 'updated';
} else {
throw new BadRequestException('At least one of old_shift or new_shift must be provided');
}
//Reload the day (truth source)