Commit Graph
452 Commits
Author SHA1 Message Date
Lizandro GuarnizoandClaude Sonnet 4.6 98507ad1a5 fix(turnero): restaurar dos plantillas WhatsApp en tab Sesión
- Plantilla con consentimiento (turnero_wa_template)
- Plantilla muestra pendiente (turnero_wa_template_muestra)
- sesion_turno.php guarda ambas en lab_config

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:17:17 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 a592ddb30d fix: restaurar cambios revertidos por rebase del servidor
- verificar.php: BASE_URL absoluta en fetch, fix paste multi-dígito
- send_otp.php: mensaje SMS correcto sin dos puntos ni expiración
- module.php: Chat Turnero y Verificar Paciente para recepcionistas

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:13:39 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 34004b4d98 feat(turnero): opción solo entrega de muestras con prioridad y badge naranja en cola
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:07:05 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 76dda4722a feat(turnero): pago combinado con desglose por efectivo, transferencia y tarjeta
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:02:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 4626ca3f28 feat(display): nombre paciente más grande y visible en overlay de llamada
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:58:09 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 38bd211ca6 feat(kiosko): mostrar nombre/cédula en ticket y quitar posición en cola
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:53:39 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c9e5744de4 feat(turnero): campo embarazada en recepción y badge en toma de muestras
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:48:03 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 7475f3c58e fix(turnero): mostrar nombre del paciente en cola al vincularlo en recepción
Al vincular un paciente al turno, actualiza paciente_nombre con el
nombre_completo real de lab_pacientes. El siguiente poll de la cola
muestra el nombre en lugar de la cédula del kiosko.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:35:45 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 8074f33b32 fix(turnero): eliminar duplicados en pantalla TV al llamar turno
callKey usaba id+llamado_at: si llamado_at llegaba null en el primer
poll y con valor en el segundo, se generaban dos claves distintas para
el mismo evento y el turno se anunciaba dos veces.

Cambia callKey a String(id) — cada turno se anuncia una sola vez
por sesión de pantalla, sin importar cambios en el timestamp.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:32:31 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c4154b5b61 fix(turnero): deduplicar historial de llamados por turno en pantalla TV
El array 'llamados' acumulaba una entrada por cada lugar al que pasaba
un turno (recepción + toma de muestras). Al insertar un nuevo llamado
se elimina la entrada previa del mismo turno, dejando solo el último lugar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:28:21 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 910edeb876 feat(turnero): botón de llamado por registro en lugar/toma de muestras
- Agrega botón campana por cada card en cola (solo turnos en_espera_lugar)
- Click en card abre ficha sin llamar; campana llama ese turno específico
- Llamar siguiente ahora también llama de verdad (antes solo abría ficha)
- Cards en_servicio mantienen indicador de estetoscopio sin botón

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:25:34 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 6adbcc3059 feat(turnero): modal completo de paciente en recepción
- Reemplaza window.open a lab_pacientes.php por modal Bootstrap inline
- Modal incluye campos completos: datos personales, contacto (con verificador WA), ubicación y EPS
- Botón Ver/Editar en paciente vinculado carga datos desde API y abre modal en modo edición
- Botón Cambiar desvincula y enfoca el buscador
- Al crear: seleccionarPaciente() auto-vincula al turno y cierra modal
- Al editar: actualiza labels en pantalla sin perder el turno activo

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:02:24 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 e90cfda3f3 feat(dashboard): accesos rápidos en dropdown por grupo, filtrado por rol
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 09:03:57 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 d6e1d083f4 revert(sidebar): eliminar sub-acordeón — restaurar sidebar y module.php a estado estable
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:56:42 -05:00
Lizandro Guarnizo f724e2e94c Revert "fix(recepcion): mostrar nombre, cédula y celular en resultados de búsqueda de paciente"
This reverts commit 1af731ee44.
2026-06-24 08:54:17 -05:00
Lizandro Guarnizo 86be0669af Revert "fix(recepcion): reemplazar template literals anidados por concatenación compatible"
This reverts commit 0021af36a5.
2026-06-24 08:54:17 -05:00
Lizandro Guarnizo 3b1b7c9333 Revert "fix(sidebar): null-check en route de children para evitar TypeError en PHP 8.2"
This reverts commit ba27511414.
2026-06-24 08:54:17 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ba27511414 fix(sidebar): null-check en route de children para evitar TypeError en PHP 8.2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:52:26 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 0021af36a5 fix(recepcion): reemplazar template literals anidados por concatenación compatible
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:50:47 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 1af731ee44 fix(recepcion): mostrar nombre, cédula y celular en resultados de búsqueda de paciente
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:45:43 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 af584bcc26 feat(pacientes): verificar WhatsApp al ingresar teléfono, vincular user_id al guardar
fix(recepcion): mostrar nombre_completo en resultados de búsqueda de paciente

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:44:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 bbee9c0a5c feat(sidebar): sub-acordeón para recepción y estaciones de muestras en turnero
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:35:42 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 90baff34f9 fix(turnero): agregar sidebar toggle en vistas standalone (recepcion, lugar, configuracion)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:31:08 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 da594e0021 fix(dashboard): mostrar todos los escritorios y lugares sin agrupar ni limitar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:28:06 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 5f0565eca2 feat(dashboard): quitar botón atrás, agregar accesos rápidos a recepción y lugares
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:24:36 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 841acf9a85 feat(turnero): filtrar sidebar por rol — recep ve solo sus desks, bacteriologo ve sus estaciones
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:56:38 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 0f07ee22c7 feat: dropdown destino muestra Toma de Muestras, Pediatría y Ginecología
Las 8 estaciones de muestras ya comparten grupo_id=1, así que se
agrupan en una sola opción 'Toma de Muestras'. Pediatría y Ginecología
tienen grupo_id=NULL y aparecen como destinos independientes.
Cualquier estación del grupo ve los turnos asignados a él.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:39:43 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c0f99fe9bc feat: mostrar todos los lugares destino en dropdown de recepción
El dropdown solo mostraba el primer lugar tipo muestras (LIMIT 1).
Ahora carga todos los lugares activos tipo muestras, incluyendo
Pediatría y Ginecología que ya estaban en la BD.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:37:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 f533891c5e fix: transición no permitida al pasar a lugar desde turno en espera
Cuando la recepcionista seleccionaba un turno de la cola sin llamarlo
formalmente (via seleccionarTurno), el turno quedaba en estado espera
en BD. Al intentar pasar a lugar, espera→en_espera_lugar no es válido.

Fix: en create_solicitud.php, si el turno está en espera al guardar
la solicitud, se promueve a en_recepcion en el mismo transaction,
preservando timestamps existentes con COALESCE.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:36:36 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 64f2e7c784 fix: recepcion_desk_id quedaba NULL en historial
Agregado selector de escritorio al abrir recepcion.php sin desk_id.
Si hay múltiples escritorios muestra un modal para elegir; si hay uno
solo se asigna automáticamente. Así recepcion_desk_id siempre queda
registrado en el turno y aparece correctamente en el historial.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:27:28 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 e80c1d180d fix: eliminar auto-llamado al siguiente turno tras pasar a lugar
La recepcionista debe llamar manualmente al siguiente turno.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:04:44 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 449b492eea fix: turno aparecía 3 veces en lista de llamados en display_global
El llamados.unshift no estaba protegido por callKey, así que el mismo
turno se agregaba una vez por cada escritorio de recepción. Ahora tanto
el anuncio como la entrada en la lista usan el mismo guard callKey.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:00:26 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 92adee6285 fix: display global sonaba 3 veces con 3 escritorios de recepción
Cuando recepcion_desk_id es NULL, el mismo turno aparecía en los 3
escritorios de recepción con claves distintas (incluían el nombre del
escritorio). Eso generaba 3 entradas nuevas en lastSeenKeys → 3 anuncios.

Fix: añadir announcedCalls Set con clave id|llamado_at (sin destino).
El sonido/anuncio solo se encola una vez por evento de llamada,
independientemente de cuántos escritorios devuelvan el mismo turno.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 00:54:56 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 4058cfe929 fix: sonido del turno se disparaba 3 veces en la pantalla TV
Dos causas:
1. sse_turno.php inicializaba \$lastPing = null, haciendo que la primera
   iteración del loop (2s después del emit inicial) siempre emitiera
   un snapshot extra aunque no hubiera cambios reales.
   Fix: inicializar \$lastPing con el sse_ping_at actual de la BD.

2. display.php comparaba activo.codigo para detectar nueva llamada.
   Si el poll y el SSE llegaban casi simultáneamente antes de que
   lastCodigoActivo se actualizara, ambos disparaban el sonido.
   Fix: comparar llamado_at en vez del código — el timestamp es
   único por llamada, por lo que sonidos duplicados son imposibles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 00:48:33 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 1c921fc7fa fix: tags de consentimiento en examenes ya no desbordan horizontalmente
- item-row con flex-wrap para que los tags pasen a la siguiente línea
- consent-tag con word-break y max-width para textos largos
- Botones de acción agrupados en .item-actions con margin-left:auto

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 00:33:35 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 cd3d3bb9c0 feat: IA configurable — probar conexión, activar/inactivar
- Toggle activo/inactivo en configuración → guarda ia_activa en lab_config
- Botón "Probar" llama api/lab/test_gemini.php con la clave actual
- test_gemini.php envía pregunta mínima a Gemini y confirma respuesta
- Dashboard oculta botón y panel IA cuando ia_activa != '1'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 23:16:06 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 a6f6449707 feat: número de orden consecutivo en recepción
- Campo N.° Orden editable en la ficha, antes de seleccionar paciente
- Se carga automáticamente al abrir un turno (YYYYMMDD-001, 002…)
- Botón para regenerar el siguiente consecutivo
- Columna numero_orden en turnero_solicitudes (VARCHAR 20)
- Nuevo endpoint get_consecutivo.php calcula el siguiente del día
- create_solicitud.php guarda el numero_orden junto con la solicitud

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 23:12:23 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9c9acbed70 feat: dashboard turnero muestra recepción, bacteriólogo y exámenes en tabla
- Columnas añadidas: Recepción (desk + recepcionista), Lugar/Bacteriólogo, Exámenes
- Elimina columnas Lugar y Entrada que eran menos informativas
- colspan actualizado a 10

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 23:06:40 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 406d542042 fix: restaurar recepcion.php original (eliminé contenido por error)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 20:54:38 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 453fb4219e fix: botón Volver en configuración turnero apunta al dashboard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 20:44:31 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 e8abffb607 fix: recepcion.php sin desk_id muestra selector de puestos
- Si llega con desk_id redirige a la URL canónica erp.php?m=turnero&v=recepcion&desk_id=N
- Si llega sin desk_id muestra lista de turnero_lugares activos para elegir
- Elimina acceso directo sin contexto de desk

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 20:29:18 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 d0152e37ce feat: asistente IA Gemini Flash en dashboard turnero + config token
- ai_chat.php: contexto completo (tiempos, facturación, franjas, turnos detallados)
- Preguntas soportadas: demoras por recepcionista, total facturado, horas pico,
  tiempo total por paciente, exámenes, búsqueda por cédula
- Panel flotante de chat en dashboard (botón robot azul)
- Búsqueda de tabla ahora filtra por cédula/documento
- Ícono de fila gira al expandir detalle (flecha → rotada)
- lab_configuracion.php: nueva sección IA con campo token Gemini
- save_config.php: permite guardar gemini_api_key

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 20:28:43 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 f738607738 feat: historial turnos — mostrar recepcionista, desk, bacteriólogo y exámenes
Columnas nuevas en tabla principal:
- Recepción: módulo de desk + nombre del recepcionista
- Lugar / Bacteriólogo: lugar destino + quien atendió toma de muestras
- Exámenes: badges con código de cada examen solicitado

Los datos ya venían del API (get_historial.php), solo se exponen en la tabla.
Se elimina columna Teléfono y Entrada de la vista principal (siguen en detalle).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 20:22:07 -05:00
Lizandro Guarnizo 5f4cf63924 Revert "fix: revertir anunciarTurno al codigo exacto de jun9 que funcionaba"
This reverts commit 266cd8301b.
2026-06-23 19:58:33 -05:00
Lizandro Guarnizo 266cd8301b fix: revertir anunciarTurno al codigo exacto de jun9 que funcionaba 2026-06-23 19:57:49 -05:00
Lizandro Guarnizo ee50a47933 fix: seleccionar voz española explícita en TTS del display_global 2026-06-23 19:55:40 -05:00
Lizandro Guarnizo 3810c898fd fix: restaurar playBeep original en display_global (revertir playBell) 2026-06-23 19:50:30 -05:00
Lizandro GuarnizoandClaude Opus 4.8 dfe3a01fee Recepción: vincular paciente atómicamente al crear token de firma
create_consent_token.php ahora acepta paciente_id y lo vincula al turno
si aún no lo tiene, eliminando la carrera con vincular_paciente.php
(fire-and-forget). Ya no hace falta refrescar para firmar el consentimiento.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 09:54:41 -05:00
Lizandro GuarnizoandClaude Opus 4.8 506f3469b4 Kiosko: auto-turno solo por escáner (ráfaga <35ms o Enter), nunca a mano
Escribir manualmente ya no dispara el turno: la persona oprime el botón.
El lector de cédula sí lo dispara porque mete los dígitos en ráfaga
(<35ms entre cada uno) o termina con Enter. Guard contra doble envío.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 09:51:58 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 a908d623e1 Kiosko: fix listener acumulado, añadir reset por inactividad 90s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 09:01:06 -05:00