Crear Cierre
Esta guía te enseñará a crear cierres para bloquear períodos de tiempo cuando tu clínica o un proveedor específico no estará disponible para atender pacientes.Antes de Empezar
Decide el tipo de cierre que necesitas:- Cierre de clínica (clinic-wide): Toda la clínica cerrada, ningún proveedor disponible
- Cierre de proveedor (provider-specific): Solo un proveedor específico no disponible, otros sí
Pasos para Crear un Cierre

1
Navegar a Cierres
Desde el menú principal, ve a:
- Gestión → Cierres → Nuevo Cierre
- Click en widget “Próximos Cierres” → Crear Nuevo
2
Seleccionar tipo de cierre
Elige el tipo de cierre:Opción A: Cierre de Clínica (clinic-wide)
- Toda la clínica cerrada
- Bloquea TODOS los slots de disponibilidad
- Usa para: vacaciones completas, días festivos, mantenimiento general
- Solo un proveedor específico no disponible
- Otros proveedores siguen atendiendo
- Usa para: permisos personales, capacitaciones, citas médicas
3
Seleccionar proveedor (si aplica)
Solo si elegiste “Cierre de Proveedor”:Del dropdown, selecciona el proveedor que no estará disponible:
- Dr. García
- Ana López
- María Fernández
- (etc.)
Si elegiste “Cierre de Clínica”, omite este paso (provider_id será NULL).
4
Seleccionar fecha y hora de inicio
Define cuándo empieza el período cerrado:Fecha: Usa el date picker para elegir día, mes, año
- Ejemplo:
2026-08-01(1 de agosto de 2026)
- Ejemplo:
00:00(medianoche del día seleccionado) - Para cierres de día completo, usa
00:00 - Para cierres parciales (medio día), usa la hora específica (ej:
09:00)
5
Seleccionar fecha y hora de fin
Define cuándo termina el período cerrado:Fecha: Debe ser igual o posterior a fecha de inicio
- Ejemplo:
2026-08-15(15 de agosto de 2026)
- Ejemplo:
23:59(última hora del día seleccionado) - Para cierres de día completo, usa
23:59 - Para cierres parciales, usa la hora específica (ej:
14:00)
6
Ingresar razón (opcional pero recomendado)
Describe el motivo del cierre. Esto ayuda para:
- Auditoría y revisión histórica
- Recordar por qué se creó el cierre
- Trazabilidad del sistema
- ✅ “Vacaciones de verano - Playa del Carmen”
- ✅ “Día festivo - Navidad”
- ✅ “Capacitación: Curso de técnicas avanzadas”
- ✅ “Permiso médico personal - Dr. García”
- ❌ “Cerrado” (sin contexto)
- ❌ “Vacaciones” (sin detalles)
7
Preview de Impacto (NUEVO - Recomendado)
Antes de confirmar, haz click en “Preview Impacto” para ver:Ver Tutorial Completo: Preview de Impacto
- Total de slots disponibles normalmente
- Slots que se bloquearán con este cierre
- Porcentaje de impacto (slots bloqueados / total slots)
- Nivel de impacto: HIGH, MEDIUM, LOW
8
Confirmar creación
Si el preview de impacto es aceptable, haz click en “Crear Cierre”.El sistema ejecutará:
- Validación de fechas (fin > inicio)
- Creación del cierre en base de datos
- Registro de jobs dinámicos (closure_start, closure_end)
- Cálculo de impacto real
- Si impacto es HIGH: Envío automático de email de alerta
- Si cierre empieza hoy: Emisión de evento WebSocket
clinic_status_changed - Invalidación de cache de disponibilidad
Resultado de Crear un Cierre
Después de crear el cierre, el sistema habrá realizado:1. Cierre Creado en Base de Datos
El cierre se almacena en la tablaclosures con:
clinic_id: Tu clínicaprovider_id: NULL (clinic-wide) o UUID del proveedorstarts_at: Fecha/hora de inicio (UTC)ends_at: Fecha/hora de fin (UTC)reason: Razón ingresada
2. Jobs Dinámicos Registrados
APScheduler registra automáticamente 2 jobs con DateTrigger: Job 1:closure_{id}_start
- Trigger:
starts_at(fecha/hora de inicio) - Acción: Emite evento WebSocket
clinic_status_changedcon statusclosed
closure_{id}_end
- Trigger:
ends_at(fecha/hora de fin) - Acción: Emite evento WebSocket
clinic_status_changedcon statusopen(si no hay otros cierres activos)
Los jobs se ejecutan automáticamente en las fechas programadas. No requieren intervención manual.
3. Impact Analysis Calculado
El sistema ejecutaAvailabilityImpactService para calcular:
- Total de slots disponibles en el período (sin el cierre)
- Slots bloqueados por el cierre
- Porcentaje de impacto
- Nivel de impacto: HIGH (100%), MEDIUM (50-99%), LOW (<50%)
4. Email Notification (si impacto HIGH)
Solo si impacto es HIGH (todos los slots bloqueados): El sistema envía automáticamente un email a los administradores de la clínica con:- Detalles del cierre (fechas, razón)
- Nivel de impacto y slots afectados
- Recomendaciones de acción
notification_sent_at + notification_impact_level)
5. WebSocket Event (si cierre empieza hoy)
Sistarts_at es hoy, el sistema emite inmediatamente:
6. Availability Cache Invalidated
El sistema invalida toda la cache de disponibilidad para tu clínica:- Cache de
get_availability(3 min TTL) - Cache de
OperationalStatusService(30 seg TTL) - Cache de
ConfigurationStatusService(5 min TTL)
Ejemplos Completos
Ejemplo 1: Vacaciones de verano (15 días, clinic-wide)
Ejemplo 1: Vacaciones de verano (15 días, clinic-wide)
Escenario: Toda la clínica cerrará del 1 al 15 de agosto de 2026.Configuración:
- Tipo: Cierre de clínica (clinic-wide)
- Proveedor: (No aplica)
- Inicio:
2026-08-01 00:00 - Fin:
2026-08-15 23:59 - Razón: “Vacaciones de verano - Playa del Carmen”
- Slots normales: 300 slots (15 días × 20 slots/día)
- Slots bloqueados: 300 slots (100%)
- Nivel: HIGH
- Email notification: Sí ✅
- Cierre creado ✅
- Jobs registrados:
closure_abc_start(2026-08-01 00:00),closure_abc_end(2026-08-15 23:59) - Email enviado a admins ✅
- Upcoming closure visible desde 2026-07-18 (14 días antes)
- NO se pueden agendar citas del 1-15 de agosto
Ejemplo 2: Día festivo (1 día, clinic-wide)
Ejemplo 2: Día festivo (1 día, clinic-wide)
Escenario: Clínica cerrada el 25 de diciembre (Navidad).Configuración:
- Tipo: Cierre de clínica
- Proveedor: (No aplica)
- Inicio:
2026-12-25 00:00 - Fin:
2026-12-25 23:59 - Razón: “Día festivo - Navidad”
- Slots normales: 20 slots
- Slots bloqueados: 20 slots (100%)
- Nivel: HIGH
- Email notification: Sí ✅
- Cierre creado ✅
- Email enviado ✅
- Upcoming closure visible desde 2026-12-11
- 25/12 completamente bloqueado
Ejemplo 3: Permiso médico (2 días, provider-specific)
Ejemplo 3: Permiso médico (2 días, provider-specific)
Escenario: Dr. García no disponible 3-4 de febrero por permiso médico.Configuración:
- Tipo: Cierre de proveedor
- Proveedor: Dr. García
- Inicio:
2026-02-03 00:00 - Fin:
2026-02-04 23:59 - Razón: “Permiso médico personal”
- Slots Dr. García: 40 slots (2 días × 20 slots/día)
- Slots bloqueados: 40 slots (100% de Dr. García)
- Slots totales clínica: 120 slots (3 proveedores)
- Porcentaje total: 33% (impacto MEDIUM)
- Email notification: No ❌ (solo HIGH)
- Cierre creado ✅
- Solo Dr. García bloqueado 3-4 febrero
- Otros proveedores (Dra. López, Dra. Fernández) siguen disponibles ✅
- NO se envía email (impacto no es HIGH)
Ejemplo 4: Capacitación (medio día, provider-specific)
Ejemplo 4: Capacitación (medio día, provider-specific)
Escenario: Ana López en curso de 9:00 a 14:00.Configuración:
- Tipo: Cierre de proveedor
- Proveedor: Ana López
- Inicio:
2026-03-10 09:00 - Fin:
2026-03-10 14:00 - Razón: “Capacitación: Curso de técnicas avanzadas”
- Slots Ana mañana (9-14): 10 slots
- Slots bloqueados: 10 slots
- Slots Ana tarde (14-18): 8 slots (siguen disponibles ✅)
- Porcentaje Ana: 56% (MEDIUM)
- Porcentaje total clínica: 12% (LOW)
- Email notification: No ❌
- Cierre creado ✅
- Ana bloqueada solo 9:00-14:00
- Ana disponible 14:00-18:00 ✅
- Otros proveedores disponibles todo el día ✅
Validaciones Automáticas
El sistema previene errores comunes:Validación de fechas
Validación de fechas
¿Qué verifica?Solución: Verifica las fechas ingresadas.
- Fecha de fin debe ser posterior a fecha de inicio
- Ambas fechas deben ser válidas (formato ISO 8601)
Validación de proveedor (si provider-specific)
Validación de proveedor (si provider-specific)
¿Qué verifica?Solución: Selecciona un proveedor válido del dropdown.
- El provider_id existe en la base de datos
- El proveedor pertenece a tu clínica
Validación de permisos
Validación de permisos
¿Qué verifica?Solución: Solicita permisos de administrador.
- Solo ADMIN o CLINIC_ADMIN pueden crear cierres