Skip to main content

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.

CoworkingBooking is built around three core JPA entities that map directly to database tables: Espacio (the physical coworking space), Usuario (the registered user), and Reserva (the reservation that links a user to a space for a specific time window). A Reserva holds foreign-key references to both Espacio and Usuario, making it the central relationship in the data model. Understanding these entities — their fields, constraints, and how they relate — is essential before working with any API endpoint.

Espacio

Espacio represents a bookable coworking space, such as a private office, meeting room, or open-desk area. It is stored in the espacios table.
FieldJava TypeDB ColumnNullableConstraintsDescription
idIntegeridNoPK, auto-incrementUnique identifier for the space.
nombreStringnombreNomax 50 charsHuman-readable name of the space (e.g., “Sala Azul”).
tipoStringtipoNomax 30 charsCategory of the space (e.g., “privado”, “abierto”, “sala”).
capacidadIntegercapacidadNoMaximum number of people the space can accommodate.
minutos_limpiezaIntegerminutos_limpiezaNoBuffer time in minutes reserved for cleaning after each booking. This value is added to horaFinUsuario to derive horaFinTotal.
The minutos_limpieza field is central to the scheduling model. It ensures that back-to-back reservations always include a cleaning window — the space is not available again until horaFinTotal has passed.
API response shape (GetEspacioResponse):
{
  "id": 3,
  "nombre": "Sala Azul",
  "tipo": "sala",
  "capacidad": 8,
  "minutos_limpieza": 15
}

Usuario

Usuario represents a registered user of the platform. It is stored in the usuarios table. The email column carries a UNIQUE database constraint — no two users may share the same email address.
FieldJava TypeDB ColumnNullableConstraintsDescription
idIntegeridNoPK, auto-incrementUnique identifier for the user.
nombreStringnombreNomax 100 charsFull name of the user.
emailStringemailNoUNIQUE, max 150 charsEmail address used for identification. Must be unique.
password_hashStringpassword_hashNomax 255 charsHashed representation of the user’s password.
rolStringrolNoRole assigned to the user (e.g., "admin", "usuario").
The @NotBlank constraint is enforced on nombre and email at the request DTO level (CreateUsuarioRequest). The @Email annotation additionally validates that the email field is a well-formed email address before the request reaches service logic.
API response shape (GetUsuarioResponse):
{
  "id": 7,
  "nombre": "María Torres",
  "email": "[email protected]",
  "password_hash": "$2a$10$...",
  "rol": "usuario"
}

Reserva

Reserva is the transactional core of the system. It records that a specific Usuario has reserved a specific Espacio for a defined time window, and it tracks the reservation’s current lifecycle state. It is stored in the reservas table.
FieldJava TypeDB ColumnNullableDescription
idIntegeridNoPK, auto-increment.
espacioEspacioespacio_id (FK)NoManyToOne reference to the reserved space.
usuarioUsuariousuario_id (FK)NoManyToOne reference to the user who made the reservation.
horaInicioTimestamphora_inicioNoThe date and time the user’s booking begins.
horaFinUsuarioTimestamphora_fin_usuarioNoThe date and time the user’s booking ends (their last usable minute).
horaFinTotalTimestamphora_fin_totalNohoraFinUsuario + espacio.minutos_limpieza. The space is occupied and unavailable until this time.
estadoStringestadoYesLifecycle state of the reservation: confirmada, pendiente, or cancelada. Max 20 chars.
versionIntegerversionYesJPA optimistic-lock counter. Managed automatically by the persistence layer via @Version.

The @Version field and optimistic locking

The version column is annotated with @Version in the JPA entity. JPA increments this integer automatically every time a Reserva row is updated. When two concurrent requests attempt to update the same reservation, the first one to commit will increment version. The second request — carrying the now-stale version number — will cause JPA to throw an OptimisticLockException, preventing a silent overwrite. See Reservations for the full explanation. API response shape (CreateReservaResponse / UpdateReservaResponse):
{
  "id": 42,
  "usuarioId": 7,
  "espacioId": 3,
  "horaInicio": "2025-07-15T09:00:00.000+00:00",
  "horaFinUsuario": "2025-07-15T11:00:00.000+00:00",
  "horaFinTotal": "2025-07-15T11:15:00.000+00:00",
  "estado": "confirmada",
  "version": 1
}

Entity Relationship Diagram

The three entities form a simple star schema centered on Reserva:
┌───────────────────┐          ┌───────────────────────────────────────┐
│     espacios      │          │               reservas                │
│───────────────────│          │───────────────────────────────────────│
│ id (PK)           │◄────┐    │ id (PK)                               │
│ nombre            │     └────│ espacio_id  (FK → espacios.id)        │
│ tipo              │          │ usuario_id  (FK → usuarios.id)  ──┐   │
│ capacidad         │          │ hora_inicio                       │   │
│ minutos_limpieza  │          │ hora_fin_usuario                  │   │
└───────────────────┘          │ hora_fin_total                    │   │
                               │ estado                            │   │
┌───────────────────┐          │ version                           │   │
│     usuarios      │          └───────────────────────────────────┼───┘
│───────────────────│                                              │
│ id (PK)           │◄─────────────────────────────────────────────┘
│ nombre            │
│ email (UNIQUE)    │
│ password_hash     │
│ rol               │
└───────────────────┘
  • ReservaEspacio: @ManyToOne — many reservations may reference the same space.
  • ReservaUsuario: @ManyToOne — many reservations may belong to the same user.

Timing Model

Every Reserva carries three timestamps that together describe how long a space is occupied:

horaInicio

When the user enters the space and their session begins.

horaFinUsuario

When the user’s booked time ends — the last minute they may occupy the space.

horaFinTotal

horaFinUsuario + espacio.minutos_limpieza. The space is physically unavailable for new bookings until this time passes.
The separation between horaFinUsuario and horaFinTotal means that scheduling logic must check against horaFinTotal — not horaFinUsuario — when deciding whether a new reservation overlaps an existing one. For example, if a space has minutos_limpieza = 15 and a booking ends at 11:00, the next booking cannot start until 11:15.
Timeline:
│── User in space ──────────────────────│── Cleaning ──│
▲                                        ▲              ▲
horaInicio                       horaFinUsuario   horaFinTotal
(09:00)                              (11:00)        (11:15)

Build docs developers (and LLMs) love