24 Reserva de Citas desde el lado del Paciente con Validación de Horarios Disponible SisOdontologíco

Duración: 20 min
Módulo: Agendamiento, Reservas & Control de Citas Interactivo Lección 1 de 5

Descripción

🎓 Lección 24: Reserva de Citas desde el Lado del Paciente con Validación de Horarios Disponibles

Objetivo General: Implementar la interfaz y lógica de negocio que permite a los pacientes consultar la disponibilidad de doctores, seleccionar especialidades/tratamientos y reservar o cancelar citas médicas en tiempo real con validaciones de horarios y calendario dinámico en Laravel 11.

🚀 Pasos Clave con Timestamps

  1. Ajustes en el Menú y Sistema de Permisos Multi-Rol
    • Se agrega la opción de menú "Citas" en Tabler UI y se actualiza el archivo de migración/seeder de permisos (Spatie) para permitir que administradores, secretarias, doctores y pacientes accedan de forma granular al módulo.
    • ⏱️ 05:51Configuración del menú de navegación en Tabler
    • ⏱️ 07:44Sincronización de permisos en la base de datos
  2. Definición de Rutas y Lógica de Controlador Separada
    • Se declaran 7 rutas HTTP específicas para el flujo del paciente (listar, ver formulario, almacenar cita, verificar disponibilidad, cargar tratamientos, consultar slots y cancelar reserva).
    • ⏱️ 06:25Estructura de las 7 rutas del módulo de citas
    • ⏱️ 09:30Estructura del controlador CitaController para pacientes
  3. Flujo de Selección Dinámica: Doctor y Tratamiento
    • El paciente elige al doctor deseado, cargando inmediatamente su horario habitual de atención y las citas previamente agendadas en FullCalendar mediante peticiones AJAX.
    • ⏱️ 05:44Demostración del panel del paciente y la lista de reservas
    • ⏱️ 13:11Formulario de reserva con FullCalendar e integración AJAX
  4. Validación Backend/Frontend de Horarios Disponibles
    • Se generan bloques de tiempo (slots) según la duración del tratamiento. El sistema previene el registro si el horario seleccionado se encuentra ocupado o fuera de la jornada de atención del odontólogo.
    • ⏱️ 14:10Generación de turnos libres según la duración del tratamiento
    • ⏱️ 15:15Verificación en tiempo real de disponibilidad del turno
  5. Registro de Cita y Gestión de Estados (Cancelación de Reserva)
    • Al confirmar la reserva, la cita guarda un token único y el estado pendiente. Si el paciente cancela la cita, el slot vuelve a quedar habilitado inmediatamente para otros usuarios.
    • ⏱️ 17:19Verificación de los registros insertados en la tabla citas
    • ⏱️ 18:18Cancelación de cita en tiempo real y liberación de horarios

🛠️ Comandos y Rutas Principales

💻 Comandos de Consola / Artisan

ComandoDescripción
php artisan migrate:fresh --seedRefresca las tablas y vuelve a ejecutar los seeders para cargar los permisos actualizados.
php artisan storage:linkCrea el enlace simbólico necesario para servir archivos desde la carpeta storage.

🌐 Rutas HTTP Esenciales

MétodoRutaAcción / Propósito
GET/admin/citas/pacienteMuestra el historial y listado de citas reservadas por el paciente.
GET/admin/citas/paciente/createCarga el formulario interactivo para la selección de cita.
POST/admin/citas/paciente/storeAlmacena la reserva de la cita en estado pendiente.
GET/admin/citas/verificar-disponibilidadConsulta vía AJAX si un turno/fecha específico se encuentra libre.
GET/admin/citas/tratamientos-doctorObtiene la lista de tratamientos y duración según el doctor elegido.
GET/admin/citas/slot-disponibleRecupera los bloques de horario disponibles para la fecha seleccionada.
POST/admin/citas/cancelar/{id}Cancela una reserva previa y libera el turno en la agenda.

🔒 Buenas Prácticas y Seguridad

  1. Separación de Controladores y Vistas por Rol:

    Organizar vistas y métodos específicos (ej. indexPaciente, createPaciente) evita mezclar la lógica de la interfaz del paciente con la del administrador o médico, manteniendo la base de código limpia y mantenible.

  2. Doble Validación de Disponibilidad (Frontend & Backend):

    Aunque el frontend bloquee la selección de horas ocupadas, la petición enviada al servidor valida nuevamente que el slot no haya sido ocupado en el milisegundo anterior, previniendo reservas duplicadas (race conditions).

  3. Inclusión Centralizada de Scripts JS:

    Para optimizar la carga de scripts de librerías pesadas (como FullCalendar o SweetAlert), es recomendable mover los scripts e inicializaciones JS desde las vistas secundarias hacia la plantilla máster o empaquetarlos usando Vite/Webpack.

  4. Identificador Único y Control de Acceso Granular:

    Asignar un token aleatorio a cada cita registrada facilita las consultas seguras y notificaciones sin exponer directamente los IDs autonumérico en las URLs.