A reservation (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/devdavco/backend_1/llms.txt
Use this file to discover all available pages before exploring further.
Reserva) is the central transaction in CoworkingBooking — it binds a registered user to a physical space for a defined time window. From the moment a reservation is created it moves through a lifecycle of states (pendiente → confirmada → cancelada), and every update is guarded by an optimistic-lock counter to ensure that concurrent API calls can never silently overwrite each other. This page explains the full lifecycle: how to create a reservation, how to update its state, the three-timestamp timing model, and how the system defends against race conditions.
Reservation States
EveryReserva record carries an estado field (max 20 characters) that reflects where it is in its lifecycle. The field is a plain string — the API does not enforce an enum at the database level, so the values below are the conventions the service layer uses.
- pendiente
- confirmada
- cancelada
Pending — the reservation has been created but not yet confirmed by an administrator or by the system’s confirmation flow. The space is tentatively held but the booking is not yet active.
Time Window Model
Each reservation records three timestamps that together define how long a space is physically occupied:| Field | Meaning |
|---|---|
horaInicio | When the user enters the space — the start of the booked session. |
horaFinUsuario | When the user’s booked time ends — the last moment they may use the space. |
horaFinTotal | horaFinUsuario + espacio.minutos_limpieza — the space is unavailable until this time. |
minutos_limpieza) lives on the Espacio entity and is applied at booking time. Because horaFinTotal is persisted on the Reserva, scheduling queries can check overlap using a single field rather than performing arithmetic on the fly.
Example: A space with minutos_limpieza = 15 is booked from 09:00 to 11:00.
11:15 (horaFinTotal).
Creating a Reservation
To create a reservation, send aPOST request to /reserva/save with a JSON body matching CreateReservaRequest.
Validation rules (enforced by ReservaServiceImpl)
The service layer performs the following checks in order before persisting:
- The request object must not be
null. usuarioIdmust be non-null and greater than0.espacioIdmust be non-null and greater than0.- The
Usuarioidentified byusuarioIdmust exist in the database. - The
Espacioidentified byespacioIdmust exist in the database.
Exception is thrown with a descriptive message and the reservation is not saved.
Request fields
The ID of the
Espacio to reserve. Must be greater than 0 and must reference an existing record.The ID of the
Usuario making the reservation. Must be greater than 0 and must reference an existing record.Start timestamp of the booking. Must use the format
yyyy-MM-dd HH:mm (e.g., "2025-07-15 09:00").End timestamp of the user’s session. Must use the format
yyyy-MM-dd HH:mm.End timestamp including the cleaning buffer (
horaFinUsuario + minutos_limpieza). Must use the format yyyy-MM-dd HH:mm.Initial lifecycle state. Recommended values:
"pendiente", "confirmada", "cancelada".Optimistic-lock seed value. Typically sent as
0 or null on creation; JPA manages this field automatically after the first save.Example request
Example response (201 Created)
Updating a Reservation
Send aPUT request to /reserva/update/{id} to update an existing reservation. The current implementation allows updating only the estado field — timestamps and foreign-key references are immutable once a reservation is created.
Request fields (UpdateReservaRequest)
The ID of the reservation to update. Also supplied as the path variable
{id}; if included in the body it is present for reference but the path variable takes precedence in routing.The new lifecycle state. Accepted values:
"confirmada", "pendiente", "cancelada".Example request
Example response (200 OK)
Notice that
version has incremented from 0 to 1. JPA automatically bumps this counter on every successful save. The client must treat the value returned in each response as the authoritative current version.Optimistic Locking
TheReserva entity carries a @Version-annotated version column. This is the standard JPA mechanism for optimistic concurrency control — it prevents two concurrent requests from silently overwriting each other’s changes without requiring the database to hold a row-level lock for the duration of a request.
How it works
OptimisticLockException is thrown the transaction is rolled back. Client B receives a server error response indicating the conflict. The correct recovery strategy is to re-fetch the reservation (to obtain the current version), apply changes to the fresh data, and retry the update.