From a14405a99820d1740a1ad9e939cbc76e09579b20 Mon Sep 17 00:00:00 2001 From: counterweight Date: Sun, 21 Dec 2025 17:53:35 +0100 Subject: [PATCH] Derive slot validation from config instead of hardcoded values - Created _get_valid_minute_boundaries() helper that derives valid minutes from SLOT_DURATION_MINUTES - Replaced hardcoded (0, 15, 30, 45) with dynamic calculation - Error message now includes valid minute values for better clarity --- backend/routes/booking.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/backend/routes/booking.py b/backend/routes/booking.py index 6d39eea..a17df64 100644 --- a/backend/routes/booking.py +++ b/backend/routes/booking.py @@ -46,6 +46,19 @@ def _to_appointment_response( ) +def _get_valid_minute_boundaries() -> tuple[int, ...]: + """Get valid minute boundaries based on SLOT_DURATION_MINUTES. + + Assumes SLOT_DURATION_MINUTES divides 60 evenly (e.g., 15 minutes = 0, 15, 30, 45). + """ + boundaries: list[int] = [] + minute = 0 + while minute < 60: + boundaries.append(minute) + minute += SLOT_DURATION_MINUTES + return tuple(boundaries) + + def _get_bookable_date_range() -> tuple[date, date]: """Get the valid date range for booking (tomorrow to +30 days).""" today = date.today() @@ -148,11 +161,12 @@ async def create_booking( slot_date = request.slot_start.date() _validate_booking_date(slot_date) - # Validate slot is on 15-minute boundary - if request.slot_start.minute not in (0, 15, 30, 45): + # Validate slot is on the correct minute boundary (derived from SLOT_DURATION_MINUTES) + valid_minutes = _get_valid_minute_boundaries() + if request.slot_start.minute not in valid_minutes: raise HTTPException( status_code=400, - detail="Slot start time must be on 15-minute boundary", + detail=f"Slot start time must be on {SLOT_DURATION_MINUTES}-minute boundary (valid minutes: {valid_minutes})", ) if request.slot_start.second != 0 or request.slot_start.microsecond != 0: raise HTTPException(