up
This commit is contained in:
+575
-81
@@ -101,14 +101,21 @@ MÓDULOS PLANIFICADOS (oleadas):
|
||||
│ ├── turnero/ ← NUEVO ★ (Oleada 1)
|
||||
│ │ ├── module.php
|
||||
│ │ ├── views/
|
||||
│ │ │ ├── dashboard.php ← Pantalla administrador
|
||||
│ │ │ ├── display.php ← Pantalla TV/recepción (sin login)
|
||||
│ │ │ └── kiosko.php ← Pantalla táctil toma de turno
|
||||
│ │ │ ├── dashboard.php ← Panel administrador (resumen del día)
|
||||
│ │ │ ├── kiosko.php ← Pantalla táctil tomar turno (sin login)
|
||||
│ │ │ ├── display.php ← Pantalla TV cola general (sin login)
|
||||
│ │ │ ├── recepcion.php ← Puesto recepcionista (llamar, solicitud, lugar)
|
||||
│ │ │ ├── lugar.php ← Puesto de servicio: llama turno, firma, atiende
|
||||
│ │ │ └── configuracion.php ← Lugares, exámenes, prioridades, sesiones
|
||||
│ │ └── api/
|
||||
│ │ ├── create_turno.php
|
||||
│ │ ├── llamar_turno.php
|
||||
│ │ ├── get_estado.php
|
||||
│ │ └── sse_turno.php ← Server-Sent Events para la pantalla TV
|
||||
│ │ ├── create_turno.php ← Genera nuevo turno (kiosko)
|
||||
│ │ ├── llamar_turno.php ← Llama siguiente de una cola
|
||||
│ │ ├── create_solicitud.php ← Crea solicitud con exámenes, pago y lugar destino
|
||||
│ │ ├── cambiar_estado.php ← Avanza estado del turno
|
||||
│ │ ├── get_cola.php ← Cola de un lugar o recepción
|
||||
│ │ ├── sse_turno.php ← Server-Sent Events para pantallas TV
|
||||
│ │ ├── send_consentimiento.php ← Envía enlace de consentimiento por WhatsApp
|
||||
│ │ └── get_consentimientos.php ← Estado de firmas del turno
|
||||
│ │
|
||||
│ ├── registro_exams/ ← PENDIENTE — Oleada 2
|
||||
│ │ ├── module.php
|
||||
@@ -215,54 +222,285 @@ HELPER PROPUESTO (core/Rbac.php):
|
||||
5. MÓDULO TURNERO — DISEÑO DETALLADO
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
CONCEPTO:
|
||||
Sistema de turnos para pacientes que llegan presencialmente a la sede.
|
||||
Tres pantallas distintas:
|
||||
A) Kiosko (tablet/touch en recepción) → el paciente toma su turno
|
||||
B) TV/Display (pantalla grande) → muestra turno actual + cola
|
||||
C) Dashboard admin → el operador llama turnos, gestiona
|
||||
PROPÓSITO:
|
||||
Diseñar, desarrollar e implementar un Sistema de Turnero Inteligente
|
||||
integrado con gestión de pacientes, clasificación por prioridades,
|
||||
flujo de atención por áreas (Recepción y Toma de Muestras) y envío
|
||||
automatizado de consentimientos informados mediante WhatsApp.
|
||||
|
||||
TABLAS BD NUEVAS:
|
||||
El sistema optimiza la atención, mejora la trazabilidad del paciente
|
||||
y garantiza el cumplimiento legal mediante la gestión digital de
|
||||
consentimientos.
|
||||
|
||||
turnero_servicios
|
||||
id, nombre, prefijo (ej. "A"), color, tiempo_estimado_min, activo
|
||||
──── 5.1 PANTALLAS / INTERFACES ────────────────────────────────────────────
|
||||
|
||||
A) Kiosko (tablet/touch, sin login)
|
||||
→ el paciente selecciona su tipo de prioridad y obtiene su turno
|
||||
|
||||
B) Pantalla TV / Display (pantalla grande, sin login, una por lugar)
|
||||
→ muestra la cola del lugar y el turno siendo llamado en tiempo real
|
||||
→ param ?lugar_id=X para que cada sala tenga su propia pantalla
|
||||
|
||||
C) Puesto Recepción (login requerido)
|
||||
→ llama turnos de la cola general
|
||||
→ vincula paciente, registra exámenes, recibe pago
|
||||
→ crea la Solicitud Interna y asigna el turno a un Lugar
|
||||
|
||||
D) Puesto Lugar / Estación de Servicio (login requerido, genérico)
|
||||
→ llama turnos de su propia cola (los asignados a él por recepción)
|
||||
→ muestra exámenes requeridos y estado de consentimientos
|
||||
• el paciente firma directamente en la pantalla del puesto (o en su celular)
|
||||
→ realiza el servicio y finaliza el turno
|
||||
→ La misma vista sirve para: Toma de Muestras 1, Toma de Muestras 2,
|
||||
Rayos X, Ultrasonido, o cualquier área que se configure
|
||||
|
||||
E) Panel Admin Turnero (login requerido)
|
||||
→ configura Lugares, exámenes, prioridades, sesiones
|
||||
|
||||
──── 5.2 SISTEMA DE PRIORIDADES ────────────────────────────────────────────
|
||||
|
||||
Código Tipo de paciente Orden motor de cola
|
||||
──────────────────────────────────────────────────────
|
||||
A Niños 1 (máxima prioridad)
|
||||
B Embarazadas 2
|
||||
C Adulto mayor 3
|
||||
D Discapacidad 4
|
||||
E Paciente general 5
|
||||
F Muestras pendientes 6 (menor prioridad)
|
||||
|
||||
Regla: dentro del mismo código se respeta el orden de llegada (FIFO).
|
||||
El motor de cola mezcla todas las filas usando el peso de prioridad + timestamp.
|
||||
|
||||
──── 5.3 FLUJO POR ÁREAS ────────────────────────────────────────────────────
|
||||
|
||||
ÁREA 1 — RECEPCIÓN
|
||||
═══════════════════
|
||||
Estados: espera → en_recepcion → finalizado_recepcion
|
||||
|
||||
1. Kiosko/recepcionista genera turno (código + prioridad)
|
||||
2. Pantalla TV muestra la cola
|
||||
3. Recepcionista llama siguiente turno → estado "en_recepcion"
|
||||
→ (opcional) Mensaje WhatsApp al paciente con su código de turno
|
||||
4. Se vincula el turno con un número de ventanilla
|
||||
5. Se registran:
|
||||
• Datos personales del paciente (buscar/crear en lab_pacientes)
|
||||
• Exámenes requeridos (lista de exam_tipos)
|
||||
6. Sistema consulta si los exámenes requieren consentimientos
|
||||
7. Si hay consentimientos pendientes:
|
||||
→ Se genera enlace único y seguro por paciente
|
||||
→ Se envía por WhatsApp usando WhatsAppService + plantilla aprobada Meta
|
||||
Si no se requieren → pasa directamente a área de muestras
|
||||
8. Turno avanza → "esperando_consentimiento" o "en_espera_muestra"
|
||||
|
||||
ÁREA 2 — TOMA DE MUESTRAS
|
||||
══════════════════════════
|
||||
Estados: en_espera_muestra → en_muestra → finalizado
|
||||
|
||||
1. Bacteriólogo/auxiliar llama siguiente de la cola de muestras
|
||||
2. Sistema BLOQUEA la atención si no existen consentimientos firmados
|
||||
→ muestra alerta visual; no permite avanzar el estado
|
||||
3. Si todos los consentimientos están firmados:
|
||||
→ Estado "en_muestra"
|
||||
→ Se validan los exámenes registrados en recepción
|
||||
4. Al terminar la toma: estado "finalizado"
|
||||
|
||||
──── 5.4 CONSENTIMIENTOS INFORMADOS ─────────────────────────────────────────
|
||||
|
||||
INTEGRACIÓN CON MÓDULO FORMULARIOS (REUTILIZAR lo que ya existe):
|
||||
• Los consentimientos son Formularios del módulo lab_formularios/
|
||||
• Se marca en la configuración del formulario si es de tipo "consentimiento"
|
||||
usando un campo nuevo: tipo ENUM(formulario, consentimiento)
|
||||
• Enlace público ya existe en el módulo → se reutiliza tal cual
|
||||
• Firma digital ya implementada → se reutiliza (canvas + checkbox legal)
|
||||
|
||||
CATÁLOGO DE TIPOS DE EXAMEN (exam_tipos):
|
||||
• Listado maestro de exámenes que ofrece el laboratorio (código + nombre)
|
||||
• Se crea en FASE 3 (Oleada 1) para dar soporte al turnero
|
||||
• La misma tabla se usa en Oleada 2 (registro_exams) sin cambios
|
||||
• Administrado desde la vista Configuración > Exámenes y Consentimientos
|
||||
|
||||
RELACIÓN EXAMEN ↔ CONSENTIMIENTO (exam_tipo_consentimientos):
|
||||
• Un consentimiento (formulario) puede cubrir VARIOS tipos de examen
|
||||
• Un examen puede estar en un solo consentimiento o en ninguno
|
||||
• Se configura UNA VEZ en el panel de administración, no en cada turno
|
||||
• Ejemplo:
|
||||
"Toma de muestra de sangre" → consentimiento id=3 ("Consentimiento hemograma")
|
||||
"Glucosa en ayunas" → consentimiento id=3
|
||||
"Cultivo de orina" → consentimiento id=5 ("Consentimiento urocultivo")
|
||||
"Presión arterial" → (sin consentimiento)
|
||||
|
||||
FLUJO DE CONSENTIMIENTOS:
|
||||
1. Recepción selecciona exámenes del turno (de la lista exam_tipos)
|
||||
2. Sistema busca en exam_tipo_consentimientos qué formularios aplican
|
||||
para los exámenes seleccionados → deduplica si varios exámenes
|
||||
comparten el mismo consentimiento → lista mínima de consentimientos
|
||||
3. Por cada consentimiento pendiente:
|
||||
• Se genera un token único (UUID) → link = /ver_formulario.php?token=XXX
|
||||
• Se registra en turnero_consentimientos con estado "pendiente"
|
||||
4. (Opcional) Recepción envía enlace por WhatsApp para pre-firma
|
||||
mientras el paciente espera en cola del Lugar
|
||||
5. En el Lugar (segunda llamada), el paciente puede firmar:
|
||||
OPCIÓN A: Hace clic en el enlace de WhatsApp en su celular
|
||||
OPCIÓN B: El auxiliar muestra la pantalla del puesto al paciente
|
||||
y firma directamente ahí (mismo ver_formulario_enviado.php)
|
||||
6. Al firmar → estado "firmado" en turnero_consentimientos
|
||||
7. Vista del Lugar muestra ✓ verde / ✗ rojo en tiempo real (polling 5s)
|
||||
BLOQUEO total si alguno pendiente → no se puede iniciar el servicio
|
||||
|
||||
MOMENTO DE LA FIRMA:
|
||||
• Preferiblemente antes de la segunda llamada (via WhatsApp, mientras espera)
|
||||
• Alternativamente EN la estación del Lugar (tablet del puesto)
|
||||
• NUNCA después de iniciado el servicio
|
||||
|
||||
EVIDENCIA REGISTRADA POR FIRMA:
|
||||
• Fecha y hora exacta
|
||||
• IP del firmante
|
||||
• User-Agent (dispositivo)
|
||||
• Versión del formulario/consentimiento al momento de firmar
|
||||
|
||||
──── 5.5 TABLAS BD NUEVAS ────────────────────────────────────────────────────
|
||||
|
||||
exam_tipos ← catálogo maestro de exámenes del laboratorio
|
||||
id, codigo VARCHAR(20), ← ej. "HEM", "GLU", "URIN"
|
||||
nombre VARCHAR(150), ← ej. "Hemograma completo"
|
||||
categoria VARCHAR(80), ← ej. "Hematología", "Química"
|
||||
activo TINYINT(1)
|
||||
NOTA: Esta tabla es compartida con Oleada 2 (registro_exams).
|
||||
En Oleada 2 se le agregan columnas precio_base, requiere_ayunas, etc.
|
||||
|
||||
exam_tipo_consentimientos ← relación M:N examen ↔ consentimiento
|
||||
id,
|
||||
exam_tipo_id INT FK exam_tipos,
|
||||
formulario_id INT FK lab_formularios, ← debe tener tipo='consentimiento'
|
||||
UNIQUE KEY (exam_tipo_id, formulario_id)
|
||||
NOTA: Si un examen no tiene registro aquí, no se exige consentimiento.
|
||||
Si varios exámenes del mismo turno apuntan al mismo formulario_id,
|
||||
se genera UN SOLO consentimiento (deduplicado en la lógica PHP).
|
||||
|
||||
turnero_lugares ← sub-módulo: estaciones/lugares de servicio
|
||||
id, nombre VARCHAR(100), ← ej. "Toma de Muestras 1", "Rayos X"
|
||||
descripcion TEXT,
|
||||
activo TINYINT(1),
|
||||
sort_order INT ← orden en la pantalla TV general
|
||||
NOTA: Recepción NO es un lugar; es el primer paso implícito del flujo.
|
||||
Cada lugar tiene su propia cola y su propia pantalla TV.
|
||||
|
||||
turnero_prioridades ← catálogo editable de códigos A-F
|
||||
id, codigo CHAR(1) UNIQUE, nombre VARCHAR(100),
|
||||
orden_peso INT, ← número menor = mayor prioridad
|
||||
color VARCHAR(7),
|
||||
activo TINYINT(1)
|
||||
|
||||
turnero_sesiones
|
||||
id, fecha, abierto_por INT FK admin_users, cerrado_por, inicio_at, fin_at
|
||||
(una sesión = un día de atención)
|
||||
id, fecha DATE,
|
||||
abierto_por INT FK admin_users, cerrado_por INT FK admin_users,
|
||||
inicio_at DATETIME, fin_at DATETIME
|
||||
|
||||
turnero_turnos
|
||||
id, sesion_id,
|
||||
numero INT, ← número correlativo de la sesión
|
||||
codigo VARCHAR(10), ← "A001", "B012"
|
||||
servicio_id,
|
||||
paciente_nombre VARCHAR(150),
|
||||
id, sesion_id FK turnero_sesiones,
|
||||
numero INT, ← correlativo dentro de la sesión
|
||||
codigo VARCHAR(10), ← "A001", "B012"
|
||||
prioridad_id INT FK turnero_prioridades,
|
||||
paciente_nombre VARCHAR(150), ← capturado en kiosko (opcional)
|
||||
paciente_cel VARCHAR(20),
|
||||
estado ENUM(espera, llamado, en_atencion, atendido, ausente, cancelado),
|
||||
modulo_atencion INT, ← puesto/ventanilla que atiende
|
||||
llamado_at, inicio_at, fin_at, creado_at
|
||||
estado ENUM(
|
||||
espera, ← código asignado, en cola general
|
||||
en_recepcion, ← recepcionista lo está procesando
|
||||
en_espera_lugar, ← solicitud creada, en cola del Lugar
|
||||
en_servicio, ← siendo atendido en el Lugar
|
||||
finalizado, ← proceso completo
|
||||
ausente, ← no se presentó
|
||||
cancelado
|
||||
),
|
||||
lugar_destino_id INT FK turnero_lugares NULL, ← asignado por recepción
|
||||
creado_at DATETIME,
|
||||
llamado_recepcion_at DATETIME,
|
||||
inicio_recepcion_at DATETIME,
|
||||
fin_recepcion_at DATETIME,
|
||||
llamado_lugar_at DATETIME,
|
||||
inicio_lugar_at DATETIME,
|
||||
fin_lugar_at DATETIME,
|
||||
atendido_recepcion_por INT FK admin_users NULL,
|
||||
atendido_lugar_por INT FK admin_users NULL
|
||||
|
||||
turnero_modulos
|
||||
id, nombre (ej. "Ventanilla 1"), activo, usuario_actual INT FK admin_users
|
||||
turnero_solicitudes ← solicitud interna de agendamiento (crea recepción)
|
||||
id,
|
||||
turno_id INT FK turnero_turnos UNIQUE, ← 1 solicitud por turno
|
||||
paciente_id INT FK lab_pacientes, ← vinculado en recepción
|
||||
lugar_id INT FK turnero_lugares, ← lugar de destino
|
||||
total_cobrado DECIMAL(10,2),
|
||||
metodo_pago ENUM(efectivo, transferencia, tarjeta, eps, cortesia),
|
||||
observaciones TEXT,
|
||||
creado_por INT FK admin_users,
|
||||
creado_at DATETIME
|
||||
|
||||
FLUJO:
|
||||
1. Recepcionista / kiosko crea turno → estado "espera"
|
||||
2. Operador en dashboard hace clic "Llamar siguiente"
|
||||
→ estado "llamado", pantalla TV muestra "A-001 → Ventanilla 2"
|
||||
→ (opcional) SMS/WhatsApp al paciente con su turno
|
||||
3. El paciente llega → operador pasa a "en_atención"
|
||||
4. Al terminar → "atendido"
|
||||
5. Si no aparece → "ausente" (puede regresar al final de la cola)
|
||||
turnero_examen_items ← exámenes de la solicitud
|
||||
id, solicitud_id FK turnero_solicitudes,
|
||||
exam_tipo_id INT FK exam_tipos,
|
||||
creado_at DATETIME
|
||||
|
||||
PANTALLA TV (display.php):
|
||||
• Sin login
|
||||
• Se actualiza por SSE (Server-Sent Events) cada vez que se llama un turno
|
||||
• Muestra: turno actual por cada ventanilla + próximos 5 en espera
|
||||
• Diseño visual grande, colores por servicio
|
||||
turnero_consentimientos ← consentimientos del turno (deduplicados)
|
||||
id, turno_id FK turnero_turnos,
|
||||
formulario_id INT FK lab_formularios,
|
||||
token VARCHAR(64) UNIQUE, ← enlace único de firma
|
||||
estado ENUM(pendiente, enviado, visto, firmado, rechazado),
|
||||
enviado_at DATETIME,
|
||||
firmado_at DATETIME,
|
||||
ip_firma VARCHAR(45),
|
||||
ua_firma VARCHAR(500),
|
||||
version_formulario INT ← snapshot de la versión al momento de firma
|
||||
|
||||
INTEGRACIÓN CON WHATSAPP (OPCIONAL):
|
||||
Cuando se llama el turno → enviar mensaje al paciente si dejó celular
|
||||
Usar WhatsAppService ya existente.
|
||||
formularios.tipo ← columna nueva en tabla existente lab_formularios
|
||||
ALTER TABLE lab_formularios ADD COLUMN tipo
|
||||
ENUM('formulario','consentimiento') DEFAULT 'formulario';
|
||||
|
||||
DIAGRAMA DE RELACIONES CLAVE:
|
||||
|
||||
lab_formularios (tipo='consentimiento')
|
||||
│ 1
|
||||
│
|
||||
exam_tipo_consentimientos ─────── exam_tipos
|
||||
(M:N) │ 1
|
||||
│ N
|
||||
turnero_examen_items
|
||||
│ N
|
||||
│ 1
|
||||
turnero_solicitudes ───── turnero_lugares
|
||||
│ 1
|
||||
│ 1
|
||||
turnero_turnos
|
||||
│ 1
|
||||
│ N
|
||||
turnero_consentimientos
|
||||
(un registro por formulario distinto requerido por el turno)
|
||||
|
||||
──── 5.6 INTEGRACIONES CON MÓDULOS EXISTENTES ──────────────────────────────
|
||||
|
||||
• lab_pacientes → buscar/crear paciente al crear la solicitud en recepción
|
||||
• lab_formularios → los consentimientos SON formularios del sistema
|
||||
• ver_formulario_enviado.php → página pública de firma (ya funcional)
|
||||
se abre también desde la pantalla del Lugar
|
||||
• WhatsAppService → envío del enlace de consentimiento (opcional, entre llamadas)
|
||||
• Plantillas Meta → crear plantilla aprobada "consentimiento_turno"
|
||||
• exam_tipos → catálogo compartido con Oleada 2 (registro_exams)
|
||||
|
||||
──── 5.7 PANTALLA TV / DISPLAY ─────────────────────────────────────────────
|
||||
|
||||
Hay VARIOS tipos de pantalla TV, todas sin login:
|
||||
|
||||
TV RECEPCIÓN (?display=recepcion)
|
||||
• Cola general (turnos en estado 'espera' ordenados por prioridad)
|
||||
• Turno actualmente en recepción (código grande + "DIRÍJASE A RECEPCIÓN")
|
||||
|
||||
TV POR LUGAR (?display=lugar&lugar_id=X)
|
||||
• Cola del Lugar X (turnos en 'en_espera_lugar' con ese lugar_destino_id)
|
||||
• Turno en servicio activo del Lugar X (código grande)
|
||||
• Cadaestación tiene su propia TV configurada con su lugar_id
|
||||
|
||||
COMPORTAMIENTO COMÚN:
|
||||
• Actualización por SSE en tiempo real sin reload
|
||||
• Colores grandes por código de prioridad
|
||||
• Animación + sonido corto al llamar un turno
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
@@ -350,10 +588,16 @@ Migración 002 – Nuevos roles
|
||||
('Operador Bot', 'operador_bot', 'Gestión de conversaciones', '#6f42c1', 0);
|
||||
|
||||
Migración 003 – Turnero [Oleada 1]
|
||||
CREATE TABLE turnero_servicios (...)
|
||||
CREATE TABLE turnero_sesiones (...)
|
||||
CREATE TABLE turnero_turnos (...)
|
||||
CREATE TABLE turnero_modulos (...)
|
||||
CREATE TABLE exam_tipos (...) ← catálogo maestro compartido con Oleada 2
|
||||
CREATE TABLE exam_tipo_consentimientos(...) ← M:N: examen ↔ formulario consentimiento
|
||||
CREATE TABLE turnero_lugares (...) ← sub-módulo: estaciones configurables
|
||||
CREATE TABLE turnero_prioridades (...) ← catálogo A-F configurable
|
||||
CREATE TABLE turnero_sesiones (...) ← sesión diaria de atención
|
||||
CREATE TABLE turnero_turnos (...) ← turno con lugar_destino_id
|
||||
CREATE TABLE turnero_solicitudes (...) ← solicitud interna de agendamiento
|
||||
CREATE TABLE turnero_examen_items (...) ← exámenes de la solicitud
|
||||
CREATE TABLE turnero_consentimientos (...) ← firma digital por consentimiento
|
||||
ALTER TABLE lab_formularios ADD COLUMN tipo ENUM('formulario','consentimiento') DEFAULT 'formulario'
|
||||
|
||||
Migración 004 – SYSTEM_MODULES dinámica (mover de config.php a BD) [Oleada 1]
|
||||
CREATE TABLE system_modules (
|
||||
@@ -372,7 +616,10 @@ Migración 004 – SYSTEM_MODULES dinámica (mover de config.php a BD) [Oleada
|
||||
config.php mantiene el array como fallback hasta que la BD esté lista.
|
||||
|
||||
Migración 005 – Registro de exámenes [Oleada 2]
|
||||
CREATE TABLE exam_tipos (...)
|
||||
-- exam_tipos ya existe desde Migración 003; solo agregar columnas:
|
||||
ALTER TABLE exam_tipos ADD COLUMN precio_base DECIMAL(10,2) NULL;
|
||||
ALTER TABLE exam_tipos ADD COLUMN requiere_ayunas TINYINT(1) DEFAULT 0;
|
||||
ALTER TABLE exam_tipos ADD COLUMN instrucciones TEXT NULL;
|
||||
CREATE TABLE exam_ordenes (...)
|
||||
CREATE TABLE exam_items (...)
|
||||
CREATE TABLE exam_etiquetas(...)
|
||||
@@ -431,7 +678,7 @@ GRUPOS DEL MENÚ LATERAL:
|
||||
🧪 Clínico (Oleada 2)
|
||||
Registro Exámenes | Resultados
|
||||
🎟️ Turnero (Oleada 1)
|
||||
Dashboard | Configurar Servicios
|
||||
Dashboard | Recepción | Toma de Muestras | Kiosko | Configuración
|
||||
📊 Reportes
|
||||
Ingresos | Rendimiento | Exportar
|
||||
⚙️ Sistema
|
||||
@@ -467,21 +714,242 @@ FASE 2 – SYSTEM_MODULES dinámica (2 días) ✅ COMPLETADA
|
||||
|
||||
── MÓDULOS NUEVOS ────────────────────────────────────────────────────────────
|
||||
|
||||
FASE 3 – Turnero MVP — Oleada 1 (3-5 días)
|
||||
□ Migración 003: tablas turnero_*
|
||||
□ modules/turnero/module.php + views/ + api/
|
||||
□ Pantalla kiosko (toma turno, sin login)
|
||||
□ Pantalla display TV (SSE, sin login)
|
||||
□ Dashboard admin (llamar, gestionar)
|
||||
□ Registrar slug turnero en system_modules
|
||||
FASE 3 – Turnero MVP — Oleada 1
|
||||
|
||||
FASE 3.1 – Base de datos y configuración (1 día) ✅ COMPLETADA
|
||||
──────────────────────────────────────────────────
|
||||
✓ Migración 003: crear tablas
|
||||
CREATE exam_tipos ← catálogo maestro (compartido con Oleada 2)
|
||||
CREATE exam_tipo_consentimientos ← M:N: examen↔formulario
|
||||
CREATE turnero_lugares ← estaciones de servicio configurables
|
||||
CREATE turnero_prioridades (insertar datos A-F por defecto)
|
||||
CREATE turnero_sesiones
|
||||
CREATE turnero_turnos ← con lugar_destino_id
|
||||
CREATE turnero_solicitudes ← solicitud interna de agendamiento
|
||||
CREATE turnero_examen_items ← FK solicitud_id
|
||||
CREATE turnero_consentimientos
|
||||
ALTER lab_formularios ADD tipo ENUM(formulario, consentimiento)
|
||||
✓ modules/turnero/module.php (descriptor)
|
||||
✓ Registrar slug 'turnero' en system_modules
|
||||
✓ Asignar módulo turnero a roles recepcionista y bacteriologo
|
||||
|
||||
✅ FASE 3.2 – Motor de cola y API core (1 día) [COMPLETADA]
|
||||
──────────────────────────────────────────────
|
||||
✓ api/create_turno.php
|
||||
• Crea/abre sesión del día si no existe
|
||||
• Genera número correlativo + código (ej. "A001") con FOR UPDATE
|
||||
• Admite paciente_nombre + paciente_cel (opcional)
|
||||
• Retorna código, número y posición en cola
|
||||
✓ api/llamar_turno.php
|
||||
• Recibe area (recepcion|lugar) + lugar_id
|
||||
• Motor de prioridades: SELECT menor orden_peso → menor creado_at
|
||||
• Área lugar: solo turnos en estado en_espera_lugar para ese lugar
|
||||
• Retorna turno llamado o null si cola vacía
|
||||
✓ api/cambiar_estado.php
|
||||
• Avanza estado con mapa de transiciones explícito
|
||||
• Bloquea en_espera_lugar→en_servicio si hay consentimientos pendientes (422)
|
||||
• Registra timestamps llamado_at / inicio_at / fin_at por área
|
||||
✓ api/get_cola.php
|
||||
• Cola actual por área (recepcion | lugar + lugar_id)
|
||||
• Turno activo + listado + estadísticas de sesión
|
||||
✓ api/sse_turno.php
|
||||
• SSE: emite 'cola_update' cuando cambia sse_ping_at en la sesión
|
||||
• ALTER TABLE IF NOT EXISTS para sse_ping_at (idempotente)
|
||||
• Keep-alive ": ping" cada 15 s, forzar refresh cada 30 s
|
||||
• Compatible con pantalla TV sin necesidad de polling activo
|
||||
|
||||
✅ FASE 3.3 – Pantallas sin login (1 día) [COMPLETADA]
|
||||
────────────────────────────────────────
|
||||
✓ views/kiosko.php
|
||||
• Pantalla táctil fullscreen 3 pasos: prioridad → datos → ticket
|
||||
• Botones A-F cargados de BD (icono + nombre + descripción + color)
|
||||
• Campo opcional: nombre y celular con validación de formato
|
||||
• Muestra código + posición en cola; auto-reinicio tras 30 s
|
||||
• Sin login; fetch POST a create_turno.php
|
||||
✓ views/display.php
|
||||
• Pantalla TV fullscreen, sin login (HTML puro, sin <?php)
|
||||
• ?display=recepcion → cola general
|
||||
• ?display=lugar&lugar_id=X → cola del Lugar X
|
||||
• SSE EventSource a sse_turno.php con reconexión exponencial
|
||||
• Código activo gigante con color de prioridad + lista de espera
|
||||
• Web Audio API para beep al llamar — sin archivos externos
|
||||
• Stats footer: en espera / atendidos / total / tiempo promedio
|
||||
|
||||
✅ FASE 3.4 – Puesto de Recepción (1 día) [COMPLETADA]
|
||||
────────────────────────────────────────
|
||||
✓ views/recepcion.php
|
||||
• Requiere login + módulo turnero; layout 2 columnas: cola | ficha
|
||||
• Cola izquierda: turnos 'espera' con color de prioridad, polling 8 s
|
||||
• Botón "Llamar siguiente" → llama_turno.php area=recepcion
|
||||
• Ficha derecha al llamar:
|
||||
- Nombre del kiosko pre-cargado en buscador
|
||||
- Buscador de paciente: GET /api/lab/get_pacientes.php?busqueda=
|
||||
- Selector de lugar destino + checkboxes de exámenes por categoría
|
||||
- Campo cobro + forma de pago + observaciones
|
||||
- Sección consentimientos (aparece tras guardar si aplican)
|
||||
- Botón "Pasar a lugar" → cambiar_estado en_espera_lugar
|
||||
- Botón "Ausente"
|
||||
✓ api/create_solicitud.php
|
||||
• POST, requireTurnero(); validaciones completas
|
||||
• DELETE + INSERT (permite re-guardar para correcciones)
|
||||
• Inserta turnero_solicitudes + N turnero_examen_items en transacción
|
||||
• Devuelve solicitud + consentimientos_requeridos (estado actual de c/u)
|
||||
✓ api/send_consentimiento.php
|
||||
• Deduplica formularios: N exámenes → M formularios distintos (M ≤ N)
|
||||
• Genera UUID por cada formulario; INSERT IGNORE para no duplicar
|
||||
• No reenvía consentimientos ya firmados o rechazados
|
||||
• Intenta sendTemplateMessage('consentimiento_turno'); fallback texto plano
|
||||
• Normaliza celular (+57 por defecto Colombia)
|
||||
• Registra enviado_at; retorna lista con enlace_firma por c/u
|
||||
• Retorna lista de consentimientos enviados
|
||||
|
||||
✅ FASE 3.5 – Puesto Lugar / Estación de Servicio (1 día) [COMPLETADA]
|
||||
────────────────────────────────────────────────────────
|
||||
✓ views/lugar.php (?lugar_id=X)
|
||||
• Genérica: funciona para cualquier lugar (Muestras, Rayos X, etc.)
|
||||
• Overlay selector si no viene lugar_id en URL; botón "Cambiar lugar"
|
||||
• Requiere login (isUserLoggedIn)
|
||||
• Cola izquierda: turnos 'en_espera_lugar' del lugar, polling 7 s
|
||||
• Botón "Llamar siguiente" → llamar_turno.php area=lugar
|
||||
• Ficha derecha al llamar (carga vía get_consentimientos.php?incluir_solicitud=1):
|
||||
- Datos del paciente (nombre, doc, fecha nac, celular)
|
||||
- Exámenes como pills coloreadas
|
||||
- Consentimientos con estado visual (firmado/enviado/visto/pendiente)
|
||||
- BLOQUEO: "Iniciar atención" disabled + banner rojo si hay pendientes
|
||||
- Botón "Reenviar WhatsApp" → send_consentimiento.php
|
||||
- Botón "Firmar aquí" → abre ver_formulario_enviado.php en modal/iframe
|
||||
- "Iniciar atención" → cambiar_estado en_servicio (validado en API)
|
||||
- "Finalizar" → estado finalizado
|
||||
- "Regresar a cola" → estado en_espera_lugar
|
||||
- "Ausente" → estado ausente
|
||||
• Polling de consentimientos cada 5 s mientras hay turno activo
|
||||
✓ api/get_consentimientos.php
|
||||
• GET público dentro del módulo (ruta protegida por la vista)
|
||||
• ?turno_id=X → retorna arreglo de consentimientos con nombre del formulario
|
||||
• ?incluir_solicitud=1 → también retorna solicitud + paciente + exámenes
|
||||
|
||||
FASE 3.6 – Firma digital (reutilizar formularios) (0.5 días) ✅ COMPLETADA
|
||||
──────────────────────────────────────────────────────────────
|
||||
✅ Marcar formularios de consentimiento en la interfaz de admin:
|
||||
lab_formularios → campo tipo = 'consentimiento'
|
||||
✅ Al firmar ver_formulario_enviado.php:
|
||||
• Detectar si el token corresponde a un turno (turnero_consentimientos)
|
||||
• Actualizar turnero_consentimientos.estado = 'firmado'
|
||||
• Registrar ip_firma, ua_firma, firmado_at, version_formulario
|
||||
• Guardar firma_svg (base64 PNG) en turnero_consentimientos
|
||||
• Notificar SSE → lugar.php/recepcion.php actualizan en tiempo real
|
||||
✅ Vista lugar.php tiene botón "Firmar aquí" → abre el mismo
|
||||
ver_formulario_enviado.php en un modal (iframe), con canvas de firma
|
||||
para firma física en la tablet del puesto
|
||||
✅ lugar.php detecta la firma en tiempo real (polling 5s) +
|
||||
postMessage instantáneo desde el iframe al firmarse
|
||||
|
||||
FASE 3.7 – Panel Admin Turnero + configuración (0.5 días) ✅ COMPLETADA
|
||||
───────────────────────────────────────────────────────────
|
||||
✅ views/configuracion.php — 4 pestañas:
|
||||
|
||||
TAB 1: Lugares ✅
|
||||
• CRUD de turnero_lugares (nombre, descripción, activo, orden)
|
||||
• Cada lugar muestra su URL de display → botón copia rápida
|
||||
• URLs de recepción y kiosko también accesibles
|
||||
• API: save_lugar.php (GET/POST crear/actualizar/eliminar con guardia FK)
|
||||
|
||||
TAB 2: Exámenes y Consentimientos ✅
|
||||
• CRUD de exam_tipos (código, nombre, categoría, activo)
|
||||
• Por cada exam_tipo: selector de consentimiento (formularios tipo='consentimiento')
|
||||
→ Guarda/actualiza en exam_tipo_consentimientos (deduplicado)
|
||||
• Vista inversa: por consentimiento → lista de exámenes vinculados
|
||||
• API: save_ex_tipo.php (GET/POST; eliminación bloqueada si hay solicitudes)
|
||||
|
||||
TAB 3: Prioridades ✅
|
||||
• Edición de nombre, color, orden, activo (sin eliminación)
|
||||
• Picker de color sincronizado con campo hexadecimal
|
||||
• API: save_prioridad.php (validación de formato #RRGGBB)
|
||||
|
||||
TAB 4: Sesión y WhatsApp ✅
|
||||
• Abrir / cerrar / reabrir sesión del día con un clic
|
||||
• Historial de sesiones (últimas 30)
|
||||
• Configuración de plantilla WhatsApp (nombre + código idioma)
|
||||
• API: sesion_turno.php (acciones: abrir, cerrar, reabrir, config_wa)
|
||||
|
||||
✅ views/dashboard.php (admin)
|
||||
• Resumen del día: turnos atendidos, tiempo promedio, pendientes
|
||||
• KPI cards + barras por prioridad + tarjetas por lugar
|
||||
• Tabla detalle de todos los turnos con búsqueda local
|
||||
• Consentimientos del día (desglose por estado)
|
||||
• Selector de fecha (consulta histórica)
|
||||
• Auto-refresh cada 30s (solo si fecha = hoy)
|
||||
• API: get_dashboard.php (consultas agregadas por sesión)
|
||||
• Exportar CSV: export_csv.php (BOM UTF-8, 24 columnas, listo para Excel)
|
||||
|
||||
FASE 4 – Oleada 2 (Registro de Exámenes + futuros)
|
||||
□ Migración 005: tablas exam_*
|
||||
□ Catálogo de tipos de examen (CRUD admin)
|
||||
□ Flujo de recepción: buscar paciente → crear orden → agregar ítems
|
||||
□ Vista bacteriólogo: lista del día, cambiar estados
|
||||
□ Impresión de etiquetas (PDF A6)
|
||||
□ Conectar con lab_pacientes (reutilizar buscador existente)
|
||||
|
||||
FASE 4.1 – Base de datos (migration 005) ✅ COMPLETADA
|
||||
─────────────────────────────────────────────────────
|
||||
✓ migrations/005_registro_exams.sql
|
||||
ALTER exam_tipos → precio_base, requiere_ayuno, horas_ayuno, instrucciones
|
||||
CREATE exam_ordenes (código EX-YYYYMMDD-NNNN, prioridad, estado, FK paciente)
|
||||
CREATE exam_items (estado por ítem, notas_tecnico)
|
||||
CREATE exam_muestras (trazabilidad: tipo, código_barras, estado)
|
||||
CREATE exam_resultados (campo, valor, unidad, referencia, es_anormal)
|
||||
UPDATE system_modules SET is_active=1 WHERE slug='registro_exams'
|
||||
INSERT role_module_access para bacteriólogo y recepcionista
|
||||
✓ run_005_registro_exams.php (runner idempotente)
|
||||
|
||||
FASE 4.2 – Módulo descriptor y helpers ✅ COMPLETADA
|
||||
─────────────────────────────────────────────────────
|
||||
✓ modules/registro_exams/module.php
|
||||
✓ modules/registro_exams/api/_helpers.php
|
||||
requireExams(), generarCodigoOrden(), jsonOk(), jsonError(), db()
|
||||
|
||||
FASE 4.3 – Lista del día ✅ COMPLETADA
|
||||
─────────────────────────────────────────────────────
|
||||
✓ modules/registro_exams/views/lista.php
|
||||
KPI cards (total/pendientes/en_proceso/completas)
|
||||
Filtros: fecha + estado + búsqueda libre
|
||||
Auto-refresh 45 s; paginación
|
||||
✓ modules/registro_exams/api/get_ordenes.php
|
||||
GET ?fecha=&estado=&busqueda=&page=&limit=
|
||||
Incluye edad calculada, contadores de ítems y muestras
|
||||
|
||||
FASE 4.4 – Nueva orden ✅ COMPLETADA
|
||||
─────────────────────────────────────────────────────
|
||||
✓ modules/registro_exams/views/nueva_orden.php
|
||||
Buscador de paciente (reutiliza GET /api/lab/get_pacientes.php)
|
||||
Catálogo de exámenes en checkbox agrupados por categoría
|
||||
Filtro de búsqueda en catálogo; badge de ayuno y precio
|
||||
Pre-carga paciente si viene ?solicitud_id= del turnero
|
||||
✓ modules/registro_exams/api/save_orden.php
|
||||
POST crear/editar; genera código EX-YYYYMMDD-NNNN
|
||||
Sync de ítems: inserta nuevos, elimina pendientes removidos
|
||||
Redirige a orden creada al guardar
|
||||
|
||||
FASE 4.5 – Detalle de orden + resultados ✅ COMPLETADA
|
||||
─────────────────────────────────────────────────────
|
||||
✓ modules/registro_exams/views/orden.php
|
||||
Cards: paciente, datos médicos (prioridad + estado badges)
|
||||
Tabla de muestras + modal "Registrar muestra" (tipo + barcode + estado)
|
||||
Lista de ítems con estado individual + dropdown cambio de estado
|
||||
Modal de resultados: tabla editable (campo/valor/unidad/referencia/anormal)
|
||||
Botón "Marcar entregada"; auto-cierre de orden cuando todos listos
|
||||
✓ modules/registro_exams/api/get_orden.php
|
||||
GET ?id= → orden + ítems + resultados + muestras
|
||||
✓ modules/registro_exams/api/save_resultado.php
|
||||
POST reemplaza resultados de un ítem; auto-marca resultado_listo
|
||||
Auto-cierra orden a 'completa' si todos los ítems tienen resultado
|
||||
✓ modules/registro_exams/api/cambiar_estado_item.php
|
||||
POST tipo=item|muestra|orden; crea muestras nuevas (tipo=muestra, id=null)
|
||||
Al crear muestra: pasa ítems pendientes a muestra_tomada + orden a en_proceso
|
||||
|
||||
FASE 4.6 – Etiqueta imprimible ✅ COMPLETADA
|
||||
─────────────────────────────────────────────────────
|
||||
✓ modules/registro_exams/views/etiqueta.php
|
||||
Página autónoma A6 landscape (sin sidebar, sin Layout::open)
|
||||
Código de barras visual (fuente Libre Barcode 128 via Google Fonts)
|
||||
Datos: paciente, doc, edad, EPS, prioridad, lista de exámenes
|
||||
Aviso de ayuno si algún ítem lo requiere
|
||||
window.print() automático al cargar (delay 800 ms para fuente)
|
||||
|
||||
□ Facturación, Inventario, CRM, Portal Paciente…
|
||||
□ API pública con tokens (para integraciones)
|
||||
□ App móvil (portal enfermero actual → Progressive Web App)
|
||||
@@ -519,28 +987,47 @@ API RESPONSE FORMAT (ya establecido, mantener):
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
12. DECISIONES CLAVE A CONFIRMAR CON EL CLIENTE
|
||||
12. DECISIONES CONFIRMADAS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
1. ¿El turnero es para UNA sede o múltiples sedes?
|
||||
(Multi-sede requiere añadir sede_id a las tablas)
|
||||
✔ 1. Sede única — No se requiere sede_id en las tablas.
|
||||
|
||||
2. ¿Facturación electrónica (DIAN) es obligatorio desde el inicio
|
||||
o puede dejarse para Oleada 2?
|
||||
✔ 2. Facturación electrónica DIAN — No se maneja en esta fase.
|
||||
Queda pendiente para una oleada futura.
|
||||
|
||||
3. ¿El portal de entrega de resultados es para los pacientes directamente
|
||||
(requiere login/token para pacientes) o solo descarga interna?
|
||||
✔ 3. Portal de resultados para pacientes — No se requiere aún.
|
||||
La entrega de resultados es solo gestión interna por ahora.
|
||||
|
||||
4. ¿Se quiere app móvil nativa o es suficiente con PWA/responsive?
|
||||
✔ 4. App móvil / PWA — No se usará PWA.
|
||||
Solo se aplica diseño responsive a: pantalla TV (display) y kiosko.
|
||||
El resto del sistema funciona como web normal desde PC.
|
||||
|
||||
5. ¿Los exámenes tienen que integrar con algún analizador automático
|
||||
(interfaz LIS) o el resultado se digita manual?
|
||||
✔ 5. Multi-tenant — Instalación para un solo cliente.
|
||||
Sin aislamiento multi-tenant en la BD.
|
||||
|
||||
6. ¿El turno se puede tomar ANTES de llegar (turno virtual por WhatsApp)?
|
||||
Esto conecta el módulo Turnero con el Bot.
|
||||
✔ 6. Consentimientos por examen — Se configura UNA VEZ en el panel admin.
|
||||
Relación M:N: exam_tipos ↔ lab_formularios (exam_tipo_consentimientos).
|
||||
El recepcionista no los marca manualmente; el sistema los calcula
|
||||
automáticamente según los exámenes del turno.
|
||||
|
||||
7. ¿El sistema será multi-tenant (varios laboratorios/clientes en el mismo
|
||||
servidor) o siempre una instalación por cliente?
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
12B. DECISIONES PENDIENTES DE CONFIRMAR
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
1. ¿Los exámenes integran con algún analizador automático (interfaz LIS)
|
||||
o el resultado se digita manual?
|
||||
(Impacta diseño de Oleada 2 — registro_exams)
|
||||
|
||||
2. ¿El turno se puede tomar ANTES de llegar (turno virtual por WhatsApp)?
|
||||
(Conectaría el módulo Turnero con el Bot de WhatsApp)
|
||||
|
||||
3. ¿Cuántas ventanillas de Recepción y cuántas estaciones de servicio
|
||||
(Toma de Muestras, Rayos X, etc.) se configurarán inicialmente?
|
||||
(Ayuda a diseñar la pantalla TV y el layout de recepción)
|
||||
|
||||
4. ¿Debe bloquearse TOTALMENTE la atención si hay un consentimiento pendiente,
|
||||
o solo mostrar advertencia y dejar que el auxiliar decida continuar?
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
@@ -556,11 +1043,18 @@ API RESPONSE FORMAT (ya establecido, mantener):
|
||||
✓ Módulos de laboratorio maduros
|
||||
|
||||
Lo que HAY QUE CONSTRUIR para el ERP:
|
||||
→ Estructura de carpetas por módulo (core/ + modules/)
|
||||
→ Router centralizado y sidebar dinámico
|
||||
→ Estructura de carpetas por módulo (core/ + modules/) ✓ hecho
|
||||
→ Router centralizado y sidebar dinámico ✓ hecho
|
||||
→ RBAC con granularidad de acciones (can_view/create/edit/delete/export)
|
||||
→ Módulo Turnero — Oleada 1 (3-5 días)
|
||||
→ SYSTEM_MODULES en BD (en lugar de hardcoded en config.php)
|
||||
→ Módulo Turnero — Oleada 1 (5-7 días)
|
||||
FASE 3.1 – BD y configuración (turnero_lugares + solicitudes + exam_tipos)
|
||||
FASE 3.2 – Motor de cola + API core (create_solicitud, llamar, SSE)
|
||||
FASE 3.3 – Pantallas sin login (kiosko + display TV por lugar)
|
||||
FASE 3.4 – Puesto de Recepción (solicitud + asignar lugar)
|
||||
FASE 3.5 – Puesto Lugar/Estación genérico (consentimientos + servicio)
|
||||
FASE 3.6 – Firma digital (reutilizar formularios, firmar en tablet)
|
||||
FASE 3.7 – Panel Admin + configuración (4 tabs)
|
||||
→ SYSTEM_MODULES en BD (en lugar de hardcoded en config.php) ✓ hecho
|
||||
→ Módulo Registro de Exámenes — Oleada 2 (5-7 días, pendiente)
|
||||
|
||||
Estrategia: EVOLUCIÓN INCREMENTAL, no reescritura.
|
||||
|
||||
Reference in New Issue
Block a user