🏥 Sistema Turnero Inteligente

Flujo completo del proceso — Desde la llegada del paciente hasta la toma de muestras
📋 9 Tablas en BD ⚡ 22 APIs REST 🖥️ 9 Vistas 📡 SSE en Tiempo Real 📱 WhatsApp Integration
👥

Actores del Sistema

Quiénes intervienen
🧑‍🦽

Paciente

Llega al laboratorio, usa el kiosko táctil para obtener su turno, firma consentimientos desde su celular vía WhatsApp.

kiosko.php ver_formulario_enviado.php
👩‍💼

Recepcionista

Llama turnos, vincula paciente, selecciona exámenes, registra pago, envía consentimientos y pasa al paciente al área de muestras.

recepcion.php display_recepcion.php
🧑‍⚕️

Auxiliar de Muestras

Llama turnos de su estación, verifica consentimientos firmados, inicia atención, toma la muestra y finaliza el turno.

lugar.php display (por lugar)
⚙️

Administrador

Configura lugares, exámenes, prioridades, plantillas WhatsApp. Monitorea dashboard e historial. Exporta reportes CSV.

configuracion.php dashboard.php historial.php
📺

Pantallas TV

Muestran en tiempo real el turno en atención y la cola de espera. Se actualizan vía SSE (Server-Sent Events).

display_global.php display.php
🎫

Sistema de Prioridades

Motor de cola

El motor de cola ordena los turnos por peso de prioridad (menor = más urgente) y luego por orden de llegada (FIFO). Las prioridades son configurables desde el panel de administración.

Código Prioridad Color Icono Descripción Peso
A Niños #ef4444 👶 fa-child Pacientes menores de edad 1 (mayor prioridad)
B Embarazadas #f97316 💗 fa-heart Mujeres en estado de embarazo 2
C Adulto mayor #eab308 🧓 fa-person-cane Mayores de 60 años 3
D Discapacidad #8b5cf6 ♿ fa-wheelchair Personas con discapacidad 4
E Paciente general #3b82f6 🧑 fa-user Atención general 5
F Muestra pendiente #6b7280 🧪 fa-vial Entrega de muestra tomada previamente 6 (menor prioridad)

💡 Ejemplo de correlativos independientes y ordenamiento

Cada prioridad tiene su propia secuencia:
A-001 (niño, llegó 8:00) → E-001 (general, llegó 8:05) → A-002 (niño, llegó 8:10) → E-002 (general, llegó 8:15)

El motor de cola ordena por peso de prioridad y luego por número correlativo: primero llama a A-001 (prioridad A, peso 1), luego A-002, después E-001, y finalmente E-002.

🔄

Máquina de Estados del Turno

Lifecycle

Estados posibles de un turno

espera
🛎️en_recepcion
🚶en_espera_lugar
🔬en_servicio
finalizado
🚫ausente
cancelado

Transiciones permitidas

espera en_recepcion (recepcionista llama)
en_recepcion en_espera_lugar (pasa a estación)
en_espera_lugar en_servicio (⚠️ requiere consentimientos OK)
en_servicio finalizado (muestra tomada)
en_servicio en_espera_lugar (regresar a cola)
cualquier estado ausente / cancelado

🔒 Bloqueo de consentimientos

La transición en_espera_lugar → en_servicio está bloqueada si el turno tiene consentimientos en estado pendiente, enviado o visto. Todos deben estar en firmado o rechazado antes de poder iniciar la atención. Esto se valida en cambiar_estado.php.

📋

Flujo Completo — Paso a Paso

Proceso end-to-end
1

🖥️ Kiosko — El paciente obtiene su turno

El paciente llega al laboratorio y se acerca al kiosko táctil (tablet o pantalla touch). No requiere login — es una pantalla pública siempre activa.

Paso 1
Selecciona su tipo de atención (A-F) tocando el botón correspondiente
Paso 2
Ingresa su número de cédula y opcionalmente su WhatsApp
Paso 3
El sistema genera un código con correlativo independiente por prioridad (ej: "A-001", "A-002", "B-001", "E-001")
Resultado
Turno en estado espera — El paciente se sienta a esperar
📄 kiosko.php ⚡ create_turno.php

🔐 Seguridad del kiosko

El kiosko nunca expone datos de otros pacientes. Solo muestra el código del turno recién creado y su posición en cola. El campo paciente_nombre almacena la cédula digitada (no el nombre real). El nombre real se vincula después en recepción.

2

🛎️ Recepción — Vinculación y solicitud

El recepcionista ve la cola de turnos en espera en su pantalla. Cuando decide atender un turno, lo llama y se abre la ficha de atención.

Llamar turno
Clic en "Llamar siguiente" o en la campana de un turno específico de la cola
Estado cambia a
en_recepcion — El turno aparece en la pantalla TV de recepción
Buscar paciente
Busca por nombre o documento en la base de datos de pacientes (reutiliza lab_pacientes)
Seleccionar exámenes
Marca los exámenes solicitados de un catálogo agrupado por categoría
Lugar destino
Selecciona a qué estación de toma de muestras enviar al paciente
Registro de pago
Monto + método (efectivo, transferencia, tarjeta, EPS, cortesía)
📄 recepcion.php ⚡ llamar_turno.php ⚡ create_solicitud.php ⚡ get_cola.php

📝 Guardar solicitud

Al hacer clic en "Guardar solicitud", se crea la turnero_solicitud con los exámenes (turnero_examen_items), el pago y el lugar destino. El sistema calcula automáticamente qué consentimientos informados se requieren basándose en los exámenes seleccionados y el lugar de destino.

3

📱 Consentimientos Informados — Firma digital

Una vez guardada la solicitud, aparecen los consentimientos requeridos. El recepcionista puede enviarlos por WhatsApp o hacer que el paciente firme presencialmente en una tablet.

Cálculo automático
El sistema cruza exam_tipo_consentimientos + turnero_lugar_consentimientos para determinar qué formularios aplica
Token UUID
Cada consentimiento genera un token único (ej: "a3f2-4b1c-...") para acceso seguro sin login
Envío por WhatsApp
Se envía mensaje con template "consentimiento_turno" + enlace de firma al celular del paciente
Firma presencial
Botón "Firmar" abre modal con iframe del formulario — el paciente firma en la tablet del puesto
⚡ send_consentimiento.php ⚡ get_consentimientos.php 📄 ver_formulario_enviado.php

📊 Estados del consentimiento

● pendiente → creado pero no enviado  |  ● enviado → WhatsApp enviado  |  ● visto → paciente abrió el enlace  |  ● firmado → paciente firmó  |  ● rechazado → paciente rechazó

🔄 Deduplicación inteligente

Si varios exámenes requieren el mismo formulario de consentimiento, el sistema lo detecta y envía un solo enlace de firma. También si el paciente ya firmó ese consentimiento en una visita anterior, se reutiliza el token existente.

4

➡️ Pasar a Lugar — El paciente se desplaza

El recepcionista hace clic en "Pasar a lugar". El turno cambia de estado y aparece en la cola de la estación de toma de muestras asignada.

Estado cambia a
en_espera_lugar
Se asigna
lugar_destino_id = la estación seleccionada (ej: "Toma de Muestras 1")
Pantalla TV
El display global muestra el anuncio: "A-001, pase a Toma de Muestras 1"
Recepción
La ficha se cierra y el recepcionista puede llamar al siguiente turno
⚡ cambiar_estado.php
5

🔬 Toma de Muestras — Proceso completo

El auxiliar de la estación de muestras ve en su pantalla la cola de pacientes asignados a su lugar. Este es el proceso detallado de toma de muestras:

5a

Llamar paciente

El auxiliar hace clic en "Llamar siguiente". El motor de cola selecciona el turno con mayor prioridad (menor peso) y mayor tiempo de espera. El turno pasa a estado en_servicio.

⚠️ Bloqueo: Si hay consentimientos sin firmar, el botón "Iniciar atención" está deshabilitado y se muestra un banner rojo indicando cuántos consentimientos faltan.

5b

Verificar ficha del paciente

Se abre la ficha con toda la información:

  • Datos del paciente: nombre, documento, fecha de nacimiento, celular
  • Exámenes solicitados: lista con código y nombre de cada examen
  • Consentimientos: estado de cada uno (firmado/rechazado/pendiente)
5c

Resolver consentimientos pendientes (si los hay)

Si algún consentimiento aún no está firmado, el auxiliar puede:

  • "Firmar aquí": Abre un modal con el formulario — el paciente firma en la tablet del puesto
  • "WA": Reenvía el enlace de firma por WhatsApp al celular del paciente
  • Polling automático: Cada 5 segundos el sistema verifica si el paciente firmó desde su celular
5d

Iniciar atención

Cuando todos los consentimientos están OK (firmados o rechazados), el botón "Iniciar atención" se habilita. El auxiliar hace clic y el estado cambia a en_servicio. Se registra inicio_lugar_at.

🧪 En este momento el auxiliar toma la muestra de sangre/orina/etc. al paciente.

5e

Finalizar atención

El auxiliar hace clic en "Finalizar". El turno pasa a estado finalizado. Se registra fin_lugar_at. La ficha se cierra y el auxiliar puede llamar al siguiente paciente.

⚠️

Casos especiales

"Ausente": El paciente no se presentó → estado ausente
"Regresar a cola": El paciente necesita esperar (ej: ayuno insuficiente) → vuelve a en_espera_lugar

📄 lugar.php ⚡ llamar_turno.php ⚡ cambiar_estado.php ⚡ get_consentimientos.php
6

📺 Pantallas TV — Información en tiempo real

Durante todo el proceso, las pantallas TV muestran el estado actualizado del sistema. Hay 3 tipos de display:

Display Global
Vista general con todas las áreas: recepción + todas las estaciones de muestras. Tema oscuro. Anuncio animado cuando se llama un turno. Video de fondo configurable.
Display Recepción
Muestra el turno activo en un escritorio de recepción específico + cola de espera. Se actualiza vía SSE.
Display por Lugar
Muestra el turno activo en una estación de muestras específica + cola de ese lugar.
Actualización
SSE (Server-Sent Events) cada 2s si hay cambios + polling de respaldo cada 4s. Beep + voz sintética al llamar turno.
📄 display_global.php 📄 display.php 📄 display_recepcion.php ⚡ sse_turno.php ⚡ get_cola.php ⚡ get_display_global.php
7

⚙️ Administración — Monitoreo y configuración

El administrador tiene acceso a vistas de control y configuración del sistema completo.

Dashboard
KPIs del día: total turnos, atendidos, en espera, ausentes, tiempo promedio de espera y servicio. Desglose por prioridad y lugar. Auto-refresh cada 30s.
Historial
Consulta multi-día con filtros por estado, lugar, prioridad y texto libre. Paginación. Detalle expandible con todos los timestamps.
Configuración
CRUD de lugares (recepción/muestras), tipos de examen, prioridades, sesiones, WhatsApp (template Meta), video TV.
Exportar
CSV con todos los turnos, timestamps, exámenes, pagos y estado de consentimientos.
📄 dashboard.php 📄 historial.php 📄 configuracion.php ⚡ get_dashboard.php ⚡ export_csv.php ⚡ get_historial.php ⚡ export_historial.php
📡

Diagrama de Secuencia — APIs y Datos

Comunicaciones
# Actor / Vista → API Acción en BD Resultado Notifica
1 Kiosko POST create_turno.php INSERT turnero_turnos (estado=espera, correlativo por prioridad) Código "A-001" + posición cola SSE notify
2 Recepción POST llamar_turno.php UPDATE estado=en_recepcion + timestamps Turno con datos completos SSE notify
3 Recepción POST create_solicitud.php INSERT turnero_solicitudes + turnero_examen_items Solicitud + consentimientos requeridos SSE notify
4 Recepción POST send_consentimiento.php INSERT/UPDATE turnero_consentimientos + tokens UUID Estado → enviado
5 Paciente (celular) GET ver_formulario_enviado.php?token=... UPDATE turnero_consentimientos estado=firmado Formulario firmado + evidencia postMessage
6 Recepción POST cambiar_estado.php → en_espera_lugar UPDATE estado + lugar_destino_id Turno pasa a cola del lugar SSE notify
7 Lugar (auxiliar) POST llamar_turno.php (area=lugar) UPDATE estado=en_servicio + timestamps Turno con ficha completa SSE notify
8 Lugar (auxiliar) GET get_consentimientos.php (polling 5s) SELECT turnero_consentimientos + paciente + exámenes Verifica si todos están firmados
9 Lugar (auxiliar) POST cambiar_estado.php → finalizado UPDATE estado + fin_lugar_at Turno completado SSE notify
10 Pantallas TV GET sse_turno.php (conexión persistente) SELECT cola + activo (cada 2s o por cambio) Render en tiempo real + audio + voz
🗄️

Tablas de Base de Datos

9 tablas del turnero

📋 turnero_turnos

Tabla principal. Cada fila = un turno. Almacena: código, número, prioridad, estado, timestamps de cada fase (creado, llamado recepción, inicio/fin recepción, llamado lugar, inicio/fin lugar), paciente_nombre (cédula del kiosko), paciente_cel.

📅 turnero_sesiones

Una por día. Controla apertura/cierre del sistema. Almacena: fecha, abierto_por, inicio_at, fin_at, sse_ping_at (para notificaciones SSE).

📝 turnero_solicitudes

Vincula un turno con un paciente real, un lugar destino y los datos de pago. Se crea en recepción después de llamar el turno.

🧪 turnero_examen_items

Relación N:M entre solicitud y tipos de examen. Cada fila = un examen solicitado para esa solicitud.

✍️ turnero_consentimientos

Cada consentimiento requerido por turno. Almacena: token UUID, estado (pendiente/enviado/visto/firmado/rechazado), timestamps.

📍 turnero_lugares

Catálogo de estaciones: recepción, toma de muestras 1, 2, etc. Campos: nombre, tipo (recepcion/muestras), descripción, sort_order, activo.

🎫 turnero_prioridades

Código (A-F), nombre, color, icono, descripción, orden_peso. Configurable desde el panel admin.

🧪 exam_tipos

Catálogo de tipos de examen del laboratorio. Código, nombre, categoría. Se usa en la ficha de recepción.

🔗 Tablas de relación

exam_tipo_consentimientos: qué formularios requiere cada tipo de examen.
turnero_lugar_consentimientos: qué formularios requiere cada lugar/servicio.

🗺️

Resumen Visual del Flujo

Big picture
🖥️
KIOSKO
Paciente obtiene
turno A-001
estado: espera
(correlativo por prioridad)
🛎️
RECEPCIÓN
Vincula paciente
exámenes + pago
estado: en_recepcion
📱
CONSENTIM.
Envío WhatsApp
firma digital
tokens UUID
🚶
TRÁNSITO
Paciente se
desplaza
estado: en_espera_lugar
🔬
MUESTRAS
Verifica + toma
muestra
estado: en_servicio
FINALIZADO
Muestra tomada
turno completo
estado: finalizado
📡 SSE (Server-Sent Events) — Cada cambio de estado notifica a todas las pantallas TV en tiempo real (beep + voz sintética + animación)