Skip to main content
JS Mini Hotel implements comprehensive validation to ensure data integrity and prevent invalid reservations. All validation logic is located in ~/workspace/source/utils/validation.js.

Date Validation

Date validation ensures that reservations have valid check-in and check-out dates according to business rules.

Check-in Date Rules

checkIn
string
required
Must be today or a future date (cannot be in the past)
Implementation: validation.js:16-19
export function isDateTodayOrFuture(checkIn) {
  const now = Temporal.Now.plainDateISO()
  return Temporal.PlainDate.compare(now, checkIn) <= 0
}
The system uses the Temporal API for date handling, which provides more accurate date comparisons than traditional Date objects.

Check-out Date Rules

checkOut
string
required
Must be after the check-in date
Implementation: validation.js:56-58
export function isEndDateOnOrAfterStartDate(checkIn, checkOut) {
  return Temporal.PlainDate.compare(checkIn, checkOut) <= 0
}
If check-out is the same as check-in, the reservation will be valid but represent a 0-night stay. The system requires at least 1 night, so check-out must be strictly after check-in.

Date Range Validation

Implementation: validation.js:6-11
export function isValidDateRange(checkIn, checkOut) {
  return (
    isDateTodayOrFuture(checkIn) &&
    isEndDateOnOrAfterStartDate(checkIn, checkOut)
  )
}
This function combines both validations:
  1. Check-in is not in the past
  2. Check-out is after check-in

Night Limit Validation

nights
number
required
Must be between 1 and 14 nights
Implementation: validation.js:92-95
if (getNumberOfNights(checkIn, checkOut) > 14) {
  validation.status = false
  validation.message = 'Solo se puede reservar hasta 14 noches.'
}
ConditionError Message
Check-in in the past”El rango de fechas no es válido.”
Check-out before check-in”El rango de fechas no es válido.”
More than 14 nights”Solo se puede reservar hasta 14 noches.”

Guest Data Validation

All guest information must pass validation before a reservation can be created. Guest data is validated using regex patterns.

Email Validation

guest.email
string
required
Must match standard email format
Regex Pattern: validation.js:116
const pattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
Pattern Breakdown:
  • ^[a-zA-Z0-9._-]+ - Starts with alphanumeric characters, dots, underscores, or hyphens
  • @ - Required @ symbol
  • [a-zA-Z0-9.-]+ - Domain name with alphanumeric, dots, or hyphens
  • \. - Required dot before TLD
  • [a-zA-Z]{2,}$ - Top-level domain (minimum 2 letters)
Valid examples: Invalid examples:
  • invalid.email (missing @)
  • @domain.com (missing local part)
  • user@domain (missing TLD)

DNI Validation

guest.dni
string
required
Must match Spanish DNI format (1-8 digits followed by a letter)
Regex Pattern: validation.js:122
const pattern = /^\d{1,8}[A-Za-z]$/
Pattern Breakdown:
  • ^\d{1,8} - Starts with 1 to 8 digits
  • [A-Za-z]$ - Ends with a single letter (uppercase or lowercase)
Valid examples:
  • 12345678A
  • 1234567B
  • 87654321b (lowercase accepted)
Invalid examples:
  • 123456789A (too many digits)
  • 12345678 (missing letter)
  • A12345678 (letter at wrong position)
The DNI validation only checks the format, not the validity of the check letter. A full DNI validation would verify that the letter matches the DNI number using the modulo-23 algorithm.

Phone Validation

guest.phone
string
required
Must match international or national phone format
Regex Pattern: validation.js:127
const pattern = /^(\+?\d{1,3})?[\s.-]?\d{9}$/
Pattern Breakdown:
  • ^(\+?\d{1,3})? - Optional country code (+ followed by 1-3 digits)
  • [\s.-]? - Optional separator (space, dot, or hyphen)
  • \d{9}$ - Exactly 9 digits for the phone number
Valid examples:
  • +34 612345678
  • 612345678
  • +1.555123456 (note: this passes but may not be a valid US format)
  • +34-612345678
Invalid examples:
  • +34 12345 (not enough digits)
  • 12345678 (only 8 digits)
  • ++34 612345678 (double plus sign)
The phone validation is permissive and accepts various formats. It validates the structure but not whether the phone number is actually valid for a specific country.

Guest Validation Function

Implementation: validation.js:107-113
function validateGuest(guest) {
  if (!isValidEmail(guest.email)) return false
  if (!isValidDNI(guest.dni)) return false
  if (!isValidPhone(guest.phone)) return false

  return true
}
All three fields must pass validation for the guest data to be accepted.
If any guest field is invalid, the reservation validation returns:
{
  status: false,
  message: 'Los datos del huesped no son válidos'
}

Room Availability Validation

Before creating a reservation, the system validates that the requested room exists and is available.

Room Existence

roomNumber
number
required
Room number must exist in the hotel’s room inventory
Implementation: validation.js:75-80
const isRoom = getRoomByNumber(hotel, roomNumber)

if (!isRoom) {
  validation.status = false
  validation.message = `La habitación número ${roomNumber} no existe.`
}

Room Availability

availability
boolean
required
Room must not have conflicting reservations for the requested dates
Implementation: validation.js:82-87
const isAvailable = isRoomAvailable(hotel, checkIn, checkOut, roomNumber)

if (!isAvailable) {
  validation.status = false
  validation.message = `La habitación número ${roomNumber} está reservada para esas fechas.`
}
A room is considered unavailable if there’s any reservation that overlaps with the requested dates, regardless of reservation status (confirmed, checked-in, or occupied).

Date Range Overlap

The availability check determines if two date ranges overlap: Overlap occurs when:
  • Existing reservation’s check-in falls within the requested dates, OR
  • Existing reservation’s check-out falls within the requested dates, OR
  • Requested dates fall entirely within an existing reservation
No overlap when:
  • Requested check-in equals existing check-out (same-day turnover allowed)
  • Requested check-out equals existing check-in (same-day turnover allowed)

Complete Reservation Validation

The validateReservation() function performs all validations before creating a reservation. Implementation: validation.js:63-102
export function validateReservation(
  hotel,
  roomNumber,
  guestData,
  checkIn,
  checkOut,
) {
  const validation = {
    status: true,
    message: '',
  }

  const isRoom = getRoomByNumber(hotel, roomNumber)
  if (!isRoom) {
    validation.status = false
    validation.message = `La habitación número ${roomNumber} no existe.`
  }

  const isAvailable = isRoomAvailable(hotel, checkIn, checkOut, roomNumber)
  if (!isAvailable) {
    validation.status = false
    validation.message = `La habitación número ${roomNumber} está reservada para esas fechas.`
  }
  
  if (!isValidDateRange(checkIn, checkOut)) {
    validation.status = false
    validation.message = 'El rango de fechas no es válido.'
  }
  
  if (getNumberOfNights(checkIn, checkOut) > 14) {
    validation.status = false
    validation.message = 'Solo se puede reservar hasta 14 noches.'
  }
  
  if (!validateGuest(guestData)) {
    validation.status = false
    validation.message = 'Los datos del huesped no son válidos'
  }

  return validation
}

Validation Order

Validations are performed in this sequence:
  1. Room existence - Check if room number is valid
  2. Room availability - Check if room is free for the dates
  3. Date range - Check if dates are valid (not in past, check-out after check-in)
  4. Night limit - Check if stay is between 1-14 nights
  5. Guest data - Validate email, DNI, and phone
The validation function returns on the first error encountered. If multiple validations fail, only the first error message is returned.

Validation Response

The function returns an object with validation status:
{
  status: true,   // or false if validation failed
  message: ''     // error message if status is false
}
Success response:
{ status: true, message: '' }
Error response examples:
{ status: false, message: 'La habitación número 999 no existe.' }
{ status: false, message: 'La habitación número 101 está reservada para esas fechas.' }
{ status: false, message: 'El rango de fechas no es válido.' }
{ status: false, message: 'Solo se puede reservar hasta 14 noches.' }
{ status: false, message: 'Los datos del huesped no son válidos' }
CategoryRuleError Message
RoomRoom must exist”La habitación número no existe.”
RoomRoom must be available”La habitación número está reservada para esas fechas.”
DatesCheck-in not in past”El rango de fechas no es válido.”
DatesCheck-out after check-in”El rango de fechas no es válido.”
DatesMaximum 14 nights”Solo se puede reservar hasta 14 noches.”
GuestValid email format”Los datos del huesped no son válidos”
GuestValid DNI format”Los datos del huesped no son válidos”
GuestValid phone format”Los datos del huesped no son válidos”

Build docs developers (and LLMs) love