Reservas y Pre-Tickets de Clínica
Una reserva es una cita agendada para una fecha futura en una clínica. A diferencia de la atención directa (ver Atender cliente), una reserva no crea ticket ni comisión hasta que el paciente llega. Sirve como “pre-ticket”: aparta la cita, valida que la suscripción estará vigente ese día y, al llegar, se convierte en un ticket real.
Estados de la reserva
Sección titulada «Estados de la reserva»| Estado | Significado |
|---|---|
scheduled | Agendada, a la espera de la llegada. |
consumed | El paciente llegó; se convirtió en un ticket (consumed_visit_id). |
cancelled | Cancelada por la recepción (con nota opcional). |
expired | Venció sin llegada (3 h después de la hora reservada). |
Campos relevantes: reserved_for (fecha/hora de la cita), consumed_visit_id (ticket resultante), consumed_at, cancelled_at, cancel_note y expiry_notified_at (sello que evita notificar dos veces).
Endpoints
Sección titulada «Endpoints»| Método y ruta | Acción |
|---|---|
POST /reservations | Crear una reserva. |
GET /reservations | Listar reservas agendadas. |
GET /reservations/check | Validar la suscripción a la fecha futura sin agendar. |
GET /reservations/summary | Conteos para el tablero (hoy / próximas). |
POST /reservations/:id/cancel | Cancelar una reserva agendada. |
POST /reservations/:id/arrive | Registrar la llegada y abrir el ticket. |
Validez de la suscripción a fecha futura
Sección titulada «Validez de la suscripción a fecha futura»Al crear o verificar una reserva, el sistema no valida la suscripción de hoy sino la de la fecha reservada. Para ello busca la suscripción que cubre esa fecha (starts_at ≤ fecha ≤ valid_until y estado activo); si ninguna la cubre, toma la más reciente para clasificarla (no iniciada, vencida o inactiva). Así una reserva para la próxima semana se acepta si la suscripción seguirá vigente entonces, aunque hoy esté por renovar.
Llegada (arrive)
Sección titulada «Llegada (arrive)»La llegada es atómica: todo ocurre en una sola transacción y, si algo falla, se revierte por completo.
graph TD
A[POST /reservations/:id/arrive] --> B[Cargar la reserva]
B --> C{Re-verificar la<br/>suscripción HOY}
C -->|No activa / sin acceso| R[Rechazo: no se abre ticket]
C -->|Activa| D[Marcar reserva consumed<br/>solo si scheduled o expired]
D --> E[Abrir ticket de clínica]
E --> F[Enlazar consumed_visit_id<br/>al ticket creado]
Nótese que la suscripción se vuelve a verificar al momento de la llegada, no en el de la reserva: si la cobertura caducó entre el agendamiento y la cita, la llegada se rechaza. Una reserva ya expired todavía puede consumirse si el paciente llega y la suscripción sigue activa.
Barrido de expiración
Sección titulada «Barrido de expiración»El detector de alertas de clínica (cada 5 minutos) marca como vencidas las reservas no atendidas:
- Umbral:
reserved_forvenció hace más de 3 horas y la reserva siguescheduled. - Operación atómica: una sola sentencia pasa el estado a
expiredy estampaexpiry_notified_at, devolviendo las filas afectadas. El filtroexpiry_notified_at IS NULLevita notificar dos veces si el trabajo se reinicia. - Notifica a quien creó la reserva (recepción) y a los administradores de la cuenta del miembro.
- Deduplicación: una sola alerta
reservation_expiredsin resolver por clínica, más una notificación por reserva.
Tablero
Sección titulada «Tablero»El resumen expone dos indicadores, calculados con el día calendario de Panamá: reservas de hoy y reservas próximas (agendadas a futuro). Solo cuentan las reservas en estado scheduled.
Casos esperados en pruebas
Sección titulada «Casos esperados en pruebas»- Una reserva no crea ticket ni comisión hasta la llegada.
- Una reserva para una fecha futura se acepta si la suscripción estará vigente ese día.
- Si la cobertura caduca antes de la cita, la llegada se rechaza.
- Una reserva no atendida pasa a
expired3 horas después y notifica una sola vez. - Una reserva
expiredaún puede consumirse si el paciente llega con suscripción activa.