¿Qué es el widget de próximas citas?
Es una tabla interactiva en el Dashboard que muestra las próximas citas del día con detalles clave para operación rápida. Características:- Muestra solo citas de hoy (según zona horaria de la clínica)
- Ordenadas por hora de inicio (más próximas primero)
- Incluye nombre del paciente, servicio, proveedor, hora y estado
- Acciones rápidas: Ver detalles, editar, cancelar
El widget se actualiza automáticamente cada 5 minutos junto con las estadísticas generales.

Columnas de la tabla
1. Hora
Formato:HH:MM - HH:MM (ej: 10:00 - 10:30)
Europe/Madrid por defecto).
2. Paciente
Formato: Nombre completo del paciente (ej:Manuel López Sánchez)
Detalles:
- Si el paciente existe en el sistema, muestra su nombre registrado
- Si es un paciente nuevo (creado vía WhatsApp), muestra el nombre capturado por el bot
- Clickeable: Al hacer clic, abre el perfil del paciente (en desarrollo)
3. Servicio
Formato: Nombre del servicio (ej:Corte de pelo, Tinte)
Detalles:
- Muestra el servicio seleccionado al crear la cita
- Incluye duración implícita (no visible, pero determina
end_datetime) - Si no hay servicio asignado, muestra
Sin servicio(raro, pero posible)
4. Proveedor
Formato: Nombre del proveedor (ej:Peluquero 1, Barbero 2)
Detalles:
- Muestra el proveedor asignado a la cita
- Si la clínica tiene varios proveedores, ayuda a distribuir carga
- Clickeable: Al hacer clic, filtra citas de ese proveedor (en desarrollo)
Si tu clínica tiene solo un proveedor, esta columna siempre mostrará el mismo nombre. Útil si planeas contratar más personal.
5. Estado
Valores posibles:| Estado | Badge | Significado |
|---|---|---|
CONFIRMED | 🔵 Azul | Cita agendada, esperando a ser completada |
COMPLETED | ✅ Verde | Cita finalizada (paciente atendido) |
CANCELLED | ❌ Rojo | Cita cancelada (por usuario o paciente) |
El cambio de
CONFIRMED a COMPLETED ocurre automáticamente cada 60 segundos (job del scheduler).6. Acciones
Botones disponibles:Ver Detalles
- Icono: 👁️ (ojo)
- Acción: Abre modal con información completa de la cita
- Incluye: Teléfono del paciente, notas, fecha de creación, canal (WhatsApp/Web)
Editar
- Icono: ✏️ (lápiz)
- Acción: Permite modificar fecha, hora, servicio o proveedor
- Validación: Verifica disponibilidad del nuevo horario antes de guardar
Cancelar
- Icono: 🗑️ (basura)
- Acción: Cambia el estado a
CANCELLED - Confirmación: Muestra diálogo “¿Estás seguro?” antes de cancelar
- Libera el horario para nuevas reservas
- Elimina la cita de “Citas Confirmadas” (contador disminuye)
- NO se puede deshacer (la cita queda marcada como cancelada permanentemente)
Ordenamiento y filtros
Ordenamiento automático
Las citas se muestran ordenadas por hora de inicio (ascendente):- Si son las 12:00, las citas de 09:00 y 10:00 se muestran con estado
COMPLETED - Permanecen en la tabla hasta la medianoche (útil para revisión del día)
Filtros disponibles
Actualmente el widget NO tiene filtros interactivos. Siempre muestra:- Fecha: Hoy (no se pueden ver citas de otros días desde el Dashboard)
- Clínica: La seleccionada en el menú superior
- Estado: Todos los estados (confirmadas, completadas, canceladas)
Para ver citas de otros días, usa la sección “Citas” en el menú lateral (calendario completo).
Actualización en tiempo real
¿Cómo se actualiza?
El widget usa el mismo mecanismo de polling que las estadísticas:- Frontend hace petición GET
/v1/dashboard/appointments?clinic_id=...cada 5 minutos - Backend consulta PostgreSQL con filtro
DATE(start_datetime) = TODAY - Frontend actualiza la tabla sin refrescar la página
- Nueva cita creada vía WhatsApp → Aparece en 5 minutos
- Usuario edita una cita → Cambios visibles en 5 minutos
- Cita se completa automáticamente → Estado cambia en 1-5 minutos
Casos de uso comunes
Escenario 1: Verificar próximas citas al llegar
Objetivo: Saber quién viene en las próximas horas. Pasos:- Abres el Dashboard a las 09:00
- El widget muestra:
- 09:30 - Manuel López (Corte de pelo)
- 10:00 - Laura García (Tinte)
- 11:00 - Pedro Martínez (Barba)
- Acción: Preparas los materiales para el tinte de Laura (requiere tiempo de setup)
Escenario 2: Cancelar cita de paciente que no viene
Objetivo: Liberar un slot cuando el paciente llama para cancelar. Pasos:- Paciente llama a las 10:15: “No puedo ir a mi cita de las 11:00”
- Abres el Dashboard
- Buscas la cita de las 11:00 en el widget
- Haces clic en el botón 🗑️ (Cancelar)
- Confirmas la cancelación
- Resultado:
- Estado cambia a
CANCELLED - El horario 11:00 queda disponible para nuevas reservas
- “Citas Confirmadas” disminuye en 1
- Estado cambia a
Escenario 3: Editar cita porque paciente llega tarde
Objetivo: Mover una cita de 10:00 a 10:30 porque el paciente avisa que llegará tarde. Pasos:- Paciente envía WhatsApp a las 09:50: “Llegaré 30 minutos tarde”
- Abres el Dashboard
- Encuentras la cita de las 10:00
- Haces clic en ✏️ (Editar)
- Cambias la hora a 10:30
- Sistema valida:
- ¿El slot 10:30 está libre? ✅
- ¿El proveedor está disponible? ✅
- ¿La clínica está abierta? ✅
- Guardas los cambios
- Resultado: Cita ahora aparece como 10:30 - 11:00
Si el slot 10:30 estaba ocupado, la edición falla y debes elegir otra hora (ej: 10:45, 11:00).
Escenario 4: Ver detalles de un paciente recurrente
Objetivo: Recordar preferencias del paciente antes de atenderlo. Pasos:- Ves en el widget:
11:00 - Juan Pérez (Corte de pelo) - Haces clic en 👁️ (Ver detalles)
- El modal muestra:
- Teléfono: +34612345678
- Notas: “Prefiere corte corto, sin tijera en las patillas”
- Historial: 5 citas previas (todas completadas)
- Acción: Preparas la máquina de afeitar (no tijera) antes de que llegue
Integración con WhatsApp
Citas creadas por el bot
Cuando un paciente agenda vía WhatsApp:- Bot captura: Nombre, fecha, hora, servicio
- Crea la cita en la base de datos con estado
CONFIRMED - En 5 minutos (máximo), la cita aparece en el widget del Dashboard
Cancelaciones vía WhatsApp
Si el paciente cancela por WhatsApp:- Paciente: “Cancela mi cita de las 16:00”
- Bot pregunta: “¿Quieres cancelar o reagendar?”
- Paciente: “Cancelar”
- Bot ejecuta
cancel_appointment(appointment_id=...) - Estado cambia a
CANCELLEDen la base de datos - En 5 minutos, el widget muestra el badge rojo ❌
Limitaciones actuales
1. Solo muestra citas de HOY
Problema: No puedes ver citas de mañana o la próxima semana desde el Dashboard. Solución: Usa la sección “Citas” (menú lateral) para ver el calendario completo.2. No permite crear citas
Problema: El widget solo visualiza, no tiene botón “Crear nueva cita”. Solución:- Vía WhatsApp: El paciente agenda con el bot
- Manualmente: Usa la sección “Citas” → Botón “Nueva Cita”
3. No filtra por proveedor
Problema: Si tienes 3 peluqueros, no puedes ver solo las citas de “Peluquero 1”. Solución (temporal): Usa la columna “Proveedor” para identificar visualmente. Mejora futura: Dropdown para filtrar por proveedor.4. No muestra citas pasadas de otros días
Problema: Una vez pasa la medianoche, las citas de ayer desaparecen del widget. Solución: Usa reportes históricos (en desarrollo) o exporta datos vía API.Estados especiales y casos raros
Cita creada pero paciente no vino
Escenario: Cita de las 10:00, paciente no apareció, ahora son las 10:45. Estado en el sistema:- Estado:
COMPLETED(marcado automáticamente por el job) - Ingresos estimados: Suma el precio del servicio (€15)
- Problema: El ingreso real fue €0 (paciente no vino)
- Cancela la cita (cambia a
CANCELLED) - Esto elimina el ingreso de “Ingresos Estimados”
- Opcional: Agrega nota en el perfil del paciente (“No se presentó el 15/01/2026”)
Cita con servicio eliminado
Escenario: Tenías un servicio “Manicura”, creaste citas con ese servicio, luego eliminaste “Manicura” de la lista de servicios. Estado en el sistema:- La cita sigue existiendo
- Columna “Servicio” muestra:
Servicio eliminado (ID: abc-123) - Puedes editar la cita para cambiar a otro servicio
El sistema conserva la relación
appointment.service_id incluso si el servicio fue eliminado (integridad referencial con ON DELETE SET NULL).Cita con proveedor suspendido
Escenario: Proveedor “Peluquero 2” fue suspendido (cambio de personal), pero tiene citas agendadas. Estado en el sistema:- Cita sigue apareciendo en el widget
- Columna “Proveedor” muestra:
Peluquero 2(nombre original) - Puedes reasignar la cita a otro proveedor activo
- Haz clic en ✏️ (Editar)
- Cambia el proveedor a “Peluquero 1”
- Guarda los cambios
- Sistema valida que “Peluquero 1” esté disponible en ese horario
Rendimiento y escalabilidad
¿Cuántas citas puede mostrar?
Límite práctico: Hasta 50 citas en el widget sin degradación de UX. Cálculo:- Clínica abierta: 10:00 - 20:00 (10 horas)
- Duración promedio por cita: 30 minutos
- Citas máximas/día: 10h × 2 citas/h = 20 citas
- Con 3 proveedores: 20 × 3 = 60 citas/día
- El widget mostrará todas, pero con scroll vertical
- Considera usar filtros por proveedor (cuando esté disponible)
Impacto en la base de datos
Cada actualización del widget ejecuta esta query:- Índice compuesto en
(clinic_id, start_datetime)→ query <10ms - Cache de 5 minutos → 12 queries/hora (carga mínima)
El sistema soporta decenas de miles de citas sin problemas de rendimiento gracias a los índices.
Solución de problemas
Las citas no aparecen en el widget
Causas posibles:- Zona horaria incorrecta: La cita está en UTC pero la clínica en
Europe/Madrid- Solución: Verifica
CLINIC_DEFAULT_TZen configuración
- Solución: Verifica
- Cita creada para otro día: El widget solo muestra HOY
- Solución: Verifica la fecha en la sección “Citas”
- Estado cancelado: Las citas canceladas aparecen pero con badge rojo
- Solución: Verifica el estado en la columna “Estado”
El estado no cambia de CONFIRMED a COMPLETED
Diagnóstico:- Verifica que el job del scheduler esté corriendo:
- Revisa los logs del scheduler:
- Job pausado: El scheduler no está activo
- Error en la query: Verifica logs de errores en PostgreSQL
Editar cita falla con “Horario no disponible”
Diagnóstico:- Verifica que el nuevo horario esté dentro de
work_hoursde la clínica - Verifica que el proveedor NO tenga otra cita en ese horario
- Verifica que NO haya un
closure(cierre) en esa fecha/hora