Bugnik
← All problems

22Dock Appointment Booking API

Java · Spring BootEasyBug fixSuggested time: 60 min

Dock appointment booking REST API (door choice, half-open slots, validation)

Sign in to start

Before you start

You'll get more out of this problem if you're comfortable with:

Language

  • Java switch expressions over enums
  • Records, streams and Comparator.comparing

Libraries and frameworks

  • Spring Boot controllers and Bean Validation (@Valid, @NotBlank, @Min, @Max)

Build and test tools

  • Reading javac errors in the Maven output
  • Reading JUnit 5 / MockMvc test failures

Reasoning

  • Half-open time intervals: when do two bookings overlap?

Background

The Inbound Yard team at a large online retailer lets carriers book a dock door before their trucks arrive. The booking service picks a door, blocks it for as long as unloading takes, and shows the yard the day's schedule. Since the last release, trucks that arrive right after another one are sent to a different door even though theirs is free, and bookings with nonsense data (no carrier, zero pallets) are accepted.

How the system works

Doors

The yard has doors 1–4 (DRY) and 5–6 (REEFER, with power for refrigerated trailers). GET /api/doors lists them, lowest number first.

Times and length

  • Start times are HH:MM on a half hour (:00 or :30), from 00:00 to 23:30. Anything else is INVALID_TIME.
  • Unloading takes one 30-minute slot per started 10 pallets: 1–10 pallets → 30 min, 11–20 → 60 min, ..., 31–40 → 120 min.
  • A booking covers the half-open interval [start, end). Two bookings on the same door overlap only if they share a minute: one ending at 09:00 and another starting at 09:00 don't overlap, so they can use the same door.
  • The yard is open 06:00–22:00: a booking must start at 06:00 or later and end at 22:00 or earlier (OUTSIDE_HOURS otherwise).

Choosing a door

  • Refrigerated loads need a REEFER door; dry loads use DRY doors only (reefer doors are kept free for cold loads).
  • With a requested door: it must exist (404 NOT_FOUND), be the right type (409 WRONG_DOOR_TYPE) and be free for the whole booking on that day (409 DOOR_TAKEN).
  • Without one: the yard picks the lowest-numbered door of the right type that's free for the whole booking; if there's none, 409 NO_DOOR_AVAILABLE.
  • Bookings on other days never block each other.

API

Method and pathBody / parametersSuccess
POST /api/appointments{carrier, date, start, pallets, refrigerated, door}201 appointment
GET /api/appointments?date=YYYY-MM-DD200 the day's appointments, by start time then door
DELETE /api/appointments/{id}204
GET /api/doors200 doors
  • carrier must not be blank, date and start are required, pallets is 1 to 40, refrigerated defaults to false and door is optional. A body that breaks these rules is rejected with 400 INVALID_REQUEST before any booking logic runs.
  • An appointment is {id, carrier, date, door, start, end, pallets, refrigerated}, with times as HH:MM. Ids are APT-1, APT-2, ...
  • Deleting an unknown id is 404 NOT_FOUND.

Errors

Errors return {"error": "<CODE>", "message": "..."}: 400 for INVALID_REQUEST and INVALID_TIME; 404 for NOT_FOUND; 409 for OUTSIDE_HOURS, WRONG_DOOR_TYPE, DOOR_TAKEN and NO_DOOR_AVAILABLE.

Project structure

src/main/java/com/bugnik/dock/
  DockApplication.java           Spring Boot entry point
  model/                         Door, DoorType, Appointment
  repository/                    in-memory DoorRepository and AppointmentRepository
  service/DockService.java       booking rules (door choice, hours, cancel, schedule)
  service/DockException.java     business errors (status + code)
  util/TimeSlots.java            time parsing/formatting, slots per pallets, overlap check
  web/                           DockController, BookRequest, AppointmentView, ApiError, ApiExceptionHandler
src/test/java/com/bugnik/dock/  unit and MockMvc tests

Your task

The yard team has reported problems since the last release:

  • The project no longer builds.
  • A truck booked to start exactly when the previous one on a door finishes is sent to another door (or refused when the yard is busy).
  • Bookings with zero pallets or no carrier name are accepted instead of being rejected.

Find and fix the defects so that all tests pass.

  • Do not modify src/test/ or pom.xml.
  • Keep your changes minimal. Fix the defects; don't rewrite modules.
  • Additional hidden tests check the behaviour described in this README.