Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Nyverie/reservafacil/llms.txt

Use this file to discover all available pages before exploring further.

The /api/reservas endpoint lets authenticated users view and create court reservations. Role-based access controls determine the scope of what each caller can see: regular users retrieve only their own bookings, while admins and superadmins receive the full reservation list. New bookings are validated against both court availability and existing time-slot conflicts before being persisted.

GET /api/reservas

Returns a list of reservations ordered by date descending. The response shape varies by role: USUARIO receives only their own reservations with court details, while ADMIN and SUPERADMIN receive all reservations including the associated user on each record. Requires authentication. Returns 401 if no valid session is present.

Role-based filtering

Regular users (USUARIO role) only ever see their own reservations — filtered internally by usuarioId. There is no query parameter to override this; the server enforces it based on the session. Admins and superadmins always receive all reservations.

Response 200

{
  "reservas": [
    {
      "id": "clx1abc2def3ghi",
      "usuarioId": "clx9usr1abc2def",
      "canchaId": "clx5crt1abc2def",
      "fecha": "2024-01-15T00:00:00.000Z",
      "horaInicio": "09:00",
      "horaFin": "10:00",
      "estado": "PENDIENTE",
      "total": 50.00,
      "notas": null,
      "creadoEn": "2024-01-14T12:00:00.000Z",
      "cancha": { "id": "clx5crt1abc2def", "nombre": "Cancha A", "tipo": "FUTBOL" },
      "usuario": { "id": "clx9usr1abc2def", "nombre": "Ana López", "email": "ana@example.com" }
    }
  ]
}
reservas
Reserva[]
required
Array of reservation objects. Always includes the nested cancha object. The usuario field is only populated for ADMIN and SUPERADMIN callers.
reservas[].id
string
CUID identifier for the reservation.
reservas[].usuarioId
string
ID of the user who created the reservation.
reservas[].canchaId
string
ID of the court being reserved.
reservas[].fecha
string (ISO 8601)
The date of the reservation, stored as a UTC midnight timestamp.
reservas[].horaInicio
string
Start time of the booking slot in HH:MM 24-hour format (e.g. "09:00").
reservas[].horaFin
string
End time of the booking slot in HH:MM 24-hour format (e.g. "10:00").
reservas[].estado
enum
Current status of the reservation. One of: PENDIENTE, CONFIRMADA, CANCELADA, COMPLETADA.
reservas[].total
number
Total cost of the reservation as a floating-point number (e.g. 50.00). Defaults to 0 if not provided at creation.
reservas[].notas
string | null
Optional free-text notes attached to the reservation.
reservas[].creadoEn
string (ISO 8601)
Timestamp of when the reservation record was created.
reservas[].cancha
object
Nested Cancha (court) object. Always present.
reservas[].usuario
object | undefined
Nested Usuario object. Only present when the caller has ADMIN or SUPERADMIN role.

Error responses

StatusBodyDescription
401{ "error": "No autenticado" }No valid session cookie / token.

POST /api/reservas

Creates a new reservation for the authenticated user. The server automatically validates that the court exists and is active, and that the requested time window does not overlap with any existing PENDIENTE or CONFIRMADA booking for that court on the same date. Requires authentication. The usuarioId is taken directly from the session — it cannot be set in the request body.

Request body

canchaId
string
required
The CUID of the court to reserve. Must match an existing, active (activa: true) Cancha record.
fecha
string
required
The date for the reservation as an ISO 8601 string (e.g. "2024-01-15T00:00:00.000Z"). Stored as a UTC DateTime.
horaInicio
string
required
Start time of the slot in HH:MM 24-hour format (e.g. "09:00").
horaFin
string
required
End time of the slot in HH:MM 24-hour format (e.g. "10:00"). Must be later than horaInicio.
notas
string
Optional free-text notes for the reservation (e.g. special requests).
total
number
Total price for the booking. If omitted, the reservation is created with total: 0.

Conflict detection logic

Before creating the reservation, the API queries for any existing reservation on the same court (canchaId) and date (fecha) whose status is PENDIENTE or CONFIRMADA and whose time window overlaps the requested slot. Two time windows overlap when:
existingHoraInicio < requested.horaFin  AND  existingHoraFin > requested.horaInicio
This correctly handles partial overlaps, fully contained slots, and exact matches. If a conflict is found, the request is rejected with 409. All new reservations are created with estado: "PENDIENTE" regardless of the caller’s role.

Response 201

{
  "ok": true,
  "reserva": {
    "id": "clx1abc2def3ghi",
    "usuarioId": "clx9usr1abc2def",
    "canchaId": "clx5crt1abc2def",
    "fecha": "2024-01-15T00:00:00.000Z",
    "horaInicio": "09:00",
    "horaFin": "10:00",
    "estado": "PENDIENTE",
    "total": 50.00,
    "notas": "Traer balón",
    "creadoEn": "2024-01-14T12:00:00.000Z",
    "cancha": { "id": "clx5crt1abc2def", "nombre": "Cancha A", "tipo": "FUTBOL" }
  }
}
ok
boolean
Always true on success.
reserva
Reserva
The newly created reservation object. Includes the nested cancha object. The usuario field is not included in the POST response.

Error responses

StatusBodyDescription
400{ "error": "Faltan campos requeridos" }One or more of canchaId, fecha, horaInicio, or horaFin is missing.
400{ "error": "Cancha no disponible" }The court does not exist or has activa: false.
401{ "error": "No autenticado" }Request has no valid session.
409{ "error": "Ya existe una reserva en ese horario" }The time slot overlaps an active (PENDIENTE or CONFIRMADA) booking on the same court and date.
500{ "error": "Error interno" }Unexpected server-side error.

Examples

# As a regular user — returns only your own reservations
curl https://your-domain.com/api/reservas \
  --cookie "token=<your_jwt_token>"

Build docs developers (and LLMs) love