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, @Param('date') date_param: string,
@Body() payload: UpsertShiftDto, @Body() payload: UpsertShiftDto,
) { ) {
const email = decodeURIComponent(email_param); return this.shiftsCommandService.upsertShfitsByDate(email_param, date_param, payload);
const date = date_param;
return this.shiftsCommandService.upsertShfitsByDate(email, date, payload);
} }
@Post() @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 const COMMENT_MAX_LENGTH = 512;
export class ShiftPayloadDto { 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; 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; end_time!: string;
@IsString() @IsString()
@ -24,6 +25,13 @@ export class ShiftPayloadDto {
export class UpsertShiftDto { export class UpsertShiftDto {
@IsOptional()
@ValidateNested()
@Type(()=> ShiftPayloadDto)
old_shift?: ShiftPayloadDto; old_shift?: ShiftPayloadDto;
@IsOptional()
@ValidateNested()
@Type(()=> ShiftPayloadDto)
new_shift?: 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 { Prisma, Shifts } from "@prisma/client";
import { BaseApprovalService } from "src/common/shared/base-approval.service"; import { BaseApprovalService } from "src/common/shared/base-approval.service";
import { PrismaService } from "src/prisma/prisma.service"; import { PrismaService } from "src/prisma/prisma.service";
@ -22,6 +22,8 @@ export class ShiftsCommandService extends BaseApprovalService<Shifts> {
//create/update/delete master method //create/update/delete master method
async upsertShfitsByDate(email:string, date_string: string, dto: UpsertShiftDto): async upsertShfitsByDate(email:string, date_string: string, dto: UpsertShiftDto):
Promise<{ action: UpsertAction; day: DayShiftResponse[] }> { Promise<{ action: UpsertAction; day: DayShiftResponse[] }> {
const { old_shift, new_shift } = dto;
if(!dto.old_shift && !dto.new_shift) { if(!dto.old_shift && !dto.new_shift) {
throw new BadRequestException('At least one of old or new shift must be provided'); 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 // DELETE
if ( dto.old_shift && !dto.new_shift ) { if ( old_shift && !new_shift ) {
const existing = await find_exact_old_shift(); const existing = await find_exact_old_shift();
if(!existing) { if(!existing) {
throw new NotFoundException({ throw new NotFoundException({
@ -157,7 +159,7 @@ async upsertShfitsByDate(email:string, date_string: string, dto: UpsertShiftDto)
action = 'deleted'; action = 'deleted';
} }
// CREATE // CREATE
else if (!dto.old_shift && dto.new_shift) { else if (!old_shift && new_shift) {
assert_no_overlap(); assert_no_overlap();
await transaction.shifts.create({ await transaction.shifts.create({
data: { data: {
@ -173,7 +175,7 @@ async upsertShfitsByDate(email:string, date_string: string, dto: UpsertShiftDto)
action = 'created'; action = 'created';
} }
//UPDATE //UPDATE
else { else if (old_shift && new_shift){
const existing = await find_exact_old_shift(); const existing = await find_exact_old_shift();
if(!existing) { if(!existing) {
throw new NotFoundException({ throw new NotFoundException({
@ -195,6 +197,8 @@ async upsertShfitsByDate(email:string, date_string: string, dto: UpsertShiftDto)
}, },
}); });
action = 'updated'; action = 'updated';
} else {
throw new BadRequestException('At least one of old_shift or new_shift must be provided');
} }
//Reload the day (truth source) //Reload the day (truth source)